1 /*============================================================================= 2 Copyright (c) 2012 Nathan Ridge 3 4 Distributed under the Boost Software License, Version 1.0. (See accompanying 5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 ==============================================================================*/ 7 8 #ifndef BOOST_FUSION_ADAPTED_STRUCT_DETAIL_DEFINE_STRUCT_INLINE_HPP 9 #define BOOST_FUSION_ADAPTED_STRUCT_DETAIL_DEFINE_STRUCT_INLINE_HPP 10 11 #include <boost/fusion/support/config.hpp> 12 #include <boost/config.hpp> 13 #include <boost/fusion/support/category_of.hpp> 14 #include <boost/fusion/sequence/sequence_facade.hpp> 15 #include <boost/fusion/iterator/iterator_facade.hpp> 16 #include <boost/fusion/algorithm/auxiliary/copy.hpp> 17 #include <boost/fusion/adapted/struct/detail/define_struct.hpp> 18 #include <boost/mpl/int.hpp> 19 #include <boost/mpl/bool.hpp> 20 #include <boost/mpl/identity.hpp> 21 #include <boost/mpl/minus.hpp> 22 #include <boost/mpl/if.hpp> 23 #include <boost/type_traits/is_const.hpp> 24 #include <boost/preprocessor/comma_if.hpp> 25 #include <boost/preprocessor/facilities/empty.hpp> 26 #include <boost/preprocessor/repeat.hpp> 27 #include <boost/preprocessor/seq/for_each_i.hpp> 28 #include <boost/preprocessor/seq/size.hpp> 29 #include <boost/preprocessor/seq/enum.hpp> 30 #include <boost/preprocessor/seq/seq.hpp> 31 #include <boost/preprocessor/tuple/elem.hpp> 32 33 // MSVC and GCC <= 4.4 have a bug that affects partial specializations of 34 // nested templates under some circumstances. This affects the implementation 35 // of BOOST_FUSION_DEFINE_STRUCT_INLINE, which uses such specializations for 36 // the iterator class's 'deref' and 'value_of' metafunctions. On these compilers 37 // an alternate implementation for these metafunctions is used that does not 38 // require such specializations. The alternate implementation takes longer 39 // to compile so its use is restricted to the offending compilers. 40 // For MSVC, the bug was reported at https://connect.microsoft.com/VisualStudio/feedback/details/757891/c-compiler-error-involving-partial-specializations-of-nested-templates 41 // For GCC, 4.4 and earlier are no longer maintained so there is no need 42 // to report a bug. 43 #if defined(BOOST_MSVC) || (defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ <= 4))) 44 #define BOOST_FUSION_NEED_NESTED_TEMPLATE_PARTIAL_SPEC_WKND 45 #endif 46 47 #ifdef BOOST_FUSION_NEED_NESTED_TEMPLATE_PARTIAL_SPEC_WKND 48 #include <boost/type_traits/add_const.hpp> 49 #include <boost/type_traits/remove_const.hpp> 50 #include <boost/mpl/if.hpp> 51 #include <boost/fusion/sequence/intrinsic/at_c.hpp> 52 #include <boost/fusion/container/vector.hpp> 53 #endif 54 55 56 #define BOOST_FUSION_MAKE_DEFAULT_INIT_LIST_ENTRY(R, DATA, N, ATTRIBUTE) \ 57 BOOST_PP_COMMA_IF(N) BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE)() 58 59 #define BOOST_FUSION_MAKE_DEFAULT_INIT_LIST(ATTRIBUTES_SEQ) \ 60 : BOOST_PP_SEQ_FOR_EACH_I( \ 61 BOOST_FUSION_MAKE_DEFAULT_INIT_LIST_ENTRY, \ 62 ~, \ 63 ATTRIBUTES_SEQ) \ 64 65 #define BOOST_FUSION_IGNORE_2(ARG1, ARG2) 66 67 #define BOOST_FUSION_MAKE_COPY_CONSTRUCTOR(NAME, ATTRIBUTES_SEQ) \ 68 BOOST_FUSION_GPU_ENABLED \ 69 NAME(BOOST_PP_SEQ_FOR_EACH_I( \ 70 BOOST_FUSION_MAKE_CONST_REF_PARAM, \ 71 ~, \ 72 ATTRIBUTES_SEQ)) \ 73 : BOOST_PP_SEQ_FOR_EACH_I( \ 74 BOOST_FUSION_MAKE_INIT_LIST_ENTRY, \ 75 ~, \ 76 ATTRIBUTES_SEQ) \ 77 { \ 78 } \ 79 80 #define BOOST_FUSION_MAKE_CONST_REF_PARAM(R, DATA, N, ATTRIBUTE) \ 81 BOOST_PP_COMMA_IF(N) \ 82 BOOST_PP_TUPLE_ELEM(2, 0, ATTRIBUTE) const& \ 83 BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE) 84 85 #define BOOST_FUSION_MAKE_INIT_LIST_ENTRY_I(NAME) NAME(NAME) 86 87 #define BOOST_FUSION_MAKE_INIT_LIST_ENTRY(R, DATA, N, ATTRIBUTE) \ 88 BOOST_PP_COMMA_IF(N) \ 89 BOOST_FUSION_MAKE_INIT_LIST_ENTRY_I(BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE)) 90 91 #define BOOST_FUSION_ITERATOR_NAME(NAME) \ 92 BOOST_PP_CAT(boost_fusion_detail_, BOOST_PP_CAT(NAME, _iterator)) 93 94 // Note: all template parameter names need to be uglified, otherwise they might 95 // shadow a template parameter of the struct when used with 96 // BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE 97 98 #define BOOST_FUSION_MAKE_ITERATOR_VALUE_OF_SPECS(Z, N, NAME) \ 99 template <typename boost_fusion_detail_Sq> \ 100 struct value_of< \ 101 BOOST_FUSION_ITERATOR_NAME(NAME)<boost_fusion_detail_Sq, N> \ 102 > \ 103 : boost::mpl::identity< \ 104 typename boost_fusion_detail_Sq::t##N##_type \ 105 > \ 106 { \ 107 }; 108 109 #define BOOST_FUSION_MAKE_ITERATOR_DEREF_SPEC( \ 110 SPEC_TYPE, CALL_ARG_TYPE, TYPE_QUAL, ATTRIBUTE, N) \ 111 \ 112 template <typename boost_fusion_detail_Sq> \ 113 struct deref<SPEC_TYPE, N> > \ 114 { \ 115 typedef typename boost_fusion_detail_Sq::t##N##_type TYPE_QUAL& type; \ 116 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \ 117 static type call(CALL_ARG_TYPE, N> const& iter) \ 118 { \ 119 return iter.seq_.BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE); \ 120 } \ 121 }; 122 123 #define BOOST_FUSION_MAKE_ITERATOR_DEREF_SPECS(R, NAME, N, ATTRIBUTE) \ 124 BOOST_FUSION_MAKE_ITERATOR_DEREF_SPEC( \ 125 BOOST_FUSION_ITERATOR_NAME(NAME)<boost_fusion_detail_Sq, \ 126 BOOST_FUSION_ITERATOR_NAME(NAME)<boost_fusion_detail_Sq, \ 127 , \ 128 ATTRIBUTE, \ 129 N) \ 130 BOOST_FUSION_MAKE_ITERATOR_DEREF_SPEC( \ 131 BOOST_FUSION_ITERATOR_NAME(NAME)<const boost_fusion_detail_Sq, \ 132 BOOST_FUSION_ITERATOR_NAME(NAME)<const boost_fusion_detail_Sq, \ 133 const, \ 134 ATTRIBUTE, \ 135 N) \ 136 BOOST_FUSION_MAKE_ITERATOR_DEREF_SPEC( \ 137 const BOOST_FUSION_ITERATOR_NAME(NAME)<boost_fusion_detail_Sq, \ 138 BOOST_FUSION_ITERATOR_NAME(NAME)<boost_fusion_detail_Sq, \ 139 , \ 140 ATTRIBUTE, \ 141 N) \ 142 BOOST_FUSION_MAKE_ITERATOR_DEREF_SPEC( \ 143 const BOOST_FUSION_ITERATOR_NAME(NAME)<const boost_fusion_detail_Sq, \ 144 BOOST_FUSION_ITERATOR_NAME(NAME)<const boost_fusion_detail_Sq, \ 145 const, \ 146 ATTRIBUTE, \ 147 N) \ 148 149 #define BOOST_FUSION_MAKE_VALUE_AT_SPECS(Z, N, DATA) \ 150 template <typename boost_fusion_detail_Sq> \ 151 struct value_at<boost_fusion_detail_Sq, boost::mpl::int_<N> > \ 152 { \ 153 typedef typename boost_fusion_detail_Sq::t##N##_type type; \ 154 }; 155 156 #define BOOST_FUSION_MAKE_AT_SPECS(R, DATA, N, ATTRIBUTE) \ 157 template <typename boost_fusion_detail_Sq> \ 158 struct at<boost_fusion_detail_Sq, boost::mpl::int_<N> > \ 159 { \ 160 typedef typename boost::mpl::if_< \ 161 boost::is_const<boost_fusion_detail_Sq>, \ 162 typename boost_fusion_detail_Sq::t##N##_type const&, \ 163 typename boost_fusion_detail_Sq::t##N##_type& \ 164 >::type type; \ 165 \ 166 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \ 167 static type call(boost_fusion_detail_Sq& sq) \ 168 { \ 169 return sq. BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE); \ 170 } \ 171 }; 172 173 #define BOOST_FUSION_MAKE_TYPEDEF(R, DATA, N, ATTRIBUTE) \ 174 typedef BOOST_PP_TUPLE_ELEM(2, 0, ATTRIBUTE) t##N##_type; 175 176 #define BOOST_FUSION_MAKE_DATA_MEMBER(R, DATA, N, ATTRIBUTE) \ 177 BOOST_PP_TUPLE_ELEM(2, 0, ATTRIBUTE) BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE); 178 179 #ifdef BOOST_FUSION_NEED_NESTED_TEMPLATE_PARTIAL_SPEC_WKND 180 181 #define BOOST_FUSION_DEFINE_ITERATOR_VALUE_OF(NAME, ATTRIBUTE_SEQ_SIZE) \ 182 template <typename boost_fusion_detail_Iterator> \ 183 struct value_of : boost::fusion::result_of::at_c< \ 184 ref_vec_t, \ 185 boost_fusion_detail_Iterator::index::value \ 186 > \ 187 { \ 188 }; 189 190 #define BOOST_FUSION_DEFINE_ITERATOR_DEREF(NAME, ATTRIBUTES_SEQ) \ 191 template <typename boost_fusion_detail_Iterator> \ 192 struct deref \ 193 { \ 194 typedef typename boost::remove_const< \ 195 boost_fusion_detail_Iterator \ 196 >::type iterator_raw_type; \ 197 \ 198 static const int index = iterator_raw_type::index::value; \ 199 \ 200 typedef typename boost::fusion::result_of::at_c< \ 201 ref_vec_t, \ 202 index \ 203 >::type result_raw_type; \ 204 \ 205 typedef typename boost::mpl::if_< \ 206 boost::is_const<typename iterator_raw_type::sequence_type>, \ 207 typename boost::add_const<result_raw_type>::type, \ 208 result_raw_type \ 209 >::type type; \ 210 \ 211 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \ 212 static type call(iterator_raw_type const& iter) \ 213 { \ 214 return boost::fusion::at_c<index>(iter.ref_vec); \ 215 } \ 216 }; 217 218 #define BOOST_FUSION_MAKE_ITERATOR_WKND_FIELD_NAME(R, DATA, N, ATTRIBUTE) \ 219 BOOST_PP_COMMA_IF(N) seq.BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE) 220 221 #define BOOST_FUSION_DEFINE_ITERATOR_WKND_INIT_LIST_ENTRIES(ATTRIBUTES_SEQ) \ 222 , ref_vec(BOOST_PP_SEQ_FOR_EACH_I( \ 223 BOOST_FUSION_MAKE_ITERATOR_WKND_FIELD_NAME, \ 224 ~, \ 225 BOOST_PP_SEQ_TAIL(ATTRIBUTES_SEQ))) 226 227 #define BOOST_FUSION_MAKE_ITERATOR_WKND_REF(Z, N, DATA) \ 228 BOOST_PP_COMMA_IF(N) \ 229 typename boost::mpl::if_< \ 230 boost::is_const<boost_fusion_detail_Seq>, \ 231 typename boost::add_const< \ 232 typename boost_fusion_detail_Seq::t##N##_type \ 233 >::type, \ 234 typename boost_fusion_detail_Seq::t##N##_type \ 235 >::type& 236 237 #define BOOST_FUSION_DEFINE_ITERATOR_WKND_MEMBERS(ATTRIBUTES_SEQ_SIZE) \ 238 typedef boost::fusion::vector< \ 239 BOOST_PP_REPEAT( \ 240 ATTRIBUTES_SEQ_SIZE, \ 241 BOOST_FUSION_MAKE_ITERATOR_WKND_REF, \ 242 ~) \ 243 > ref_vec_t; \ 244 \ 245 ref_vec_t ref_vec; 246 247 #else 248 249 #define BOOST_FUSION_DEFINE_ITERATOR_VALUE_OF(NAME, ATTRIBUTES_SEQ_SIZE) \ 250 template <typename boost_fusion_detail_T> struct value_of; \ 251 BOOST_PP_REPEAT( \ 252 ATTRIBUTES_SEQ_SIZE, \ 253 BOOST_FUSION_MAKE_ITERATOR_VALUE_OF_SPECS, \ 254 NAME) 255 256 #define BOOST_FUSION_DEFINE_ITERATOR_DEREF(NAME, ATTRIBUTES_SEQ) \ 257 template <typename boost_fusion_detail_T> struct deref; \ 258 BOOST_PP_SEQ_FOR_EACH_I( \ 259 BOOST_FUSION_MAKE_ITERATOR_DEREF_SPECS, \ 260 NAME, \ 261 ATTRIBUTES_SEQ) 262 263 #define BOOST_FUSION_DEFINE_ITERATOR_WKND_INIT_LIST_ENTRIES(ATTRIBUTES_SEQ) 264 265 #define BOOST_FUSION_DEFINE_ITERATOR_WKND_MEMBERS(ATTRIBUTES_SEQ_SIZE) 266 267 #endif // BOOST_FUSION_NEED_NESTED_TEMPLATE_PARTIAL_SPEC_WKND 268 269 // Note: We can't nest the iterator inside the struct because we run into 270 // a MSVC10 bug involving partial specializations of nested templates. 271 272 #define BOOST_FUSION_DEFINE_STRUCT_INLINE_IMPL(NAME, ATTRIBUTES) \ 273 BOOST_FUSION_DEFINE_STRUCT_INLINE_ITERATOR(NAME, ATTRIBUTES) \ 274 struct NAME : boost::fusion::sequence_facade< \ 275 NAME, \ 276 boost::fusion::random_access_traversal_tag \ 277 > \ 278 { \ 279 BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS(NAME, ATTRIBUTES) \ 280 }; 281 282 #define BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE_IMPL( \ 283 TEMPLATE_PARAMS_SEQ, NAME, ATTRIBUTES) \ 284 \ 285 BOOST_FUSION_DEFINE_STRUCT_INLINE_ITERATOR(NAME, ATTRIBUTES) \ 286 \ 287 template < \ 288 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL( \ 289 (0)TEMPLATE_PARAMS_SEQ) \ 290 > \ 291 struct NAME : boost::fusion::sequence_facade< \ 292 NAME< \ 293 BOOST_PP_SEQ_ENUM(TEMPLATE_PARAMS_SEQ) \ 294 >, \ 295 boost::fusion::random_access_traversal_tag \ 296 > \ 297 { \ 298 BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS(NAME, ATTRIBUTES) \ 299 }; 300 301 #define BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS(NAME, ATTRIBUTES) \ 302 BOOST_FUSION_DEFINE_STRUCT_MEMBERS_IMPL( \ 303 NAME, \ 304 BOOST_PP_CAT(BOOST_FUSION_DEFINE_STRUCT_FILLER_0 ATTRIBUTES,_END)) 305 306 // Note: can't compute BOOST_PP_SEQ_SIZE(ATTRIBUTES_SEQ) directly because 307 // ATTRIBUTES_SEQ may be empty and calling BOOST_PP_SEQ_SIZE on an empty 308 // sequence produces warnings on MSVC. 309 #define BOOST_FUSION_DEFINE_STRUCT_MEMBERS_IMPL(NAME, ATTRIBUTES_SEQ) \ 310 BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS_IMPL_IMPL( \ 311 NAME, \ 312 ATTRIBUTES_SEQ, \ 313 BOOST_PP_DEC(BOOST_PP_SEQ_SIZE((0)ATTRIBUTES_SEQ))) 314 315 #define BOOST_FUSION_DEFINE_STRUCT_INLINE_ITERATOR(NAME, ATTRIBUTES) \ 316 BOOST_FUSION_DEFINE_STRUCT_ITERATOR_IMPL( \ 317 NAME, \ 318 BOOST_PP_CAT(BOOST_FUSION_DEFINE_STRUCT_FILLER_0 ATTRIBUTES,_END)) 319 320 #define BOOST_FUSION_DEFINE_STRUCT_ITERATOR_IMPL(NAME, ATTRIBUTES_SEQ) \ 321 BOOST_FUSION_DEFINE_STRUCT_INLINE_ITERATOR_IMPL_IMPL( \ 322 NAME, \ 323 ATTRIBUTES_SEQ, \ 324 BOOST_PP_DEC(BOOST_PP_SEQ_SIZE((0)ATTRIBUTES_SEQ))) 325 326 #define BOOST_FUSION_DEFINE_STRUCT_INLINE_ITERATOR_IMPL_IMPL( \ 327 NAME, ATTRIBUTES_SEQ, ATTRIBUTES_SEQ_SIZE) \ 328 \ 329 template <typename boost_fusion_detail_Seq, int N> \ 330 struct BOOST_FUSION_ITERATOR_NAME(NAME) \ 331 : boost::fusion::iterator_facade< \ 332 BOOST_FUSION_ITERATOR_NAME(NAME)<boost_fusion_detail_Seq, N>, \ 333 boost::fusion::random_access_traversal_tag \ 334 > \ 335 { \ 336 typedef boost::mpl::int_<N> index; \ 337 typedef boost_fusion_detail_Seq sequence_type; \ 338 \ 339 BOOST_FUSION_GPU_ENABLED \ 340 BOOST_FUSION_ITERATOR_NAME(NAME)(boost_fusion_detail_Seq& seq) \ 341 : seq_(seq) \ 342 BOOST_FUSION_DEFINE_ITERATOR_WKND_INIT_LIST_ENTRIES( \ 343 (0)ATTRIBUTES_SEQ) \ 344 {} \ 345 \ 346 boost_fusion_detail_Seq& seq_; \ 347 \ 348 BOOST_FUSION_DEFINE_ITERATOR_WKND_MEMBERS(ATTRIBUTES_SEQ_SIZE) \ 349 \ 350 BOOST_FUSION_DEFINE_ITERATOR_VALUE_OF(NAME, ATTRIBUTES_SEQ_SIZE) \ 351 \ 352 BOOST_FUSION_DEFINE_ITERATOR_DEREF(NAME, ATTRIBUTES_SEQ) \ 353 \ 354 template <typename boost_fusion_detail_It> \ 355 struct next \ 356 { \ 357 typedef BOOST_FUSION_ITERATOR_NAME(NAME)< \ 358 typename boost_fusion_detail_It::sequence_type, \ 359 boost_fusion_detail_It::index::value + 1 \ 360 > type; \ 361 \ 362 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \ 363 static type call(boost_fusion_detail_It const& it) \ 364 { \ 365 return type(it.seq_); \ 366 } \ 367 }; \ 368 \ 369 template <typename boost_fusion_detail_It> \ 370 struct prior \ 371 { \ 372 typedef BOOST_FUSION_ITERATOR_NAME(NAME)< \ 373 typename boost_fusion_detail_It::sequence_type, \ 374 boost_fusion_detail_It::index::value - 1 \ 375 > type; \ 376 \ 377 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \ 378 static type call(boost_fusion_detail_It const& it) \ 379 { \ 380 return type(it.seq_); \ 381 } \ 382 }; \ 383 \ 384 template < \ 385 typename boost_fusion_detail_It1, \ 386 typename boost_fusion_detail_It2 \ 387 > \ 388 struct distance \ 389 { \ 390 typedef typename boost::mpl::minus< \ 391 typename boost_fusion_detail_It2::index, \ 392 typename boost_fusion_detail_It1::index \ 393 >::type type; \ 394 \ 395 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \ 396 static type call(boost_fusion_detail_It1 const& /* it1 */, \ 397 boost_fusion_detail_It2 const& /* it2 */) \ 398 { \ 399 return type(); \ 400 } \ 401 }; \ 402 \ 403 template < \ 404 typename boost_fusion_detail_It, \ 405 typename boost_fusion_detail_M \ 406 > \ 407 struct advance \ 408 { \ 409 typedef BOOST_FUSION_ITERATOR_NAME(NAME)< \ 410 typename boost_fusion_detail_It::sequence_type, \ 411 boost_fusion_detail_It::index::value \ 412 + boost_fusion_detail_M::value \ 413 > type; \ 414 \ 415 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \ 416 static type call(boost_fusion_detail_It const& it) \ 417 { \ 418 return type(it.seq_); \ 419 } \ 420 }; \ 421 }; 422 423 424 #define BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS_IMPL_IMPL( \ 425 NAME, ATTRIBUTES_SEQ, ATTRIBUTES_SEQ_SIZE) \ 426 \ 427 NAME() \ 428 BOOST_PP_IF(ATTRIBUTES_SEQ_SIZE, \ 429 BOOST_FUSION_MAKE_DEFAULT_INIT_LIST, \ 430 BOOST_PP_EMPTY)(ATTRIBUTES_SEQ) \ 431 { \ 432 } \ 433 \ 434 BOOST_PP_IF( \ 435 ATTRIBUTES_SEQ_SIZE, \ 436 BOOST_FUSION_MAKE_COPY_CONSTRUCTOR, \ 437 BOOST_FUSION_IGNORE_2) \ 438 (NAME, ATTRIBUTES_SEQ) \ 439 \ 440 template <typename boost_fusion_detail_Seq> \ 441 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED \ 442 NAME(const boost_fusion_detail_Seq& rhs) \ 443 { \ 444 boost::fusion::copy(rhs, *this); \ 445 } \ 446 \ 447 template <typename boost_fusion_detail_Seq> \ 448 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED \ 449 NAME& operator=(const boost_fusion_detail_Seq& rhs) \ 450 { \ 451 boost::fusion::copy(rhs, *this); \ 452 return *this; \ 453 } \ 454 \ 455 template <typename boost_fusion_detail_Sq> \ 456 struct begin \ 457 { \ 458 typedef BOOST_FUSION_ITERATOR_NAME(NAME)<boost_fusion_detail_Sq, 0> \ 459 type; \ 460 \ 461 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \ 462 static type call(boost_fusion_detail_Sq& sq) \ 463 { \ 464 return type(sq); \ 465 } \ 466 }; \ 467 \ 468 template <typename boost_fusion_detail_Sq> \ 469 struct end \ 470 { \ 471 typedef BOOST_FUSION_ITERATOR_NAME(NAME)< \ 472 boost_fusion_detail_Sq, \ 473 ATTRIBUTES_SEQ_SIZE \ 474 > type; \ 475 \ 476 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \ 477 static type call(boost_fusion_detail_Sq& sq) \ 478 { \ 479 return type(sq); \ 480 } \ 481 }; \ 482 \ 483 template <typename boost_fusion_detail_Sq> \ 484 struct size : boost::mpl::int_<ATTRIBUTES_SEQ_SIZE> \ 485 { \ 486 }; \ 487 \ 488 template <typename boost_fusion_detail_Sq> \ 489 struct empty : boost::mpl::bool_<ATTRIBUTES_SEQ_SIZE == 0> \ 490 { \ 491 }; \ 492 \ 493 template < \ 494 typename boost_fusion_detail_Sq, \ 495 typename boost_fusion_detail_N \ 496 > \ 497 struct value_at : value_at< \ 498 boost_fusion_detail_Sq, \ 499 boost::mpl::int_<boost_fusion_detail_N::value> \ 500 > \ 501 { \ 502 }; \ 503 \ 504 BOOST_PP_REPEAT( \ 505 ATTRIBUTES_SEQ_SIZE, \ 506 BOOST_FUSION_MAKE_VALUE_AT_SPECS, \ 507 ~) \ 508 \ 509 template < \ 510 typename boost_fusion_detail_Sq, \ 511 typename boost_fusion_detail_N \ 512 > \ 513 struct at : at< \ 514 boost_fusion_detail_Sq, \ 515 boost::mpl::int_<boost_fusion_detail_N::value> \ 516 > \ 517 { \ 518 }; \ 519 \ 520 BOOST_PP_SEQ_FOR_EACH_I(BOOST_FUSION_MAKE_AT_SPECS, ~, ATTRIBUTES_SEQ) \ 521 \ 522 BOOST_PP_SEQ_FOR_EACH_I(BOOST_FUSION_MAKE_TYPEDEF, ~, ATTRIBUTES_SEQ) \ 523 \ 524 BOOST_PP_SEQ_FOR_EACH_I( \ 525 BOOST_FUSION_MAKE_DATA_MEMBER, \ 526 ~, \ 527 ATTRIBUTES_SEQ) 528 529 #endif 530