fork(2) download
  1. #include <type_traits>
  2. #include <utility>
  3.  
  4. namespace ns_crap
  5. {
  6. struct Fruit;
  7. } // namespace ns_crap
  8.  
  9. template <int V, typename T, const ns_crap::Fruit& O>
  10. struct MapEntry
  11. {
  12. static constexpr int value = V;
  13. using type = T;
  14. static constexpr const ns_crap::Fruit& object = O;
  15. };
  16.  
  17. template <int> struct from_val;
  18. template <typename> struct from_type;
  19. template <const ns_crap::Fruit&> struct from_crap;
  20.  
  21. #define MAKE_MAP_ENTRY(value, type, object) \
  22.   template <> struct from_val<value> : MapEntry<value, type, object> {}; \
  23.   template <> struct from_type<type> : MapEntry<value, type, object> {}; \
  24.   template <> struct from_crap<object> : MapEntry<value, type, object> {};
  25.  
  26. namespace ns_val
  27. {
  28. const int APPLE = 0;
  29. const int PINEAPPLE = 1;
  30. const int PEAR = 2;
  31.  
  32. } // namespace ns_val
  33.  
  34. namespace ns_types
  35. {
  36. struct Apple {};
  37. struct Pineapple {};
  38. struct Pear {};
  39.  
  40. } // namespace ns_types
  41.  
  42. namespace ns_crap
  43. {
  44. struct Fruit
  45. {
  46. static const Fruit Apple;
  47. static const Fruit Pinapple;
  48. static const Fruit Pear;
  49. };
  50. const Fruit Fruit::Apple;
  51. const Fruit Fruit::Pinapple;
  52. const Fruit Fruit::Pear;
  53.  
  54. } // namespace ns_crap
  55.  
  56. MAKE_MAP_ENTRY(ns_val::APPLE, ns_types::Apple, ns_crap::Fruit::Apple)
  57. MAKE_MAP_ENTRY(ns_val::PINEAPPLE, ns_types::Pineapple, ns_crap::Fruit::Pinapple)
  58. MAKE_MAP_ENTRY(ns_val::PEAR, ns_types::Pear, ns_crap::Fruit::Pear)
  59.  
  60. // getting values
  61. static_assert(from_val<ns_val::APPLE>::value == ns_val::APPLE, "");
  62. static_assert(from_type<ns_types::Pineapple>::value == ns_val::PINEAPPLE, "");
  63. static_assert(from_crap<ns_crap::Fruit::Pear>::value == ns_val::PEAR, "");
  64.  
  65. // getting types
  66. static_assert(std::is_same<from_val<ns_val::APPLE>::type, ns_types::Apple>::value, "");
  67. static_assert(std::is_same<from_type<ns_types::Pineapple>::type, ns_types::Pineapple>::value, "");
  68. static_assert(std::is_same<from_crap<ns_crap::Fruit::Pear>::type, ns_types::Pear>::value, "");
  69.  
  70. // getting objects
  71. static_assert(&from_val<ns_val::APPLE>::object == &ns_crap::Fruit::Apple, "");
  72. static_assert(&from_type<ns_types::Pineapple>::object == &ns_crap::Fruit::Pinapple, "");
  73. static_assert(&from_crap<ns_crap::Fruit::Pear>::object == &ns_crap::Fruit::Pear, "");
  74.  
  75. int main()
  76. {
  77.  
  78. }
Success #stdin #stdout 0s 15232KB
stdin
Standard input is empty
stdout
Standard output is empty