fork download
  1. #include <iostream>
  2. #include <iterator>
  3.  
  4. struct Foo;
  5.  
  6. template<typename Type>
  7. struct MemberPtrBase {
  8. virtual ~MemberPtrBase() { }
  9.  
  10. virtual Type get() const = 0;
  11. virtual MemberPtrBase & set(Type const &) = 0;
  12. };
  13.  
  14. template<typename Class, typename RealType, typename CommonType>
  15. struct MemberPtr : MemberPtrBase<CommonType> {
  16. public:
  17. MemberPtr(Class * object, RealType(Class::*member))
  18. : m_object(object), m_ptr(member)
  19. { }
  20.  
  21. CommonType get() const {
  22. return m_object->*m_ptr;
  23. }
  24.  
  25. MemberPtr & set(CommonType const & val) {
  26. m_object->*m_ptr = val;
  27. return *this;
  28. }
  29.  
  30. MemberPtr & operator=(RealType const & val) {
  31. return set(val);
  32. }
  33.  
  34. operator CommonType() const {
  35. return get();
  36. }
  37. private:
  38. Class * m_object;
  39. RealType (Class::*m_ptr);
  40. };
  41.  
  42. template<typename Class, typename... Types>
  43. struct MemberIterator {
  44. public:
  45. using CommonType = typename std::common_type<Types...>::type;
  46. public:
  47. MemberIterator(Class & obj, std::size_t idx, Types(Class::*...member))
  48. : m_object(obj), m_index(idx), m_members { new MemberPtr<Class, Types, CommonType>(&obj, member)... }
  49. { }
  50.  
  51. MemberPtrBase<CommonType> & operator*() const {
  52. return *m_members[m_index];
  53. }
  54.  
  55. bool operator==(MemberIterator const & it) const {
  56. return (&m_object == &it.m_object) && (m_index == it.m_index);
  57. }
  58.  
  59. bool operator!=(MemberIterator const & it) const {
  60. return (&m_object != &it.m_object) || (m_index != it.m_index);
  61. }
  62.  
  63. MemberIterator & operator++() {
  64. ++m_index;
  65. return *this;
  66. }
  67. private:
  68. Class & m_object;
  69. std::size_t m_index;
  70. MemberPtrBase<CommonType> * m_members[sizeof...(Types)];
  71. };
  72.  
  73. struct Foo {
  74. public:
  75. using iterator = MemberIterator<Foo, int, int, int, int>;
  76. public:
  77. Foo(int a, int b, int c, int d)
  78. : m_a(a), m_b(b), m_c(c), m_d(d)
  79. { }
  80.  
  81. iterator begin() {
  82. return iterator(*this, 0, &Foo::m_b, &Foo::m_d, &Foo::m_c, &Foo::m_a);
  83. }
  84.  
  85. iterator end() {
  86. return iterator(*this, 4, &Foo::m_b, &Foo::m_d, &Foo::m_c, &Foo::m_a);
  87. }
  88. private:
  89. int m_a, m_b, m_c, m_d;
  90. };
  91.  
  92. int main(int argc, char ** argv) {
  93. Foo foo { 1, 2, 3, 4 };
  94.  
  95. for(auto & mem : foo) {
  96. std::cout << mem.get() << std::endl;
  97. mem.set(3);
  98. }
  99.  
  100. for(auto & mem : foo) {
  101. std::cout << mem.get() << std::endl;
  102. }
  103. }
Success #stdin #stdout 0s 3472KB
stdin
Standard input is empty
stdout
2
4
3
1
3
3
3
3