fork(5) download
  1. #include <iostream>
  2. #include <tuple>
  3. using namespace std;
  4.  
  5. template<
  6. typename Callable,
  7. typename Tuple,
  8. size_t... Indexes
  9. >
  10. constexpr void tuple_for_each(Tuple&& t, Callable&& f, std::index_sequence<Indexes...>)
  11. {
  12. // ideone only has C++14 :(
  13. int _[] = {(f(std::get<Indexes>(t)),0)...};
  14. }
  15.  
  16. template<
  17. typename Callable,
  18. typename... Args,
  19. template<typename...> typename Tuple,
  20. typename Is = std::make_index_sequence<sizeof...(Args)>
  21. >
  22. constexpr void tuple_for_each(Tuple<Args...>&& t, Callable&& f)
  23. {
  24. tuple_for_each(t, f, Is{});
  25. }
  26.  
  27. template<typename T>
  28. struct ReflectionLayout
  29. {
  30. static constexpr auto GetLayout()
  31. {
  32. return std::make_tuple(
  33. std::make_tuple(
  34. "#Unknown", "Unknown"
  35. )
  36. );
  37. }
  38. };
  39.  
  40. template<typename T>
  41. struct Reflection
  42. {
  43. static constexpr bool has_reflection_info = false;
  44. static constexpr char const* name{ "Unknown" };
  45. static constexpr auto layout() { return ReflectionLayout<T>::GetLayout(); }
  46. static constexpr bool is_complex{ false };
  47. };
  48.  
  49. #define REGISTER_REFLECTION_INFO(Class) \
  50. template<> \
  51. struct Reflection<Class> \
  52. { \
  53. static constexpr bool has_reflection_info = true; \
  54. static constexpr char const* name{ #Class }; \
  55. static constexpr auto layout() { return ReflectionLayout<Class>::GetLayout(); } \
  56. static constexpr bool is_complex{ true }; \
  57. };
  58.  
  59. #define REGISTER_REFLECTION_LAYOUT(Class) \
  60. template<> \
  61. struct ReflectionLayout<Class> \
  62. { \
  63. using Type = Class; \
  64. static constexpr auto GetLayout() \
  65. { \
  66. return std::make_tuple(
  67.  
  68. #define MEMBER(Name) std::make_tuple(#Name, &Type::Name)
  69.  
  70. #define END_REFLECTION_LAYOUT(Class) \
  71. ); \
  72. } \
  73. }; \
  74. REGISTER_REFLECTION_INFO(Class)
  75.  
  76. struct namedValue
  77. {
  78. string name;
  79. int x;
  80. };
  81. REGISTER_REFLECTION_LAYOUT(namedValue)
  82. MEMBER(name),
  83. MEMBER(x)
  84. END_REFLECTION_LAYOUT(namedValue)
  85.  
  86. template<typename T>
  87. void printInfo(T val)
  88. {
  89. tuple_for_each(Reflection<T>::layout(),[&](auto&& x) {
  90. // auto [] is C++17, so we have to do this instead
  91. auto& name = get<0>(x);
  92. auto& ptr = get<1>(x);
  93. cout << name << ": " << val.*ptr << endl;
  94. });
  95. }
  96.  
  97. int main() {
  98. printInfo(namedValue{"numEggs", 37});
  99. return 0;
  100. }
Success #stdin #stdout 0s 4356KB
stdin
Standard input is empty
stdout
name: numEggs
x: 37