1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
#pragma once
/**
* Detect members in a class. From: http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Member_Detector
*
* Usage:
* CREATE_DETECTOR(attribute)
* or
* CREATE_DETECTOR_MEMBER(suffix, member)
* where 'suffix' is used in the name of the detect-class, and "memeber" is checked for.
*
* detect_<attribute><T>::value -> true or false.
*/
#define CREATE_DETECTOR_MEMBER(suffix, member) \
template <class T> \
class detect_##suffix { \
struct Fallback { int member; }; \
struct Derived : T, Fallback {}; \
\
template <class U, U> struct Check; \
\
typedef char ArrayOfOne[1]; \
typedef char ArrayOfTwo[2]; \
\
template <class U> \
static ArrayOfOne &func(Check<int Fallback::*, &U::member> *); \
template <class U> \
static ArrayOfTwo &func(...); \
public: \
typedef detect_##suffix type; \
enum { value = sizeof(func<Derived>(0)) == sizeof(ArrayOfTwo) }; \
}; \
template <> \
class detect_##suffix<int> { \
public: \
enum { value = false }; \
}; \
template <> \
class detect_##suffix<nat> { \
public: \
enum { value = false }; \
}; \
template <> \
class detect_##suffix<byte> { \
public: \
enum { value = false }; \
}; \
template <> \
class detect_##suffix<char> { \
public: \
enum { value = false }; \
}; \
template <> \
class detect_##suffix<wchar_t> { \
public: \
enum { value = false }; \
}; \
template <> \
class detect_##suffix<bool> { \
public: \
enum { value = false }; \
}; \
template <> \
class detect_##suffix<void> { \
public: \
enum { value = false }; \
};
#define CREATE_DETECTOR(X) CREATE_DETECTOR_MEMBER(X, X)
|