adapt_base.hpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*=============================================================================
  2. Copyright (c) 2001-2009 Joel de Guzman
  3. Copyright (c) 2005-2006 Dan Marsden
  4. Copyright (c) 2009-2011 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_STRUCT_DETAIL_ADAPT_BASE_HPP
  9. #define BOOST_FUSION_ADAPTED_STRUCT_DETAIL_ADAPT_BASE_HPP
  10. #include <boost/config.hpp>
  11. #include <boost/fusion/support/tag_of_fwd.hpp>
  12. #include <boost/preprocessor/empty.hpp>
  13. #include <boost/preprocessor/stringize.hpp>
  14. #include <boost/preprocessor/control/if.hpp>
  15. #include <boost/preprocessor/seq/size.hpp>
  16. #include <boost/preprocessor/seq/for_each.hpp>
  17. #include <boost/preprocessor/seq/for_each_i.hpp>
  18. #include <boost/preprocessor/seq/enum.hpp>
  19. #include <boost/preprocessor/seq/seq.hpp>
  20. #include <boost/preprocessor/tuple/eat.hpp>
  21. #include <boost/preprocessor/tuple/elem.hpp>
  22. #include <boost/preprocessor/arithmetic/dec.hpp>
  23. #include <boost/mpl/bool.hpp>
  24. #include <boost/mpl/tag.hpp>
  25. #include <boost/mpl/eval_if.hpp>
  26. #include <boost/mpl/identity.hpp>
  27. #include <boost/type_traits/add_const.hpp>
  28. #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME_TEMPLATE_PARAMS(SEQ) \
  29. BOOST_PP_SEQ_HEAD(SEQ)<BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TAIL(SEQ))> \
  30. BOOST_PP_EMPTY()
  31. #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(SEQ) \
  32. BOOST_PP_IF( \
  33. BOOST_PP_SEQ_HEAD(SEQ), \
  34. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME_TEMPLATE_PARAMS, \
  35. BOOST_PP_SEQ_HEAD)(BOOST_PP_SEQ_TAIL(SEQ))
  36. #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL_C(R, _, ELEM) \
  37. (typename ELEM)
  38. #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL(SEQ) \
  39. BOOST_PP_SEQ_ENUM( \
  40. BOOST_PP_SEQ_FOR_EACH( \
  41. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL_C, \
  42. _, \
  43. BOOST_PP_SEQ_TAIL(SEQ)))
  44. #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(SEQ) \
  45. BOOST_PP_IF( \
  46. BOOST_PP_SEQ_HEAD(SEQ), \
  47. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL, \
  48. BOOST_PP_TUPLE_EAT(1))(SEQ)
  49. #ifdef BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS
  50. # define BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \
  51. MODIFIER, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \
  52. \
  53. template< \
  54. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
  55. > \
  56. struct tag_of< \
  57. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) MODIFIER \
  58. , void \
  59. > \
  60. { \
  61. typedef TAG type; \
  62. };
  63. #else
  64. # define BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \
  65. MODIFIER, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \
  66. \
  67. template< \
  68. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
  69. > \
  70. struct tag_of<BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) MODIFIER> \
  71. { \
  72. typedef TAG type; \
  73. };
  74. #endif
  75. #define BOOST_FUSION_ADAPT_STRUCT_BASE_UNPACK_AND_CALL(R,DATA,I,ATTRIBUTE) \
  76. BOOST_PP_TUPLE_ELEM(3,0,DATA)( \
  77. BOOST_PP_TUPLE_ELEM(3,1,DATA), \
  78. BOOST_PP_TUPLE_ELEM(3,2,DATA), \
  79. I, \
  80. ATTRIBUTE)
  81. #ifdef BOOST_MSVC
  82. # define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAM(R,_,ELEM) \
  83. typedef ELEM ELEM;
  84. # define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS_IMPL(SEQ) \
  85. BOOST_PP_SEQ_FOR_EACH( \
  86. BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAM, \
  87. _, \
  88. BOOST_PP_SEQ_TAIL(SEQ))
  89. # define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS(SEQ) \
  90. BOOST_PP_IF( \
  91. BOOST_PP_SEQ_HEAD(SEQ), \
  92. BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS_IMPL, \
  93. BOOST_PP_TUPLE_EAT(1))(SEQ)
  94. #else
  95. # define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS(SEQ)
  96. #endif
  97. #define BOOST_FUSION_ADAPT_STRUCT_C_BASE( \
  98. TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,PREFIX,ATTRIBUTE,ATTRIBUTE_TUPEL_SIZE) \
  99. \
  100. template< \
  101. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
  102. > \
  103. struct access::struct_member< \
  104. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  105. , I \
  106. > \
  107. { \
  108. typedef \
  109. BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) \
  110. attribute_type; \
  111. BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \
  112. TEMPLATE_PARAMS_SEQ) \
  113. \
  114. typedef attribute_type type; \
  115. \
  116. template<typename Seq> \
  117. struct apply \
  118. { \
  119. typedef typename \
  120. add_reference< \
  121. typename mpl::eval_if< \
  122. is_const<Seq> \
  123. , add_const<attribute_type> \
  124. , mpl::identity<attribute_type> \
  125. >::type \
  126. >::type \
  127. type; \
  128. \
  129. static type \
  130. call(Seq& seq) \
  131. { \
  132. return seq.PREFIX() \
  133. BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 1, ATTRIBUTE); \
  134. } \
  135. }; \
  136. }; \
  137. \
  138. template< \
  139. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
  140. > \
  141. struct struct_member_name< \
  142. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  143. , I \
  144. > \
  145. { \
  146. typedef char const* type; \
  147. \
  148. static type \
  149. call() \
  150. { \
  151. return BOOST_PP_STRINGIZE( \
  152. BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE,1,ATTRIBUTE)); \
  153. } \
  154. };
  155. #define BOOST_FUSION_ADAPT_STRUCT_BASE( \
  156. TEMPLATE_PARAMS_SEQ, \
  157. NAME_SEQ, \
  158. TAG, \
  159. IS_VIEW, \
  160. ATTRIBUTES_SEQ, \
  161. ATTRIBUTES_CALLBACK) \
  162. \
  163. namespace boost \
  164. { \
  165. namespace fusion \
  166. { \
  167. namespace traits \
  168. { \
  169. BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \
  170. BOOST_PP_EMPTY(), TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \
  171. BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \
  172. const, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \
  173. } \
  174. \
  175. namespace extension \
  176. { \
  177. BOOST_PP_IF( \
  178. BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ATTRIBUTES_SEQ)), \
  179. BOOST_PP_SEQ_FOR_EACH_I_R, \
  180. BOOST_PP_TUPLE_EAT(4))( \
  181. 1, \
  182. BOOST_FUSION_ADAPT_STRUCT_BASE_UNPACK_AND_CALL, \
  183. (ATTRIBUTES_CALLBACK,TEMPLATE_PARAMS_SEQ,NAME_SEQ), \
  184. BOOST_PP_SEQ_TAIL(ATTRIBUTES_SEQ)) \
  185. \
  186. template< \
  187. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS( \
  188. TEMPLATE_PARAMS_SEQ) \
  189. > \
  190. struct struct_size<BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)> \
  191. : mpl::int_<BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ATTRIBUTES_SEQ))> \
  192. {}; \
  193. \
  194. template< \
  195. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS( \
  196. TEMPLATE_PARAMS_SEQ) \
  197. > \
  198. struct struct_is_view< \
  199. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  200. > \
  201. : mpl::BOOST_PP_IF(IS_VIEW,true_,false_) \
  202. {}; \
  203. } \
  204. } \
  205. \
  206. namespace mpl \
  207. { \
  208. template<typename> \
  209. struct sequence_tag; \
  210. \
  211. template< \
  212. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS( \
  213. TEMPLATE_PARAMS_SEQ) \
  214. > \
  215. struct sequence_tag<BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)> \
  216. { \
  217. typedef fusion::fusion_sequence_tag type; \
  218. }; \
  219. \
  220. template< \
  221. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS( \
  222. TEMPLATE_PARAMS_SEQ) \
  223. > \
  224. struct sequence_tag< \
  225. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const \
  226. > \
  227. { \
  228. typedef fusion::fusion_sequence_tag type; \
  229. }; \
  230. } \
  231. }
  232. #endif