adapt_base.hpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /*=============================================================================
  2. Copyright (c) 2001-2009 Joel de Guzman
  3. Copyright (c) 2005-2006 Dan Marsden
  4. Copyright (c) 2010 Christopher Schmidt
  5. Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. ==============================================================================*/
  8. #ifndef BOOST_FUSION_ADAPTED_ADT_DETAIL_ADAPT_BASE_HPP
  9. #define BOOST_FUSION_ADAPTED_ADT_DETAIL_ADAPT_BASE_HPP
  10. #include <boost/fusion/support/config.hpp>
  11. #include <boost/fusion/adapted/struct/detail/adapt_auto.hpp>
  12. #include <boost/fusion/adapted/struct/detail/adapt_is_tpl.hpp>
  13. #include <boost/preprocessor/control/if.hpp>
  14. #include <boost/preprocessor/control/expr_if.hpp>
  15. #include <boost/preprocessor/seq/seq.hpp>
  16. #include <boost/preprocessor/seq/elem.hpp>
  17. #include <boost/preprocessor/tuple/elem.hpp>
  18. #include <boost/mpl/if.hpp>
  19. #include <boost/type_traits/is_const.hpp>
  20. #include <boost/type_traits/remove_const.hpp>
  21. #include <boost/type_traits/remove_reference.hpp>
  22. #include <boost/typeof/typeof.hpp>
  23. #define BOOST_FUSION_ADAPT_ADT_GET_IDENTITY_TEMPLATE_IMPL(TEMPLATE_PARAMS_SEQ) \
  24. typename detail::get_identity< \
  25. lvalue \
  26. , BOOST_PP_SEQ_ELEM(1,TEMPLATE_PARAMS_SEQ) \
  27. >::type
  28. #define BOOST_FUSION_ADAPT_ADT_GET_IDENTITY_NON_TEMPLATE_IMPL( \
  29. TEMPLATE_PARAMS_SEQ) \
  30. \
  31. boost::remove_const<boost::remove_reference<lvalue>::type>::type
  32. #define BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR(ATTRIBUTE, \
  33. ATTRIBUTE_TUPLE_SIZE, DEDUCE_TYPE) \
  34. BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE, \
  35. BOOST_PP_IF(DEDUCE_TYPE, 0, 2), ATTRIBUTE)
  36. #define BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_SETEXPR(ATTRIBUTE, \
  37. ATTRIBUTE_TUPLE_SIZE, DEDUCE_TYPE) \
  38. BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE, \
  39. BOOST_PP_IF(DEDUCE_TYPE, 1, 3), ATTRIBUTE)
  40. #ifdef BOOST_MSVC
  41. # define BOOST_FUSION_DEDUCED_ATTR_TYPE(NAME_SEQ, ATTRIBUTE, \
  42. ATTRIBUTE_TUPLE_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
  43. \
  44. BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \
  45. TEMPLATE_PARAMS_SEQ) \
  46. \
  47. struct deduced_attr_type { \
  48. static const BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj; \
  49. typedef \
  50. BOOST_PP_EXPR_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), \
  51. typename) \
  52. BOOST_TYPEOF( PREFIX() BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR( \
  53. ATTRIBUTE, ATTRIBUTE_TUPLE_SIZE, 1)) type; \
  54. };
  55. #else
  56. # define BOOST_FUSION_DEDUCED_ATTR_TYPE(NAME_SEQ, ATTRIBUTE, \
  57. ATTRIBUTE_TUPLE_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
  58. struct deduced_attr_type { \
  59. static const BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj; \
  60. typedef BOOST_TYPEOF( PREFIX() BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR( \
  61. ATTRIBUTE, ATTRIBUTE_TUPLE_SIZE, 1)) type; \
  62. };
  63. #endif
  64. #define BOOST_FUSION_ADT_ATTRIBUTE_TYPEOF( \
  65. NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPLE_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
  66. \
  67. BOOST_FUSION_DEDUCED_ATTR_TYPE( \
  68. NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPLE_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
  69. \
  70. typedef \
  71. BOOST_PP_EXPR_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), \
  72. typename) \
  73. deduced_attr_type::type type; \
  74. typedef type const_type;
  75. #define BOOST_FUSION_ADT_ATTRIBUTE_GIVENTYPE( \
  76. NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPLE_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
  77. \
  78. typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE, 0, ATTRIBUTE) type; \
  79. typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE, 1, ATTRIBUTE) const_type;
  80. #define BOOST_FUSION_ADAPT_ADT_C_BASE( \
  81. TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,PREFIX, \
  82. ATTRIBUTE,ATTRIBUTE_TUPLE_SIZE, DEDUCE_TYPE) \
  83. \
  84. template< \
  85. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
  86. > \
  87. struct access::adt_attribute_access< \
  88. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  89. , I \
  90. > \
  91. { \
  92. \
  93. BOOST_PP_IF(DEDUCE_TYPE, \
  94. BOOST_FUSION_ADT_ATTRIBUTE_TYPEOF, \
  95. BOOST_FUSION_ADT_ATTRIBUTE_GIVENTYPE)( \
  96. NAME_SEQ, \
  97. ATTRIBUTE, \
  98. ATTRIBUTE_TUPLE_SIZE, \
  99. PREFIX, \
  100. TEMPLATE_PARAMS_SEQ) \
  101. \
  102. template<class Val> \
  103. BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
  104. static void \
  105. boost_fusion_adapt_adt_impl_set( \
  106. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj, \
  107. Val const& val) \
  108. { \
  109. PREFIX() BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_SETEXPR(ATTRIBUTE, \
  110. ATTRIBUTE_TUPLE_SIZE, DEDUCE_TYPE); \
  111. } \
  112. \
  113. BOOST_FUSION_GPU_ENABLED \
  114. static type \
  115. boost_fusion_adapt_adt_impl_get( \
  116. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj) \
  117. { \
  118. return PREFIX() BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR(ATTRIBUTE, \
  119. ATTRIBUTE_TUPLE_SIZE, DEDUCE_TYPE); \
  120. } \
  121. \
  122. BOOST_FUSION_GPU_ENABLED \
  123. static const_type \
  124. boost_fusion_adapt_adt_impl_get( \
  125. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const& obj) \
  126. { \
  127. return PREFIX() BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR(ATTRIBUTE, \
  128. ATTRIBUTE_TUPLE_SIZE, DEDUCE_TYPE); \
  129. } \
  130. }; \
  131. \
  132. template< \
  133. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
  134. > \
  135. struct adt_attribute_proxy< \
  136. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  137. , I \
  138. , true \
  139. > \
  140. { \
  141. typedef \
  142. BOOST_PP_EXPR_IF(BOOST_PP_SEQ_HEAD(TEMPLATE_PARAMS_SEQ), typename) \
  143. access::adt_attribute_access< \
  144. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  145. , I \
  146. >::const_type type; \
  147. \
  148. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
  149. explicit \
  150. adt_attribute_proxy( \
  151. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const& o) \
  152. : obj(&o) \
  153. {} \
  154. \
  155. BOOST_FUSION_GPU_ENABLED \
  156. type get() const \
  157. { \
  158. return access::adt_attribute_access< \
  159. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  160. , I \
  161. >::boost_fusion_adapt_adt_impl_get(*obj); \
  162. } \
  163. \
  164. BOOST_FUSION_GPU_ENABLED \
  165. operator type() const \
  166. { \
  167. return get(); \
  168. } \
  169. \
  170. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const* obj; \
  171. }; \
  172. \
  173. template< \
  174. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
  175. > \
  176. struct adt_attribute_proxy< \
  177. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  178. , I \
  179. , false \
  180. > \
  181. { \
  182. typedef \
  183. BOOST_PP_EXPR_IF(BOOST_PP_SEQ_HEAD(TEMPLATE_PARAMS_SEQ), typename) \
  184. access::adt_attribute_access< \
  185. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  186. , I \
  187. >::type type; \
  188. \
  189. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
  190. explicit \
  191. adt_attribute_proxy( \
  192. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& o) \
  193. : obj(&o) \
  194. {} \
  195. \
  196. template<class Val> \
  197. BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
  198. adt_attribute_proxy& \
  199. operator=(Val const& val) \
  200. { \
  201. access::adt_attribute_access< \
  202. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  203. , I \
  204. >::boost_fusion_adapt_adt_impl_set(*obj, val); \
  205. return *this; \
  206. } \
  207. \
  208. BOOST_FUSION_GPU_ENABLED \
  209. type get() const \
  210. { \
  211. return access::adt_attribute_access< \
  212. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  213. , I \
  214. >::boost_fusion_adapt_adt_impl_get(*obj); \
  215. } \
  216. \
  217. BOOST_FUSION_GPU_ENABLED \
  218. operator type() const \
  219. { \
  220. return get(); \
  221. } \
  222. \
  223. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)* obj; \
  224. }; \
  225. \
  226. template< \
  227. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
  228. > \
  229. struct access::struct_member< \
  230. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  231. , I \
  232. > \
  233. { \
  234. typedef BOOST_PP_EXPR_IF(BOOST_PP_SEQ_HEAD(TEMPLATE_PARAMS_SEQ), \
  235. typename) \
  236. adt_attribute_proxy< \
  237. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  238. , I \
  239. , false \
  240. >::type lvalue; \
  241. \
  242. BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \
  243. TEMPLATE_PARAMS_SEQ) \
  244. \
  245. typedef \
  246. BOOST_PP_IF( \
  247. BOOST_PP_SEQ_HEAD(TEMPLATE_PARAMS_SEQ), \
  248. BOOST_FUSION_ADAPT_ADT_GET_IDENTITY_TEMPLATE_IMPL, \
  249. BOOST_FUSION_ADAPT_ADT_GET_IDENTITY_NON_TEMPLATE_IMPL)( \
  250. TEMPLATE_PARAMS_SEQ) \
  251. type; \
  252. \
  253. template<typename Seq> \
  254. struct apply \
  255. { \
  256. typedef \
  257. adt_attribute_proxy< \
  258. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  259. , I \
  260. , is_const<Seq>::value \
  261. > \
  262. type; \
  263. \
  264. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
  265. static type \
  266. call(Seq& obj) \
  267. { \
  268. return type(obj); \
  269. } \
  270. }; \
  271. };
  272. #endif