diff --git a/include/boost/fusion/adapted.hpp b/include/boost/fusion/adapted.hpp index 0dd1f0e7..09684204 100644 --- a/include/boost/fusion/adapted.hpp +++ b/include/boost/fusion/adapted.hpp @@ -8,11 +8,12 @@ #if !defined(BOOST_FUSION_ADAPTED_30122005_1420) #define BOOST_FUSION_ADAPTED_30122005_1420 -#include -#include #include -#include -#include +#include +#include #include +#include +#include +#include #endif diff --git a/include/boost/fusion/algorithm/iteration.hpp b/include/boost/fusion/algorithm/iteration.hpp index 5d0fefa0..c94d4786 100644 --- a/include/boost/fusion/algorithm/iteration.hpp +++ b/include/boost/fusion/algorithm/iteration.hpp @@ -10,5 +10,8 @@ #include #include #include +#include +#include +#include #endif diff --git a/include/boost/fusion/algorithm/iteration/detail/fold.hpp b/include/boost/fusion/algorithm/iteration/detail/fold.hpp index 62a677de..3ce672b3 100644 --- a/include/boost/fusion/algorithm/iteration/detail/fold.hpp +++ b/include/boost/fusion/algorithm/iteration/detail/fold.hpp @@ -1,278 +1,434 @@ /*============================================================================= Copyright (c) 2001-2006 Joel de Guzman Copyright (c) 2006 Dan Marsden + Copyright (c) 2009-2010 Christopher Schmidt Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ==============================================================================*/ -#if !defined(BOOST_FUSION_FOLD_HPP_20070528_1253) -#define BOOST_FUSION_FOLD_HPP_20070528_1253 -#include -#include -#include -#include +#ifndef BOOST_FUSION_ALGORITHM_ITERATION_DETAIL_FOLD_HPP +#define BOOST_FUSION_ALGORITHM_ITERATION_DETAIL_FOLD_HPP + +#include #include #include +#include +#include +#include #include #include +#include #include -#include +#include +#include +#include +#include #include - #include #include -namespace boost { namespace fusion { -namespace result_of -{ - template - struct fold; -} -namespace detail -{ - template - struct apply_fold_result - { - template - struct apply - : boost::result_of - {}; - }; - - template - struct fold_apply - { - typedef typename result_of::deref::type dereferenced; - typedef typename add_reference::type>::type lvalue_state; - typedef typename boost::result_of::type type; - }; - - template - struct static_fold; - - template - struct next_result_of_fold - { - typedef typename - static_fold< - typename result_of::next::type - , Last - , typename fold_apply::type - , F - >::type - type; - }; - - template - struct static_fold - { - typedef typename - mpl::if_< - result_of::equal_to - , mpl::identity - , next_result_of_fold - >::type - result; - - typedef typename result::type type; - }; - - template - struct result_of_unrolled_fold; - - template - struct unrolled_fold - { - template - static typename result_of_unrolled_fold::type - call(State const& state, I0 const& i0, F f) - { - typedef typename result_of::next::type I1; - I1 i1 = fusion::next(i0); - typedef typename result_of::next::type I2; - I2 i2 = fusion::next(i1); - typedef typename result_of::next::type I3; - I3 i3 = fusion::next(i2); - typedef typename result_of::next::type I4; - I4 i4 = fusion::next(i3); - - return unrolled_fold::call(f(f(f(f(state, *i0), *i1), *i2), *i3), i4, f); - } - }; - - template<> - struct unrolled_fold<3> - { - template - static typename result_of_unrolled_fold::type - call(State const& state, I0 const& i0, F f) - { - typedef typename result_of::next::type I1; - I1 i1 = fusion::next(i0); - typedef typename result_of::next::type I2; - I2 i2 = fusion::next(i1); - return f(f(f(state, *i0), *i1), *i2); - } - }; - - template<> - struct unrolled_fold<2> - { - template - static typename result_of_unrolled_fold::type - call(State const& state, I0 const& i0, F f) - { - typedef typename result_of::next::type I1; - I1 i1 = fusion::next(i0); - return f(f(state, *i0), *i1); - } - }; - - template<> - struct unrolled_fold<1> - { - template - static typename result_of_unrolled_fold::type - call(State const& state, I0 const& i0, F f) - { - return f(state, *i0); - } - }; - - template<> - struct unrolled_fold<0> - { - template - static State call(State const& state, I0 const&, F) - { - return state; - } - }; - - // terminal case - template - inline State const& - linear_fold(First const&, Last const&, State const& state, F, mpl::true_) - { - return state; - } - - // non-terminal case - template - inline typename static_fold::type - linear_fold( - First const& first - , Last const& last - , State const& state - , F f - , mpl::false_) - { - return detail::linear_fold( - fusion::next(first) - , last - , f(state, *first) - , f - , result_of::equal_to::type, Last>() - ); - } - - template - struct result_of_unrolled_fold - { - typedef typename result_of::next::type I1; - typedef typename result_of::next::type I2; - typedef typename result_of::next::type I3; - typedef typename result_of::next::type I4; - typedef typename fold_apply::type Rest1; - typedef typename fold_apply::type Rest2; - typedef typename fold_apply::type Rest3; - typedef typename fold_apply::type Rest4; - - typedef typename result_of_unrolled_fold::type type; - }; - - template - struct result_of_unrolled_fold - { - typedef typename result_of::next::type I1; - typedef typename result_of::next::type I2; - typedef typename fold_apply::type Rest; - typedef typename fold_apply::type Rest2; - typedef typename fold_apply::type type; - }; - - template - struct result_of_unrolled_fold - { - typedef typename result_of::next::type I1; - typedef typename fold_apply::type Rest; - typedef typename fold_apply::type type; - }; - - template - struct result_of_unrolled_fold - { - typedef typename fold_apply::type type; - }; - - template - struct result_of_unrolled_fold - { - typedef State type; - }; - - template - struct choose_fold; - - template - struct choose_fold - { - typedef typename result_of::begin::type begin; - typedef typename result_of::end::type end; - typedef typename result_of_unrolled_fold< - State, begin, F, result_of::distance::type::value>::type type; - }; - - template - struct choose_fold - { - typedef typename - detail::static_fold< - typename result_of::begin::type - , typename result_of::end::type - , State - , F - >::type - type; - }; - - template - typename result_of::fold::type - fold(Sequence& seq, State const& state, F f, Tag) - { - return linear_fold( - fusion::begin(seq) - , fusion::end(seq) - , state - , f - , result_of::equal_to< - typename result_of::begin::type - , typename result_of::end::type>() - ); - } - - template - typename result_of::fold::type - fold(Sequence& seq, State const& state, F f, random_access_traversal_tag) - { - typedef typename result_of::begin::type begin; - typedef typename result_of::end::type end; - return unrolled_fold::type::value>::call( - state - , fusion::begin(seq) - , f); - } -}}} - #endif + +#ifdef BOOST_FUSION_REVERSE_FOLD +# ifdef BOOST_FUSION_ITER_FOLD +# define BOOST_FUSION_FOLD_NAME reverse_iter_fold +# else +# define BOOST_FUSION_FOLD_NAME reverse_fold +# endif + +# define BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION end +# define BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION prior +# define BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(IT) \ + typename fusion::result_of::prior::type +# define BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM(IT) fusion::prior(IT) +#else +# ifdef BOOST_FUSION_ITER_FOLD +# define BOOST_FUSION_FOLD_NAME iter_fold +# else +# define BOOST_FUSION_FOLD_NAME fold +# endif + +# define BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION begin +# define BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION next +# define BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(IT) IT +# define BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM(IT) IT +#endif +#ifdef BOOST_FUSION_ITER_FOLD +# define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(IT) IT& +# define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(IT) IT +#else +# define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(IT) \ + typename fusion::result_of::deref::type +# define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(IT) fusion::deref(IT) +#endif + +namespace boost { namespace fusion +{ + namespace detail + { + template + struct BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _rvalue_state) + : boost::result_of< + F( + typename add_reference::type>::type, + BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(It)) + > + {}; + + template + struct BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME) + { + template + static Result + call(State const& state,It0 const& it0,F f) + { + typedef typename + result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION< + It0 const + >::type + It1; + It1 it1 = fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it0); + typedef typename + result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION< + It1 + >::type + It2; + It2 it2 = fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it1); + typedef typename + result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION< + It2 + >::type + It3; + It3 it3 = fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it2); + + return BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)< + Result + , N-4 + >::call( + f( + f( + f( + f( + state, + BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM( + it0) + ), + BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it1) + ), + BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it2) + ), + BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it3) + ), + fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it3), + f); + } + }; + + template + struct BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME) + { + template + static Result + call(State const& state,It0 const& it0,F f) + { + typedef typename + result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION< + It0 const + >::type + It1; + It1 it1 = fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it0); + typedef typename + result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION< + It1 + >::type + It2; + It2 it2 = fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it1); + + return f( + f( + f( + state, + BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it0) + ), + BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it1) + ), + BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM( + fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it1) + )); + } + }; + + template + struct BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME) + { + template + static Result + call(State const& state,It0 const& it0,F f) + { + return f( + f(state, + BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it0)), + BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM( + fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it0))); + } + }; + + template + struct BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME) + { + template + static Result + call(State const& state,It0 const& it0,F f) + { + return f(state, + BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it0)); + } + }; + + template + struct BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME) + { + template + static Result + call(State const& state,It0 const& it0,F f) + { + return static_cast(state); + } + }; + + template + struct BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME) + { + typedef typename + BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _rvalue_state)< + StateRef + , It0 const + , F + >::type + rest1; + typedef typename + result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION< + It0 const + >::type + it1; + typedef typename + BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _rvalue_state)< + rest1 + , it1 + , F + >::type + rest2; + typedef typename + result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION::type + it2; + typedef typename + BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _rvalue_state)< + rest2 + , it2 + , F + >::type + rest3; + typedef typename + result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION::type + it3; + + typedef typename + BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME)< + typename BOOST_PP_CAT( + BOOST_FUSION_FOLD_NAME, _rvalue_state)< + rest3 + , it3 + , F + >::type + , typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION< + it3 + >::type + , F + , N-4 + >::type + type; + }; + + template + struct BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME)< + StateRef + , It0 + , F + , 3 + > + { + typedef typename + BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _rvalue_state)< + StateRef + , It0 const + , F + >::type + rest1; + typedef typename + result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION< + It0 const + >::type + it1; + + typedef typename + BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _rvalue_state)< + typename BOOST_PP_CAT( + BOOST_FUSION_FOLD_NAME, _rvalue_state)< + rest1 + , it1 + , F + >::type + , typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION< + it1 const + >::type const + , F + >::type + type; + }; + + template + struct BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME)< + StateRef + , It0 + , F + , 2 + > + : BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _rvalue_state)< + typename BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _rvalue_state)< + StateRef + , It0 const + , F + >::type + , typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION< + It0 const + >::type const + , F + > + {}; + + template + struct BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME)< + StateRef + , It0 + , F + , 1 + > + : BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _rvalue_state)< + StateRef + , It0 const + , F + > + {}; + + template + struct BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME)< + StateRef + , It0 + , F + , 0 + > + { + typedef StateRef type; + }; + + template + struct BOOST_PP_CAT(result_of_first_unrolled,BOOST_FUSION_FOLD_NAME) + { + typedef typename + BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME)< + typename boost::result_of< + F( + StateRef, + BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM( + It0 const) + ) + >::type + , typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION< + It0 const + >::type + , F + , SeqSize-1 + >::type + type; + }; + + template + struct BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl) + { + typedef typename + BOOST_PP_CAT( + result_of_first_unrolled,BOOST_FUSION_FOLD_NAME)< + StateRef + , BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(It0) + , F + , SeqSize + >::type + type; + + static type + call(StateRef state, It0 const& it0, F f) + { + return BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)< + type + , SeqSize + >::call(state,BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM(it0),f); + } + }; + + template + struct BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl)<0,StateRef,It0,F> + { + typedef StateRef type; + + static StateRef + call(StateRef state, It0 const&, F) + { + return static_cast(state); + } + }; + } + + namespace result_of + { + template + struct BOOST_FUSION_FOLD_NAME + : detail::BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl)< + size::value + , typename add_reference< + typename add_const::type + >::type + , typename BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION::type + , F + > + {}; + } + + template + inline typename result_of::fold::type + BOOST_FUSION_FOLD_NAME(Seq& seq,State const& state,F f) + { + return result_of::BOOST_FUSION_FOLD_NAME::call( + state, + fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq), + f); + } + + template + inline typename result_of::fold::type + BOOST_FUSION_FOLD_NAME(Seq const& seq,State const& state,F f) + { + return result_of::BOOST_FUSION_FOLD_NAME::call( + state, + fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq), + f); + } +}} + +#undef BOOST_FUSION_FOLD_NAME +#undef BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION +#undef BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION +#undef BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM +#undef BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM +#undef BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM +#undef BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM diff --git a/include/boost/fusion/algorithm/iteration/fold.hpp b/include/boost/fusion/algorithm/iteration/fold.hpp index 75c63b8f..347fb4f1 100644 --- a/include/boost/fusion/algorithm/iteration/fold.hpp +++ b/include/boost/fusion/algorithm/iteration/fold.hpp @@ -1,48 +1,15 @@ /*============================================================================= Copyright (c) 2001-2007 Joel de Guzman Copyright (c) 2007 Dan Marsden + Copyright (c) 2009-2010 Christopher Schmidt - Distributed under the Boost Software License, Version 1.0. (See accompanying + Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ==============================================================================*/ -#if !defined(BOOST_FUSION_FOLD_05052005_1214) -#define BOOST_FUSION_FOLD_05052005_1214 + +#ifndef BOOST_FUSION_ALGORITHM_ITERATION_FOLD_HPP +#define BOOST_FUSION_ALGORITHM_ITERATION_FOLD_HPP #include -#include -#include - -#include -#include - -namespace boost { namespace fusion { - - struct random_access_traversal_tag; - - namespace result_of - { - template - struct fold - : fusion::detail::choose_fold< - Sequence, State, F - , is_base_of::type>::value> - {}; - } - - template - inline typename result_of::fold::type - fold(Sequence& seq, State const& state, F f) - { - return detail::fold(seq, state, f, typename traits::category_of::type()); - } - - template - inline typename result_of::fold::type - fold(Sequence const& seq, State const& state, F f) - { - return detail::fold(seq, state, f, typename traits::category_of::type()); - } -}} #endif - diff --git a/include/boost/fusion/algorithm/iteration/iter_fold.hpp b/include/boost/fusion/algorithm/iteration/iter_fold.hpp new file mode 100644 index 00000000..d1529fc1 --- /dev/null +++ b/include/boost/fusion/algorithm/iteration/iter_fold.hpp @@ -0,0 +1,17 @@ +/*============================================================================= + Copyright (c) 2010 Christopher Schmidt + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#ifndef BOOST_FUSION_ALGORITHM_ITERATION_ITER_FOLD_HPP +#define BOOST_FUSION_ALGORITHM_ITERATION_ITER_FOLD_HPP + +#define BOOST_FUSION_ITER_FOLD + +#include + +#undef BOOST_FUSION_REVERSE_FOLD + +#endif diff --git a/include/boost/fusion/algorithm/iteration/reverse_fold.hpp b/include/boost/fusion/algorithm/iteration/reverse_fold.hpp new file mode 100644 index 00000000..bb09db5d --- /dev/null +++ b/include/boost/fusion/algorithm/iteration/reverse_fold.hpp @@ -0,0 +1,17 @@ +/*============================================================================= + Copyright (c) 2010 Christopher Schmidt + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#ifndef BOOST_FUSION_ALGORITHM_ITERATION_REVERSE_FOLD_HPP +#define BOOST_FUSION_ALGORITHM_ITERATION_REVERSE_FOLD_HPP + +#define BOOST_FUSION_REVERSE_FOLD + +#include + +#undef BOOST_FUSION_REVERSE_FOLD + +#endif diff --git a/include/boost/fusion/algorithm/iteration/reverse_iter_fold.hpp b/include/boost/fusion/algorithm/iteration/reverse_iter_fold.hpp new file mode 100644 index 00000000..80079f48 --- /dev/null +++ b/include/boost/fusion/algorithm/iteration/reverse_iter_fold.hpp @@ -0,0 +1,19 @@ +/*============================================================================= + Copyright (c) 2010 Christopher Schmidt + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#ifndef BOOST_FUSION_ALGORITHM_ITERATION_REVERSE_ITER_FOLD_HPP +#define BOOST_FUSION_ALGORITHM_ITERATION_REVERSE_ITER_FOLD_HPP + +#define BOOST_FUSION_REVERSE_FOLD +#define BOOST_FUSION_ITER_FOLD + +#include + +#undef BOOST_FUSION_REVERSE_FOLD +#undef BOOST_FUSION_ITER_FOLD + +#endif diff --git a/include/boost/fusion/include/iter_fold.hpp b/include/boost/fusion/include/iter_fold.hpp new file mode 100644 index 00000000..ba6f9b7e --- /dev/null +++ b/include/boost/fusion/include/iter_fold.hpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2010 Christopher Schmidt + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#ifndef BOOST_FUSION_INCLUDE_ITER_FOLD_HPP +#define BOOST_FUSION_INCLUDE_ITER_FOLD_HPP + +#include + +#endif diff --git a/include/boost/fusion/include/reverse_fold.hpp b/include/boost/fusion/include/reverse_fold.hpp new file mode 100644 index 00000000..f2379e67 --- /dev/null +++ b/include/boost/fusion/include/reverse_fold.hpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2010 Christopher Schmidt + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#ifndef BOOST_FUSION_INCLUDE_REVERSE_FOLD_HPP +#define BOOST_FUSION_INCLUDE_REVERSE_FOLD_HPP + +#include + +#endif diff --git a/include/boost/fusion/include/reverse_iter_fold.hpp b/include/boost/fusion/include/reverse_iter_fold.hpp new file mode 100644 index 00000000..ba92d5fe --- /dev/null +++ b/include/boost/fusion/include/reverse_iter_fold.hpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2010 Christopher Schmidt + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#ifndef BOOST_FUSION_INCLUDE_REVERSE_ITER_FOLD_HPP +#define BOOST_FUSION_INCLUDE_REVERSE_ITER_FOLD_HPP + +#include + +#endif diff --git a/test/Jamfile b/test/Jamfile index 2ddf7912..dba81ec5 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -23,9 +23,11 @@ import testing ; [ run algorithm/find.cpp : : : : ] [ run algorithm/find_if.cpp : : : : ] [ run algorithm/fold.cpp : : : : ] + [ run algorithm/fold2.cpp : : : : ] [ run algorithm/for_each.cpp : : : : ] [ run algorithm/insert.cpp : : : : ] [ run algorithm/insert_range.cpp : : : : ] + [ run algorithm/iter_fold.cpp : : : : ] [ run algorithm/none.cpp : : : : ] [ run algorithm/pop_back.cpp : : : : ] [ run algorithm/pop_front.cpp : : : : ] @@ -35,6 +37,8 @@ import testing ; [ run algorithm/remove_if.cpp : : : : ] [ run algorithm/replace.cpp : : : : ] [ run algorithm/replace_if.cpp : : : : ] + [ run algorithm/reverse_fold.cpp : : : : ] + [ run algorithm/reverse_iter_fold.cpp : : : : ] [ run algorithm/reverse.cpp : : : : ] [ run algorithm/transform.cpp : : : : ] [ run algorithm/join.cpp : : : : ] diff --git a/test/algorithm/fold.hpp b/test/algorithm/fold.hpp new file mode 100644 index 00000000..df42d7d7 --- /dev/null +++ b/test/algorithm/fold.hpp @@ -0,0 +1,212 @@ +/*============================================================================= + Copyright (c) 2010 Christopher Schmidt + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mpl=boost::mpl; +namespace fusion=boost::fusion; + +#ifdef BOOST_FUSION_TEST_REVERSE_FOLD +# ifdef BOOST_FUSION_TEST_ITER_FOLD +# define BOOST_FUSION_TEST_FOLD_NAME reverse_iter_fold +# else +# define BOOST_FUSION_TEST_FOLD_NAME reverse_fold +# endif +#else +# ifdef BOOST_FUSION_TEST_ITER_FOLD +# define BOOST_FUSION_TEST_FOLD_NAME iter_fold +# else +# define BOOST_FUSION_TEST_FOLD_NAME fold +# endif +#endif + +struct sum +{ + template + struct result; + + template + struct result + : fusion::result_of::make_pair< + mpl::int_< + boost::remove_reference< + State + >::type::first_type::value+1 + > + , int + > + { + BOOST_MPL_ASSERT((typename boost::is_reference::type)); + BOOST_MPL_ASSERT((typename boost::is_reference::type)); + }; + +#ifdef BOOST_FUSION_TEST_ITER_FOLD + template + typename result::type + operator()(State const& state, It const& it)const + { + static const int n=State::first_type::value; + return fusion::make_pair >( + state.second+fusion::deref(it)*n); + } +#else + template + typename result::type + operator()(State const& state, int const& e)const + { + static const int n=State::first_type::value; + return fusion::make_pair >(state.second+e*n); + } +#endif +}; + +struct meta_sum +{ + template + struct result; + + template + struct result + { + BOOST_MPL_ASSERT((typename boost::is_reference::type)); + BOOST_MPL_ASSERT((typename boost::is_reference::type)); + + typedef typename boost::remove_reference::type state; + static const int n=mpl::front::type::value; + +#ifdef BOOST_FUSION_TEST_ITER_FOLD + typedef typename + fusion::result_of::value_of< + typename boost::remove_reference::type + >::type + t; +#else + typedef typename boost::remove_reference::type t; +#endif + + typedef + mpl::vector< + mpl::int_ + , mpl::int_< + mpl::back::type::value+t::value*n + > + > + type; + }; + + template + typename result::type + operator()(State const&, T const&)const; +}; + +struct fold_test_n +{ + template + void + operator()(I)const + { + static const int n=I::value; + typedef mpl::range_c range; + + static const int squares_sum=n*(n+1)*(2*n+1)/6; + + { + mpl::range_c init_range; + typename fusion::result_of::as_vector< + typename mpl::transform< + range + , mpl::always + , mpl::back_inserter > + >::type + >::type vec( +#ifdef BOOST_FUSION_TEST_REVERSE_FOLD + fusion::reverse(init_range) +#else + init_range +#endif + ); + + int result=BOOST_FUSION_TEST_FOLD_NAME( + vec, + fusion::make_pair >(0), + sum()).second; + std::cout << n << ": " << result << std::endl; + BOOST_TEST(result==squares_sum); + } + + { + typedef typename +#ifdef BOOST_FUSION_TEST_REVERSE_FOLD + fusion::result_of::as_vector< + typename mpl::copy< + mpl::range_c + , mpl::front_inserter > + >::type + >::type +#else + fusion::result_of::as_vector >::type +#endif + vec; + + typedef + boost::is_same< + typename fusion::result_of::BOOST_FUSION_TEST_FOLD_NAME< + vec + , mpl::vector, mpl::int_<0> > + , meta_sum + >::type + , typename mpl::if_c< + !n + , mpl::vector, mpl::int_<0> > const& + , mpl::vector, mpl::int_ > + >::type + > + result_test; + + BOOST_MPL_ASSERT((result_test)); + } + } +}; + +int +main() +{ + mpl::for_each >(fold_test_n()); + + return boost::report_errors(); +} + +#undef BOOST_FUSION_TEST_FOLD_NAME + diff --git a/test/algorithm/fold2.cpp b/test/algorithm/fold2.cpp new file mode 100644 index 00000000..51ef975d --- /dev/null +++ b/test/algorithm/fold2.cpp @@ -0,0 +1,8 @@ +/*============================================================================= + Copyright (c) 2010 Christopher Schmidt + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#include "fold.hpp" diff --git a/test/algorithm/iter_fold.cpp b/test/algorithm/iter_fold.cpp new file mode 100644 index 00000000..b37f90db --- /dev/null +++ b/test/algorithm/iter_fold.cpp @@ -0,0 +1,10 @@ +/*============================================================================= + Copyright (c) 2010 Christopher Schmidt + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#define BOOST_FUSION_TEST_ITER_FOLD +#include "fold.hpp" +#undef BOOST_FUSION_TEST_ITER_FOLD diff --git a/test/algorithm/reverse_fold.cpp b/test/algorithm/reverse_fold.cpp new file mode 100644 index 00000000..7742bca8 --- /dev/null +++ b/test/algorithm/reverse_fold.cpp @@ -0,0 +1,10 @@ +/*============================================================================= + Copyright (c) 2010 Christopher Schmidt + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#define BOOST_FUSION_TEST_REVERSE_FOLD +#include "fold.hpp" +#undef BOOST_FUSION_TEST_REVERSE_FOLD diff --git a/test/algorithm/reverse_iter_fold.cpp b/test/algorithm/reverse_iter_fold.cpp new file mode 100644 index 00000000..31e4cf26 --- /dev/null +++ b/test/algorithm/reverse_iter_fold.cpp @@ -0,0 +1,12 @@ +/*============================================================================= + Copyright (c) 2010 Christopher Schmidt + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#define BOOST_FUSION_TEST_REVERSE_FOLD +#define BOOST_FUSION_TEST_ITER_FOLD +#include "fold.hpp" +#undef BOOST_FUSION_TEST_ITER_FOLD +#undef BOOST_FUSION_TEST_REVERSE_FOLD diff --git a/test/functional/unfused_typed.cpp b/test/functional/unfused_typed.cpp index 2d49f77f..85783c86 100644 --- a/test/functional/unfused_typed.cpp +++ b/test/functional/unfused_typed.cpp @@ -15,6 +15,7 @@ #include #include +#include #include diff --git a/test/sequence/filter_view.cpp b/test/sequence/filter_view.cpp index 5c4c1a0c..c052a37b 100644 --- a/test/sequence/filter_view.cpp +++ b/test/sequence/filter_view.cpp @@ -80,7 +80,9 @@ main() BOOST_STATIC_ASSERT(result_of::size::value == 4); } - { + //cschmidt: This is illegal C++. ADL instantiates less<_, int_<3> > - which + //leads to compile errors. + /*{ // $$$ JDG $$$ For some obscure reason, EDG based compilers // (e.g. comeau 4.3.3, intel) have problems with this. // vc7.1 and g++ are ok. The errors from comeau are useless. @@ -94,7 +96,7 @@ main() BOOST_TEST((view == make_vector(1, 2, 0, -1))); BOOST_STATIC_ASSERT(result_of::size::value == 4); #endif - } + }*/ { // Previous filtering out all values caused problems as begin was not equal to end