adapt_base.hpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  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/add_const.hpp>
  21. #include <boost/type_traits/remove_const.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. boost::remove_const< \
  74. BOOST_PP_EXPR_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), \
  75. typename) \
  76. deduced_attr_type::type \
  77. >::type type; \
  78. \
  79. typedef \
  80. BOOST_PP_EXPR_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), \
  81. typename) \
  82. boost::add_const< \
  83. BOOST_PP_EXPR_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), \
  84. typename) \
  85. deduced_attr_type::type \
  86. >::type const_type;
  87. #define BOOST_FUSION_ADT_ATTRIBUTE_GIVENTYPE( \
  88. NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPLE_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
  89. \
  90. typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE, 0, ATTRIBUTE) type; \
  91. typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE, 1, ATTRIBUTE) const_type;
  92. #define BOOST_FUSION_ADAPT_ADT_C_BASE( \
  93. TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,PREFIX, \
  94. ATTRIBUTE,ATTRIBUTE_TUPLE_SIZE, DEDUCE_TYPE) \
  95. \
  96. template< \
  97. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
  98. > \
  99. struct access::adt_attribute_access< \
  100. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  101. , I \
  102. > \
  103. { \
  104. \
  105. BOOST_PP_IF(DEDUCE_TYPE, \
  106. BOOST_FUSION_ADT_ATTRIBUTE_TYPEOF, \
  107. BOOST_FUSION_ADT_ATTRIBUTE_GIVENTYPE)( \
  108. NAME_SEQ, \
  109. ATTRIBUTE, \
  110. ATTRIBUTE_TUPLE_SIZE, \
  111. PREFIX, \
  112. TEMPLATE_PARAMS_SEQ) \
  113. \
  114. template<class Val> \
  115. BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
  116. static void \
  117. boost_fusion_adapt_adt_impl_set( \
  118. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj, \
  119. Val const& val) \
  120. { \
  121. PREFIX() BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_SETEXPR(ATTRIBUTE, \
  122. ATTRIBUTE_TUPLE_SIZE, DEDUCE_TYPE); \
  123. } \
  124. \
  125. BOOST_FUSION_GPU_ENABLED \
  126. static type \
  127. boost_fusion_adapt_adt_impl_get( \
  128. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj) \
  129. { \
  130. return PREFIX() BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR(ATTRIBUTE, \
  131. ATTRIBUTE_TUPLE_SIZE, DEDUCE_TYPE); \
  132. } \
  133. \
  134. BOOST_FUSION_GPU_ENABLED \
  135. static const_type \
  136. boost_fusion_adapt_adt_impl_get( \
  137. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const& obj) \
  138. { \
  139. return PREFIX() BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR(ATTRIBUTE, \
  140. ATTRIBUTE_TUPLE_SIZE, DEDUCE_TYPE); \
  141. } \
  142. }; \
  143. \
  144. template< \
  145. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
  146. > \
  147. struct adt_attribute_proxy< \
  148. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  149. , I \
  150. , true \
  151. > \
  152. { \
  153. typedef \
  154. BOOST_PP_EXPR_IF(BOOST_PP_SEQ_HEAD(TEMPLATE_PARAMS_SEQ), typename) \
  155. access::adt_attribute_access< \
  156. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  157. , I \
  158. >::const_type type; \
  159. \
  160. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
  161. explicit \
  162. adt_attribute_proxy( \
  163. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const& o) \
  164. : obj(&o) \
  165. {} \
  166. \
  167. BOOST_FUSION_GPU_ENABLED \
  168. type get() const \
  169. { \
  170. return access::adt_attribute_access< \
  171. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  172. , I \
  173. >::boost_fusion_adapt_adt_impl_get(*obj); \
  174. } \
  175. \
  176. BOOST_FUSION_GPU_ENABLED \
  177. operator type() const \
  178. { \
  179. return get(); \
  180. } \
  181. \
  182. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const* obj; \
  183. }; \
  184. \
  185. template< \
  186. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
  187. > \
  188. struct adt_attribute_proxy< \
  189. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  190. , I \
  191. , false \
  192. > \
  193. { \
  194. typedef \
  195. BOOST_PP_EXPR_IF(BOOST_PP_SEQ_HEAD(TEMPLATE_PARAMS_SEQ), typename) \
  196. access::adt_attribute_access< \
  197. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  198. , I \
  199. >::type type; \
  200. \
  201. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
  202. explicit \
  203. adt_attribute_proxy( \
  204. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& o) \
  205. : obj(&o) \
  206. {} \
  207. \
  208. template<class Val> \
  209. BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
  210. adt_attribute_proxy& \
  211. operator=(Val const& val) \
  212. { \
  213. access::adt_attribute_access< \
  214. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  215. , I \
  216. >::boost_fusion_adapt_adt_impl_set(*obj, val); \
  217. return *this; \
  218. } \
  219. \
  220. BOOST_FUSION_GPU_ENABLED \
  221. type get() const \
  222. { \
  223. return access::adt_attribute_access< \
  224. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  225. , I \
  226. >::boost_fusion_adapt_adt_impl_get(*obj); \
  227. } \
  228. \
  229. BOOST_FUSION_GPU_ENABLED \
  230. operator type() const \
  231. { \
  232. return get(); \
  233. } \
  234. \
  235. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)* obj; \
  236. }; \
  237. \
  238. template< \
  239. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
  240. > \
  241. struct access::struct_member< \
  242. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  243. , I \
  244. > \
  245. { \
  246. typedef BOOST_PP_EXPR_IF(BOOST_PP_SEQ_HEAD(TEMPLATE_PARAMS_SEQ), \
  247. typename) \
  248. adt_attribute_proxy< \
  249. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  250. , I \
  251. , false \
  252. >::type lvalue; \
  253. \
  254. BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \
  255. TEMPLATE_PARAMS_SEQ) \
  256. \
  257. typedef \
  258. BOOST_PP_IF( \
  259. BOOST_PP_SEQ_HEAD(TEMPLATE_PARAMS_SEQ), \
  260. BOOST_FUSION_ADAPT_ADT_GET_IDENTITY_TEMPLATE_IMPL, \
  261. BOOST_FUSION_ADAPT_ADT_GET_IDENTITY_NON_TEMPLATE_IMPL)( \
  262. TEMPLATE_PARAMS_SEQ) \
  263. type; \
  264. \
  265. template<typename Seq> \
  266. struct apply \
  267. { \
  268. typedef \
  269. adt_attribute_proxy< \
  270. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  271. , I \
  272. , is_const<Seq>::value \
  273. > \
  274. type; \
  275. \
  276. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
  277. static type \
  278. call(Seq& obj) \
  279. { \
  280. return type(obj); \
  281. } \
  282. }; \
  283. };
  284. #endif