]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*============================================================================= |
2 | Copyright (c) 2001-2011 Joel de Guzman | |
3 | Copyright (c) 2006 Dan Marsden | |
4 | Copyright (c) 2009-2010 Christopher Schmidt | |
5 | Copyright (c) 2015 Kohei Takahashi | |
6 | ||
7 | Distributed under the Boost Software License, Version 1.0. (See accompanying | |
8 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
9 | ==============================================================================*/ | |
10 | #include <boost/preprocessor/cat.hpp> | |
11 | ||
12 | #define FUSION_HASH # | |
13 | ||
14 | #ifdef BOOST_FUSION_REVERSE_FOLD | |
15 | # ifdef BOOST_FUSION_ITER_FOLD | |
16 | # define BOOST_FUSION_FOLD_NAME reverse_iter_fold | |
17 | # else | |
18 | # define BOOST_FUSION_FOLD_NAME reverse_fold | |
19 | # endif | |
20 | ||
21 | # define BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION end | |
22 | # define BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION prior | |
23 | # define BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(IT) \ | |
24 | typename fusion::result_of::prior<IT>::type | |
25 | # define BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM(IT) fusion::prior(IT) | |
26 | #else | |
27 | # ifdef BOOST_FUSION_ITER_FOLD | |
28 | # define BOOST_FUSION_FOLD_NAME iter_fold | |
29 | # else | |
30 | # define BOOST_FUSION_FOLD_NAME fold | |
31 | # endif | |
32 | ||
33 | # define BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION begin | |
34 | # define BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION next | |
35 | # define BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(IT) IT | |
36 | # define BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM(IT) IT | |
37 | #endif | |
38 | #ifdef BOOST_FUSION_ITER_FOLD | |
39 | # define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(IT) IT& | |
40 | # define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(IT) IT | |
41 | #else | |
42 | # define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(IT) \ | |
43 | typename fusion::result_of::deref<IT>::type | |
44 | # define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(IT) fusion::deref(IT) | |
45 | #endif | |
46 | ||
47 | #if (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)) | |
48 | FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, < 1500) | |
49 | FUSION_HASH define BOOST_FUSION_FOLD_IMPL_ENABLER(T) void | |
50 | FUSION_HASH else | |
51 | FUSION_HASH define BOOST_FUSION_FOLD_IMPL_ENABLER(T) typename T::type | |
52 | FUSION_HASH endif | |
53 | #else | |
54 | # if BOOST_WORKAROUND(BOOST_MSVC, < 1500) | |
55 | # define BOOST_FUSION_FOLD_IMPL_ENABLER(T) void | |
56 | # else | |
57 | # define BOOST_FUSION_FOLD_IMPL_ENABLER(T) typename T::type | |
58 | # endif | |
59 | #endif | |
60 | ||
61 | namespace boost { namespace fusion | |
62 | { | |
63 | namespace detail | |
64 | { | |
65 | template<int SeqSize, typename It, typename State, typename F, typename = void | |
66 | #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) | |
67 | FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, < 1500) | |
68 | #endif | |
69 | #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) || \ | |
70 | (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)) | |
71 | // Dirty hack: those compilers cannot choose exactly one partial specialization. | |
72 | , bool = SeqSize == 0 | |
73 | #endif | |
74 | #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) | |
75 | FUSION_HASH endif | |
76 | #endif | |
77 | > | |
78 | struct BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME) | |
79 | {}; | |
80 | ||
81 | template<typename It, typename State, typename F> | |
82 | struct BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)<0,It,State,F | |
83 | , typename boost::enable_if_has_type<BOOST_FUSION_FOLD_IMPL_ENABLER(State)>::type | |
84 | #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) | |
85 | FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, < 1500) | |
86 | #endif | |
87 | #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) || \ | |
88 | (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)) | |
89 | , true | |
90 | #endif | |
91 | #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) | |
92 | FUSION_HASH endif | |
93 | #endif | |
94 | > | |
95 | { | |
96 | typedef typename State::type type; | |
97 | }; | |
98 | ||
99 | template<int SeqSize, typename It, typename State, typename F> | |
100 | struct BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)<SeqSize,It,State,F | |
101 | , typename boost::enable_if_has_type< | |
102 | #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) | |
103 | FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, >= 1500) | |
104 | #endif | |
105 | #if BOOST_WORKAROUND(BOOST_MSVC, >= 1500) || \ | |
106 | (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)) | |
107 | // Following SFINAE enables to avoid MSVC 9's partial specialization | |
108 | // ambiguous bug but MSVC 8 don't compile, and moreover MSVC 8 style | |
109 | // workaround won't work with MSVC 9. | |
110 | typename boost::disable_if_c<SeqSize == 0, State>::type::type | |
111 | #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) | |
112 | FUSION_HASH else | |
113 | BOOST_FUSION_FOLD_IMPL_ENABLER(State) | |
114 | #endif | |
115 | #else | |
116 | BOOST_FUSION_FOLD_IMPL_ENABLER(State) | |
117 | #endif | |
118 | #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) | |
119 | FUSION_HASH endif | |
120 | #endif | |
121 | >::type | |
122 | #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) | |
123 | FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, < 1500) | |
124 | #endif | |
125 | #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) || \ | |
126 | (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)) | |
127 | , false | |
128 | #endif | |
129 | #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) | |
130 | FUSION_HASH endif | |
131 | #endif | |
132 | > | |
133 | : BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)< | |
134 | SeqSize-1 | |
135 | , typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<It>::type | |
136 | , boost::result_of< | |
137 | F( | |
138 | typename add_reference<typename State::type>::type, | |
139 | BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(It const) | |
140 | ) | |
141 | > | |
142 | , F | |
143 | > | |
144 | {}; | |
145 | ||
146 | template<typename It, typename State, typename F> | |
147 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED | |
148 | inline typename BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)< | |
149 | 0 | |
150 | , It | |
151 | , State | |
152 | , F | |
153 | >::type | |
154 | BOOST_PP_CAT(it_,BOOST_FUSION_FOLD_NAME)(mpl::int_<0>, It const&, typename State::type state, F&) | |
155 | { | |
156 | return state; | |
157 | } | |
158 | ||
159 | template<typename It, typename State, typename F, int SeqSize> | |
160 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED | |
161 | inline typename lazy_enable_if_c< | |
162 | SeqSize != 0 | |
163 | , BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)< | |
164 | SeqSize | |
165 | , It | |
166 | , State | |
167 | , F | |
168 | > | |
169 | >::type | |
170 | BOOST_PP_CAT(it_,BOOST_FUSION_FOLD_NAME)(mpl::int_<SeqSize>, It const& it, typename State::type state, F& f) | |
171 | { | |
172 | return BOOST_PP_CAT(it_,BOOST_FUSION_FOLD_NAME)< | |
173 | typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<It>::type | |
174 | , boost::result_of< | |
175 | F( | |
176 | typename add_reference<typename State::type>::type, | |
177 | BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(It const) | |
178 | ) | |
179 | > | |
180 | , F | |
181 | >( | |
182 | mpl::int_<SeqSize-1>() | |
183 | , fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it) | |
184 | , f(state, BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it)) | |
185 | , f | |
186 | ); | |
187 | } | |
188 | ||
189 | template<typename Seq, typename State, typename F | |
190 | , bool = traits::is_sequence<Seq>::value | |
191 | , bool = traits::is_segmented<Seq>::value> | |
192 | struct BOOST_PP_CAT(result_of_,BOOST_FUSION_FOLD_NAME) | |
193 | {}; | |
194 | ||
195 | template<typename Seq, typename State, typename F> | |
196 | struct BOOST_PP_CAT(result_of_,BOOST_FUSION_FOLD_NAME)<Seq, State, F, true, false> | |
197 | : BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)< | |
198 | result_of::size<Seq>::value | |
199 | , BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM( | |
200 | typename result_of::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION<Seq>::type | |
201 | ) | |
202 | , add_reference<State> | |
203 | , F | |
204 | > | |
205 | {}; | |
206 | ||
207 | template<typename Seq, typename State, typename F> | |
208 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED | |
209 | inline typename BOOST_PP_CAT(result_of_,BOOST_FUSION_FOLD_NAME)<Seq, State, F>::type | |
210 | BOOST_FUSION_FOLD_NAME(Seq& seq, State& state, F& f) | |
211 | { | |
212 | return BOOST_PP_CAT(it_,BOOST_FUSION_FOLD_NAME)< | |
213 | BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM( | |
214 | typename result_of::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION<Seq>::type | |
215 | ) | |
216 | , add_reference<State> | |
217 | , F | |
218 | >( | |
219 | typename result_of::size<Seq>::type() | |
220 | , BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM( | |
221 | fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq) | |
222 | ) | |
223 | , state | |
224 | , f | |
225 | ); | |
226 | } | |
227 | } | |
228 | ||
229 | namespace result_of | |
230 | { | |
231 | template<typename Seq, typename State, typename F> | |
232 | struct BOOST_FUSION_FOLD_NAME | |
233 | : detail::BOOST_PP_CAT(result_of_,BOOST_FUSION_FOLD_NAME)<Seq, State, F> | |
234 | {}; | |
235 | } | |
236 | ||
237 | template<typename Seq, typename State, typename F> | |
238 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED | |
239 | inline typename result_of::BOOST_FUSION_FOLD_NAME< | |
240 | Seq | |
241 | , State const | |
242 | , F | |
243 | >::type | |
244 | BOOST_FUSION_FOLD_NAME(Seq& seq, State const& state, F f) | |
245 | { | |
246 | return detail::BOOST_FUSION_FOLD_NAME<Seq, State const, F>(seq, state, f); | |
247 | } | |
248 | ||
249 | template<typename Seq, typename State, typename F> | |
250 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED | |
251 | inline typename result_of::BOOST_FUSION_FOLD_NAME< | |
252 | Seq const | |
253 | , State const | |
254 | , F | |
255 | >::type | |
256 | BOOST_FUSION_FOLD_NAME(Seq const& seq, State const& state, F f) | |
257 | { | |
258 | return detail::BOOST_FUSION_FOLD_NAME<Seq const, State const, F>(seq, state, f); | |
259 | } | |
260 | ||
261 | template<typename Seq, typename State, typename F> | |
262 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED | |
263 | inline typename result_of::BOOST_FUSION_FOLD_NAME< | |
264 | Seq | |
265 | , State | |
266 | , F | |
267 | >::type | |
268 | BOOST_FUSION_FOLD_NAME(Seq& seq, State& state, F f) | |
269 | { | |
270 | return detail::BOOST_FUSION_FOLD_NAME<Seq, State, F>(seq, state, f); | |
271 | } | |
272 | ||
273 | template<typename Seq, typename State, typename F> | |
274 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED | |
275 | inline typename result_of::BOOST_FUSION_FOLD_NAME< | |
276 | Seq const | |
277 | , State | |
278 | , F | |
279 | >::type | |
280 | BOOST_FUSION_FOLD_NAME(Seq const& seq, State& state, F f) | |
281 | { | |
282 | return detail::BOOST_FUSION_FOLD_NAME<Seq const, State, F>(seq, state, f); | |
283 | } | |
284 | }} | |
285 | ||
286 | #undef BOOST_FUSION_FOLD_NAME | |
287 | #undef BOOST_FUSION_FOLD_IMPL_ENABLER | |
288 | #undef BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION | |
289 | #undef BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION | |
290 | #undef BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM | |
291 | #undef BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM | |
292 | #undef BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM | |
293 | #undef BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM | |
294 | #undef FUSION_HASH |