#include <iostream>
#include <type_traits>
#include <vector>
#include <iostream>
#include <set>
template<typename T, typename Iterator, typename=void>
struct is_iterator_of_type: std::false_type {};
template<typename T, typename Iterator>
struct is_iterator_of_type<
T,
Iterator,
typename std::enable_if<
std::is_same<
T,
typename std::iterator_traits< Iterator >::value_type
>::value
>::type
>: std::true_type {};
void test1() {
std::cout << is_iterator_of_type<int, std::vector<int>::iterator>::value << "\n";
}
template<typename T, typename Container>
auto foo(Container const&) -> typename std::enable_if< is_iterator_of_type<T, typename Container::iterator>::value >::type
{
std::cout << "Container of int\n";
}
template<typename T>
void foo(...)
{
std::cout << "No match\n";
}
void test2() {
std::vector<int> test;
foo<int>(test);
foo<int>(test.begin());
foo<int>(std::set<int>());
}
template<typename Container>
auto operator<<( std::ostream& stream, Container const& c ) ->
typename std::enable_if< is_iterator_of_type<int, typename Container::iterator>::value, std::ostream& >::type
{
stream << "int container\n";
}
void test3() {
std::vector<int> test;
std::cout << test;
std::set<int> bar;
std::cout << bar;
}
template<typename Container>
auto operator<<( std::ostream& stream, Container const& c ) ->
typename std::enable_if< is_iterator_of_type<double, typename Container::iterator>::value, std::ostream& >::type
{
stream << "double container\n";
}
void test4() {
std::vector<int> test;
std::cout << test;
std::set<int> bar;
std::cout << bar;
std::vector<double> dtest;
std::cout << dtest;
}
void test5() {
std::vector<bool> test;
// does not compile (naturall):
// std::cout << test;
}
template<typename Container>
auto operator<<( std::ostream& stream, Container const& c ) ->
typename std::enable_if< is_iterator_of_type<bool, typename Container::iterator>::value, std::ostream& >::type
{
stream << "bool container\n";
}
void test6() {
std::vector<bool> test;
// now compiles:
std::cout << test;
}
int main() {
test1();
test2();
test3();
test4();
test5();
test6();
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHNldD4KCnRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEl0ZXJhdG9yLCB0eXBlbmFtZT12b2lkPgpzdHJ1Y3QgaXNfaXRlcmF0b3Jfb2ZfdHlwZTogc3RkOjpmYWxzZV90eXBlIHt9OwoKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgSXRlcmF0b3I+CnN0cnVjdCBpc19pdGVyYXRvcl9vZl90eXBlPAogICAgVCwKCUl0ZXJhdG9yLAoJdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8CgkJc3RkOjppc19zYW1lPAoJCQlULAoJCQl0eXBlbmFtZSBzdGQ6Oml0ZXJhdG9yX3RyYWl0czwgSXRlcmF0b3IgPjo6dmFsdWVfdHlwZQoJCT46OnZhbHVlCgk+Ojp0eXBlCj46IHN0ZDo6dHJ1ZV90eXBlIHt9OwoKdm9pZCB0ZXN0MSgpIHsKICBzdGQ6OmNvdXQgPDwgaXNfaXRlcmF0b3Jfb2ZfdHlwZTxpbnQsIHN0ZDo6dmVjdG9yPGludD46Oml0ZXJhdG9yPjo6dmFsdWUgPDwgIlxuIjsKfQp0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSBDb250YWluZXI+CmF1dG8gZm9vKENvbnRhaW5lciBjb25zdCYpIC0+IHR5cGVuYW1lIHN0ZDo6ZW5hYmxlX2lmPCBpc19pdGVyYXRvcl9vZl90eXBlPFQsIHR5cGVuYW1lIENvbnRhaW5lcjo6aXRlcmF0b3I+Ojp2YWx1ZSA+Ojp0eXBlCnsKCXN0ZDo6Y291dCA8PCAiQ29udGFpbmVyIG9mIGludFxuIjsKfQp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgp2b2lkIGZvbyguLi4pCnsKCXN0ZDo6Y291dCA8PCAiTm8gbWF0Y2hcbiI7Cn0Kdm9pZCB0ZXN0MigpIHsKICBzdGQ6OnZlY3RvcjxpbnQ+IHRlc3Q7Cglmb288aW50Pih0ZXN0KTsKCWZvbzxpbnQ+KHRlc3QuYmVnaW4oKSk7Cglmb288aW50PihzdGQ6OnNldDxpbnQ+KCkpOwp9CnRlbXBsYXRlPHR5cGVuYW1lIENvbnRhaW5lcj4KYXV0byBvcGVyYXRvcjw8KCBzdGQ6Om9zdHJlYW0mIHN0cmVhbSwgQ29udGFpbmVyIGNvbnN0JiBjICkgLT4KCXR5cGVuYW1lIHN0ZDo6ZW5hYmxlX2lmPCBpc19pdGVyYXRvcl9vZl90eXBlPGludCwgdHlwZW5hbWUgQ29udGFpbmVyOjppdGVyYXRvcj46OnZhbHVlLCBzdGQ6Om9zdHJlYW0mID46OnR5cGUKewoJc3RyZWFtIDw8ICJpbnQgY29udGFpbmVyXG4iOwp9CnZvaWQgdGVzdDMoKSB7CglzdGQ6OnZlY3RvcjxpbnQ+IHRlc3Q7CglzdGQ6OmNvdXQgPDwgdGVzdDsKCXN0ZDo6c2V0PGludD4gYmFyOwoJc3RkOjpjb3V0IDw8IGJhcjsKfQp0ZW1wbGF0ZTx0eXBlbmFtZSBDb250YWluZXI+CmF1dG8gb3BlcmF0b3I8PCggc3RkOjpvc3RyZWFtJiBzdHJlYW0sIENvbnRhaW5lciBjb25zdCYgYyApIC0+Cgl0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjwgaXNfaXRlcmF0b3Jfb2ZfdHlwZTxkb3VibGUsIHR5cGVuYW1lIENvbnRhaW5lcjo6aXRlcmF0b3I+Ojp2YWx1ZSwgc3RkOjpvc3RyZWFtJiA+Ojp0eXBlCnsKCXN0cmVhbSA8PCAiZG91YmxlIGNvbnRhaW5lclxuIjsKfQp2b2lkIHRlc3Q0KCkgewoJc3RkOjp2ZWN0b3I8aW50PiB0ZXN0OwoJc3RkOjpjb3V0IDw8IHRlc3Q7CglzdGQ6OnNldDxpbnQ+IGJhcjsKCXN0ZDo6Y291dCA8PCBiYXI7CglzdGQ6OnZlY3Rvcjxkb3VibGU+IGR0ZXN0OwoJc3RkOjpjb3V0IDw8IGR0ZXN0Owp9CnZvaWQgdGVzdDUoKSB7CglzdGQ6OnZlY3Rvcjxib29sPiB0ZXN0OwoJLy8gZG9lcyBub3QgY29tcGlsZSAobmF0dXJhbGwpOgoJLy8gc3RkOjpjb3V0IDw8IHRlc3Q7Cn0KdGVtcGxhdGU8dHlwZW5hbWUgQ29udGFpbmVyPgphdXRvIG9wZXJhdG9yPDwoIHN0ZDo6b3N0cmVhbSYgc3RyZWFtLCBDb250YWluZXIgY29uc3QmIGMgKSAtPgoJdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8IGlzX2l0ZXJhdG9yX29mX3R5cGU8Ym9vbCwgdHlwZW5hbWUgQ29udGFpbmVyOjppdGVyYXRvcj46OnZhbHVlLCBzdGQ6Om9zdHJlYW0mID46OnR5cGUKewoJc3RyZWFtIDw8ICJib29sIGNvbnRhaW5lclxuIjsKfQp2b2lkIHRlc3Q2KCkgewoJc3RkOjp2ZWN0b3I8Ym9vbD4gdGVzdDsKCS8vIG5vdyBjb21waWxlczoKCXN0ZDo6Y291dCA8PCB0ZXN0Owp9CmludCBtYWluKCkgewoJdGVzdDEoKTsKCXRlc3QyKCk7Cgl0ZXN0MygpOwoJdGVzdDQoKTsKCXRlc3Q1KCk7Cgl0ZXN0NigpOwp9Cgo=