• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
BOOST_FUSION_FOLD_IMPL_ENABLER(T)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
295