| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- #include <vector>
- #include <cstdlib>
- #include <boost/preprocessor.hpp>
- template <typename T, typename I, I T::*mem>
- 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 <typename T, typename...Members>
- class rotate;
- template <typename T, typename...Members> class proxy;
- template <typename T, typename Member>
- class rotate<T, Member> {
- public:
- using value_type = typename Member::value_type;
- using data_type = std::vector<value_type>;
-
- 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 <typename T, typename Member0, typename...Members>
- class rotate<T, Member0, Members...> : public rotate<T, Member0>, public rotate<T, Members...> {
- public:
- proxy<T, Member0, Members...> get(size_t n);
- void push_back(T const& t) {
- rotate<T, Member0>::push_back(t);
- rotate<T, Members...>::push_back(t);
- }
-
- using rotate<T, Member0>::get;
- using rotate<T, Members...>::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<T BOOST_PP_SEQ_FOR_EACH(ROTATE_ACCESS, T, mseq)>
- #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<T, access_t(T, elem)>::get(n, access_t(T, elem)()),
- #define rotate_t(T, mseq) rotate<T BOOST_PP_SEQ_FOR_EACH(ROTATE_ACCESS, T, mseq)>
- #define access_t(T, M) access<T, decltype(T::M), &T::M>
- //#define DEFINE_ROTATE_NAME(name, T, mseq) \
- // using name = rotate_t(T, mseq); \
- // ROTATE_PROXY(T, mseq); \
- // template <typename T, typename M0, typename...Ms> \
- // proxy<T, M0, Ms...> rotate<T, M0, Ms...>::get(size_t n) { \
- // return proxy<T, M0, Ms...>{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 <iostream>
- //
- //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<particle> pp = pr.get(0);
- // pp.x = 5;
- // }
- //
- // {
- // proxy<particle> pp = pr.get(0);
- // std::cout << pp.x << std::endl;
- // particle copy = particle(pp);
- // std::cout << copy.x << std::endl;
- // }
- //
- // return 0;
- //}
|