1
2#ifndef BOOST_MPL_AUX_ITER_FOLD_IF_IMPL_HPP_INCLUDED
3#define BOOST_MPL_AUX_ITER_FOLD_IF_IMPL_HPP_INCLUDED
4
5// Copyright Aleksey Gurtovoy 2001-2004
6// Copyright David Abrahams 2001-2002
7//
8// Distributed under the Boost Software License, Version 1.0.
9// (See accompanying file LICENSE_1_0.txt or copy at
10// http://www.boost.org/LICENSE_1_0.txt)
11//
12// See http://www.boost.org/libs/mpl for documentation.
13
14// $Id$
15// $Date$
16// $Revision$
17
18#if !defined(BOOST_MPL_PREPROCESSING_MODE)
19# include <boost/mpl/identity.hpp>
20# include <boost/mpl/next.hpp>
21# include <boost/mpl/if.hpp>
22# include <boost/mpl/apply.hpp>
23# include <boost/mpl/aux_/value_wknd.hpp>
24#endif
25
26#include <boost/mpl/aux_/config/use_preprocessed.hpp>
27
28#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
29 && !defined(BOOST_MPL_PREPROCESSING_MODE)
30
31# define BOOST_MPL_PREPROCESSED_HEADER iter_fold_if_impl.hpp
32# include <boost/mpl/aux_/include_preprocessed.hpp>
33
34#else
35
36# include <boost/mpl/limits/unrolling.hpp>
37# include <boost/preprocessor/arithmetic/sub.hpp>
38# include <boost/preprocessor/repeat.hpp>
39# include <boost/preprocessor/inc.hpp>
40# include <boost/preprocessor/dec.hpp>
41# include <boost/preprocessor/cat.hpp>
42
43namespace boost { namespace mpl { namespace aux {
44
45template< typename Iterator, typename State >
46struct iter_fold_if_null_step
47{
48 typedef State state;
49 typedef Iterator iterator;
50};
51
52template< bool >
53struct iter_fold_if_step_impl
54{
55 template<
56 typename Iterator
57 , typename State
58 , typename StateOp
59 , typename IteratorOp
60 >
61 struct result_
62 {
63 typedef typename apply2<StateOp,State,Iterator>::type state;
64 typedef typename IteratorOp::type iterator;
65 };
66};
67
68template<>
69struct iter_fold_if_step_impl<false>
70{
71 template<
72 typename Iterator
73 , typename State
74 , typename StateOp
75 , typename IteratorOp
76 >
77 struct result_
78 {
79 typedef State state;
80 typedef Iterator iterator;
81 };
82};
83
84// agurt, 25/jun/02: MSVC 6.5 workaround, had to get rid of inheritance
85// here and in 'iter_fold_if_backward_step', because sometimes it interfered
86// with the "early template instantiation bug" in _really_ ugly ways
87template<
88 typename Iterator
89 , typename State
90 , typename ForwardOp
91 , typename Predicate
92 >
93struct iter_fold_if_forward_step
94{
95 typedef typename apply2<Predicate,State,Iterator>::type not_last;
96 typedef typename iter_fold_if_step_impl<
97 BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value
98 >::template result_< Iterator,State,ForwardOp,mpl::next<Iterator> > impl_;
99
100 typedef typename impl_::state state;
101 typedef typename impl_::iterator iterator;
102};
103
104template<
105 typename Iterator
106 , typename State
107 , typename BackwardOp
108 , typename Predicate
109 >
110struct iter_fold_if_backward_step
111{
112 typedef typename apply2<Predicate,State,Iterator>::type not_last;
113 typedef typename iter_fold_if_step_impl<
114 BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value
115 >::template result_< Iterator,State,BackwardOp,identity<Iterator> > impl_;
116
117 typedef typename impl_::state state;
118 typedef typename impl_::iterator iterator;
119};
120
121
122// local macros, #undef-ined at the end of the header
123
124# define AUX_ITER_FOLD_FORWARD_STEP(unused, i, unused2) \
125 typedef iter_fold_if_forward_step< \
126 typename BOOST_PP_CAT(forward_step,i)::iterator \
127 , typename BOOST_PP_CAT(forward_step,i)::state \
128 , ForwardOp \
129 , ForwardPredicate \
130 > BOOST_PP_CAT(forward_step, BOOST_PP_INC(i)); \
131 /**/
132
133# define AUX_ITER_FOLD_BACKWARD_STEP_FUNC(i) \
134 typedef iter_fold_if_backward_step< \
135 typename BOOST_PP_CAT(forward_step,BOOST_PP_DEC(i))::iterator \
136 , typename BOOST_PP_CAT(backward_step,i)::state \
137 , BackwardOp \
138 , BackwardPredicate \
139 > BOOST_PP_CAT(backward_step,BOOST_PP_DEC(i)); \
140 /**/
141
142# define AUX_ITER_FOLD_BACKWARD_STEP(unused, i, unused2) \
143 AUX_ITER_FOLD_BACKWARD_STEP_FUNC( \
144 BOOST_PP_SUB_D(1,BOOST_MPL_LIMIT_UNROLLING,i) \
145 ) \
146 /**/
147
148# define AUX_LAST_FORWARD_STEP \
149 BOOST_PP_CAT(forward_step, BOOST_MPL_LIMIT_UNROLLING) \
150 /**/
151
152# define AUX_LAST_BACKWARD_STEP \
153 BOOST_PP_CAT(backward_step, BOOST_MPL_LIMIT_UNROLLING) \
154 /**/
155
156template<
157 typename Iterator
158 , typename State
159 , typename ForwardOp
160 , typename ForwardPredicate
161 , typename BackwardOp
162 , typename BackwardPredicate
163 >
164struct iter_fold_if_impl
165{
166 private:
167 typedef iter_fold_if_null_step<Iterator,State> forward_step0;
168 BOOST_PP_REPEAT(
169 BOOST_MPL_LIMIT_UNROLLING
170 , AUX_ITER_FOLD_FORWARD_STEP
171 , unused
172 )
173
174 typedef typename if_<
175 typename AUX_LAST_FORWARD_STEP::not_last
176 , iter_fold_if_impl<
177 typename AUX_LAST_FORWARD_STEP::iterator
178 , typename AUX_LAST_FORWARD_STEP::state
179 , ForwardOp
180 , ForwardPredicate
181 , BackwardOp
182 , BackwardPredicate
183 >
184 , iter_fold_if_null_step<
185 typename AUX_LAST_FORWARD_STEP::iterator
186 , typename AUX_LAST_FORWARD_STEP::state
187 >
188 >::type AUX_LAST_BACKWARD_STEP;
189
190 BOOST_PP_REPEAT(
191 BOOST_MPL_LIMIT_UNROLLING
192 , AUX_ITER_FOLD_BACKWARD_STEP
193 , unused
194 )
195
196 public:
197 typedef typename backward_step0::state state;
198 typedef typename AUX_LAST_BACKWARD_STEP::iterator iterator;
199};
200
201# undef AUX_LAST_BACKWARD_STEP
202# undef AUX_LAST_FORWARD_STEP
203# undef AUX_ITER_FOLD_BACKWARD_STEP
204# undef AUX_ITER_FOLD_BACKWARD_STEP_FUNC
205# undef AUX_ITER_FOLD_FORWARD_STEP
206
207}}}
208
209#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
210#endif // BOOST_MPL_AUX_ITER_FOLD_IF_IMPL_HPP_INCLUDED
211