#include<iostream>
#define Contains(NAME) \
template<typename T> \
struct Contains_##NAME \
{ \
typedef char (&yes)[2]; \
\
template<unsigned int> struct exists; \
template<typename V> static yes checkFunc (exists<sizeof(&V::NAME)>*); \
template<typename> static char checkFunc (...); \
\
static const bool value = (sizeof(checkFunc<T>(0)) == sizeof(yes)); \
}
#define ContainsType(NAME) \
template<typename T, typename Function> \
struct ContainsType_##NAME \
{ \
typedef char (&yes)[2]; \
\
template<unsigned int> struct exists; \
template<typename V> static yes checkFunc (exists<sizeof(static_cast<Function>(&V::NAME))>*); \
template<typename> static char checkFunc (...); \
\
static const bool value = (sizeof(checkFunc<T>(0)) == sizeof(yes)); \
}
struct X {
int begin () const;
};
struct Y {
int begin ();
int begin () const;
};
struct Z {
int begin ();
};
Contains(begin);
ContainsType(begin);
int main ()
{
std::cout << "Contains_begin<X>::value = " << Contains_begin<X>::value << "\n";
std::cout << "Contains_begin<Y>::value = " << Contains_begin<Y>::value << "\n";
std::cout << "Contains_begin<Z>::value = " << Contains_begin<Z>::value << "\n";
std::cout << "ContainsType_begin<X, int (X::*)()>::value = " << ContainsType_begin<X, int (X::*)() const>::value << "\n";
std::cout << "ContainsType_begin<Y, int (Y::*)()>::value = " << ContainsType_begin<Y, int (Y::*)() const>::value << "\n";
std::cout << "ContainsType_begin<Z, int (Z::*)()>::value = " << ContainsType_begin<Z, int (Z::*)() const>::value << "\n";
}
I2luY2x1ZGU8aW9zdHJlYW0+CgojZGVmaW5lIENvbnRhaW5zKE5BTUUpIFwKdGVtcGxhdGU8dHlwZW5hbWUgVD4gXApzdHJ1Y3QgQ29udGFpbnNfIyNOQU1FIFwKeyBcCiAgdHlwZWRlZiBjaGFyICgmeWVzKVsyXTsgXApcCiAgdGVtcGxhdGU8dW5zaWduZWQgaW50PiBzdHJ1Y3QgZXhpc3RzOyBcCiAgdGVtcGxhdGU8dHlwZW5hbWUgVj4gc3RhdGljIHllcyBjaGVja0Z1bmMgKGV4aXN0czxzaXplb2YoJlY6Ok5BTUUpPiopOyBcCiAgdGVtcGxhdGU8dHlwZW5hbWU+IHN0YXRpYyBjaGFyIGNoZWNrRnVuYyAoLi4uKTsgXApcCiAgc3RhdGljIGNvbnN0IGJvb2wgdmFsdWUgPSAoc2l6ZW9mKGNoZWNrRnVuYzxUPigwKSkgPT0gc2l6ZW9mKHllcykpOyBcCn0KCiNkZWZpbmUgQ29udGFpbnNUeXBlKE5BTUUpIFwKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgRnVuY3Rpb24+IFwKc3RydWN0IENvbnRhaW5zVHlwZV8jI05BTUUgXAp7IFwKICB0eXBlZGVmIGNoYXIgKCZ5ZXMpWzJdOyBcClwKICB0ZW1wbGF0ZTx1bnNpZ25lZCBpbnQ+IHN0cnVjdCBleGlzdHM7IFwKICB0ZW1wbGF0ZTx0eXBlbmFtZSBWPiBzdGF0aWMgeWVzIGNoZWNrRnVuYyAoZXhpc3RzPHNpemVvZihzdGF0aWNfY2FzdDxGdW5jdGlvbj4oJlY6Ok5BTUUpKT4qKTsgXAogIHRlbXBsYXRlPHR5cGVuYW1lPiBzdGF0aWMgY2hhciBjaGVja0Z1bmMgKC4uLik7IFwKXAogIHN0YXRpYyBjb25zdCBib29sIHZhbHVlID0gKHNpemVvZihjaGVja0Z1bmM8VD4oMCkpID09IHNpemVvZih5ZXMpKTsgXAp9CgpzdHJ1Y3QgWCB7IAogIGludCBiZWdpbiAoKSBjb25zdDsKfTsKCnN0cnVjdCBZIHsgCiAgaW50IGJlZ2luICgpOyAKICBpbnQgYmVnaW4gKCkgY29uc3Q7Cn07CnN0cnVjdCBaIHsKICBpbnQgYmVnaW4gKCk7Cn07CgpDb250YWlucyhiZWdpbik7CkNvbnRhaW5zVHlwZShiZWdpbik7CgppbnQgbWFpbiAoKQp7CiAgc3RkOjpjb3V0IDw8ICJDb250YWluc19iZWdpbjxYPjo6dmFsdWUgPSAiIDw8IENvbnRhaW5zX2JlZ2luPFg+Ojp2YWx1ZSA8PCAiXG4iOwogIHN0ZDo6Y291dCA8PCAiQ29udGFpbnNfYmVnaW48WT46OnZhbHVlID0gIiA8PCBDb250YWluc19iZWdpbjxZPjo6dmFsdWUgPDwgIlxuIjsKICBzdGQ6OmNvdXQgPDwgIkNvbnRhaW5zX2JlZ2luPFo+Ojp2YWx1ZSA9ICIgPDwgQ29udGFpbnNfYmVnaW48Wj46OnZhbHVlIDw8ICJcbiI7CgogIHN0ZDo6Y291dCA8PCAiQ29udGFpbnNUeXBlX2JlZ2luPFgsIGludCAoWDo6KikoKT46OnZhbHVlID0gIiA8PCBDb250YWluc1R5cGVfYmVnaW48WCwgaW50IChYOjoqKSgpIGNvbnN0Pjo6dmFsdWUgPDwgIlxuIjsKICBzdGQ6OmNvdXQgPDwgIkNvbnRhaW5zVHlwZV9iZWdpbjxZLCBpbnQgKFk6OiopKCk+Ojp2YWx1ZSA9ICIgPDwgQ29udGFpbnNUeXBlX2JlZ2luPFksIGludCAoWTo6KikoKSBjb25zdD46OnZhbHVlIDw8ICJcbiI7CiAgc3RkOjpjb3V0IDw8ICJDb250YWluc1R5cGVfYmVnaW48WiwgaW50IChaOjoqKSgpPjo6dmFsdWUgPSAiIDw8IENvbnRhaW5zVHlwZV9iZWdpbjxaLCBpbnQgKFo6OiopKCkgY29uc3Q+Ojp2YWx1ZSA8PCAiXG4iOwp9Cg==