#include <iostream>
#include <type_traits>
#include <vector>
#include <algorithm>
using namespace std;
template<class T> struct container {
vector<T> ts;
template<class F> auto contains(F&& f) const ->
typename enable_if< is_convertible< decltype(f(declval<T>())), bool >::value, bool >::type
{
cout << "predicate\n";
return find_if(begin(ts), end(ts), f) != end(ts);
}
template<class V> auto contains(V&& v) const ->
typename enable_if< is_convertible< decltype(declval<T>() == v), bool >::value, bool >::type
{
cout << "match\n";
return find(begin(ts), end(ts), v) != end(ts);
}
};
struct XZ { void xz() {} };
typedef void(XZ::*unspecified_bool)();
unspecified_bool unspec(bool v) { return v ? &XZ::xz : (unspecified_bool)0; }
struct ONE {};
unspecified_bool operator == (int x, ONE y) {
cout << "compare " << x << " to ONE...\n";
return unspec(x == 1);
}
int main() {
container<int> d { {0, 3, 1, 2} };
cout << d.contains([](double x) {
cout << "examine " << x << "...\n";
return unspec(x==1); })
<< endl;
cout << d.contains(ONE()) << endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxhbGdvcml0aG0+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0ZW1wbGF0ZTxjbGFzcyBUPiBzdHJ1Y3QgY29udGFpbmVyIHsKCXZlY3RvcjxUPiB0czsKCXRlbXBsYXRlPGNsYXNzIEY+IGF1dG8gY29udGFpbnMoRiYmIGYpIGNvbnN0IC0+CgkJdHlwZW5hbWUgZW5hYmxlX2lmPCBpc19jb252ZXJ0aWJsZTwgZGVjbHR5cGUoZihkZWNsdmFsPFQ+KCkpKSwgYm9vbCA+Ojp2YWx1ZSwgYm9vbCA+Ojp0eXBlCgl7CgkJY291dCA8PCAicHJlZGljYXRlXG4iOwoJCXJldHVybiBmaW5kX2lmKGJlZ2luKHRzKSwgZW5kKHRzKSwgZikgIT0gZW5kKHRzKTsKCX0KCXRlbXBsYXRlPGNsYXNzIFY+IGF1dG8gY29udGFpbnMoViYmIHYpIGNvbnN0IC0+CgkJdHlwZW5hbWUgZW5hYmxlX2lmPCBpc19jb252ZXJ0aWJsZTwgZGVjbHR5cGUoZGVjbHZhbDxUPigpID09IHYpLCBib29sID46OnZhbHVlLCBib29sID46OnR5cGUKCXsKCQljb3V0IDw8ICJtYXRjaFxuIjsKCQlyZXR1cm4gZmluZChiZWdpbih0cyksIGVuZCh0cyksIHYpICE9IGVuZCh0cyk7Cgl9Cn07CgpzdHJ1Y3QgWFogeyB2b2lkIHh6KCkge30gfTsKdHlwZWRlZiB2b2lkKFhaOjoqdW5zcGVjaWZpZWRfYm9vbCkoKTsKCnVuc3BlY2lmaWVkX2Jvb2wgdW5zcGVjKGJvb2wgdikgeyByZXR1cm4gdiA/ICZYWjo6eHogOiAodW5zcGVjaWZpZWRfYm9vbCkwOyB9CgpzdHJ1Y3QgT05FIHt9Owp1bnNwZWNpZmllZF9ib29sIG9wZXJhdG9yID09IChpbnQgeCwgT05FIHkpIHsKCWNvdXQgPDwgImNvbXBhcmUgIiA8PCB4IDw8ICIgdG8gT05FLi4uXG4iOwoJcmV0dXJuIHVuc3BlYyh4ID09IDEpOwp9CgoKaW50IG1haW4oKSB7Cgljb250YWluZXI8aW50PiBkIHsgezAsIDMsIDEsIDJ9IH07Cgljb3V0IDw8IGQuY29udGFpbnMoW10oZG91YmxlIHgpIHsKCQljb3V0IDw8ICJleGFtaW5lICIgPDwgeCA8PCAiLi4uXG4iOwoJCXJldHVybiB1bnNwZWMoeD09MSk7IH0pCgk8PCBlbmRsOwoJY291dCA8PCBkLmNvbnRhaW5zKE9ORSgpKSA8PCBlbmRsOwp9Cg==