fork download
  1. #include <functional>
  2.  
  3.  
  4. #define CHECKABLE_TYPEDEF(Name) \
  5.   template <typename T> \
  6.   struct HasTypedef_##Name { \
  7.   typedef char yes[1]; \
  8.   typedef char no[2]; \
  9.   template <typename C> static yes& test(typename C::Name*); \
  10.   template <typename> static no& test(...); \
  11.   static const bool value = sizeof(test<T>(0)) == sizeof(yes);\
  12.   };
  13.  
  14.  
  15. #define HAS_TYPEDEF(Type, Name) HasTypedef_##Name<Type>::value
  16.  
  17. #define SELECTABLE_POLICY(NAME) \
  18.   template<class Traits, class Enable = void> \
  19.   struct Select##NAME { \
  20.   typedef Default##NAME<Traits> NAME; \
  21.   }; \
  22.   template<class Traits> \
  23.   struct Select##NAME<Traits, typename std::enable_if<HAS_TYPEDEF(Traits, NAME)>::type> { \
  24.   typedef typename Traits::NAME NAME; \
  25.   };
  26.  
  27.  
  28. #define SELECT_POLICY(NAME) Select##NAME<Traits>::NAME
  29.  
  30.  
  31. template<typename Traits> struct DefaultAllocator {};
  32. template<typename Traits> struct DefaultCleanup {};
  33.  
  34.  
  35. CHECKABLE_TYPEDEF(Allocator)
  36. CHECKABLE_TYPEDEF(Cleanup)
  37.  
  38.  
  39. SELECTABLE_POLICY(Allocator)
  40. SELECTABLE_POLICY(Cleanup)
  41.  
  42.  
  43. template<typename Traits>
  44. struct Vector : SELECT_POLICY(Allocator), SELECT_POLICY(Cleanup)
  45. {
  46. };
  47.  
  48.  
  49. struct MyTraits
  50. {
  51. struct Allocator {}; // custom allocator
  52.  
  53. // no custom clenaup
  54. };
  55.  
  56.  
  57. typedef Vector<MyTraits> MyVector;
  58.  
  59.  
  60. int main()
  61. {}
Success #stdin #stdout 0s 2924KB
stdin
Standard input is empty
stdout
Standard output is empty