File indexing completed on 2025-01-31 09:41:54
0001
0002
0003
0004
0005
0006
0007 #if !defined(BOOST_FUSION_SEGMENTED_ITERATOR_RANGE_HPP_INCLUDED)
0008 #define BOOST_FUSION_SEGMENTED_ITERATOR_RANGE_HPP_INCLUDED
0009
0010 #include <boost/fusion/support/config.hpp>
0011 #include <boost/detail/workaround.hpp>
0012 #include <boost/mpl/assert.hpp>
0013 #include <boost/type_traits/add_const.hpp>
0014 #include <boost/type_traits/remove_reference.hpp>
0015 #include <boost/fusion/support/tag_of.hpp>
0016 #include <boost/fusion/sequence/intrinsic/begin.hpp>
0017 #include <boost/fusion/sequence/intrinsic/end.hpp>
0018 #include <boost/fusion/iterator/next.hpp>
0019 #include <boost/fusion/iterator/deref.hpp>
0020 #include <boost/fusion/sequence/intrinsic/segments.hpp>
0021 #include <boost/fusion/algorithm/transformation/push_back.hpp>
0022 #include <boost/fusion/algorithm/transformation/push_front.hpp>
0023 #include <boost/fusion/iterator/equal_to.hpp>
0024 #include <boost/fusion/container/list/detail/reverse_cons.hpp>
0025 #include <boost/fusion/iterator/detail/segment_sequence.hpp>
0026 #include <boost/fusion/support/is_sequence.hpp>
0027 #include <boost/utility/enable_if.hpp>
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 namespace boost { namespace fusion
0038 {
0039 template <typename First, typename Last>
0040 struct iterator_range;
0041
0042 namespace result_of
0043 {
0044 template <typename Sequence, typename T>
0045 struct push_back;
0046
0047 template <typename Sequence, typename T>
0048 struct push_front;
0049 }
0050
0051 template <typename Sequence, typename T>
0052 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0053 inline typename
0054 lazy_enable_if<
0055 traits::is_sequence<Sequence>
0056 , result_of::push_back<Sequence const, T>
0057 >::type
0058 push_back(Sequence const& seq, T const& x);
0059
0060 template <typename Sequence, typename T>
0061 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0062 inline typename
0063 lazy_enable_if<
0064 traits::is_sequence<Sequence>
0065 , result_of::push_front<Sequence const, T>
0066 >::type
0067 push_front(Sequence const& seq, T const& x);
0068 }}
0069
0070 namespace boost { namespace fusion { namespace detail
0071 {
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096 template <typename Stack, std::size_t Size = Stack::size::value>
0097 struct make_segment_sequence_front
0098 {
0099
0100 BOOST_MPL_ASSERT((
0101 result_of::equal_to<
0102 typename result_of::end<
0103 typename remove_reference<
0104 typename add_const<
0105 typename result_of::segments<
0106 typename remove_reference<
0107 typename add_const<
0108 typename result_of::deref<
0109 typename Stack::car_type::begin_type
0110 >::type
0111 >::type
0112 >::type
0113 >::type
0114 >::type
0115 >::type
0116 >::type
0117 , typename Stack::cdr_type::car_type::end_type
0118 >));
0119
0120 typedef
0121 iterator_range<
0122 typename result_of::next<
0123 typename Stack::cdr_type::car_type::begin_type
0124 >::type
0125 , typename result_of::end<
0126 typename remove_reference<
0127 typename add_const<
0128 typename result_of::segments<
0129 typename remove_reference<
0130 typename add_const<
0131 typename result_of::deref<
0132 typename Stack::car_type::begin_type
0133 >::type
0134 >::type
0135 >::type
0136 >::type
0137 >::type
0138 >::type
0139 >::type
0140 >
0141 rest_type;
0142
0143 typedef
0144 make_segment_sequence_front<typename Stack::cdr_type>
0145 recurse;
0146
0147 typedef
0148 segment_sequence<
0149 typename result_of::push_front<
0150 rest_type const
0151 , typename recurse::type
0152 >::type
0153 >
0154 type;
0155
0156 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0157 static type call(Stack const& stack)
0158 {
0159
0160
0161
0162
0163 return type(
0164 fusion::push_front(
0165 rest_type(fusion::next(stack.cdr.car.first), fusion::end(fusion::segments(*stack.car.first)))
0166 , recurse::call(stack.cdr)));
0167 }
0168 };
0169
0170 template <typename Stack>
0171 struct make_segment_sequence_front<Stack, 2>
0172 {
0173
0174 BOOST_MPL_ASSERT((
0175 result_of::equal_to<
0176 typename result_of::end<
0177 typename remove_reference<
0178 typename add_const<
0179 typename result_of::deref<
0180 typename Stack::car_type::begin_type
0181 >::type
0182 >::type
0183 >::type
0184 >::type
0185 , typename Stack::cdr_type::car_type::end_type
0186 >));
0187
0188 typedef
0189 iterator_range<
0190 typename Stack::cdr_type::car_type::begin_type
0191 , typename result_of::end<
0192 typename remove_reference<
0193 typename add_const<
0194 typename result_of::deref<
0195 typename Stack::car_type::begin_type
0196 >::type
0197 >::type
0198 >::type
0199 >::type
0200 >
0201 type;
0202
0203 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0204 static type call(Stack const& stack)
0205 {
0206
0207 return type(stack.cdr.car.first, fusion::end(*stack.car.first));
0208 }
0209 };
0210
0211 template <typename Stack>
0212 struct make_segment_sequence_front<Stack, 1>
0213 {
0214 typedef typename Stack::cdr_type type;
0215
0216 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0217 static type call(Stack const &stack)
0218 {
0219 return stack.cdr;
0220 }
0221 };
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244 template <typename Stack, std::size_t Size = Stack::size::value>
0245 struct make_segment_sequence_back
0246 {
0247
0248 BOOST_MPL_ASSERT((
0249 result_of::equal_to<
0250 typename result_of::end<
0251 typename remove_reference<
0252 typename add_const<
0253 typename result_of::segments<
0254 typename remove_reference<
0255 typename add_const<
0256 typename result_of::deref<
0257 typename Stack::car_type::begin_type
0258 >::type
0259 >::type
0260 >::type
0261 >::type
0262 >::type
0263 >::type
0264 >::type
0265 , typename Stack::cdr_type::car_type::end_type
0266 >));
0267
0268 typedef
0269 iterator_range<
0270 typename result_of::begin<
0271 typename remove_reference<
0272 typename add_const<
0273 typename result_of::segments<
0274 typename remove_reference<
0275 typename add_const<
0276 typename result_of::deref<
0277 typename Stack::car_type::begin_type
0278 >::type
0279 >::type
0280 >::type
0281 >::type
0282 >::type
0283 >::type
0284 >::type
0285 , typename Stack::cdr_type::car_type::begin_type
0286 >
0287 rest_type;
0288
0289 typedef
0290 make_segment_sequence_back<typename Stack::cdr_type>
0291 recurse;
0292
0293 typedef
0294 segment_sequence<
0295 typename result_of::push_back<
0296 rest_type const
0297 , typename recurse::type
0298 >::type
0299 >
0300 type;
0301
0302 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0303 static type call(Stack const& stack)
0304 {
0305
0306
0307
0308
0309 return type(
0310 fusion::push_back(
0311 rest_type(fusion::begin(fusion::segments(*stack.car.first)), stack.cdr.car.first)
0312 , recurse::call(stack.cdr)));
0313 }
0314 };
0315
0316 template <typename Stack>
0317 struct make_segment_sequence_back<Stack, 2>
0318 {
0319
0320 BOOST_MPL_ASSERT((
0321 result_of::equal_to<
0322 typename result_of::end<
0323 typename remove_reference<
0324 typename add_const<
0325 typename result_of::deref<
0326 typename Stack::car_type::begin_type
0327 >::type
0328 >::type
0329 >::type
0330 >::type
0331 , typename Stack::cdr_type::car_type::end_type
0332 >));
0333
0334 typedef
0335 iterator_range<
0336 typename result_of::begin<
0337 typename remove_reference<
0338 typename add_const<
0339 typename result_of::deref<
0340 typename Stack::car_type::begin_type
0341 >::type
0342 >::type
0343 >::type
0344 >::type
0345 , typename Stack::cdr_type::car_type::begin_type
0346 >
0347 type;
0348
0349 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0350 static type call(Stack const& stack)
0351 {
0352
0353 return type(fusion::begin(*stack.car.first), stack.cdr.car.first);
0354 }
0355 };
0356
0357 template <typename Stack>
0358 struct make_segment_sequence_back<Stack, 1>
0359 {
0360 typedef typename Stack::cdr_type type;
0361
0362 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0363 static type call(Stack const& stack)
0364 {
0365 return stack.cdr;
0366 }
0367 };
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403 template <
0404 typename StackBegin
0405 , typename StackEnd
0406 , int StackBeginSize = StackBegin::size::value
0407 , int StackEndSize = StackEnd::size::value>
0408 struct make_segmented_range_reduce;
0409
0410 template <
0411 typename StackBegin
0412 , typename StackEnd
0413 , bool SameSegment
0414 #if !(BOOST_WORKAROUND(BOOST_GCC, >= 40000) && BOOST_WORKAROUND(BOOST_GCC, < 40200))
0415 = result_of::equal_to<
0416 typename StackBegin::car_type::begin_type
0417 , typename StackEnd::car_type::begin_type
0418 >::type::value
0419 #endif
0420 >
0421 struct make_segmented_range_reduce2
0422 {
0423 typedef
0424 iterator_range<
0425 typename result_of::next<
0426 typename StackBegin::car_type::begin_type
0427 >::type
0428 , typename StackEnd::car_type::begin_type
0429 >
0430 rest_type;
0431
0432 typedef
0433 segment_sequence<
0434 typename result_of::push_back<
0435 typename result_of::push_front<
0436 rest_type const
0437 , typename make_segment_sequence_front<StackBegin>::type
0438 >::type const
0439 , typename make_segment_sequence_back<StackEnd>::type
0440 >::type
0441 >
0442 type;
0443
0444 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0445 static type call(StackBegin stack_begin, StackEnd stack_end)
0446 {
0447
0448
0449
0450
0451
0452
0453
0454
0455 return type(
0456 fusion::push_back(
0457 fusion::push_front(
0458 rest_type(fusion::next(stack_begin.car.first), stack_end.car.first)
0459 , make_segment_sequence_front<StackBegin>::call(stack_begin))
0460 , make_segment_sequence_back<StackEnd>::call(stack_end)));
0461 }
0462 };
0463
0464 template <typename StackBegin, typename StackEnd>
0465 struct make_segmented_range_reduce2<StackBegin, StackEnd, true>
0466 {
0467 typedef
0468 make_segmented_range_reduce<
0469 typename StackBegin::cdr_type
0470 , typename StackEnd::cdr_type
0471 >
0472 impl;
0473
0474 typedef
0475 typename impl::type
0476 type;
0477
0478 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0479 static type call(StackBegin stack_begin, StackEnd stack_end)
0480 {
0481 return impl::call(stack_begin.cdr, stack_end.cdr);
0482 }
0483 };
0484
0485 template <typename StackBegin, typename StackEnd, int StackBeginSize, int StackEndSize>
0486 struct make_segmented_range_reduce
0487 : make_segmented_range_reduce2<StackBegin, StackEnd
0488 #if BOOST_WORKAROUND(BOOST_GCC, >= 40000) && BOOST_WORKAROUND(BOOST_GCC, < 40200)
0489 , result_of::equal_to<
0490 typename StackBegin::car_type::begin_type
0491 , typename StackEnd::car_type::begin_type
0492 >::type::value
0493 #endif
0494 >
0495 {};
0496
0497 template <typename StackBegin, typename StackEnd>
0498 struct make_segmented_range_reduce<StackBegin, StackEnd, 1, 1>
0499 {
0500 typedef
0501 iterator_range<
0502 typename StackBegin::car_type::begin_type
0503 , typename StackEnd::car_type::begin_type
0504 >
0505 range_type;
0506
0507 typedef
0508 single_view<range_type>
0509 segment_type;
0510
0511 typedef
0512 segment_sequence<segment_type>
0513 type;
0514
0515 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0516 static type call(StackBegin stack_begin, StackEnd stack_end)
0517 {
0518
0519
0520
0521 return type(segment_type(range_type(stack_begin.car.first, stack_end.car.first)));
0522 }
0523 };
0524
0525
0526
0527
0528
0529
0530 template <typename Begin, typename End>
0531 struct make_segmented_range
0532 {
0533 typedef reverse_cons<typename Begin::context_type> reverse_begin_cons;
0534 typedef reverse_cons<typename End::context_type> reverse_end_cons;
0535
0536 typedef
0537 make_segmented_range_reduce<
0538 typename reverse_begin_cons::type
0539 , typename reverse_end_cons::type
0540 >
0541 impl;
0542
0543 typedef typename impl::type type;
0544
0545 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0546 static type call(Begin const& begin, End const& end)
0547 {
0548 return impl::call(
0549 reverse_begin_cons::call(begin.context)
0550 , reverse_end_cons::call(end.context));
0551 }
0552 };
0553
0554 }}}
0555
0556 #endif