Ticket #3044: while.cpp

File while.cpp, 9.3 KB (added by cppljevans@…, 13 years ago)

possible solution

Line 
1#ifndef BOOST_MPL_WHILE_HPP_INCLUDED
2#define BOOST_MPL_WHILE_HPP_INCLUDED
3// Copyright Larry Evans 2009
4//
5
6// $Id: while.cpp,v 1.20 2009/04/23 15:29:47 evansl Exp evansl $
7// $Date: 2009/04/23 15:29:47 $
8// $Revision: 1.20 $
9
10#include <boost/mpl/eval_if.hpp>
11#include <boost/mpl/apply.hpp>
12#include <boost/mpl/identity.hpp>
13#include <boost/mpl/arg.hpp>
14#include <boost/mpl/always.hpp>
15
16namespace boost
17{
18namespace mpl
19{
20 //Notation:
21 // MFC_or_LE = Metafunction class or Lambda Expression
22 // (See Description on libs/mpl/doc/refmanual/apply.html)
23 //
24 // State = Any type.
25 // (this is term used in libs/mpl/doc/refmanual/fold.html)
26 //
27 template
28 < class StateMeta//nullary metafunction returning current State.
29 , class PredOp=always<false_>//unary MFC_or_LE from State to Bool.
30 , class ThenOp=identity<arg<1> >//unary MFC_or_LE from State to State,
31 >
32 struct while_
33 {
34 typedef
35 typename eval_if
36 < typename apply<PredOp,typename StateMeta::type>::type
37 , while_
38 < apply<ThenOp,typename StateMeta::type>
39 , PredOp
40 , ThenOp
41 >
42 , StateMeta
43 >::type
44 type
45 ;
46 };
47
48}//exit mpl namespace
49}//exit boost namespace
50#endif
51
52#ifndef BOOST_MPL_WHILE_RECUR_SEQ_HPP_INCLUDED
53#define BOOST_MPL_WHILE_RECUR_SEQ_HPP_INCLUDED
54//#include <boost/mpl/while.hpp>
55#include <boost/mpl/begin_end.hpp>
56#include <boost/mpl/next.hpp>
57#include <boost/mpl/deref.hpp>
58#include <boost/mpl/push_front.hpp>
59#include <boost/mpl/and.hpp>
60#include <boost/mpl/list.hpp>
61
62namespace boost
63{
64namespace mpl
65{
66namespace aux
67{
68namespace while_recur_seq
69{
70
71 template
72 < typename State
73 >
74struct while_state
75{
76 typedef State state;
77 typedef while_state type;
78};
79 template
80 < typename Stack
81 , typename State
82 >
83struct while_stack_state
84: while_state<State>
85{
86 typedef Stack stack;
87 typedef while_stack_state type;
88};
89 template
90 < typename State
91 , typename Iter
92 >
93struct while_state_iter
94: State //either while_state or while_stack_state
95{
96 typedef Iter iter;
97 typedef while_state_iter type;
98};
99
100 template
101 < typename State
102 , typename Op
103 >
104struct forward_step
105{
106 typedef
107 typename deref<typename State::iter>::type
108 item;
109 typedef
110 while_state_iter
111 < while_stack_state
112 < typename push_front<typename State::stack, item>::type
113 , typename apply<Op,typename State::state,item>::type
114 >
115 , typename next<typename State::iter>::type
116 >
117 type;
118
119};
120
121 template
122 < typename State
123 , typename Op
124 >
125struct backward_step
126{
127 typedef
128 typename deref<typename State::iter>::type
129 item;
130 typedef
131 while_state_iter
132 < while_state<typename apply<Op,typename State::state,item>::type>
133 , typename next<typename State::iter>::type
134 >
135 type;
136
137};
138
139 template
140 < typename State
141 , typename Op
142 >
143struct direction_step
144;
145
146 template
147 < typename State
148 , typename Iter
149 , typename Op
150 >
151struct direction_step
152 < while_state_iter
153 < while_state<State>
154 , Iter
155 >
156 , Op
157 >
158: backward_step
159 < while_state_iter<State,Iter>
160 , Op
161 >
162{
163};
164
165 template
166 < typename Stack
167 , typename State
168 , typename Iter
169 , typename Op
170 >
171struct direction_step
172 < while_state_iter
173 < while_stack_state<Stack,State>
174 , Iter
175 >
176 , Op
177 >
178: forward_step
179 < while_state_iter
180 < while_stack_state<Stack,State>
181 , Iter
182 >
183 , Op
184 >
185{
186};
187
188 template
189 < typename StateNow
190 , typename IterLast
191 >
192struct not_iter_last
193: not_
194 < is_same
195 < typename StateNow::iter
196 , IterLast
197 >
198 >
199{
200};
201
202 template
203 < typename Op
204 , typename LazyExpr
205 >
206struct apply_lazy1
207{
208 typedef typename apply<Op,typename LazyExpr::type>::type type;
209};
210 template
211 < typename StateNow
212 , typename IterLast
213 , typename Predicate=always<true_>
214 >
215struct not_iter_last_pred
216: and_
217 < not_iter_last<StateNow,IterLast>
218 , apply_lazy1<Predicate, deref<typename StateNow::iter> >
219 >
220{
221};
222
223}//exit while_recur_seq namespace
224
225}//exit aux namespace
226
227 template
228 < typename Seq
229 , typename State
230 , typename OperStateVal
231 , typename PredicateVal=always<true_>
232 , template<class,class>class Step=while_recur_seq::backward_step
233 >
234struct while_seq
235{
236 typedef
237 typename begin<Seq>::type
238 first;
239 typedef
240 typename end<Seq>::type
241 last;
242 typedef
243 while_recur_seq::while_state_iter<State,first>
244 state_iter;
245 typedef
246 Step
247 < arg<1>
248 , typename lambda<OperStateVal>::type
249 >
250 oper_state_ref;
251 typedef
252 while_recur_seq::not_iter_last_pred
253 < arg<1>
254 , last
255 , typename lambda<PredicateVal>::type
256 >
257 predicate_ref;
258 typedef
259 typename while_
260 < state_iter
261 , predicate_ref
262 , oper_state_ref
263 >::type
264 type;
265};
266
267 template
268 < typename BOOST_MPL_AUX_NA_PARAM(Sequence)
269 , typename BOOST_MPL_AUX_NA_PARAM(State)
270 , typename BOOST_MPL_AUX_NA_PARAM(ForwardOp)
271 , typename BOOST_MPL_AUX_NA_PARAM(ForwardPredicate)
272 , typename BOOST_MPL_AUX_NA_PARAM(BackwardOp)
273 , typename BOOST_MPL_AUX_NA_PARAM(BackwardPredicate)
274 >
275struct while_recur_seq
276{
277 struct forward
278 {
279 #if 0
280 typedef list<> stack0;
281 typedef Sequence seq;
282 typedef State state;
283 typedef typename begin<seq>::type first;
284 typedef typename end<seq>::type last;
285 typedef typename lambda<ForwardOp>::type state_op;
286 typedef typename lambda<ForwardPredicate>::type pred_op;
287
288 typedef
289 aux::while_recur_seq::while_state_iter
290 < aux::while_recur_seq::while_stack_state<stack0,state>
291 , first
292 >
293 aux_state;
294 typedef aux::while_recur_seq::not_iter_last_pred< arg<1>, last, pred_op> aux_pred;
295 typedef aux::while_recur_seq::forward_step< arg<1>, state_op> aux_op;
296
297 typedef typename while_<aux_state,aux_pred,aux_op>::type result;
298 #else
299 typedef
300 typename while_seq
301 < seq
302 , aux::while_recur_seq::while_stack_state
303 < list<>
304 , State
305 >
306 , ForwardOp
307 , ForwardPredicate
308 , aux::while_recur_seq::forward_step
309 >::type
310 result
311 ;
312 #endif
313 };
314
315 struct backward
316 {
317 typedef typename forward::result::stack seq;
318 typedef typename forward::result::state state;
319 typedef typename begin<seq>::type first;
320 typedef typename end<seq>::type last;
321 typedef typename lambda<BackwardOp>::type state_op;
322 typedef typename lambda<BackwardPredicate>::type pred_op;
323
324 typedef
325 aux::while_recur_seq::while_state_iter
326 < aux::while_recur_seq::while_state<state>
327 , first
328 >
329 aux_state;
330 typedef aux::while_recur_seq::not_iter_last_pred< arg<1>, last, pred_op> aux_pred;
331 typedef aux::while_recur_seq::backward_step<arg<1>,state_op> aux_op;
332
333 typedef typename while_<aux_state,aux_pred,aux_op>::type result;
334 };
335
336 typedef typename backward::result::state type;
337
338};
339
340}//exit mpl namespace
341}//exit boost namespace
342#endif
343
344//-{--while_recur_seq_test--
345#include <boost/mpl/list.hpp>
346#include <boost/mpl/list_c.hpp>
347#include <boost/mpl/range_c.hpp>
348#include <boost/mpl/vector.hpp>
349#include <boost/mpl/vector_c.hpp>
350
351#include <boost/mpl/less.hpp>
352#include <boost/mpl/greater.hpp>
353#include <boost/mpl/equal.hpp>
354
355#include <boost/mpl/aux_/test.hpp>
356
357namespace boost
358{
359namespace mpl
360{
361namespace test_while
362{
363 typedef
364 int
365int_type
366;
367 typedef
368#if 0
369 range_c< int_type, 9, 13>
370#else
371 list_c< int_type, 9, 10, 11, 12>
372#endif
373numbers
374;
375 namespace palindrome
376 {
377 typedef
378 while_recur_seq
379 < numbers
380 , vector<>
381 , push_front<arg<1>, arg<2> >
382 , always<true_>
383 , push_front<arg<1>, arg<2> >
384 , always<true_>
385 >
386 while_result
387 ;
388 typedef
389 while_result::type
390 actual_result
391 ;
392 typedef
393 vector_c<int_type, 9,10,11,12,12,11,10,9>
394 expected_result
395 ;
396 BOOST_MPL_ASSERT((equal<actual_result,expected_result>))
397 ;
398
399 }//exit palindrome namespace
400
401 namespace palindrome_pred_fwd
402 {
403 typedef
404 while_recur_seq
405 < numbers
406 , vector<>
407 , push_front<arg<1>, arg<2> >
408 , less<arg<1>,integral_c<int_type,12> >
409 , push_front<arg<1>, arg<2> >
410 , always<true_>
411 >
412 while_result
413 ;
414 typedef
415 while_result::type
416 actual_result
417 ;
418 typedef
419 vector_c<int, 9,10,11,11,10,9>
420 expected_result
421 ;
422 BOOST_MPL_ASSERT((equal<actual_result,expected_result>))
423 ;
424
425 }//exit palindrome_pred_fwd namespace
426
427 namespace palindrome_pred_both
428 {
429 typedef
430 while_recur_seq
431 < numbers
432 , vector<>
433 , push_front<arg<1>, arg<2> >
434 , less<arg<1>,integral_c<int_type,12> >
435 , push_front<arg<1>, arg<2> >
436 , greater<arg<1>,integral_c<int_type,9> >
437 >
438 while_result
439 ;
440 typedef
441 while_result::type
442 actual_result
443 ;
444 typedef
445 vector_c<int, 10,11,11,10,9>
446 expected_result
447 ;
448 BOOST_MPL_ASSERT((equal<actual_result,expected_result>))
449 ;
450
451 }//exit palindrome_pred_both namespace
452
453}//exit test_while namespace4
454}//exit mpl namespace
455}//exit boost namespace
456//-}--while_recur_seq_test--