1 /*=============================================================================
2 Copyright (c) 2001-2009 Joel de Guzman
3 Copyright (c) 2005-2006 Dan Marsden
4 Copyright (c) 2010 Christopher Schmidt
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 ==============================================================================*/
10 #ifndef BOOST_FUSION_ADAPTED_ADT_DETAIL_ADAPT_BASE_HPP
11 #define BOOST_FUSION_ADAPTED_ADT_DETAIL_ADAPT_BASE_HPP
13 #include <boost/fusion/support/config.hpp>
14 #include <boost/fusion/adapted/struct/detail/adapt_auto.hpp>
15 #include <boost/fusion/adapted/struct/detail/adapt_is_tpl.hpp>
17 #include <boost/preprocessor/control/if.hpp>
18 #include <boost/preprocessor/control/expr_if.hpp>
19 #include <boost/preprocessor/seq/seq.hpp>
20 #include <boost/preprocessor/seq/elem.hpp>
21 #include <boost/preprocessor/tuple/elem.hpp>
22 #include <boost/mpl/if.hpp>
23 #include <boost/type_traits/is_const.hpp>
24 #include <boost/type_traits/add_const.hpp>
25 #include <boost/type_traits/remove_const.hpp>
27 #include <boost/typeof/typeof.hpp>
29 #define BOOST_FUSION_ADAPT_ADT_GET_IDENTITY_TEMPLATE_IMPL(TEMPLATE_PARAMS_SEQ) \
30 typename detail::get_identity< \
32 , BOOST_PP_SEQ_ELEM(1,TEMPLATE_PARAMS_SEQ) \
35 #define BOOST_FUSION_ADAPT_ADT_GET_IDENTITY_NON_TEMPLATE_IMPL( \
36 TEMPLATE_PARAMS_SEQ) \
38 boost::remove_const<boost::remove_reference<lvalue>::type>::type
40 #define BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR(ATTRIBUTE, \
41 ATTRIBUTE_TUPLE_SIZE, DEDUCE_TYPE) \
42 BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE, \
43 BOOST_PP_IF(DEDUCE_TYPE, 0, 2), ATTRIBUTE)
45 #define BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_SETEXPR(ATTRIBUTE, \
46 ATTRIBUTE_TUPLE_SIZE, DEDUCE_TYPE) \
47 BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE, \
48 BOOST_PP_IF(DEDUCE_TYPE, 1, 3), ATTRIBUTE)
51 # define BOOST_FUSION_DEDUCED_ATTR_TYPE(NAME_SEQ, ATTRIBUTE, \
52 ATTRIBUTE_TUPLE_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
54 BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \
55 TEMPLATE_PARAMS_SEQ) \
57 struct deduced_attr_type { \
58 static const BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj; \
60 BOOST_PP_EXPR_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), \
62 BOOST_TYPEOF( PREFIX() BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR( \
63 ATTRIBUTE, ATTRIBUTE_TUPLE_SIZE, 1)) type; \
67 # define BOOST_FUSION_DEDUCED_ATTR_TYPE(NAME_SEQ, ATTRIBUTE, \
68 ATTRIBUTE_TUPLE_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
69 struct deduced_attr_type { \
70 static const BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj; \
71 typedef BOOST_TYPEOF( PREFIX() BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR( \
72 ATTRIBUTE, ATTRIBUTE_TUPLE_SIZE, 1)) type; \
77 #define BOOST_FUSION_ADT_ATTRIBUTE_TYPEOF( \
78 NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPLE_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
80 BOOST_FUSION_DEDUCED_ATTR_TYPE( \
81 NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPLE_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
84 BOOST_PP_EXPR_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), \
86 boost::remove_const< \
87 BOOST_PP_EXPR_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), \
89 deduced_attr_type::type \
93 BOOST_PP_EXPR_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), \
96 BOOST_PP_EXPR_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), \
98 deduced_attr_type::type \
101 #define BOOST_FUSION_ADT_ATTRIBUTE_GIVENTYPE( \
102 NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPLE_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
104 typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE, 0, ATTRIBUTE) type; \
105 typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE, 1, ATTRIBUTE) const_type;
108 #define BOOST_FUSION_ADAPT_ADT_C_BASE( \
109 TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,PREFIX, \
110 ATTRIBUTE,ATTRIBUTE_TUPLE_SIZE, DEDUCE_TYPE) \
113 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
115 struct access::adt_attribute_access< \
116 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
121 BOOST_PP_IF(DEDUCE_TYPE, \
122 BOOST_FUSION_ADT_ATTRIBUTE_TYPEOF, \
123 BOOST_FUSION_ADT_ATTRIBUTE_GIVENTYPE)( \
126 ATTRIBUTE_TUPLE_SIZE, \
128 TEMPLATE_PARAMS_SEQ) \
130 template<class Val> \
131 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
133 boost_fusion_adapt_adt_impl_set( \
134 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj, \
137 PREFIX() BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_SETEXPR(ATTRIBUTE, \
138 ATTRIBUTE_TUPLE_SIZE, DEDUCE_TYPE); \
141 BOOST_FUSION_GPU_ENABLED \
143 boost_fusion_adapt_adt_impl_get( \
144 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj) \
146 return PREFIX() BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR(ATTRIBUTE, \
147 ATTRIBUTE_TUPLE_SIZE, DEDUCE_TYPE); \
150 BOOST_FUSION_GPU_ENABLED \
152 boost_fusion_adapt_adt_impl_get( \
153 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const& obj) \
155 return PREFIX() BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR(ATTRIBUTE, \
156 ATTRIBUTE_TUPLE_SIZE, DEDUCE_TYPE); \
161 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
163 struct adt_attribute_proxy< \
164 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
170 BOOST_PP_EXPR_IF(BOOST_PP_SEQ_HEAD(TEMPLATE_PARAMS_SEQ), typename) \
171 access::adt_attribute_access< \
172 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
174 >::const_type type; \
176 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
178 adt_attribute_proxy( \
179 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const& o) \
183 BOOST_FUSION_GPU_ENABLED \
186 return access::adt_attribute_access< \
187 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
189 >::boost_fusion_adapt_adt_impl_get(*obj); \
192 BOOST_FUSION_GPU_ENABLED \
193 operator type() const \
198 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const* obj; \
202 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
204 struct adt_attribute_proxy< \
205 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
211 BOOST_PP_EXPR_IF(BOOST_PP_SEQ_HEAD(TEMPLATE_PARAMS_SEQ), typename) \
212 access::adt_attribute_access< \
213 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
217 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
219 adt_attribute_proxy( \
220 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& o) \
224 template<class Val> \
225 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
226 adt_attribute_proxy& \
227 operator=(Val const& val) \
229 access::adt_attribute_access< \
230 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
232 >::boost_fusion_adapt_adt_impl_set(*obj, val); \
236 BOOST_FUSION_GPU_ENABLED \
239 return access::adt_attribute_access< \
240 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
242 >::boost_fusion_adapt_adt_impl_get(*obj); \
245 BOOST_FUSION_GPU_ENABLED \
246 operator type() const \
251 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)* obj; \
255 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
257 struct access::struct_member< \
258 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
262 typedef BOOST_PP_EXPR_IF(BOOST_PP_SEQ_HEAD(TEMPLATE_PARAMS_SEQ), \
264 adt_attribute_proxy< \
265 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
270 BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \
271 TEMPLATE_PARAMS_SEQ) \
275 BOOST_PP_SEQ_HEAD(TEMPLATE_PARAMS_SEQ), \
276 BOOST_FUSION_ADAPT_ADT_GET_IDENTITY_TEMPLATE_IMPL, \
277 BOOST_FUSION_ADAPT_ADT_GET_IDENTITY_NON_TEMPLATE_IMPL)( \
278 TEMPLATE_PARAMS_SEQ) \
281 template<typename Seq> \
285 adt_attribute_proxy< \
286 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
288 , is_const<Seq>::value \
292 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \