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)
#define FUSION_ACCUMULATE_09172005_1032
#include <boost/fusion/algorithm/iteration/accumulate_fwd.hpp>
#include <boost/fusion/algorithm/iteration/fold.hpp>
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/empty.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/deref.hpp>
#include <boost/fusion/iterator/value_of.hpp>
@ -347,53 +348,73 @@ namespace boost { namespace fusion
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)
{
typedef typename
BOOST_PP_CAT(
result_of_first_unrolled,BOOST_FUSION_FOLD_NAME)<
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
, SeqSize
>::type
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
BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)<
type
, SeqSize
>::call(state,BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM(it0),f);
>
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>
struct BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl)<0,StateRef,It0,F>
template<typename StateRef, typename Seq, typename F>
struct BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl)<0,StateRef,Seq,F>
{
typedef StateRef type;
static StateRef
call(StateRef state, It0 const&, F)
call(StateRef state, Seq&, F)
{
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
{
template<typename Seq, typename State, typename F>
struct BOOST_FUSION_FOLD_NAME
: detail::BOOST_PP_CAT(BOOST_FUSION_FOLD_NAME,_impl)<
size<Seq>::value
, typename add_reference<
typename add_const<State>::type
>::type
, typename BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION<Seq>::type
: detail::BOOST_PP_CAT(result_of_, BOOST_FUSION_FOLD_NAME)<
Seq
, State
, 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(
state,
fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq),
seq,
f);
}
@ -422,7 +443,7 @@ namespace boost { namespace fusion
{
return result_of::BOOST_FUSION_FOLD_NAME<Seq const,State const,F>::call(
state,
fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq),
seq,
f);
}
@ -436,7 +457,7 @@ namespace boost { namespace fusion
{
return result_of::BOOST_FUSION_FOLD_NAME<Seq,State,F>::call(
state,
fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq),
seq,
f);
}
@ -450,7 +471,7 @@ namespace boost { namespace fusion
{
return result_of::BOOST_FUSION_FOLD_NAME<Seq const,State,F>::call(
state,
fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq),
seq,
f);
}
}}

View File

@ -7,7 +7,7 @@
#if !defined(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>
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>
struct result_of_fold;
template <typename Sequence, typename State, typename Fun>
struct result_of_fold<Sequence, State, Fun, true>
{
namespace result_of
{
template <typename Sequence, typename State, typename F>
struct fold_s
: result_of::segmented_fold_until<
typedef
typename result_of::segmented_fold_until<
Sequence,
State,
detail::segmented_fold_fun<F>
>
{};
}
segmented_fold_fun<Fun>
>::type
type;
template <typename Sequence, typename State, typename F>
typename result_of::fold_s<Sequence, State, F>::type
fold_s(Sequence& seq, State const& state, F const& f)
static type call(State& state, Sequence& seq, Fun fun)
{
return fusion::segmented_fold_until(seq, state, detail::segmented_fold_fun<F>(f));
return fusion::segmented_fold_until(seq, state, segmented_fold_fun<Fun>(fun));
}
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

View File

@ -10,6 +10,8 @@
#ifndef 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/segmented_fold.hpp>
#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
#include <boost/fusion/algorithm/iteration/iter_fold_fwd.hpp>
#include <boost/fusion/algorithm/iteration/detail/fold.hpp>
#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
#include <boost/fusion/algorithm/iteration/reverse_fold_fwd.hpp>
#include <boost/fusion/algorithm/iteration/detail/fold.hpp>
#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_ITER_FOLD
#include <boost/fusion/algorithm/iteration/reverse_iter_fold_fwd.hpp>
#include <boost/fusion/algorithm/iteration/detail/fold.hpp>
#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 <boost/detail/lightweight_test.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 "../sequence/tree.hpp"
@ -31,7 +31,7 @@ process_tree(Tree const &tree)
using namespace boost;
std::stringstream str;
fusion::fold_s(tree, &str, write_string());
fusion::fold(tree, &str, write_string());
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 ");

View File

@ -7,7 +7,7 @@
==============================================================================*/
#include <sstream>
#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/container/vector/vector.hpp>
#include <boost/fusion/container/generation/make_vector.hpp>
@ -59,7 +59,7 @@ process_tree(Tree const &tree)
slice_t slice(si, fi);
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 "));
}