#ifndef BOOST_MPL_WHILE_HPP_INCLUDED #define BOOST_MPL_WHILE_HPP_INCLUDED // Copyright Larry Evans 2009 // // $Id: while.cpp,v 1.20 2009/04/23 15:29:47 evansl Exp evansl $ // $Date: 2009/04/23 15:29:47 $ // $Revision: 1.20 $ #include #include #include #include #include namespace boost { namespace mpl { //Notation: // MFC_or_LE = Metafunction class or Lambda Expression // (See Description on libs/mpl/doc/refmanual/apply.html) // // State = Any type. // (this is term used in libs/mpl/doc/refmanual/fold.html) // template < class StateMeta//nullary metafunction returning current State. , class PredOp=always//unary MFC_or_LE from State to Bool. , class ThenOp=identity >//unary MFC_or_LE from State to State, > struct while_ { typedef typename eval_if < typename apply::type , while_ < apply , PredOp , ThenOp > , StateMeta >::type type ; }; }//exit mpl namespace }//exit boost namespace #endif #ifndef BOOST_MPL_WHILE_RECUR_SEQ_HPP_INCLUDED #define BOOST_MPL_WHILE_RECUR_SEQ_HPP_INCLUDED //#include #include #include #include #include #include #include namespace boost { namespace mpl { namespace aux { namespace while_recur_seq { template < typename State > struct while_state { typedef State state; typedef while_state type; }; template < typename Stack , typename State > struct while_stack_state : while_state { typedef Stack stack; typedef while_stack_state type; }; template < typename State , typename Iter > struct while_state_iter : State //either while_state or while_stack_state { typedef Iter iter; typedef while_state_iter type; }; template < typename State , typename Op > struct forward_step { typedef typename deref::type item; typedef while_state_iter < while_stack_state < typename push_front::type , typename apply::type > , typename next::type > type; }; template < typename State , typename Op > struct backward_step { typedef typename deref::type item; typedef while_state_iter < while_state::type> , typename next::type > type; }; template < typename State , typename Op > struct direction_step ; template < typename State , typename Iter , typename Op > struct direction_step < while_state_iter < while_state , Iter > , Op > : backward_step < while_state_iter , Op > { }; template < typename Stack , typename State , typename Iter , typename Op > struct direction_step < while_state_iter < while_stack_state , Iter > , Op > : forward_step < while_state_iter < while_stack_state , Iter > , Op > { }; template < typename StateNow , typename IterLast > struct not_iter_last : not_ < is_same < typename StateNow::iter , IterLast > > { }; template < typename Op , typename LazyExpr > struct apply_lazy1 { typedef typename apply::type type; }; template < typename StateNow , typename IterLast , typename Predicate=always > struct not_iter_last_pred : and_ < not_iter_last , apply_lazy1 > > { }; }//exit while_recur_seq namespace }//exit aux namespace template < typename Seq , typename State , typename OperStateVal , typename PredicateVal=always , templateclass Step=while_recur_seq::backward_step > struct while_seq { typedef typename begin::type first; typedef typename end::type last; typedef while_recur_seq::while_state_iter state_iter; typedef Step < arg<1> , typename lambda::type > oper_state_ref; typedef while_recur_seq::not_iter_last_pred < arg<1> , last , typename lambda::type > predicate_ref; typedef typename while_ < state_iter , predicate_ref , oper_state_ref >::type type; }; template < typename BOOST_MPL_AUX_NA_PARAM(Sequence) , typename BOOST_MPL_AUX_NA_PARAM(State) , typename BOOST_MPL_AUX_NA_PARAM(ForwardOp) , typename BOOST_MPL_AUX_NA_PARAM(ForwardPredicate) , typename BOOST_MPL_AUX_NA_PARAM(BackwardOp) , typename BOOST_MPL_AUX_NA_PARAM(BackwardPredicate) > struct while_recur_seq { struct forward { #if 0 typedef list<> stack0; typedef Sequence seq; typedef State state; typedef typename begin::type first; typedef typename end::type last; typedef typename lambda::type state_op; typedef typename lambda::type pred_op; typedef aux::while_recur_seq::while_state_iter < aux::while_recur_seq::while_stack_state , first > aux_state; typedef aux::while_recur_seq::not_iter_last_pred< arg<1>, last, pred_op> aux_pred; typedef aux::while_recur_seq::forward_step< arg<1>, state_op> aux_op; typedef typename while_::type result; #else typedef typename while_seq < seq , aux::while_recur_seq::while_stack_state < list<> , State > , ForwardOp , ForwardPredicate , aux::while_recur_seq::forward_step >::type result ; #endif }; struct backward { typedef typename forward::result::stack seq; typedef typename forward::result::state state; typedef typename begin::type first; typedef typename end::type last; typedef typename lambda::type state_op; typedef typename lambda::type pred_op; typedef aux::while_recur_seq::while_state_iter < aux::while_recur_seq::while_state , first > aux_state; typedef aux::while_recur_seq::not_iter_last_pred< arg<1>, last, pred_op> aux_pred; typedef aux::while_recur_seq::backward_step,state_op> aux_op; typedef typename while_::type result; }; typedef typename backward::result::state type; }; }//exit mpl namespace }//exit boost namespace #endif //-{--while_recur_seq_test-- #include #include #include #include #include #include #include #include #include namespace boost { namespace mpl { namespace test_while { typedef int int_type ; typedef #if 0 range_c< int_type, 9, 13> #else list_c< int_type, 9, 10, 11, 12> #endif numbers ; namespace palindrome { typedef while_recur_seq < numbers , vector<> , push_front, arg<2> > , always , push_front, arg<2> > , always > while_result ; typedef while_result::type actual_result ; typedef vector_c expected_result ; BOOST_MPL_ASSERT((equal)) ; }//exit palindrome namespace namespace palindrome_pred_fwd { typedef while_recur_seq < numbers , vector<> , push_front, arg<2> > , less,integral_c > , push_front, arg<2> > , always > while_result ; typedef while_result::type actual_result ; typedef vector_c expected_result ; BOOST_MPL_ASSERT((equal)) ; }//exit palindrome_pred_fwd namespace namespace palindrome_pred_both { typedef while_recur_seq < numbers , vector<> , push_front, arg<2> > , less,integral_c > , push_front, arg<2> > , greater,integral_c > > while_result ; typedef while_result::type actual_result ; typedef vector_c expected_result ; BOOST_MPL_ASSERT((equal)) ; }//exit palindrome_pred_both namespace }//exit test_while namespace4 }//exit mpl namespace }//exit boost namespace //-}--while_recur_seq_test--