diff options
Diffstat (limited to 'boost/fusion/algorithm/iteration/detail/fold.hpp')
-rw-r--r-- | boost/fusion/algorithm/iteration/detail/fold.hpp | 530 |
1 files changed, 169 insertions, 361 deletions
diff --git a/boost/fusion/algorithm/iteration/detail/fold.hpp b/boost/fusion/algorithm/iteration/detail/fold.hpp index 1813bd247a..4c82b80029 100644 --- a/boost/fusion/algorithm/iteration/detail/fold.hpp +++ b/boost/fusion/algorithm/iteration/detail/fold.hpp @@ -2,12 +2,15 @@ Copyright (c) 2001-2011 Joel de Guzman Copyright (c) 2006 Dan Marsden Copyright (c) 2009-2010 Christopher Schmidt + Copyright (c) 2015 Kohei Takahashi 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 <boost/preprocessor/cat.hpp> +#define FUSION_HASH # + #ifdef BOOST_FUSION_REVERSE_FOLD # ifdef BOOST_FUSION_ITER_FOLD # define BOOST_FUSION_FOLD_NAME reverse_iter_fold @@ -41,378 +44,193 @@ # define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(IT) fusion::deref(IT) #endif +#if (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)) +FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, < 1500) +FUSION_HASH define BOOST_FUSION_FOLD_IMPL_ENABLER(T) void +FUSION_HASH else +FUSION_HASH define BOOST_FUSION_FOLD_IMPL_ENABLER(T) typename T::type +FUSION_HASH endif +#else +# if BOOST_WORKAROUND(BOOST_MSVC, < 1500) +# define BOOST_FUSION_FOLD_IMPL_ENABLER(T) void +# else +# define BOOST_FUSION_FOLD_IMPL_ENABLER(T) typename T::type +# endif +#endif + namespace boost { namespace fusion { namespace detail { - template<typename State, typename It, typename F> - struct BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state) - : fusion::detail::result_of_with_decltype< - F( - typename add_reference<typename add_const<State>::type>::type, - BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(It)) - > + template<int SeqSize, typename It, typename State, typename F, typename = void +#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) +FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, < 1500) +#endif +#if BOOST_WORKAROUND(BOOST_MSVC, < 1500) || \ + (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)) + // Dirty hack: those compilers cannot choose exactly one partial specialization. + , bool = SeqSize == 0 +#endif +#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) +FUSION_HASH endif +#endif + > + struct BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME) {}; - template<typename Result,int N> - struct BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME) - { - template<typename State3, typename It3, typename F> - BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED - static Result - call_3(State3 const& state3,It3 const& it3,F& f) - { - return BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)< - Result - , N-4 - >::call( - f(state3,BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it3)), - fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it3), - f); - } - - template<typename State2, typename It2, typename F> - BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED - static Result - call_2(State2 const& state2,It2 const& it2,F& f) - { - return call_3( - f(state2,BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it2)), - fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it2), - f); - } - - template<typename State1, typename It1, typename F> - BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED - static Result - call_1(State1 const& state1,It1 const& it1,F& f) - { - return call_2( - f(state1,BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it1)), - fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it1), - f); - } - - template<typename State, typename It0, typename F> - BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED - static Result - call(State const& state,It0 const& it0,F f) - { - return call_1( - f(state,BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it0)), - fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it0), - f); - } - }; - - template<typename Result> - struct BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)<Result,3> - { - template<typename State2, typename It2, typename F> - BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED - static Result - call_2(State2 const& state2,It2 const& it2,F& f) - { - return f(state2,BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it2)); - } - - template<typename State1, typename It1, typename F> - BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED - static Result - call_1(State1 const& state1,It1 const& it1,F& f) - { - return call_2( - f(state1,BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it1)), - fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it1), - f); - } - - template<typename State, typename It0, typename F> - BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED - static Result - call(State const& state,It0 const& it0,F f) - { - return call_1( - f(state,BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it0)), - fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it0), - f); - } - }; - - template<typename Result> - struct BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)<Result,2> - { - template<typename State1, typename It1, typename F> - BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED - static Result - call_1(State1 const& state1,It1 const& it1,F& f) - { - return f(state1,BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it1)); - } - - template<typename State, typename It0, typename F> - BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED - static Result - call(State const& state,It0 const& it0,F f) - { - return call_1( - f(state,BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it0)), - fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it0), - f); - } - }; - - template<typename Result> - struct BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)<Result,1> - { - template<typename State, typename It0, typename F> - BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED - static Result - call(State const& state,It0 const& it0,F f) - { - return f(state, - BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it0)); - } - }; - - template<typename Result> - struct BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)<Result,0> - { - template<typename State, typename It0, typename F> - BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED - static Result - call(State const& state,It0 const&, F) - { - return static_cast<Result>(state); - } - }; - - template<typename StateRef, typename It0, typename F, int N> - struct BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME) - { - typedef typename - BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_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, _lvalue_state)< - rest1 - , it1 - , F - >::type - rest2; - typedef typename - result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<it1>::type - it2; - typedef typename - BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state)< - rest2 - , it2 - , F - >::type - rest3; - typedef typename - result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<it2>::type - it3; - - typedef typename - BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME)< - typename BOOST_PP_CAT( - BOOST_FUSION_FOLD_NAME, _lvalue_state)< - rest3 - , it3 - , F - >::type - , typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION< - it3 - >::type - , F - , N-4 - >::type - type; - }; - - template<typename StateRef, typename It0, typename F> - struct BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME)< - StateRef - , It0 - , F - , 3 - > + template<typename It, typename State, typename F> + struct BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)<0,It,State,F + , typename boost::enable_if_has_type<BOOST_FUSION_FOLD_IMPL_ENABLER(State)>::type +#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) +FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, < 1500) +#endif +#if BOOST_WORKAROUND(BOOST_MSVC, < 1500) || \ + (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)) + , true +#endif +#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) +FUSION_HASH endif +#endif + > { - typedef typename - BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_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, _lvalue_state)< - typename BOOST_PP_CAT( - BOOST_FUSION_FOLD_NAME, _lvalue_state)< - rest1 - , it1 - , F - >::type - , typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION< - it1 const - >::type const - , F - >::type - type; + typedef typename State::type type; }; - template<typename StateRef, typename It0, typename F> - struct BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME)< - StateRef - , It0 - , F - , 2 - > - : BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state)< - typename BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state)< - StateRef - , It0 const - , F - >::type - , typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION< - It0 const - >::type const + template<int SeqSize, typename It, typename State, typename F> + struct BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)<SeqSize,It,State,F + , typename boost::enable_if_has_type< +#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) +FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, >= 1500) +#endif +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1500) || \ + (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)) + // Following SFINAE enables to avoid MSVC 9's partial specialization + // ambiguous bug but MSVC 8 don't compile, and moreover MSVC 8 style + // workaround won't work with MSVC 9. + typename boost::disable_if_c<SeqSize == 0, State>::type::type +#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) +FUSION_HASH else + BOOST_FUSION_FOLD_IMPL_ENABLER(State) +#endif +#else + BOOST_FUSION_FOLD_IMPL_ENABLER(State) +#endif +#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) +FUSION_HASH endif +#endif + >::type +#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) +FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, < 1500) +#endif +#if BOOST_WORKAROUND(BOOST_MSVC, < 1500) || \ + (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)) + , false +#endif +#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) +FUSION_HASH endif +#endif + > + : BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)< + SeqSize-1 + , typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<It>::type + , boost::result_of< + F( + typename add_reference<typename State::type>::type, + BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(It const) + ) + > , F > {}; - template<typename StateRef, typename It0, typename F> - struct BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME)< - StateRef - , It0 + template<typename It, typename State, typename F> + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + inline typename BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)< + 0 + , It + , State , F - , 1 - > - : BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME, _lvalue_state)< - StateRef - , It0 const + >::type + BOOST_PP_CAT(it_,BOOST_FUSION_FOLD_NAME)(mpl::int_<0>, It const&, typename State::type state, F&) + { + return state; + } + + template<typename It, typename State, typename F, int SeqSize> + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + inline typename lazy_enable_if_c< + SeqSize != 0 + , BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)< + SeqSize + , It + , State , F > - {}; - - template<typename StateRef, typename It0, typename F> - struct BOOST_PP_CAT(result_of_unrolled_,BOOST_FUSION_FOLD_NAME)< - StateRef - , It0 - , F - , 0 - > - { - typedef StateRef type; - }; - - template<typename StateRef, typename It0, typename F, int SeqSize> - 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 fusion::detail::result_of_with_decltype< - 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<int SeqSize, typename StateRef, typename Seq, typename F> - struct BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl) + >::type + BOOST_PP_CAT(it_,BOOST_FUSION_FOLD_NAME)(mpl::int_<SeqSize>, It const& it, typename State::type state, F& f) { - typedef typename - BOOST_PP_CAT( - result_of_first_unrolled,BOOST_FUSION_FOLD_NAME)< - StateRef - , BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM( - typename result_of::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION<Seq>::type + return BOOST_PP_CAT(it_,BOOST_FUSION_FOLD_NAME)< + typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<It>::type + , boost::result_of< + F( + typename add_reference<typename State::type>::type, + BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(It const) ) - , F - , SeqSize - >::type - type; - - BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED - static type - call(StateRef state, Seq& seq, F f) - { - typedef - BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)< - type - , SeqSize - > - unrolled_impl; - - return unrolled_impl::call( - state, - BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM( - fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq)), - f); - } - }; - - template<typename StateRef, typename Seq, typename F> - struct BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl)<0,StateRef,Seq,F> - { - typedef StateRef type; - - BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED - static StateRef - call(StateRef state, Seq&, F) - { - return static_cast<StateRef>(state); - } - }; + > + , F + >( + mpl::int_<SeqSize-1>() + , fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it) + , f(state, BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it)) + , f + ); + } + + template<typename Seq, typename State, typename F + , bool = traits::is_sequence<Seq>::value + , bool = traits::is_segmented<Seq>::value> + struct BOOST_PP_CAT(result_of_,BOOST_FUSION_FOLD_NAME) + {}; - template<typename Seq, typename State, typename F, bool IsSegmented> - struct BOOST_PP_CAT(result_of_, BOOST_FUSION_FOLD_NAME) - : BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl)< + template<typename Seq, typename State, typename F> + struct BOOST_PP_CAT(result_of_,BOOST_FUSION_FOLD_NAME)<Seq, State, F, true, false> + : BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)< result_of::size<Seq>::value - , typename add_reference< - typename add_const<State>::type - >::type - , Seq + , BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM( + typename result_of::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION<Seq>::type + ) + , add_reference<State> , F > {}; + + template<typename Seq, typename State, typename F> + BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED + inline typename BOOST_PP_CAT(result_of_,BOOST_FUSION_FOLD_NAME)<Seq, State, F>::type + BOOST_FUSION_FOLD_NAME(Seq& seq, State& state, F& f) + { + return BOOST_PP_CAT(it_,BOOST_FUSION_FOLD_NAME)< + BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM( + typename result_of::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION<Seq>::type + ) + , add_reference<State> + , F + >( + typename result_of::size<Seq>::type() + , BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM( + fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq) + ) + , state + , f + ); + } } namespace result_of { template<typename Seq, typename State, typename F> struct BOOST_FUSION_FOLD_NAME - : detail::BOOST_PP_CAT(result_of_, BOOST_FUSION_FOLD_NAME)< - Seq - , State - , F - , traits::is_segmented<Seq>::type::value - > + : detail::BOOST_PP_CAT(result_of_,BOOST_FUSION_FOLD_NAME)<Seq, State, F> {}; } @@ -425,10 +243,7 @@ namespace boost { namespace fusion >::type BOOST_FUSION_FOLD_NAME(Seq& seq, State const& state, F f) { - return result_of::BOOST_FUSION_FOLD_NAME<Seq,State const,F>::call( - state, - seq, - f); + return detail::BOOST_FUSION_FOLD_NAME<Seq, State const, F>(seq, state, f); } template<typename Seq, typename State, typename F> @@ -440,47 +255,40 @@ namespace boost { namespace fusion >::type BOOST_FUSION_FOLD_NAME(Seq const& seq, State const& state, F f) { - return result_of::BOOST_FUSION_FOLD_NAME<Seq const,State const,F>::call( - state, - seq, - f); + return detail::BOOST_FUSION_FOLD_NAME<Seq const, State const, F>(seq, state, f); } template<typename Seq, typename State, typename F> BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED inline typename result_of::BOOST_FUSION_FOLD_NAME< Seq - , State const + , State , F >::type BOOST_FUSION_FOLD_NAME(Seq& seq, State& state, F f) { - return result_of::BOOST_FUSION_FOLD_NAME<Seq,State,F>::call( - state, - seq, - f); + return detail::BOOST_FUSION_FOLD_NAME<Seq, State, F>(seq, state, f); } template<typename Seq, typename State, typename F> BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED inline typename result_of::BOOST_FUSION_FOLD_NAME< Seq const - , State const + , State , F >::type BOOST_FUSION_FOLD_NAME(Seq const& seq, State& state, F f) { - return result_of::BOOST_FUSION_FOLD_NAME<Seq const,State,F>::call( - state, - seq, - f); + return detail::BOOST_FUSION_FOLD_NAME<Seq const, State, F>(seq, state, f); } }} #undef BOOST_FUSION_FOLD_NAME +#undef BOOST_FUSION_FOLD_IMPL_ENABLER #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 +#undef FUSION_HASH |