1 | /*============================================================================= |
2 | Copyright (c) 2001-2011 Joel de Guzman |
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 | #if !defined(FUSION_ERASE_07232005_0534) |
8 | #define FUSION_ERASE_07232005_0534 |
9 | |
10 | #include <boost/fusion/support/config.hpp> |
11 | #include <boost/fusion/iterator/equal_to.hpp> |
12 | #include <boost/fusion/iterator/mpl/convert_iterator.hpp> |
13 | #include <boost/fusion/view/joint_view/joint_view.hpp> |
14 | #include <boost/fusion/view/iterator_range/iterator_range.hpp> |
15 | #include <boost/fusion/support/detail/as_fusion_element.hpp> |
16 | #include <boost/fusion/sequence/intrinsic/begin.hpp> |
17 | #include <boost/fusion/sequence/intrinsic/end.hpp> |
18 | #include <boost/fusion/adapted/mpl/mpl_iterator.hpp> |
19 | #include <boost/fusion/support/is_sequence.hpp> |
20 | #include <boost/utility/enable_if.hpp> |
21 | #include <boost/mpl/if.hpp> |
22 | |
23 | namespace boost { namespace fusion |
24 | { |
25 | namespace result_of |
26 | { |
27 | template <typename Sequence, typename First> |
28 | struct compute_erase_last // put this in detail!!! |
29 | { |
30 | typedef typename result_of::end<Sequence>::type seq_last_type; |
31 | typedef typename convert_iterator<First>::type first_type; |
32 | typedef typename |
33 | mpl::if_< |
34 | result_of::equal_to<first_type, seq_last_type> |
35 | , first_type |
36 | , typename result_of::next<first_type>::type |
37 | >::type |
38 | type; |
39 | |
40 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
41 | static type |
42 | call(First const& first, mpl::false_) |
43 | { |
44 | return fusion::next(convert_iterator<First>::call(first)); |
45 | } |
46 | |
47 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
48 | static type |
49 | call(First const& first, mpl::true_) |
50 | { |
51 | return convert_iterator<First>::call(first); |
52 | } |
53 | |
54 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
55 | static type |
56 | call(First const& first) |
57 | { |
58 | return call(first, result_of::equal_to<first_type, seq_last_type>()); |
59 | } |
60 | }; |
61 | |
62 | struct use_default; |
63 | |
64 | template <class T, class Default> |
65 | struct fusion_default_help |
66 | : mpl::if_< |
67 | is_same<T, use_default> |
68 | , Default |
69 | , T |
70 | > |
71 | { |
72 | }; |
73 | |
74 | template < |
75 | typename Sequence |
76 | , typename First |
77 | , typename Last = use_default> |
78 | struct erase |
79 | { |
80 | typedef typename result_of::begin<Sequence>::type seq_first_type; |
81 | typedef typename result_of::end<Sequence>::type seq_last_type; |
82 | BOOST_STATIC_ASSERT((!result_of::equal_to<seq_first_type, seq_last_type>::value)); |
83 | |
84 | typedef First FirstType; |
85 | typedef typename |
86 | fusion_default_help< |
87 | Last |
88 | , typename compute_erase_last<Sequence, First>::type |
89 | >::type |
90 | LastType; |
91 | |
92 | typedef typename convert_iterator<FirstType>::type first_type; |
93 | typedef typename convert_iterator<LastType>::type last_type; |
94 | typedef iterator_range<seq_first_type, first_type> left_type; |
95 | typedef iterator_range<last_type, seq_last_type> right_type; |
96 | typedef joint_view<left_type, right_type> type; |
97 | }; |
98 | } |
99 | |
100 | template <typename Sequence, typename First> |
101 | BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
102 | inline typename |
103 | lazy_enable_if< |
104 | traits::is_sequence<Sequence> |
105 | , typename result_of::erase<Sequence const, First> |
106 | >::type |
107 | erase(Sequence const& seq, First const& first) |
108 | { |
109 | typedef result_of::erase<Sequence const, First> result_of; |
110 | typedef typename result_of::left_type left_type; |
111 | typedef typename result_of::right_type right_type; |
112 | typedef typename result_of::type result_type; |
113 | |
114 | left_type left( |
115 | fusion::begin(seq) |
116 | , convert_iterator<First>::call(first)); |
117 | right_type right( |
118 | fusion::result_of::compute_erase_last<Sequence const, First>::call(first) |
119 | , fusion::end(seq)); |
120 | return result_type(left, right); |
121 | } |
122 | |
123 | template <typename Sequence, typename First, typename Last> |
124 | BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
125 | inline typename result_of::erase<Sequence const, First, Last>::type |
126 | erase(Sequence const& seq, First const& first, Last const& last) |
127 | { |
128 | typedef result_of::erase<Sequence const, First, Last> result_of; |
129 | typedef typename result_of::left_type left_type; |
130 | typedef typename result_of::right_type right_type; |
131 | typedef typename result_of::type result_type; |
132 | |
133 | left_type left(fusion::begin(seq), first); |
134 | right_type right(last, fusion::end(seq)); |
135 | return result_type(left, right); |
136 | } |
137 | }} |
138 | |
139 | #endif |
140 | |
141 | |