fork download
  1. #include <iostream>
  2. #include <string>
  3.  
  4. namespace memenum
  5. {
  6. template <int Counter>
  7. struct member_iterator : member_iterator<Counter - 1> { static int const value = Counter; };
  8. template <>
  9. struct member_iterator<0> { static int const value = 0; };
  10.  
  11. template <class This, class Op>
  12. void call_for_members(This*, member_iterator<__COUNTER__>, Op const&) { }
  13.  
  14. template <class T>
  15. struct member_wrapper
  16. {
  17. T value;
  18. member_wrapper(T const &v) : value(v) { }
  19. };
  20.  
  21. #define DEFINE_MEMBER(type, memname, ...) \
  22. struct _##memname##_type : ::memenum::member_wrapper<type> \
  23. { \
  24. static int const counter = __COUNTER__; \
  25. _##memname##_type() : ::memenum::member_wrapper<type>(__VA_ARGS__) { } \
  26. char const* name() const { return #memname; } \
  27. } memname; \
  28. template <class This, class Op> \
  29. friend void call_for_members(This *self, ::memenum::member_iterator<_##memname##_type::counter> i, Op const &op, typename This::_##memname##_type* = nullptr) \
  30. { \
  31. call_for_members(self, ::memenum::member_iterator<_##memname##_type::counter - 1>(), op); \
  32. op(self->memname); \
  33. }
  34.  
  35. #define MAKE_MEMBER_ITERATOR() ::memenum::member_iterator<__COUNTER__>()
  36.  
  37. } // namespace
  38.  
  39. namespace test
  40. {
  41.  
  42. struct foo
  43. {
  44. DEFINE_MEMBER(int, a, 2);
  45. DEFINE_MEMBER(float, b, 2.5f);
  46.  
  47. public:
  48. struct Printer
  49. {
  50. template <class T>
  51. void operator ()(T &member) const
  52. {
  53. std::cout << member.name() << " = " << member.value << std::endl;
  54. }
  55. };
  56. void print() const
  57. {
  58. call_for_members(this, MAKE_MEMBER_ITERATOR(), Printer());
  59. }
  60.  
  61. struct Multiplier
  62. {
  63. int factor;
  64.  
  65. template <class T>
  66. void operator ()(T &member) const
  67. {
  68. member.value *= factor;
  69. }
  70. };
  71.  
  72. void multiply(int factor)
  73. {
  74. Multiplier multi = { factor };
  75. call_for_members(this, MAKE_MEMBER_ITERATOR(), multi);
  76. }
  77. };
  78.  
  79. struct bar
  80. {
  81. DEFINE_MEMBER(char, c, 'd');
  82. DEFINE_MEMBER(std::string, d, "hello world");
  83.  
  84. public:
  85. struct Printer
  86. {
  87. template <class T>
  88. void operator ()(T &member) const
  89. {
  90. std::cout << member.name() << " = " << member.value << std::endl;
  91. }
  92. };
  93. void print() const
  94. {
  95. call_for_members(this, MAKE_MEMBER_ITERATOR(), Printer());
  96. }
  97. };
  98.  
  99. } // namespace
  100.  
  101. int main()
  102. {
  103. test::foo test1;
  104. test1.print();
  105. test1.multiply(5);
  106. test1.print();
  107.  
  108. const test::bar test2;
  109. test2.print();
  110. }
  111.  
Success #stdin #stdout 0s 3028KB
stdin
Standard input is empty
stdout
a = 2
b = 2.5
a = 10
b = 12.5
c = d
d = hello world