]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/proto/transform/fold.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / proto / transform / fold.hpp
1 ///////////////////////////////////////////////////////////////////////////////
2 /// \file fold.hpp
3 /// Contains definition of the fold<> and reverse_fold<> transforms.
4 //
5 // Copyright 2008 Eric Niebler. Distributed under the Boost
6 // Software License, Version 1.0. (See accompanying file
7 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8
9 #ifndef BOOST_PROTO_TRANSFORM_FOLD_HPP_EAN_11_04_2007
10 #define BOOST_PROTO_TRANSFORM_FOLD_HPP_EAN_11_04_2007
11
12 #include <boost/preprocessor/cat.hpp>
13 #include <boost/preprocessor/iteration/iterate.hpp>
14 #include <boost/preprocessor/arithmetic/inc.hpp>
15 #include <boost/preprocessor/arithmetic/sub.hpp>
16 #include <boost/preprocessor/repetition/repeat.hpp>
17 #include <boost/fusion/include/fold.hpp>
18 #include <boost/fusion/include/reverse_fold.hpp>
19 #include <boost/proto/proto_fwd.hpp>
20 #include <boost/proto/traits.hpp>
21 #include <boost/proto/transform/impl.hpp>
22 #include <boost/proto/transform/when.hpp>
23
24 namespace boost { namespace proto
25 {
26 namespace detail
27 {
28 template<typename Transform, typename Data>
29 struct as_callable
30 {
31 as_callable(Data d)
32 : d_(d)
33 {}
34
35 template<typename Sig>
36 struct result;
37
38 template<typename This, typename State, typename Expr>
39 struct result<This(State, Expr)>
40 {
41 typedef
42 typename when<_, Transform>::template impl<Expr, State, Data>::result_type
43 type;
44 };
45
46 template<typename State, typename Expr>
47 typename when<_, Transform>::template impl<Expr &, State const &, Data>::result_type
48 operator ()(State const &s, Expr &e) const
49 {
50 return typename when<_, Transform>::template impl<Expr &, State const &, Data>()(e, s, this->d_);
51 }
52
53 private:
54 Data d_;
55 };
56
57 template<
58 typename State0
59 , typename Fun
60 , typename Expr
61 , typename State
62 , typename Data
63 , long Arity = arity_of<Expr>::value
64 >
65 struct fold_impl
66 {};
67
68 template<
69 typename State0
70 , typename Fun
71 , typename Expr
72 , typename State
73 , typename Data
74 , long Arity = arity_of<Expr>::value
75 >
76 struct reverse_fold_impl
77 {};
78
79 #include <boost/proto/transform/detail/fold_impl.hpp>
80
81 } // namespace detail
82
83 /// \brief A PrimitiveTransform that invokes the <tt>fusion::fold\<\></tt>
84 /// algorithm to accumulate
85 template<typename Sequence, typename State0, typename Fun>
86 struct fold : transform<fold<Sequence, State0, Fun> >
87 {
88 template<typename Expr, typename State, typename Data>
89 struct impl : transform_impl<Expr, State, Data>
90 {
91 /// \brief A Fusion sequence.
92 typedef
93 typename remove_reference<
94 typename when<_, Sequence>::template impl<Expr, State, Data>::result_type
95 >::type
96 sequence;
97
98 /// \brief An initial state for the fold.
99 typedef
100 typename remove_reference<
101 typename when<_, State0>::template impl<Expr, State, Data>::result_type
102 >::type
103 state0;
104
105 /// \brief <tt>fun(d)(e,s) == when\<_,Fun\>()(e,s,d)</tt>
106 typedef
107 detail::as_callable<Fun, Data>
108 fun;
109
110 typedef
111 typename fusion::result_of::fold<
112 sequence
113 , state0
114 , fun
115 >::type
116 result_type;
117
118 /// Let \c seq be <tt>when\<_, Sequence\>()(e, s, d)</tt>, let
119 /// \c state0 be <tt>when\<_, State0\>()(e, s, d)</tt>, and
120 /// let \c fun(d) be an object such that <tt>fun(d)(e, s)</tt>
121 /// is equivalent to <tt>when\<_, Fun\>()(e, s, d)</tt>. Then, this
122 /// function returns <tt>fusion::fold(seq, state0, fun(d))</tt>.
123 ///
124 /// \param e The current expression
125 /// \param s The current state
126 /// \param d An arbitrary data
127 result_type operator ()(
128 typename impl::expr_param e
129 , typename impl::state_param s
130 , typename impl::data_param d
131 ) const
132 {
133 typename when<_, Sequence>::template impl<Expr, State, Data> seq;
134 detail::as_callable<Fun, Data> f(d);
135 return fusion::fold(
136 seq(e, s, d)
137 , typename when<_, State0>::template impl<Expr, State, Data>()(e, s, d)
138 , f
139 );
140 }
141 };
142 };
143
144 /// \brief A PrimitiveTransform that is the same as the
145 /// <tt>fold\<\></tt> transform, except that it folds
146 /// back-to-front instead of front-to-back.
147 template<typename Sequence, typename State0, typename Fun>
148 struct reverse_fold : transform<reverse_fold<Sequence, State0, Fun> >
149 {
150 template<typename Expr, typename State, typename Data>
151 struct impl : transform_impl<Expr, State, Data>
152 {
153 /// \brief A Fusion sequence.
154 typedef
155 typename remove_reference<
156 typename when<_, Sequence>::template impl<Expr, State, Data>::result_type
157 >::type
158 sequence;
159
160 /// \brief An initial state for the fold.
161 typedef
162 typename remove_reference<
163 typename when<_, State0>::template impl<Expr, State, Data>::result_type
164 >::type
165 state0;
166
167 /// \brief <tt>fun(d)(e,s) == when\<_,Fun\>()(e,s,d)</tt>
168 typedef
169 detail::as_callable<Fun, Data>
170 fun;
171
172 typedef
173 typename fusion::result_of::reverse_fold<
174 sequence
175 , state0
176 , fun
177 >::type
178 result_type;
179
180 /// Let \c seq be <tt>when\<_, Sequence\>()(e, s, d)</tt>, let
181 /// \c state0 be <tt>when\<_, State0\>()(e, s, d)</tt>, and
182 /// let \c fun(d) be an object such that <tt>fun(d)(e, s)</tt>
183 /// is equivalent to <tt>when\<_, Fun\>()(e, s, d)</tt>. Then, this
184 /// function returns <tt>fusion::fold(seq, state0, fun(d))</tt>.
185 ///
186 /// \param e The current expression
187 /// \param s The current state
188 /// \param d An arbitrary data
189 result_type operator ()(
190 typename impl::expr_param e
191 , typename impl::state_param s
192 , typename impl::data_param d
193 ) const
194 {
195 typename when<_, Sequence>::template impl<Expr, State, Data> seq;
196 detail::as_callable<Fun, Data> f(d);
197 return fusion::reverse_fold(
198 seq(e, s, d)
199 , typename when<_, State0>::template impl<Expr, State, Data>()(e, s, d)
200 , f
201 );
202 }
203 };
204 };
205
206 // This specialization is only for improved compile-time performance
207 // in the commom case when the Sequence transform is \c proto::_.
208 //
209 /// INTERNAL ONLY
210 ///
211 template<typename State0, typename Fun>
212 struct fold<_, State0, Fun> : transform<fold<_, State0, Fun> >
213 {
214 template<typename Expr, typename State, typename Data>
215 struct impl
216 : detail::fold_impl<State0, Fun, Expr, State, Data>
217 {};
218 };
219
220 // This specialization is only for improved compile-time performance
221 // in the commom case when the Sequence transform is \c proto::_.
222 //
223 /// INTERNAL ONLY
224 ///
225 template<typename State0, typename Fun>
226 struct reverse_fold<_, State0, Fun> : transform<reverse_fold<_, State0, Fun> >
227 {
228 template<typename Expr, typename State, typename Data>
229 struct impl
230 : detail::reverse_fold_impl<State0, Fun, Expr, State, Data>
231 {};
232 };
233
234 /// INTERNAL ONLY
235 ///
236 template<typename Sequence, typename State, typename Fun>
237 struct is_callable<fold<Sequence, State, Fun> >
238 : mpl::true_
239 {};
240
241 /// INTERNAL ONLY
242 ///
243 template<typename Sequence, typename State, typename Fun>
244 struct is_callable<reverse_fold<Sequence, State, Fun> >
245 : mpl::true_
246 {};
247
248 }}
249
250 #endif