|
@@ -1,15 +1,19 @@
|
|
|
|
|
+
|
|
|
|
|
+#pragma once
|
|
|
#include <vector>
|
|
#include <vector>
|
|
|
#include <cstdlib>
|
|
#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; }
|
|
|
|
|
-};
|
|
|
|
|
|
|
+#include <boost/preprocessor/seq/for_each.hpp>
|
|
|
|
|
+
|
|
|
|
|
+namespace data {
|
|
|
|
|
+ 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>
|
|
template <typename T, typename...Members>
|
|
|
class rotate;
|
|
class rotate;
|
|
@@ -22,10 +26,10 @@ public:
|
|
|
using value_type = typename Member::value_type;
|
|
using value_type = typename Member::value_type;
|
|
|
using data_type = std::vector<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); }
|
|
|
|
|
|
|
+ inline value_type& get(size_t n, Member) { return rotated_.at(n); }
|
|
|
|
|
+ inline value_type const& get(size_t n, Member) const { return rotated_.at(n); }
|
|
|
|
|
|
|
|
- data_type const& get(Member) const { return rotated_; }
|
|
|
|
|
|
|
+ inline data_type const& get(Member) const { return rotated_; }
|
|
|
|
|
|
|
|
protected:
|
|
protected:
|
|
|
void push_back(T const& t) {
|
|
void push_back(T const& t) {
|
|
@@ -40,8 +44,9 @@ template <typename T, typename Member0, typename...Members>
|
|
|
class rotate<T, Member0, Members...> : public rotate<T, Member0>, public rotate<T, Members...> {
|
|
class rotate<T, Member0, Members...> : public rotate<T, Member0>, public rotate<T, Members...> {
|
|
|
public:
|
|
public:
|
|
|
proxy<T, Member0, Members...> get(size_t n);
|
|
proxy<T, Member0, Members...> get(size_t n);
|
|
|
|
|
+ template <typename...Proxied> proxy<T, Proxied...> getp(size_t n);
|
|
|
|
|
|
|
|
- void push_back(T const& t) {
|
|
|
|
|
|
|
+ inline void push_back(T const& t) {
|
|
|
rotate<T, Member0>::push_back(t);
|
|
rotate<T, Member0>::push_back(t);
|
|
|
rotate<T, Members...>::push_back(t);
|
|
rotate<T, Members...>::push_back(t);
|
|
|
}
|
|
}
|
|
@@ -52,17 +57,29 @@ public:
|
|
|
|
|
|
|
|
#define PROXY_ELEMENT(T, elem) decltype(T::elem)& elem
|
|
#define PROXY_ELEMENT(T, elem) decltype(T::elem)& elem
|
|
|
#define PROXY_MEMBER(r, T, elem) PROXY_ELEMENT(T, 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_CONSTR(T, elem) BOOST_PP_CAT(PROXY_ELEMENT(T, elem),_)
|
|
|
|
|
+#define PROXY_CONSTR_J(r, T, elem) , PROXY_CONSTR(T, elem)
|
|
|
|
|
+#define PROXY_INIT(T, elem) elem(BOOST_PP_CAT(elem,_))
|
|
|
|
|
+#define PROXY_INIT_J(r, T, elem) , PROXY_INIT(T, elem)
|
|
|
#define PROXY_SET(r, t, elem) t.elem = elem;
|
|
#define PROXY_SET(r, t, elem) t.elem = elem;
|
|
|
|
|
+#define PROXY_RSET(r, t, elem) elem = t.elem;
|
|
|
|
|
|
|
|
-#define proxy_t(T, mseq) proxy<T BOOST_PP_SEQ_FOR_EACH(ROTATE_ACCESS, T, mseq)>
|
|
|
|
|
|
|
+#define proxy_t(T, mseq) proxy<T, rotate_members(T, mseq)>
|
|
|
|
|
|
|
|
#define ROTATE_PROXY(T, mseq) \
|
|
#define ROTATE_PROXY(T, mseq) \
|
|
|
template<> class proxy_t(T, mseq) { \
|
|
template<> class proxy_t(T, mseq) { \
|
|
|
public: \
|
|
public: \
|
|
|
- proxy(BOOST_PP_SEQ_FOR_EACH(PROXY_CONSTR, T, mseq) bool) \
|
|
|
|
|
- : BOOST_PP_SEQ_FOR_EACH(PROXY_INIT, T, mseq) dummy(false) {} \
|
|
|
|
|
|
|
+ proxy(PROXY_CONSTR(T, BOOST_PP_SEQ_HEAD(mseq)) \
|
|
|
|
|
+ BOOST_PP_SEQ_FOR_EACH(PROXY_CONSTR_J, T, BOOST_PP_SEQ_TAIL(mseq))) \
|
|
|
|
|
+ : PROXY_INIT(T, BOOST_PP_SEQ_HEAD(mseq)) \
|
|
|
|
|
+ BOOST_PP_SEQ_FOR_EACH(PROXY_INIT_J, T, BOOST_PP_SEQ_TAIL(mseq)) \
|
|
|
|
|
+ { \
|
|
|
|
|
+ } \
|
|
|
|
|
+ \
|
|
|
|
|
+ proxy & operator=( T const & obj ) { \
|
|
|
|
|
+ BOOST_PP_SEQ_FOR_EACH(PROXY_RSET, obj, mseq) \
|
|
|
|
|
+ return *this; \
|
|
|
|
|
+ } \
|
|
|
\
|
|
\
|
|
|
explicit operator T() const { \
|
|
explicit operator T() const { \
|
|
|
T t; \
|
|
T t; \
|
|
@@ -71,62 +88,57 @@ public:
|
|
|
} \
|
|
} \
|
|
|
\
|
|
\
|
|
|
BOOST_PP_SEQ_FOR_EACH(PROXY_MEMBER, T, mseq) \
|
|
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_ACCESS(T, elem) access_t(T, elem)
|
|
|
|
|
+#define ROTATE_ACCESS_J(r, T, elem) ,ROTATE_ACCESS(T, elem)
|
|
|
|
|
+#define PROXY_ASSIGN(T, elem) rotate<T, access_t(T, elem)>::get(n, access_t(T, elem)())
|
|
|
|
|
+#define PROXY_ASSIGN_J(r, T, elem) ,PROXY_ASSIGN(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 rotate_members(T, mseq) ROTATE_ACCESS(T, BOOST_PP_SEQ_HEAD(mseq)) \
|
|
|
|
|
+ BOOST_PP_SEQ_FOR_EACH(ROTATE_ACCESS_J, T, BOOST_PP_SEQ_TAIL(mseq))
|
|
|
|
|
+#define rotate_t(T, mseq) rotate<T, rotate_members(T, mseq)>
|
|
|
|
|
+#define access_t(T, M) data::access<T, decltype(T::M), &T::M>
|
|
|
|
|
|
|
|
//#define DEFINE_ROTATE_NAME(name, T, mseq) \
|
|
//#define DEFINE_ROTATE_NAME(name, T, mseq) \
|
|
|
-// using name = rotate_t(T, mseq); \
|
|
|
|
|
// ROTATE_PROXY(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}; \
|
|
|
|
|
|
|
+// class name : public rotate_t(T, mseq) { \
|
|
|
|
|
+// public:\
|
|
|
|
|
+// proxy_t(T, mseq) get(size_t n) { \
|
|
|
|
|
+// return proxy_t(T, mseq){ \
|
|
|
|
|
+// PROXY_ASSIGN(T, BOOST_PP_SEQ_HEAD(mseq)) \
|
|
|
|
|
+// BOOST_PP_SEQ_FOR_EACH(PROXY_ASSIGN_J, T, BOOST_PP_SEQ_TAIL(mseq)) \
|
|
|
|
|
+// }; \
|
|
|
|
|
+// } \
|
|
|
|
|
+// using rotate_t(T, mseq)::get; \
|
|
|
// }
|
|
// }
|
|
|
|
|
|
|
|
#define DEFINE_ROTATE_NAME(name, T, mseq) \
|
|
#define DEFINE_ROTATE_NAME(name, T, mseq) \
|
|
|
ROTATE_PROXY(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; \
|
|
|
|
|
|
|
+ using name##_proxy = proxy_t(T, mseq); \
|
|
|
|
|
+ template <> \
|
|
|
|
|
+ proxy_t(T, mseq) rotate_t(T, mseq)::get(size_t n) { \
|
|
|
|
|
+ return proxy_t(T, mseq){ \
|
|
|
|
|
+ PROXY_ASSIGN(T, BOOST_PP_SEQ_HEAD(mseq)) \
|
|
|
|
|
+ BOOST_PP_SEQ_FOR_EACH(PROXY_ASSIGN_J, T, BOOST_PP_SEQ_TAIL(mseq)) \
|
|
|
|
|
+ }; \
|
|
|
|
|
+ } \
|
|
|
|
|
+ using name = rotate_t(T, mseq)
|
|
|
|
|
+
|
|
|
|
|
+#define DEFINE_PROXY_NAME( name, T, mseq ) \
|
|
|
|
|
+ ROTATE_PROXY( T, mseq ); \
|
|
|
|
|
+ using name = proxy_t( T, mseq );
|
|
|
|
|
+
|
|
|
|
|
+#define DEFINE_PROXY_CONVERSION(T, mseq1, mseq2) \
|
|
|
|
|
+ template <> \
|
|
|
|
|
+ template <> \
|
|
|
|
|
+ proxy_t(T, mseq2) rotate_t(T, mseq1)::getp(size_t n) { \
|
|
|
|
|
+ return proxy_t(T, mseq2){ \
|
|
|
|
|
+ PROXY_ASSIGN(T, BOOST_PP_SEQ_HEAD(mseq2)) \
|
|
|
|
|
+ BOOST_PP_SEQ_FOR_EACH(PROXY_ASSIGN_J, T, BOOST_PP_SEQ_TAIL(mseq2)) \
|
|
|
|
|
+ }; \
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-#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;
|
|
|
|
|
-//}
|
|
|
|
|
|
|
+#define DEFINE_ROTATE(T, mseq) \
|
|
|
|
|
+ using T##_proxy = proxy_t(T, mseq); \
|
|
|
|
|
+ DEFINE_ROTATE_NAME(T##_rotate, T, mseq)
|