adapt_base.hpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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/preprocessor/control/if.hpp>
  11. #include <boost/preprocessor/seq/seq.hpp>
  12. #include <boost/preprocessor/seq/elem.hpp>
  13. #include <boost/mpl/if.hpp>
  14. #include <boost/type_traits/is_const.hpp>
  15. #define BOOST_FUSION_ADAPT_ADT_GET_IDENTITY_TEMPLATE_IMPL(TEMPLATE_PARAMS_SEQ) \
  16. typename detail::get_identity< \
  17. lvalue \
  18. , BOOST_PP_SEQ_ELEM(1,TEMPLATE_PARAMS_SEQ) \
  19. >::type
  20. #define BOOST_FUSION_ADAPT_ADT_GET_IDENTITY_NON_TEMPLATE_IMPL( \
  21. TEMPLATE_PARAMS_SEQ) \
  22. \
  23. boost::remove_const<boost::remove_reference<lvalue>::type>::type
  24. #define BOOST_FUSION_ADAPT_ADT_C_BASE( \
  25. TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,ATTRIBUTE,ATTRIBUTE_TUPEL_SIZE) \
  26. \
  27. template< \
  28. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
  29. > \
  30. struct access::adt_attribute_access< \
  31. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  32. , I \
  33. > \
  34. { \
  35. template<class Val> \
  36. static void \
  37. boost_fusion_adapt_adt_impl_set( \
  38. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj, \
  39. Val const& val) \
  40. { \
  41. BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 3, ATTRIBUTE); \
  42. } \
  43. \
  44. static BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) \
  45. boost_fusion_adapt_adt_impl_get( \
  46. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj) \
  47. { \
  48. return BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 2, ATTRIBUTE); \
  49. } \
  50. \
  51. static BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 1, ATTRIBUTE) \
  52. boost_fusion_adapt_adt_impl_get( \
  53. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const& obj) \
  54. { \
  55. return BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 2, ATTRIBUTE); \
  56. } \
  57. }; \
  58. \
  59. template< \
  60. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
  61. > \
  62. struct adt_attribute_proxy< \
  63. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  64. , I \
  65. , true \
  66. > \
  67. { \
  68. typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 1, ATTRIBUTE) type; \
  69. \
  70. explicit \
  71. adt_attribute_proxy( \
  72. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const& o) \
  73. : obj(&o) \
  74. {} \
  75. \
  76. type get() const \
  77. { \
  78. return access::adt_attribute_access< \
  79. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  80. , I \
  81. >::boost_fusion_adapt_adt_impl_get(*obj); \
  82. } \
  83. \
  84. operator type() const \
  85. { \
  86. return get(); \
  87. } \
  88. \
  89. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const* obj; \
  90. }; \
  91. \
  92. template< \
  93. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
  94. > \
  95. struct adt_attribute_proxy< \
  96. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  97. , I \
  98. , false \
  99. > \
  100. { \
  101. typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) type; \
  102. \
  103. explicit \
  104. adt_attribute_proxy( \
  105. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& o) \
  106. : obj(&o) \
  107. {} \
  108. \
  109. template<class Val> \
  110. adt_attribute_proxy& \
  111. operator=(Val const& val) \
  112. { \
  113. access::adt_attribute_access< \
  114. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  115. , I \
  116. >::boost_fusion_adapt_adt_impl_set(*obj, val); \
  117. return *this; \
  118. } \
  119. \
  120. type get() const \
  121. { \
  122. return access::adt_attribute_access< \
  123. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  124. , I \
  125. >::boost_fusion_adapt_adt_impl_get(*obj); \
  126. } \
  127. \
  128. operator type() const \
  129. { \
  130. return get(); \
  131. } \
  132. \
  133. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)* obj; \
  134. }; \
  135. \
  136. template< \
  137. BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
  138. > \
  139. struct access::struct_member< \
  140. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  141. , I \
  142. > \
  143. { \
  144. typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) lvalue; \
  145. BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \
  146. TEMPLATE_PARAMS_SEQ) \
  147. \
  148. typedef \
  149. BOOST_PP_IF( \
  150. BOOST_PP_SEQ_HEAD(TEMPLATE_PARAMS_SEQ), \
  151. BOOST_FUSION_ADAPT_ADT_GET_IDENTITY_TEMPLATE_IMPL, \
  152. BOOST_FUSION_ADAPT_ADT_GET_IDENTITY_NON_TEMPLATE_IMPL)( \
  153. TEMPLATE_PARAMS_SEQ) \
  154. type; \
  155. \
  156. template<typename Seq> \
  157. struct apply \
  158. { \
  159. typedef \
  160. adt_attribute_proxy< \
  161. BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
  162. , I \
  163. , is_const<Seq>::value \
  164. > \
  165. type; \
  166. \
  167. static type \
  168. call(Seq& obj) \
  169. { \
  170. return type(obj); \
  171. } \
  172. }; \
  173. };
  174. #endif