#include <functional>
#define CHECKABLE_TYPEDEF(Name) \
template <typename T> \
struct HasTypedef_##Name { \
typedef char yes[1]; \
typedef char no[2]; \
template <typename C> static yes& test(typename C::Name*); \
template <typename> static no& test(...); \
static const bool value = sizeof(test<T>(0)) == sizeof(yes);\
};
#define HAS_TYPEDEF(Type, Name) HasTypedef_##Name<Type>::value
#define SELECTABLE_POLICY(NAME) \
template<class Traits, class Enable = void> \
struct Select##NAME { \
typedef Default##NAME<Traits> NAME; \
}; \
template<class Traits> \
struct Select##NAME<Traits, typename std::enable_if<HAS_TYPEDEF(Traits, NAME)>::type> { \
typedef typename Traits::NAME NAME; \
};
#define SELECT_POLICY(NAME) Select##NAME<Traits>::NAME
template<typename Traits> struct DefaultAllocator {};
template<typename Traits> struct DefaultCleanup {};
CHECKABLE_TYPEDEF(Allocator)
CHECKABLE_TYPEDEF(Cleanup)
SELECTABLE_POLICY(Allocator)
SELECTABLE_POLICY(Cleanup)
template<typename Traits>
struct Vector : SELECT_POLICY(Allocator), SELECT_POLICY(Cleanup)
{
};
struct MyTraits
{
struct Allocator {}; // custom allocator
// no custom clenaup
};
typedef Vector<MyTraits> MyVector;
int main()
{}