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
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>
14 #ifdef BOOST_FUSION_REVERSE_FOLD
15 # ifdef BOOST_FUSION_ITER_FOLD
16 # define BOOST_FUSION_FOLD_NAME reverse_iter_fold
18 # define BOOST_FUSION_FOLD_NAME reverse_fold
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)
27 # ifdef BOOST_FUSION_ITER_FOLD
28 # define BOOST_FUSION_FOLD_NAME iter_fold
30 # define BOOST_FUSION_FOLD_NAME fold
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
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
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)
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
51 FUSION_HASH define BOOST_FUSION_FOLD_IMPL_ENABLER(T) typename T::type
54 # if BOOST_WORKAROUND(BOOST_MSVC, < 1500)
55 # define BOOST_FUSION_FOLD_IMPL_ENABLER(T) void
57 # define BOOST_FUSION_FOLD_IMPL_ENABLER(T) typename T::type
61 namespace boost { namespace fusion
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)
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.
74 #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
78 struct BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)
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)
87 #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) || \
88 (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
91 #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
96 typedef typename State::type type;
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)
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)
113 BOOST_FUSION_FOLD_IMPL_ENABLER(State)
116 BOOST_FUSION_FOLD_IMPL_ENABLER(State)
118 #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
122 #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
123 FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, < 1500)
125 #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) || \
126 (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
129 #if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
133 : BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)<
135 , typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<It>::type
138 typename add_reference<typename State::type>::type,
139 BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(It const)
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)<
154 BOOST_PP_CAT(it_,BOOST_FUSION_FOLD_NAME)(mpl::int_<0>, It const&, typename State::type state, F&)
159 template<typename It, typename State, typename F, int SeqSize>
160 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
161 inline typename lazy_enable_if_c<
163 , BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)<
170 BOOST_PP_CAT(it_,BOOST_FUSION_FOLD_NAME)(mpl::int_<SeqSize>, It const& it, typename State::type state, F& f)
172 return BOOST_PP_CAT(it_,BOOST_FUSION_FOLD_NAME)<
173 typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<It>::type
176 typename add_reference<typename State::type>::type,
177 BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(It const)
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))
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)
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
202 , add_reference<State>
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)
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
216 , add_reference<State>
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)
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>
237 template<typename Seq, typename State, typename F>
238 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
239 inline typename result_of::BOOST_FUSION_FOLD_NAME<
244 BOOST_FUSION_FOLD_NAME(Seq& seq, State const& state, F f)
246 return detail::BOOST_FUSION_FOLD_NAME<Seq, State const, F>(seq, state, f);
249 template<typename Seq, typename State, typename F>
250 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
251 inline typename result_of::BOOST_FUSION_FOLD_NAME<
256 BOOST_FUSION_FOLD_NAME(Seq const& seq, State const& state, F f)
258 return detail::BOOST_FUSION_FOLD_NAME<Seq const, State const, F>(seq, state, f);
261 template<typename Seq, typename State, typename F>
262 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
263 inline typename result_of::BOOST_FUSION_FOLD_NAME<
268 BOOST_FUSION_FOLD_NAME(Seq& seq, State& state, F f)
270 return detail::BOOST_FUSION_FOLD_NAME<Seq, State, F>(seq, state, f);
273 template<typename Seq, typename State, typename F>
274 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
275 inline typename result_of::BOOST_FUSION_FOLD_NAME<
280 BOOST_FUSION_FOLD_NAME(Seq const& seq, State& state, F f)
282 return detail::BOOST_FUSION_FOLD_NAME<Seq const, State, F>(seq, state, f);
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