make fold aware of segments

[SVN r73906]
This commit is contained in:
Eric Niebler
2011-08-18 23:14:48 +00:00
parent 5ff6210759
commit 9fcb3105e5
14 changed files with 305 additions and 50 deletions

View File

@ -7,6 +7,7 @@
#if !defined(FUSION_ACCUMULATE_09172005_1032) #if !defined(FUSION_ACCUMULATE_09172005_1032)
#define FUSION_ACCUMULATE_09172005_1032 #define FUSION_ACCUMULATE_09172005_1032
#include <boost/fusion/algorithm/iteration/accumulate_fwd.hpp>
#include <boost/fusion/algorithm/iteration/fold.hpp> #include <boost/fusion/algorithm/iteration/fold.hpp>
namespace boost { namespace fusion namespace boost { namespace fusion

View File

@ -0,0 +1,28 @@
/*=============================================================================
Copyright (c) 2011 Eric Niebler
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_ACCUMULATE_FWD_HPP_INCLUDED)
#define BOOST_FUSION_ACCUMULATE_FWD_HPP_INCLUDED
namespace boost { namespace fusion
{
namespace result_of
{
template <typename Sequence, typename State, typename F>
struct accumulate;
}
template <typename Sequence, typename State, typename F>
typename result_of::accumulate<Sequence, State const, F>::type
accumulate(Sequence& seq, State const& state, F f);
template <typename Sequence, typename State, typename F>
typename result_of::accumulate<Sequence const, State const, F>::type
accumulate(Sequence const& seq, State const& state, F f);
}}
#endif

View File

@ -15,6 +15,7 @@
#include <boost/fusion/sequence/intrinsic/end.hpp> #include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/sequence/intrinsic/empty.hpp> #include <boost/fusion/sequence/intrinsic/empty.hpp>
#include <boost/fusion/sequence/intrinsic/size.hpp> #include <boost/fusion/sequence/intrinsic/size.hpp>
#include <boost/fusion/support/is_segmented.hpp>
#include <boost/fusion/iterator/equal_to.hpp> #include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/iterator/deref.hpp> #include <boost/fusion/iterator/deref.hpp>
#include <boost/fusion/iterator/value_of.hpp> #include <boost/fusion/iterator/value_of.hpp>
@ -347,53 +348,73 @@ namespace boost { namespace fusion
type; type;
}; };
template<int SeqSize, typename StateRef, typename It0, typename F> template<int SeqSize, typename StateRef, typename Seq, typename F>
struct BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl) struct BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl)
{ {
typedef typename typedef typename
BOOST_PP_CAT( BOOST_PP_CAT(
result_of_first_unrolled,BOOST_FUSION_FOLD_NAME)< result_of_first_unrolled,BOOST_FUSION_FOLD_NAME)<
StateRef StateRef
, BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(It0) , BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(
typename result_of::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION<Seq>::type
)
, F , F
, SeqSize , SeqSize
>::type >::type
type; type;
static type static type
call(StateRef state, It0 const& it0, F f) call(StateRef state, Seq& seq, F f)
{ {
return BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)< typedef
type BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)<
, SeqSize type
>::call(state,BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM(it0),f); , 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 It0, typename F> template<typename StateRef, typename Seq, typename F>
struct BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl)<0,StateRef,It0,F> struct BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl)<0,StateRef,Seq,F>
{ {
typedef StateRef type; typedef StateRef type;
static StateRef static StateRef
call(StateRef state, It0 const&, F) call(StateRef state, Seq&, F)
{ {
return static_cast<StateRef>(state); return static_cast<StateRef>(state);
} }
}; };
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)<
result_of::size<Seq>::value
, typename add_reference<
typename add_const<State>::type
>::type
, Seq
, F
>
{};
} }
namespace result_of namespace result_of
{ {
template<typename Seq, typename State, typename F> template<typename Seq, typename State, typename F>
struct BOOST_FUSION_FOLD_NAME struct BOOST_FUSION_FOLD_NAME
: detail::BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl)< : detail::BOOST_PP_CAT(result_of_, BOOST_FUSION_FOLD_NAME)<
size<Seq>::value Seq
, typename add_reference< , State
typename add_const<State>::type
>::type
, typename BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION<Seq>::type
, F , F
, traits::is_segmented<Seq>::type::value
> >
{}; {};
} }
@ -408,7 +429,7 @@ namespace boost { namespace fusion
{ {
return result_of::BOOST_FUSION_FOLD_NAME<Seq,State const,F>::call( return result_of::BOOST_FUSION_FOLD_NAME<Seq,State const,F>::call(
state, state,
fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq), seq,
f); f);
} }
@ -422,7 +443,7 @@ namespace boost { namespace fusion
{ {
return result_of::BOOST_FUSION_FOLD_NAME<Seq const,State const,F>::call( return result_of::BOOST_FUSION_FOLD_NAME<Seq const,State const,F>::call(
state, state,
fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq), seq,
f); f);
} }
@ -436,7 +457,7 @@ namespace boost { namespace fusion
{ {
return result_of::BOOST_FUSION_FOLD_NAME<Seq,State,F>::call( return result_of::BOOST_FUSION_FOLD_NAME<Seq,State,F>::call(
state, state,
fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq), seq,
f); f);
} }
@ -450,7 +471,7 @@ namespace boost { namespace fusion
{ {
return result_of::BOOST_FUSION_FOLD_NAME<Seq const,State,F>::call( return result_of::BOOST_FUSION_FOLD_NAME<Seq const,State,F>::call(
state, state,
fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq), seq,
f); f);
} }
}} }}

View File

@ -7,7 +7,7 @@
#if !defined(BOOST_FUSION_FOLD_S_HPP_INCLUDED) #if !defined(BOOST_FUSION_FOLD_S_HPP_INCLUDED)
#define BOOST_FUSION_FOLD_S_HPP_INCLUDED #define BOOST_FUSION_FOLD_S_HPP_INCLUDED
#include <boost/fusion/algorithm/iteration/fold.hpp> #include <boost/fusion/algorithm/iteration/fold_fwd.hpp>
#include <boost/fusion/support/segmented_fold_until.hpp> #include <boost/fusion/support/segmented_fold_until.hpp>
namespace boost { namespace fusion { namespace detail namespace boost { namespace fusion { namespace detail
@ -33,35 +33,27 @@ namespace boost { namespace fusion { namespace detail
} }
}; };
}; };
}}}
namespace boost { namespace fusion // The default implementation of this lives in detail/fold.hpp
{ template <typename Sequence, typename State, typename Fun, bool IsSegmented>
namespace result_of struct result_of_fold;
template <typename Sequence, typename State, typename Fun>
struct result_of_fold<Sequence, State, Fun, true>
{ {
template <typename Sequence, typename State, typename F> typedef
struct fold_s typename result_of::segmented_fold_until<
: result_of::segmented_fold_until<
Sequence, Sequence,
State, State,
detail::segmented_fold_fun<F> segmented_fold_fun<Fun>
> >::type
{}; type;
}
template <typename Sequence, typename State, typename F> static type call(State& state, Sequence& seq, Fun fun)
typename result_of::fold_s<Sequence, State, F>::type {
fold_s(Sequence& seq, State const& state, F const& f) return fusion::segmented_fold_until(seq, state, segmented_fold_fun<Fun>(fun));
{ }
return fusion::segmented_fold_until(seq, state, detail::segmented_fold_fun<F>(f)); };
} }}}
template <typename Sequence, typename State, typename F>
typename result_of::fold_s<Sequence const, State, F>::type
fold_s(Sequence const& seq, State const& state, F const& f)
{
return fusion::segmented_fold_until(seq, state, detail::segmented_fold_fun<F>(f));
}
}}
#endif #endif

View File

@ -10,6 +10,8 @@
#ifndef BOOST_FUSION_ALGORITHM_ITERATION_FOLD_HPP #ifndef BOOST_FUSION_ALGORITHM_ITERATION_FOLD_HPP
#define BOOST_FUSION_ALGORITHM_ITERATION_FOLD_HPP #define BOOST_FUSION_ALGORITHM_ITERATION_FOLD_HPP
#include <boost/fusion/algorithm/iteration/fold_fwd.hpp>
#include <boost/fusion/algorithm/iteration/detail/fold.hpp> #include <boost/fusion/algorithm/iteration/detail/fold.hpp>
#include <boost/fusion/algorithm/iteration/detail/segmented_fold.hpp>
#endif #endif

View File

@ -0,0 +1,52 @@
/*=============================================================================
Copyright (c) 2011 Eric Niebler
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_FOLD_FWD_HPP
#define BOOST_FUSION_ALGORITHM_ITERATION_FOLD_FWD_HPP
namespace boost { namespace fusion
{
namespace result_of
{
template<typename Seq, typename State, typename F>
struct fold;
}
template<typename Seq, typename State, typename F>
typename result_of::fold<
Seq
, State const
, F
>::type
fold(Seq& seq, State const& state, F f);
template<typename Seq, typename State, typename F>
typename result_of::fold<
Seq const
, State const
, F
>::type
fold(Seq const& seq, State const& state, F f);
template<typename Seq, typename State, typename F>
typename result_of::fold<
Seq
, State const
, F
>::type
fold(Seq& seq, State& state, F f);
template<typename Seq, typename State, typename F>
typename result_of::fold<
Seq const
, State const
, F
>::type
fold(Seq const& seq, State& state, F f);
}}
#endif

View File

@ -10,6 +10,7 @@
#define BOOST_FUSION_ITER_FOLD #define BOOST_FUSION_ITER_FOLD
#include <boost/fusion/algorithm/iteration/iter_fold_fwd.hpp>
#include <boost/fusion/algorithm/iteration/detail/fold.hpp> #include <boost/fusion/algorithm/iteration/detail/fold.hpp>
#undef BOOST_FUSION_ITER_FOLD #undef BOOST_FUSION_ITER_FOLD

View File

@ -0,0 +1,52 @@
/*=============================================================================
Copyright (c) 2011 Eric Niebler
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_FWD_HPP
#define BOOST_FUSION_ALGORITHM_ITERATION_ITER_FOLD_FWD_HPP
namespace boost { namespace fusion
{
namespace result_of
{
template<typename Seq, typename State, typename F>
struct iter_fold;
}
template<typename Seq, typename State, typename F>
typename result_of::iter_fold<
Seq
, State const
, F
>::type
iter_fold(Seq& seq, State const& state, F f);
template<typename Seq, typename State, typename F>
typename result_of::iter_fold<
Seq const
, State const
, F
>::type
iter_fold(Seq const& seq, State const& state, F f);
template<typename Seq, typename State, typename F>
typename result_of::iter_fold<
Seq
, State const
, F
>::type
iter_fold(Seq& seq, State& state, F f);
template<typename Seq, typename State, typename F>
typename result_of::iter_fold<
Seq const
, State const
, F
>::type
iter_fold(Seq const& seq, State& state, F f);
}}
#endif

View File

@ -10,6 +10,7 @@
#define BOOST_FUSION_REVERSE_FOLD #define BOOST_FUSION_REVERSE_FOLD
#include <boost/fusion/algorithm/iteration/reverse_fold_fwd.hpp>
#include <boost/fusion/algorithm/iteration/detail/fold.hpp> #include <boost/fusion/algorithm/iteration/detail/fold.hpp>
#undef BOOST_FUSION_REVERSE_FOLD #undef BOOST_FUSION_REVERSE_FOLD

View File

@ -0,0 +1,52 @@
/*=============================================================================
Copyright (c) 2011 Eric Niebler
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_FWD_HPP
#define BOOST_FUSION_ALGORITHM_ITERATION_REVERSE_FOLD_FWD_HPP
namespace boost { namespace fusion
{
namespace result_of
{
template<typename Seq, typename State, typename F>
struct reverse_fold;
}
template<typename Seq, typename State, typename F>
typename result_of::reverse_fold<
Seq
, State const
, F
>::type
reverse_fold(Seq& seq, State const& state, F f);
template<typename Seq, typename State, typename F>
typename result_of::reverse_fold<
Seq const
, State const
, F
>::type
reverse_fold(Seq const& seq, State const& state, F f);
template<typename Seq, typename State, typename F>
typename result_of::reverse_fold<
Seq
, State const
, F
>::type
reverse_fold(Seq& seq, State& state, F f);
template<typename Seq, typename State, typename F>
typename result_of::reverse_fold<
Seq const
, State const
, F
>::type
reverse_fold(Seq const& seq, State& state, F f);
}}
#endif

View File

@ -11,6 +11,7 @@
#define BOOST_FUSION_REVERSE_FOLD #define BOOST_FUSION_REVERSE_FOLD
#define BOOST_FUSION_ITER_FOLD #define BOOST_FUSION_ITER_FOLD
#include <boost/fusion/algorithm/iteration/reverse_iter_fold_fwd.hpp>
#include <boost/fusion/algorithm/iteration/detail/fold.hpp> #include <boost/fusion/algorithm/iteration/detail/fold.hpp>
#undef BOOST_FUSION_REVERSE_FOLD #undef BOOST_FUSION_REVERSE_FOLD

View File

@ -0,0 +1,52 @@
/*=============================================================================
Copyright (c) 2011 Eric Niebler
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_FWD_HPP
#define BOOST_FUSION_ALGORITHM_ITERATION_REVERSE_ITER_FOLD_FWD_HPP
namespace boost { namespace fusion
{
namespace result_of
{
template<typename Seq, typename State, typename F>
struct reverse_iter_fold;
}
template<typename Seq, typename State, typename F>
typename result_of::reverse_iter_fold<
Seq
, State const
, F
>::type
reverse_iter_fold(Seq& seq, State const& state, F f);
template<typename Seq, typename State, typename F>
typename result_of::reverse_iter_fold<
Seq const
, State const
, F
>::type
reverse_iter_fold(Seq const& seq, State const& state, F f);
template<typename Seq, typename State, typename F>
typename result_of::reverse_iter_fold<
Seq
, State const
, F
>::type
reverse_iter_fold(Seq& seq, State& state, F f);
template<typename Seq, typename State, typename F>
typename result_of::reverse_iter_fold<
Seq const
, State const
, F
>::type
reverse_iter_fold(Seq const& seq, State& state, F f);
}}
#endif

View File

@ -9,7 +9,7 @@
#include <iostream> #include <iostream>
#include <boost/detail/lightweight_test.hpp> #include <boost/detail/lightweight_test.hpp>
#include <boost/fusion/container/vector/vector.hpp> #include <boost/fusion/container/vector/vector.hpp>
#include <boost/fusion/algorithm/iteration/ext_/fold_s.hpp> #include <boost/fusion/algorithm/iteration/fold.hpp>
#include <boost/fusion/container/generation/make_vector.hpp> #include <boost/fusion/container/generation/make_vector.hpp>
#include "../sequence/tree.hpp" #include "../sequence/tree.hpp"
@ -31,7 +31,7 @@ process_tree(Tree const &tree)
using namespace boost; using namespace boost;
std::stringstream str; std::stringstream str;
fusion::fold_s(tree, &str, write_string()); fusion::fold(tree, &str, write_string());
std::string res = str.str(); std::string res = str.str();
BOOST_TEST_EQ(res, "a b c 1 2 3 100 e f 0 B 1 h i 4 5 6 j k l "); BOOST_TEST_EQ(res, "a b c 1 2 3 100 e f 0 B 1 h i 4 5 6 j k l ");

View File

@ -7,7 +7,7 @@
==============================================================================*/ ==============================================================================*/
#include <sstream> #include <sstream>
#include <boost/detail/lightweight_test.hpp> #include <boost/detail/lightweight_test.hpp>
#include <boost/fusion/algorithm/iteration/ext_/for_each_s.hpp> #include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/algorithm/query/find_if.hpp> #include <boost/fusion/algorithm/query/find_if.hpp>
#include <boost/fusion/container/vector/vector.hpp> #include <boost/fusion/container/vector/vector.hpp>
#include <boost/fusion/container/generation/make_vector.hpp> #include <boost/fusion/container/generation/make_vector.hpp>
@ -59,7 +59,7 @@ process_tree(Tree const &tree)
slice_t slice(si, fi); slice_t slice(si, fi);
std::stringstream sout; std::stringstream sout;
fusion::for_each_s(slice, ostream_fun(sout)); fusion::for_each(slice, ostream_fun(sout));
BOOST_TEST((sout.str() == "100 e f 0 B ")); BOOST_TEST((sout.str() == "100 e f 0 B "));
} }