#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <type_traits>
template <typename T>
class has_find {
template <typename C> static std::true_type test( decltype(&C::find) ) ;
template <typename C> static std::false_type test(...);
public:
using type = decltype(test<T>(nullptr));
static const bool value = type();
};
template <typename T>
int foo( const T & t ) { return 1; }
// overload for std::vector
template <class T>
int foo( const std::vector< T> & vec ) { return 2; }
template <class... T>
int foo( const std::map< T... > & vec ) { return 3; }
template<class...T>
int foo(const std::basic_string<T...>& str){ return 4; }
template <class... T>
int foo( const std::set< T... > & vec ) { return 5; }
template<class C>
bool contains(C const& c, typename C::value_type const& e){
return std::find(begin(c), end(c), e) != std::end(c);
}
template<template<class...> class C, class E, class ... Etc>
auto contains(C<E, Etc...> const& c, E const& e) -> decltype(c.find(e), true) {
return c.find(e) != std::end(c);
}
template<class E>
auto contains(std::basic_string<E> const& c, E const& e) -> bool {
return c.find(e) != std::string::npos;
}
template<class C, class E, class ... Es>
auto contains(C const& s, E const & e, Es...es) -> bool {
return contains(s, e) && contains(s, es...);
}
int main() {
std::map<int, std::string> m {{4,"test"}};
std::vector<int> v;
std::set<int> s {2,4,6,8};
int i{};
std::string str = "abcz";
std::cout << foo(i) << foo(v) << foo(m) << foo(str);
std::cout << contains(v, 4) << contains(m, 4) << contains(s, 2, 4, 6) << contains(str, 'z')
<< contains(str, 'z', 'a');
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWFwPgojaW5jbHVkZSA8c2V0PgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KY2xhc3MgaGFzX2ZpbmQgewogICAgdGVtcGxhdGUgPHR5cGVuYW1lIEM+IHN0YXRpYyBzdGQ6OnRydWVfdHlwZSB0ZXN0KCBkZWNsdHlwZSgmQzo6ZmluZCkgKSA7CiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQz4gc3RhdGljIHN0ZDo6ZmFsc2VfdHlwZSB0ZXN0KC4uLik7CnB1YmxpYzoKCXVzaW5nIHR5cGUgPSBkZWNsdHlwZSh0ZXN0PFQ+KG51bGxwdHIpKTsKICAgIHN0YXRpYyBjb25zdCBib29sIHZhbHVlID0gdHlwZSgpOwp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CmludCBmb28oIGNvbnN0IFQgJiB0ICkgeyByZXR1cm4gMTsgfQoKLy8gb3ZlcmxvYWQgZm9yIHN0ZDo6dmVjdG9yCnRlbXBsYXRlIDxjbGFzcyBUPgppbnQgZm9vKCBjb25zdCBzdGQ6OnZlY3RvcjwgVD4gJiB2ZWMgKSB7IHJldHVybiAyOyB9Cgp0ZW1wbGF0ZSA8Y2xhc3MuLi4gVD4KaW50IGZvbyggY29uc3Qgc3RkOjptYXA8IFQuLi4gPiAmIHZlYyApIHsgcmV0dXJuIDM7IH0KCnRlbXBsYXRlPGNsYXNzLi4uVD4KaW50IGZvbyhjb25zdCBzdGQ6OmJhc2ljX3N0cmluZzxULi4uPiYgc3RyKXsgcmV0dXJuIDQ7IH0KCnRlbXBsYXRlIDxjbGFzcy4uLiBUPgppbnQgZm9vKCBjb25zdCBzdGQ6OnNldDwgVC4uLiA+ICYgdmVjICkgeyByZXR1cm4gNTsgfQoKdGVtcGxhdGU8Y2xhc3MgQz4KYm9vbCBjb250YWlucyhDIGNvbnN0JiBjLCB0eXBlbmFtZSBDOjp2YWx1ZV90eXBlIGNvbnN0JiBlKXsKCXJldHVybiBzdGQ6OmZpbmQoYmVnaW4oYyksIGVuZChjKSwgZSkgIT0gc3RkOjplbmQoYyk7Cn0KCnRlbXBsYXRlPHRlbXBsYXRlPGNsYXNzLi4uPiBjbGFzcyBDLCBjbGFzcyBFLCBjbGFzcyAuLi4gRXRjPgphdXRvIGNvbnRhaW5zKEM8RSwgRXRjLi4uPiBjb25zdCYgYywgRSBjb25zdCYgZSkgLT4gZGVjbHR5cGUoYy5maW5kKGUpLCB0cnVlKSB7CglyZXR1cm4gYy5maW5kKGUpICE9IHN0ZDo6ZW5kKGMpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBFPgphdXRvIGNvbnRhaW5zKHN0ZDo6YmFzaWNfc3RyaW5nPEU+IGNvbnN0JiBjLCBFIGNvbnN0JiBlKSAtPiBib29sIHsKCXJldHVybiBjLmZpbmQoZSkgIT0gc3RkOjpzdHJpbmc6Om5wb3M7Cn0KCnRlbXBsYXRlPGNsYXNzIEMsIGNsYXNzIEUsIGNsYXNzIC4uLiBFcz4KYXV0byBjb250YWlucyhDIGNvbnN0JiBzLCBFIGNvbnN0ICYgZSwgRXMuLi5lcykgLT4gYm9vbCB7CglyZXR1cm4gY29udGFpbnMocywgZSkgJiYgY29udGFpbnMocywgZXMuLi4pOwp9CgppbnQgbWFpbigpIHsKCXN0ZDo6bWFwPGludCwgc3RkOjpzdHJpbmc+IG0ge3s0LCJ0ZXN0In19OwoJc3RkOjp2ZWN0b3I8aW50PiB2OwoJc3RkOjpzZXQ8aW50PiBzIHsyLDQsNiw4fTsKCWludCBpe307CglzdGQ6OnN0cmluZyBzdHIgPSAiYWJjeiI7CglzdGQ6OmNvdXQgPDwgZm9vKGkpIDw8IGZvbyh2KSA8PCBmb28obSkgPDwgZm9vKHN0cik7CglzdGQ6OmNvdXQgPDwgY29udGFpbnModiwgNCkgPDwgY29udGFpbnMobSwgNCkgPDwgY29udGFpbnMocywgMiwgNCwgNikgPDwgY29udGFpbnMoc3RyLCAneicpCgk8PCBjb250YWlucyhzdHIsICd6JywgJ2EnKTsKfQo=