#include #include #include template struct access { using value_type = I; using access_type = T; value_type& get(access_type& t) const { return t.*mem; } value_type const& get(access_type const& t) const { return t.*mem; } }; template class rotate; template class proxy; template class rotate { public: using value_type = typename Member::value_type; using data_type = std::vector; value_type& get(size_t n, Member) { return rotated_.at(n); } value_type const& get(size_t n, Member) const { return rotated_.at(n); } data_type const& get(Member) const { return rotated_; } protected: void push_back(T const& t) { rotated_.push_back(Member().get(t)); } private: data_type rotated_; }; template class rotate : public rotate, public rotate { public: proxy get(size_t n); void push_back(T const& t) { rotate::push_back(t); rotate::push_back(t); } using rotate::get; using rotate::get; }; #define PROXY_ELEMENT(T, elem) decltype(T::elem)& elem #define PROXY_MEMBER(r, T, elem) PROXY_ELEMENT(T, elem); #define PROXY_CONSTR(r, T, elem) BOOST_PP_CAT(PROXY_ELEMENT(T, elem),_), #define PROXY_INIT(r, T, elem) elem(BOOST_PP_CAT(elem,_)), #define PROXY_SET(r, t, elem) t.elem = elem; #define proxy_t(T, mseq) proxy #define ROTATE_PROXY(T, mseq) \ template<> class proxy_t(T, mseq) { \ public: \ proxy(BOOST_PP_SEQ_FOR_EACH(PROXY_CONSTR, T, mseq) bool) \ : BOOST_PP_SEQ_FOR_EACH(PROXY_INIT, T, mseq) dummy(false) {} \ \ explicit operator T() const { \ T t; \ BOOST_PP_SEQ_FOR_EACH(PROXY_SET, t, mseq) \ return t; \ } \ \ BOOST_PP_SEQ_FOR_EACH(PROXY_MEMBER, T, mseq) \ bool dummy; \ } #define ROTATE_ACCESS(r, T, elem) ,access_t(T, elem) #define PROXY_ASSIGN(r, T, elem) rotate::get(n, access_t(T, elem)()), #define rotate_t(T, mseq) rotate #define access_t(T, M) access //#define DEFINE_ROTATE_NAME(name, T, mseq) \ // using name = rotate_t(T, mseq); \ // ROTATE_PROXY(T, mseq); \ // template \ // proxy rotate::get(size_t n) { \ // return proxy{BOOST_PP_SEQ_FOR_EACH(PROXY_ASSIGN, T, mseq) false}; \ // } #define DEFINE_ROTATE_NAME(name, T, mseq) \ ROTATE_PROXY(T, mseq); \ class name : public rotate_t(T, mseq) { \ public:\ proxy_t(T, mseq) get(size_t n) { \ return proxy_t(T, mseq){BOOST_PP_SEQ_FOR_EACH(PROXY_ASSIGN, T, mseq) false}; \ } \ using rotate_t(T, mseq)::get; \ } #define DEFINE_ROTATE(T, mseq) DEFINE_ROTATE_NAME(T##_rotate, T, mseq) //#include // //struct particle { // int x, y, dx, dy; // char color; //}; // //DEFINE_ROTATE(particle, (color)(x)(y)(dx)(dy)) // //int main(int argc, char const *argv[]) { // (void) argc; // (void) argv; // particle p{0, 0, 0, 0, 0}; // particle_rotate pr; // pr.push_back(p); // // { // proxy pp = pr.get(0); // pp.x = 5; // } // // { // proxy pp = pr.get(0); // std::cout << pp.x << std::endl; // particle copy = particle(pp); // std::cout << copy.x << std::endl; // } // // return 0; //}