merge [70965] [73644] [73668] [73669] [73683] [73770] [73771] [73831] [73834] [73854] [73892] [73898] [73899] [73906] [73908] [73927] [74019] [74048] [74113] from trunk to release

[SVN r74325]
This commit is contained in:
Eric Niebler
2011-09-09 03:27:28 +00:00
139 changed files with 3858 additions and 2176 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
BOOST_PP_CAT(unrolled_,BOOST_FUSION_FOLD_NAME)<
type type
, SeqSize , 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> 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,35 @@ 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);
}
template<typename Seq, typename State, typename F>
inline typename result_of::BOOST_FUSION_FOLD_NAME<
Seq
, State const
, 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);
}
template<typename Seq, typename State, typename F>
inline typename result_of::BOOST_FUSION_FOLD_NAME<
Seq const
, State const
, 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); f);
} }
}} }}

View File

@ -13,6 +13,7 @@
#include <boost/fusion/iterator/next.hpp> #include <boost/fusion/iterator/next.hpp>
#include <boost/fusion/iterator/deref.hpp> #include <boost/fusion/iterator/deref.hpp>
#include <boost/fusion/iterator/distance.hpp> #include <boost/fusion/iterator/distance.hpp>
#include <boost/fusion/support/category_of.hpp>
#include <boost/mpl/bool.hpp> #include <boost/mpl/bool.hpp>
namespace boost { namespace fusion { namespace boost { namespace fusion {
@ -36,7 +37,7 @@ namespace detail
template <typename Sequence, typename F, typename Tag> template <typename Sequence, typename F, typename Tag>
inline void inline void
for_each(Sequence& seq, F const& f, Tag) for_each_dispatch(Sequence& seq, F const& f, Tag)
{ {
detail::for_each_linear( detail::for_each_linear(
fusion::begin(seq) fusion::begin(seq)
@ -117,12 +118,19 @@ namespace detail
template <typename Sequence, typename F> template <typename Sequence, typename F>
inline void inline void
for_each(Sequence& seq, F const& f, random_access_traversal_tag) for_each_dispatch(Sequence& seq, F const& f, random_access_traversal_tag)
{ {
typedef typename result_of::begin<Sequence>::type begin; typedef typename result_of::begin<Sequence>::type begin;
typedef typename result_of::end<Sequence>::type end; typedef typename result_of::end<Sequence>::type end;
for_each_unrolled<result_of::distance<begin, end>::type::value>::call(fusion::begin(seq), f); for_each_unrolled<result_of::distance<begin, end>::type::value>::call(fusion::begin(seq), f);
} }
template <typename Sequence, typename F>
inline void
for_each(Sequence& seq, F const& f, mpl::false_) // unsegmented implementation
{
detail::for_each_dispatch(seq, f, typename traits::category_of<Sequence>::type());
}
}}} }}}

View File

@ -0,0 +1,59 @@
/*=============================================================================
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_FOLD_S_HPP_INCLUDED)
#define BOOST_FUSION_FOLD_S_HPP_INCLUDED
#include <boost/fusion/algorithm/iteration/fold_fwd.hpp>
#include <boost/fusion/support/segmented_fold_until.hpp>
namespace boost { namespace fusion { namespace detail
{
template <typename Fun>
struct segmented_fold_fun
{
explicit segmented_fold_fun(Fun const& f)
: fun(f)
{}
Fun const& fun;
template <typename Sequence, typename State, typename Context>
struct apply
{
typedef typename result_of::fold<Sequence, State, Fun>::type type;
typedef mpl::true_ continue_type;
static type call(Sequence& seq, State const& state, Context const&, segmented_fold_fun const& fun)
{
return fusion::fold(seq, state, fun.fun);
}
};
};
// 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>
{
typedef
typename result_of::segmented_fold_until<
Sequence,
State,
segmented_fold_fun<Fun>
>::type
type;
static type call(State& state, Sequence& seq, Fun fun)
{
return fusion::segmented_fold_until(seq, state, segmented_fold_fun<Fun>(fun));
}
};
}}}
#endif

View File

@ -0,0 +1,48 @@
/*=============================================================================
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_SEGMENTED_FOR_EACH_HPP_INCLUDED)
#define BOOST_FUSION_SEGMENTED_FOR_EACH_HPP_INCLUDED
#include <boost/mpl/bool.hpp>
#include <boost/fusion/support/void.hpp>
#include <boost/fusion/algorithm/iteration/for_each_fwd.hpp>
#include <boost/fusion/support/segmented_fold_until.hpp>
namespace boost { namespace fusion { namespace detail
{
template <typename Fun>
struct segmented_for_each_fun
{
explicit segmented_for_each_fun(Fun const& f)
: fun(f)
{}
Fun const& fun;
template <typename Sequence, typename State, typename Context>
struct apply
{
typedef void_ type;
typedef mpl::true_ continue_type;
static type call(Sequence& seq, State const&, Context const&, segmented_for_each_fun const& fun)
{
fusion::for_each(seq, fun.fun);
return void_();
}
};
};
template <typename Sequence, typename F>
inline void
for_each(Sequence& seq, F const& f, mpl::true_) // segmented implementation
{
fusion::segmented_fold_until(seq, void_(), segmented_for_each_fun<F>(f));
}
}}}
#endif

View File

@ -1,91 +0,0 @@
/*=============================================================================
Copyright (c) 2006 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(FUSION_FOR_EACH_S_05022006_1027)
#define FUSION_FOR_EACH_S_05022006_1027
#include <boost/mpl/assert.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/sequence/intrinsic/ext_/segments.hpp>
#include <boost/fusion/support/ext_/is_segmented.hpp>
// fwd declarations
namespace boost { namespace fusion
{
template <typename Sequence, typename F>
void
for_each_s(Sequence& seq, F const& f);
template <typename Sequence, typename F>
void
for_each_s(Sequence const& seq, F const& f);
}}
namespace boost { namespace fusion { namespace detail
{
template<typename F>
struct for_each_s_bind
{
explicit for_each_s_bind(F const &f)
: f_(f)
{}
template<typename Sequence>
void operator ()(Sequence &seq) const
{
fusion::for_each_s(seq, this->f_);
}
template<typename Sequence>
void operator ()(Sequence const &seq) const
{
fusion::for_each_s(seq, this->f_);
}
private:
F const &f_;
};
template<typename Sequence, typename F>
void for_each_s(Sequence &seq, F const &f, mpl::true_)
{
fusion::for_each_s(fusion::segments(seq), for_each_s_bind<F>(f));
}
template<typename Sequence, typename F>
void for_each_s(Sequence &seq, F const &f, mpl::false_)
{
fusion::for_each(seq, f);
}
}}}
namespace boost { namespace fusion
{
namespace result_of
{
template <typename Sequence, typename F>
struct for_each_s
{
typedef void type;
};
}
template <typename Sequence, typename F>
inline void
for_each_s(Sequence& seq, F const& f)
{
detail::for_each_s(seq, f, traits::is_segmented<Sequence>());
}
template <typename Sequence, typename F>
inline void
for_each_s(Sequence const& seq, F const& f)
{
detail::for_each_s(seq, f, traits::is_segmented<Sequence>());
}
}}
#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

@ -9,11 +9,11 @@
#define BOOST_FUSION_FOR_EACH_20070527_0943 #define BOOST_FUSION_FOR_EACH_20070527_0943
#include <boost/fusion/algorithm/iteration/detail/for_each.hpp> #include <boost/fusion/algorithm/iteration/detail/for_each.hpp>
#include <boost/fusion/algorithm/iteration/detail/segmented_for_each.hpp>
#include <boost/fusion/support/is_segmented.hpp>
#include <boost/fusion/support/category_of.hpp> namespace boost { namespace fusion
{
namespace boost { namespace fusion {
namespace result_of namespace result_of
{ {
template <typename Sequence, typename F> template <typename Sequence, typename F>
@ -23,20 +23,18 @@ namespace boost { namespace fusion {
}; };
} }
struct random_access_traversal_tag;
template <typename Sequence, typename F> template <typename Sequence, typename F>
inline void inline void
for_each(Sequence& seq, F const& f) for_each(Sequence& seq, F const& f)
{ {
detail::for_each(seq, f, typename traits::category_of<Sequence>::type()); detail::for_each(seq, f, typename traits::is_segmented<Sequence>::type());
} }
template <typename Sequence, typename F> template <typename Sequence, typename F>
inline void inline void
for_each(Sequence const& seq, F const& f) for_each(Sequence const& seq, F const& f)
{ {
detail::for_each(seq, f, typename traits::category_of<Sequence>::type()); detail::for_each(seq, f, typename traits::is_segmented<Sequence>::type());
} }
}} }}

View File

@ -0,0 +1,27 @@
/*=============================================================================
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_FOR_EACH_FWD_HPP_INCLUDED)
#define BOOST_FUSION_FOR_EACH_FWD_HPP_INCLUDED
namespace boost { namespace fusion
{
namespace result_of
{
template <typename Sequence, typename F>
struct for_each;
}
template <typename Sequence, typename F>
void
for_each(Sequence& seq, F const& f);
template <typename Sequence, typename F>
void
for_each(Sequence const& seq, F const& 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,19 +9,18 @@
#if !defined(FUSION_FIND_IF_05052005_1107) #if !defined(FUSION_FIND_IF_05052005_1107)
#define FUSION_FIND_IF_05052005_1107 #define FUSION_FIND_IF_05052005_1107
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/apply.hpp> #include <boost/mpl/apply.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp> #include <boost/mpl/identity.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/or.hpp>
#include <boost/fusion/iterator/advance.hpp>
#include <boost/fusion/iterator/distance.hpp>
#include <boost/fusion/iterator/equal_to.hpp> #include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/iterator/next.hpp> #include <boost/fusion/iterator/next.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp> #include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/iterator/advance.hpp> #include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/iterator/distance.hpp>
#include <boost/fusion/support/category_of.hpp> #include <boost/fusion/support/category_of.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
namespace boost { namespace fusion { namespace boost { namespace fusion {
struct random_access_traversal_tag; struct random_access_traversal_tag;
@ -222,10 +221,31 @@ namespace detail
template <typename Iterator> template <typename Iterator>
static type static type
call(Iterator const& iter) iter_call(Iterator const& iter)
{ {
return choose_call(iter, typename traits::category_of<Iterator>::type()); return choose_call(iter, typename traits::category_of<Iterator>::type());
} }
template <typename Sequence>
static type
call(Sequence& seq)
{
return iter_call(fusion::begin(seq));
}
};
template <typename Sequence, typename Pred>
struct result_of_find_if
{
typedef
static_find_if<
typename result_of::begin<Sequence>::type
, typename result_of::end<Sequence>::type
, Pred
>
filter;
typedef typename filter::type type;
}; };
}}} }}}

View File

@ -0,0 +1,90 @@
/*=============================================================================
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_SEGMENTED_FIND_HPP_INCLUDED)
#define BOOST_FUSION_SEGMENTED_FIND_HPP_INCLUDED
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/fusion/algorithm/query/find_fwd.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/support/segmented_fold_until.hpp>
namespace boost { namespace fusion { namespace detail
{
template <typename T>
struct segmented_find_fun
{
template <typename Sequence, typename State, typename Context>
struct apply
{
typedef
typename result_of::find<Sequence, T>::type
iterator_type;
typedef
typename result_of::equal_to<
iterator_type
, typename result_of::end<Sequence>::type
>::type
continue_type;
typedef
typename mpl::eval_if<
continue_type
, mpl::identity<State>
, result_of::make_segmented_iterator<
iterator_type
, Context
>
>::type
type;
static type call(Sequence& seq, State const&state, Context const& context, segmented_find_fun)
{
return call_impl(seq, state, context, continue_type());
}
static type call_impl(Sequence&, State const&state, Context const&, mpl::true_)
{
return state;
}
static type call_impl(Sequence& seq, State const&, Context const& context, mpl::false_)
{
return fusion::make_segmented_iterator(fusion::find<T>(seq), context);
}
};
};
template <typename Sequence, typename T>
struct result_of_segmented_find
{
struct filter
{
typedef
typename result_of::segmented_fold_until<
Sequence
, typename result_of::end<Sequence>::type
, segmented_find_fun<T>
>::type
type;
static type call(Sequence& seq)
{
return fusion::segmented_fold_until(
seq
, fusion::end(seq)
, detail::segmented_find_fun<T>());
}
};
typedef typename filter::type type;
};
}}}
#endif

View File

@ -0,0 +1,90 @@
/*=============================================================================
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_SEGMENTED_FIND_IF_HPP_INCLUDED)
#define BOOST_FUSION_SEGMENTED_FIND_IF_HPP_INCLUDED
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/fusion/algorithm/query/find_if_fwd.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/support/segmented_fold_until.hpp>
namespace boost { namespace fusion { namespace detail
{
template <typename Pred>
struct segmented_find_if_fun
{
template <typename Sequence, typename State, typename Context>
struct apply
{
typedef
typename result_of::find_if<Sequence, Pred>::type
iterator_type;
typedef
typename result_of::equal_to<
iterator_type
, typename result_of::end<Sequence>::type
>::type
continue_type;
typedef
typename mpl::eval_if<
continue_type
, mpl::identity<State>
, result_of::make_segmented_iterator<
iterator_type
, Context
>
>::type
type;
static type call(Sequence& seq, State const&state, Context const& context, segmented_find_if_fun)
{
return call_impl(seq, state, context, continue_type());
}
static type call_impl(Sequence&, State const&state, Context const&, mpl::true_)
{
return state;
}
static type call_impl(Sequence& seq, State const&, Context const& context, mpl::false_)
{
return fusion::make_segmented_iterator(fusion::find_if<Pred>(seq), context);
}
};
};
template <typename Sequence, typename Pred>
struct result_of_segmented_find_if
{
struct filter
{
typedef
typename result_of::segmented_fold_until<
Sequence
, typename result_of::end<Sequence>::type
, segmented_find_if_fun<Pred>
>::type
type;
static type call(Sequence& seq)
{
return fusion::segmented_fold_until(
seq
, fusion::end(seq)
, segmented_find_if_fun<Pred>());
}
};
typedef typename filter::type type;
};
}}}
#endif

View File

@ -1,222 +0,0 @@
/*=============================================================================
Copyright (c) 2006 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(FIND_IF_S_05152006_1027)
#define FIND_IF_S_05152006_1027
#include <boost/mpl/not.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/fusion/algorithm/query/find_if.hpp>
#include <boost/fusion/container/list/cons.hpp>
#include <boost/fusion/sequence/intrinsic/ext_/segments.hpp>
#include <boost/fusion/view/ext_/segmented_iterator.hpp>
#include <boost/fusion/view/ext_/segmented_iterator_range.hpp>
#include <boost/fusion/support/ext_/is_segmented.hpp>
// fwd declarations
namespace boost { namespace fusion
{
namespace detail
{
template<typename Sequence, typename Pred, bool IsSegmented = traits::is_segmented<Sequence>::value>
struct static_find_if_s_recurse;
}
namespace result_of
{
template <typename Sequence, typename Pred>
struct find_if_s;
}
}}
namespace boost { namespace fusion { namespace detail
{
template<typename Sequence, typename Where, bool IsSegmented = traits::is_segmented<Sequence>::value>
struct is_found
: mpl::not_<result_of::equal_to<Where, typename result_of::end<Sequence>::type> >
{};
template<typename Sequence, typename Cons>
struct is_found<Sequence, Cons, true>
: mpl::not_<is_same<nil, Cons> >
{};
template<
typename SegmentedRange
, typename Where
, typename Sequence = typename remove_reference<
typename result_of::deref<
typename SegmentedRange::iterator_type
>::type
>::type
, bool IsSegmented = traits::is_segmented<Sequence>::value
>
struct as_segmented_cons
{
typedef cons<
SegmentedRange
, cons<segmented_range<Sequence, Where, false> >
> type;
static type call(SegmentedRange const &range, Where const &where)
{
return fusion::make_cons(
range
, fusion::make_cons(
segmented_range<Sequence, Where, false>(*fusion::begin(range), where)
)
);
}
};
template<
typename SegmentedRange
, typename Where
, typename Sequence
>
struct as_segmented_cons<SegmentedRange, Where, Sequence, true>
{
typedef cons<SegmentedRange, Where> type;
static type call(SegmentedRange const &range, Where const &where)
{
return fusion::make_cons(range, where);
}
};
template<
typename SegmentedRange
, typename Pred
, bool IsEmpty = is_empty<SegmentedRange>::value
>
struct static_find_if_s_seg
{
typedef typename SegmentedRange::iterator_type first;
typedef typename result_of::deref<first>::type segment_ref;
typedef typename remove_reference<segment_ref>::type segment;
typedef static_find_if_s_recurse<segment, Pred> where;
typedef range_next<SegmentedRange> next;
typedef is_found<segment, typename where::type> is_found;
typedef as_segmented_cons<SegmentedRange, typename where::type> found;
typedef static_find_if_s_seg<typename next::type, Pred> not_found;
typedef typename mpl::eval_if<is_found, found, not_found>::type type;
static type call(SegmentedRange const &range)
{
return call_(range, is_found());
}
private:
static type call_(SegmentedRange const &range, mpl::true_)
{
return found::call(range, where::call(*range.where_));
}
static type call_(SegmentedRange const &range, mpl::false_)
{
return not_found::call(next::call(range));
}
};
template<
typename SegmentedRange
, typename Pred
>
struct static_find_if_s_seg<SegmentedRange, Pred, true>
{
typedef nil type;
static type call(SegmentedRange const &)
{
return nil();
}
};
template<typename Sequence, typename Pred>
struct static_find_if_s_recurse<Sequence, Pred, true>
{
typedef typename as_segmented_range<Sequence>::type range;
typedef static_find_if_s_seg<range, Pred> find_if;
typedef typename find_if::type type;
static type call(Sequence &seq)
{
return find_if::call(range(fusion::segments(seq)));
}
};
template<typename Sequence, typename Pred>
struct static_find_if_s_recurse<Sequence, Pred, false>
{
typedef typename result_of::find_if<Sequence, Pred>::type type;
static type call(Sequence &seq)
{
return fusion::find_if<Pred>(seq);
}
};
template<typename Sequence, typename Pred, bool IsSegmented = traits::is_segmented<Sequence>::value>
struct static_find_if_s
: static_find_if_s_recurse<Sequence, Pred, IsSegmented>
{};
template<typename Sequence, typename Pred>
struct static_find_if_s<Sequence, Pred, true>
{
typedef typename as_segmented_range<Sequence>::type range;
typedef static_find_if_s_recurse<Sequence, Pred> find_if;
typedef typename find_if::type found;
typedef segmented_iterator<typename reverse_cons<found>::type> type;
static type call(Sequence &seq)
{
return type(reverse_cons<found>::call(find_if::call(seq)));
}
};
}}}
namespace boost { namespace fusion
{
namespace result_of
{
template <typename Sequence, typename Pred>
struct find_if_s
{
typedef typename
detail::static_find_if_s<
Sequence
, Pred
>::type
type;
};
}
template <typename Pred, typename Sequence>
typename lazy_disable_if<
is_const<Sequence>
, result_of::find_if_s<Sequence, Pred>
>::type
find_if_s(Sequence& seq)
{
return detail::static_find_if_s<Sequence, Pred>::call(seq);
}
template <typename Pred, typename Sequence>
typename result_of::find_if_s<Sequence const, Pred>::type
find_if_s(Sequence const& seq)
{
return detail::static_find_if_s<Sequence const, Pred>::call(seq);
}
}}
#endif

View File

@ -1,5 +1,6 @@
/*============================================================================= /*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman Copyright (c) 2001-2006 Joel de Guzman
Copyright (c) 2011 Eric Niebler
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) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -7,13 +8,15 @@
#if !defined(FUSION_FIND_05052005_1107) #if !defined(FUSION_FIND_05052005_1107)
#define FUSION_FIND_05052005_1107 #define FUSION_FIND_05052005_1107
#include <boost/fusion/algorithm/query/find_if_fwd.hpp>
#include <boost/fusion/algorithm/query/detail/find_if.hpp> #include <boost/fusion/algorithm/query/detail/find_if.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp> #include <boost/fusion/algorithm/query/detail/segmented_find.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/iterator/key_of.hpp> #include <boost/fusion/iterator/key_of.hpp>
#include <boost/fusion/iterator/value_of.hpp> #include <boost/fusion/iterator/value_of.hpp>
#include <boost/fusion/support/category_of.hpp> #include <boost/fusion/support/category_of.hpp>
#include <boost/fusion/support/is_segmented.hpp>
#include <boost/mpl/if.hpp> #include <boost/mpl/if.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/type_traits/is_same.hpp> #include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_const.hpp> #include <boost/type_traits/is_const.hpp>
#include <boost/utility/enable_if.hpp> #include <boost/utility/enable_if.hpp>
@ -22,17 +25,14 @@ namespace boost { namespace fusion
{ {
namespace result_of namespace result_of
{ {
template < template <typename Sequence, typename T>
typename Sequence
, typename T
>
struct find struct find
{ : mpl::if_<
typedef traits::is_segmented<Sequence>
detail::static_find_if< , detail::result_of_segmented_find<Sequence, T>
typename result_of::begin<Sequence>::type , detail::result_of_find_if<
, typename result_of::end<Sequence>::type Sequence,
, is_same< is_same<
typename mpl::if_< typename mpl::if_<
traits::is_associative<Sequence> traits::is_associative<Sequence>
, key_of<mpl::_1> , key_of<mpl::_1>
@ -41,10 +41,8 @@ namespace boost { namespace fusion
, T , T
> >
> >
filter; >::type
{};
typedef typename filter::type type;
};
} }
template <typename T, typename Sequence> template <typename T, typename Sequence>
@ -56,7 +54,7 @@ namespace boost { namespace fusion
find(Sequence& seq) find(Sequence& seq)
{ {
typedef typename result_of::find<Sequence, T>::filter filter; typedef typename result_of::find<Sequence, T>::filter filter;
return filter::call(fusion::begin(seq)); return filter::call(seq);
} }
template <typename T, typename Sequence> template <typename T, typename Sequence>
@ -64,9 +62,8 @@ namespace boost { namespace fusion
find(Sequence const& seq) find(Sequence const& seq)
{ {
typedef typename result_of::find<Sequence const, T>::filter filter; typedef typename result_of::find<Sequence const, T>::filter filter;
return filter::call(fusion::begin(seq)); return filter::call(seq);
} }
}} }}
#endif #endif

View File

@ -0,0 +1,34 @@
/*=============================================================================
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_FIND_FWD_HPP_INCLUDED)
#define BOOST_FUSION_FIND_FWD_HPP_INCLUDED
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_const.hpp>
namespace boost { namespace fusion
{
namespace result_of
{
template <typename Sequence, typename T>
struct find;
}
template <typename T, typename Sequence>
inline typename
lazy_disable_if<
is_const<Sequence>
, result_of::find<Sequence, T>
>::type const
find(Sequence& seq);
template <typename T, typename Sequence>
inline typename result_of::find<Sequence const, T>::type const
find(Sequence const& seq);
}}
#endif

View File

@ -1,5 +1,6 @@
/*============================================================================= /*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman Copyright (c) 2001-2006 Joel de Guzman
Copyright (c) 2011 Eric Niebler
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) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -7,15 +8,17 @@
#if !defined(FUSION_FIND_IF_05052005_1108) #if !defined(FUSION_FIND_IF_05052005_1108)
#define FUSION_FIND_IF_05052005_1108 #define FUSION_FIND_IF_05052005_1108
#include <boost/fusion/algorithm/query/find_if_fwd.hpp>
#include <boost/fusion/algorithm/query/detail/find_if.hpp> #include <boost/fusion/algorithm/query/detail/find_if.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp> #include <boost/fusion/algorithm/query/detail/segmented_find_if.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/iterator/value_of.hpp> #include <boost/fusion/iterator/value_of.hpp>
#include <boost/mpl/bind.hpp> #include <boost/fusion/support/is_segmented.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/quote.hpp>
#include <boost/utility/enable_if.hpp> #include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_const.hpp> #include <boost/type_traits/is_const.hpp>
#include <boost/mpl/bind.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/quote.hpp>
namespace boost { namespace fusion namespace boost { namespace fusion
{ {
@ -23,20 +26,18 @@ namespace boost { namespace fusion
{ {
template <typename Sequence, typename Pred> template <typename Sequence, typename Pred>
struct find_if struct find_if
{ : mpl::if_<
typedef traits::is_segmented<Sequence>
detail::static_find_if< , detail::result_of_segmented_find_if<Sequence, Pred>
typename result_of::begin<Sequence>::type , detail::result_of_find_if<
, typename result_of::end<Sequence>::type Sequence,
, mpl::bind1< mpl::bind1<
typename mpl::lambda<Pred>::type typename mpl::lambda<Pred>::type
, mpl::bind1<mpl::quote1<value_of>, mpl::_1> , mpl::bind1<mpl::quote1<value_of>, mpl::_1>
> >
> >
filter; >::type
{};
typedef typename filter::type type;
};
} }
template <typename Pred, typename Sequence> template <typename Pred, typename Sequence>
@ -48,7 +49,7 @@ namespace boost { namespace fusion
find_if(Sequence& seq) find_if(Sequence& seq)
{ {
typedef typename result_of::find_if<Sequence, Pred>::filter filter; typedef typename result_of::find_if<Sequence, Pred>::filter filter;
return filter::call(fusion::begin(seq)); return filter::call(seq);
} }
template <typename Pred, typename Sequence> template <typename Pred, typename Sequence>
@ -56,9 +57,8 @@ namespace boost { namespace fusion
find_if(Sequence const& seq) find_if(Sequence const& seq)
{ {
typedef typename result_of::find_if<Sequence const, Pred>::filter filter; typedef typename result_of::find_if<Sequence const, Pred>::filter filter;
return filter::call(fusion::begin(seq)); return filter::call(seq);
} }
}} }}
#endif #endif

View File

@ -0,0 +1,35 @@
/*=============================================================================
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_FIND_IF_FWD_HPP_INCLUDED)
#define BOOST_FUSION_FIND_IF_FWD_HPP_INCLUDED
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_const.hpp>
// Forward declaration of find_if algorithm
namespace boost { namespace fusion
{
namespace result_of
{
template <typename Sequence, typename Pred>
struct find_if;
}
template <typename Pred, typename Sequence>
typename
lazy_disable_if<
is_const<Sequence>
, result_of::find_if<Sequence, Pred>
>::type
find_if(Sequence& seq);
template <typename Pred, typename Sequence>
typename result_of::find_if<Sequence const, Pred>::type const
find_if(Sequence const& seq);
}}
#endif

View File

@ -8,6 +8,7 @@
#if !defined(FUSION_CONS_07172005_0843) #if !defined(FUSION_CONS_07172005_0843)
#define FUSION_CONS_07172005_0843 #define FUSION_CONS_07172005_0843
#include <boost/fusion/container/list/cons_fwd.hpp>
#include <boost/fusion/support/detail/access.hpp> #include <boost/fusion/support/detail/access.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp> #include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp> #include <boost/fusion/sequence/intrinsic/end.hpp>
@ -55,7 +56,7 @@ namespace boost { namespace fusion
} }
}; };
template <typename Car, typename Cdr = nil> template <typename Car, typename Cdr /*= nil*/>
struct cons : sequence_base<cons<Car, Cdr> > struct cons : sequence_base<cons<Car, Cdr> >
{ {
typedef mpl::int_<Cdr::size::value+1> size; typedef mpl::int_<Cdr::size::value+1> size;

View File

@ -0,0 +1,20 @@
/*=============================================================================
Copyright (c) 2005 Joel de Guzman
Copyright (c) 2005 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_CONS_FWD_HPP_INCLUDED)
#define BOOST_FUSION_CONS_FWD_HPP_INCLUDED
namespace boost { namespace fusion
{
struct nil;
template <typename Car, typename Cdr = nil>
struct cons;
}}
#endif

View File

@ -0,0 +1,43 @@
/*=============================================================================
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_REVERSE_CONS_HPP_INCLUDED)
#define BOOST_FUSION_REVERSE_CONS_HPP_INCLUDED
#include <boost/fusion/container/list/cons_fwd.hpp>
namespace boost { namespace fusion { namespace detail
{
////////////////////////////////////////////////////////////////////////////
template<typename Cons, typename State = nil>
struct reverse_cons;
template<typename Car, typename Cdr, typename State>
struct reverse_cons<cons<Car, Cdr>, State>
{
typedef reverse_cons<Cdr, cons<Car, State> > impl;
typedef typename impl::type type;
static type call(cons<Car, Cdr> const &cons, State const &state = State())
{
typedef fusion::cons<Car, State> cdr_type;
return impl::call(cons.cdr, cdr_type(cons.car, state));
}
};
template<typename State>
struct reverse_cons<nil, State>
{
typedef State type;
static State const &call(nil const &, State const &state = State())
{
return state;
}
};
}}}
#endif

View File

@ -7,6 +7,7 @@
#if !defined(FUSION_VECTOR10_05042005_0257) #if !defined(FUSION_VECTOR10_05042005_0257)
#define FUSION_VECTOR10_05042005_0257 #define FUSION_VECTOR10_05042005_0257
#include <boost/fusion/container/vector/vector10_fwd.hpp>
#include <boost/fusion/support/sequence_base.hpp> #include <boost/fusion/support/sequence_base.hpp>
#include <boost/fusion/support/detail/access.hpp> #include <boost/fusion/support/detail/access.hpp>
#include <boost/fusion/iterator/next.hpp> #include <boost/fusion/iterator/next.hpp>
@ -39,7 +40,7 @@ namespace boost { namespace fusion
struct fusion_sequence_tag; struct fusion_sequence_tag;
struct random_access_traversal_tag; struct random_access_traversal_tag;
template <typename Dummy = void> template <typename Dummy>
struct vector0 : sequence_base<vector0<Dummy> > struct vector0 : sequence_base<vector0<Dummy> >
{ {
typedef mpl::vector0<> types; typedef mpl::vector0<> types;

View File

@ -0,0 +1,34 @@
#ifndef BOOST_PP_IS_ITERATING
/*=============================================================================
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_VECTOR10_FWD_HPP_INCLUDED)
#define BOOST_FUSION_VECTOR10_FWD_HPP_INCLUDED
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
namespace boost { namespace fusion
{
template <typename Dummy = void>
struct vector0;
// expand vector1 to vector10
#define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/vector10_fwd.hpp>
#define BOOST_PP_ITERATION_LIMITS (1, 10)
#include BOOST_PP_ITERATE()
}}
#endif
#else
template <BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), typename T)>
struct BOOST_PP_CAT(vector, BOOST_PP_ITERATION());
#endif

View File

@ -7,6 +7,7 @@
#if !defined(FUSION_VECTOR20_05052005_0205) #if !defined(FUSION_VECTOR20_05052005_0205)
#define FUSION_VECTOR20_05052005_0205 #define FUSION_VECTOR20_05052005_0205
#include <boost/fusion/container/vector/vector20_fwd.hpp>
#include <boost/fusion/support/sequence_base.hpp> #include <boost/fusion/support/sequence_base.hpp>
#include <boost/fusion/support/detail/access.hpp> #include <boost/fusion/support/detail/access.hpp>
#include <boost/fusion/iterator/next.hpp> #include <boost/fusion/iterator/next.hpp>

View File

@ -0,0 +1,31 @@
#ifndef BOOST_PP_IS_ITERATING
/*=============================================================================
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_VECTOR20_FWD_HPP_INCLUDED)
#define BOOST_FUSION_VECTOR20_FWD_HPP_INCLUDED
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
namespace boost { namespace fusion
{
// expand vector11 to vector20
#define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/vector20_fwd.hpp>
#define BOOST_PP_ITERATION_LIMITS (11, 20)
#include BOOST_PP_ITERATE()
}}
#endif
#else
template <BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), typename T)>
struct BOOST_PP_CAT(vector, BOOST_PP_ITERATION());
#endif

View File

@ -7,6 +7,7 @@
#if !defined(FUSION_VECTOR30_05052005_0206) #if !defined(FUSION_VECTOR30_05052005_0206)
#define FUSION_VECTOR30_05052005_0206 #define FUSION_VECTOR30_05052005_0206
#include <boost/fusion/container/vector/vector30_fwd.hpp>
#include <boost/fusion/support/sequence_base.hpp> #include <boost/fusion/support/sequence_base.hpp>
#include <boost/fusion/support/detail/access.hpp> #include <boost/fusion/support/detail/access.hpp>
#include <boost/fusion/iterator/next.hpp> #include <boost/fusion/iterator/next.hpp>

View File

@ -0,0 +1,31 @@
#ifndef BOOST_PP_IS_ITERATING
/*=============================================================================
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_VECTOR30_FWD_HPP_INCLUDED)
#define BOOST_FUSION_VECTOR30_FWD_HPP_INCLUDED
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
namespace boost { namespace fusion
{
// expand vector21 to vector30
#define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/vector30_fwd.hpp>
#define BOOST_PP_ITERATION_LIMITS (21, 30)
#include BOOST_PP_ITERATE()
}}
#endif
#else
template <BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), typename T)>
struct BOOST_PP_CAT(vector, BOOST_PP_ITERATION());
#endif

View File

@ -7,6 +7,7 @@
#if !defined(FUSION_VECTOR40_05052005_0208) #if !defined(FUSION_VECTOR40_05052005_0208)
#define FUSION_VECTOR40_05052005_0208 #define FUSION_VECTOR40_05052005_0208
#include <boost/fusion/container/vector/vector40_fwd.hpp>
#include <boost/fusion/support/sequence_base.hpp> #include <boost/fusion/support/sequence_base.hpp>
#include <boost/fusion/support/detail/access.hpp> #include <boost/fusion/support/detail/access.hpp>
#include <boost/fusion/iterator/next.hpp> #include <boost/fusion/iterator/next.hpp>

View File

@ -0,0 +1,31 @@
#ifndef BOOST_PP_IS_ITERATING
/*=============================================================================
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_VECTOR40_FWD_HPP_INCLUDED)
#define BOOST_FUSION_VECTOR40_FWD_HPP_INCLUDED
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
namespace boost { namespace fusion
{
// expand vector31 to vector40
#define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/vector40_fwd.hpp>
#define BOOST_PP_ITERATION_LIMITS (31, 40)
#include BOOST_PP_ITERATE()
}}
#endif
#else
template <BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), typename T)>
struct BOOST_PP_CAT(vector, BOOST_PP_ITERATION());
#endif

View File

@ -7,6 +7,7 @@
#if !defined(FUSION_VECTOR50_05052005_0207) #if !defined(FUSION_VECTOR50_05052005_0207)
#define FUSION_VECTOR50_05052005_0207 #define FUSION_VECTOR50_05052005_0207
#include <boost/fusion/container/vector/vector50_fwd.hpp>
#include <boost/fusion/support/sequence_base.hpp> #include <boost/fusion/support/sequence_base.hpp>
#include <boost/fusion/support/detail/access.hpp> #include <boost/fusion/support/detail/access.hpp>
#include <boost/fusion/iterator/next.hpp> #include <boost/fusion/iterator/next.hpp>

View File

@ -0,0 +1,31 @@
#ifndef BOOST_PP_IS_ITERATING
/*=============================================================================
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_VECTOR50_FWD_HPP_INCLUDED)
#define BOOST_FUSION_VECTOR50_FWD_HPP_INCLUDED
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
namespace boost { namespace fusion
{
// expand vector41 to vector50
#define BOOST_PP_FILENAME_1 <boost/fusion/container/vector/vector50_fwd.hpp>
#define BOOST_PP_ITERATION_LIMITS (41, 50)
#include BOOST_PP_ITERATE()
}}
#endif
#else
template <BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), typename T)>
struct BOOST_PP_CAT(vector, BOOST_PP_ITERATION());
#endif

View File

@ -10,6 +10,11 @@
#include <boost/fusion/container/vector/limits.hpp> #include <boost/fusion/container/vector/limits.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp> #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/fusion/container/vector/vector10_fwd.hpp>
#include <boost/fusion/container/vector/vector20_fwd.hpp>
#include <boost/fusion/container/vector/vector30_fwd.hpp>
#include <boost/fusion/container/vector/vector40_fwd.hpp>
#include <boost/fusion/container/vector/vector50_fwd.hpp>
namespace boost { namespace fusion namespace boost { namespace fusion
{ {

View File

@ -0,0 +1,12 @@
/*=============================================================================
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_INCLUDE_IS_SEGMENTED)
#define BOOST_FUSION_INCLUDE_IS_SEGMENTED
#include <boost/fusion/support/is_segmented.hpp>
#endif

View File

@ -0,0 +1,12 @@
/*=============================================================================
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_INCLUDE_SEGMENTED_FOLD_UNTIL)
#define BOOST_FUSION_INCLUDE_SEGMENTED_FOLD_UNTIL
#include <boost/fusion/support/segmented_fold_until.hpp>
#endif

View File

@ -0,0 +1,12 @@
/*=============================================================================
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_INCLUDE_SEGMENTED_ITERATOR)
#define BOOST_FUSION_INCLUDE_SEGMENTED_ITERATOR
#include <boost/fusion/iterator/segmented_iterator.hpp>
#endif

View File

@ -0,0 +1,12 @@
/*=============================================================================
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_INCLUDE_SEGMENTS)
#define BOOST_FUSION_INCLUDE_SEGMENTS
#include <boost/fusion/sequence/intrinsic/segments.hpp>
#endif

View File

@ -8,6 +8,7 @@
#define FUSION_ITERATOR_10022005_0559 #define FUSION_ITERATOR_10022005_0559
#include <boost/fusion/iterator/iterator_facade.hpp> #include <boost/fusion/iterator/iterator_facade.hpp>
#include <boost/fusion/iterator/segmented_iterator.hpp>
#include <boost/fusion/iterator/advance.hpp> #include <boost/fusion/iterator/advance.hpp>
#include <boost/fusion/iterator/deref.hpp> #include <boost/fusion/iterator/deref.hpp>
#include <boost/fusion/iterator/distance.hpp> #include <boost/fusion/iterator/distance.hpp>

View File

@ -0,0 +1,71 @@
/*=============================================================================
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_SEGMENTED_SEQUENCE_HPP_INCLUDED)
#define BOOST_FUSION_SEGMENTED_SEQUENCE_HPP_INCLUDED
#include <boost/mpl/bool.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/fusion/support/tag_of.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
namespace boost { namespace fusion { namespace detail
{
struct segment_sequence_tag {};
// Here, Sequence is a sequence of ranges (which may or may not be
// segmented).
template<typename Sequence>
struct segment_sequence
: sequence_base<segment_sequence<Sequence> >
{
typedef fusion_sequence_tag tag;
typedef segment_sequence_tag fusion_tag;
typedef typename Sequence::is_view is_view;
typedef typename Sequence::category category;
typedef Sequence sequence_type;
sequence_type sequence;
explicit segment_sequence(Sequence const & seq)
: sequence(seq)
{}
};
}
namespace extension
{
template<typename Tag>
struct is_segmented_impl;
template<>
struct is_segmented_impl<detail::segment_sequence_tag>
{
template<typename Sequence>
struct apply
: mpl::true_
{};
};
template<typename Tag>
struct segments_impl;
template<>
struct segments_impl<detail::segment_sequence_tag>
{
template<typename Sequence>
struct apply
{
typedef typename Sequence::sequence_type type;
static type call(Sequence & seq)
{
return seq.sequence;
}
};
};
}}}
#endif

View File

@ -0,0 +1,41 @@
/*=============================================================================
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_SEGMENTED_ITERATOR_EQUAL_TO_HPP_INCLUDED)
#define BOOST_FUSION_SEGMENTED_ITERATOR_EQUAL_TO_HPP_INCLUDED
#include <boost/mpl/and.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
namespace boost { namespace fusion
{
struct nil;
namespace detail
{
template <typename Stack1, typename Stack2>
struct segmented_equal_to
: mpl::and_<
segmented_equal_to<
typename Stack1::cdr_type,
typename Stack2::cdr_type
>
, result_of::equal_to<
typename Stack1::car_type::begin_type,
typename Stack2::car_type::begin_type
>
>
{};
template <>
struct segmented_equal_to<fusion::nil, fusion::nil>
: mpl::true_
{};
}
}}
#endif

View File

@ -0,0 +1,144 @@
/*=============================================================================
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_SEGMENTED_ITERATOR_SEGMENTED_ITERATOR_HPP_INCLUDED)
#define BOOST_FUSION_SEGMENTED_ITERATOR_SEGMENTED_ITERATOR_HPP_INCLUDED
#include <boost/mpl/bool.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/iterator/iterator_facade.hpp>
#include <boost/fusion/iterator/deref.hpp>
#include <boost/fusion/iterator/deref_data.hpp>
#include <boost/fusion/iterator/key_of.hpp>
#include <boost/fusion/iterator/value_of.hpp>
#include <boost/fusion/iterator/value_of_data.hpp>
#include <boost/fusion/iterator/detail/segmented_equal_to.hpp>
namespace boost { namespace fusion
{
struct nil;
namespace detail
{
template <typename Stack>
struct segmented_next_impl;
}
// A segmented iterator wraps a "context", which is a cons list
// of ranges, the frontmost is range over values and the rest
// are ranges over internal segments.
template <typename Context>
struct segmented_iterator
: iterator_facade<segmented_iterator<Context>, forward_traversal_tag>
{
explicit segmented_iterator(Context const& ctx)
: context(ctx)
{}
//auto deref(it)
//{
// return deref(begin(car(it.context)))
//}
template <typename It>
struct deref
{
typedef
typename result_of::deref<
typename It::context_type::car_type::begin_type
>::type
type;
static type call(It const& it)
{
return *it.context.car.first;
}
};
//auto deref_data(it)
//{
// return deref_data(begin(car(it.context)))
//}
template <typename It>
struct deref_data
{
typedef
typename result_of::deref_data<
typename It::context_type::car_type::begin_type
>::type
type;
static type call(It const& it)
{
return fusion::deref_data(it.context.car.first);
}
};
//auto key_of(it)
//{
// return key_of(begin(car(it.context)))
//}
template <typename It>
struct key_of
: result_of::key_of<typename It::context_type::car_type::begin_type>
{};
//auto value_of(it)
//{
// return value_of(begin(car(it.context)))
//}
template <typename It>
struct value_of
: result_of::value_of<typename It::context_type::car_type::begin_type>
{};
//auto value_of_data(it)
//{
// return value_of_data(begin(car(it.context)))
//}
template <typename It>
struct value_of_data
: result_of::value_of_data<typename It::context_type::car_type::begin_type>
{};
// Compare all the segment iterators in each stack, starting with
// the bottom-most.
template <
typename It1
, typename It2
, int Size1 = It1::context_type::size::value
, int Size2 = It2::context_type::size::value
>
struct equal_to
: mpl::false_
{};
template <typename It1, typename It2, int Size>
struct equal_to<It1, It2, Size, Size>
: detail::segmented_equal_to<
typename It1::context_type
, typename It2::context_type
>
{};
template <typename It>
struct next
{
typedef detail::segmented_next_impl<typename It::context_type> impl;
typedef segmented_iterator<typename impl::type> type;
static type call(It const& it)
{
return type(impl::call(it.context));
}
};
typedef Context context_type;
context_type context;
};
}}
#endif

View File

@ -0,0 +1,254 @@
/*=============================================================================
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_SEGMENTED_ITERATOR_NEXT_IMPL_HPP_INCLUDED)
#define BOOST_FUSION_SEGMENTED_ITERATOR_NEXT_IMPL_HPP_INCLUDED
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/container/list/cons_fwd.hpp>
#include <boost/fusion/iterator/next.hpp>
#include <boost/fusion/iterator/deref.hpp>
namespace boost { namespace fusion
{
template <typename First, typename Second>
struct iterator_range;
template <typename Context>
struct segmented_iterator;
namespace detail
{
template <typename Sequence, typename Stack>
struct segmented_begin_impl;
//bool is_invalid(stack)
//{
// return empty(car(stack));
//}
template <typename Stack>
struct is_invalid
: result_of::equal_to<
typename Stack::car_type::begin_type,
typename Stack::car_type::end_type
>
{};
////Advance the first iterator in the seq at the
////top of a stack of iterator ranges. Return the
////new stack.
//auto pop_front_car(stack)
//{
// return cons(iterator_range(next(begin(car(stack))), end(car(stack))), cdr(stack));
//}
template <typename Stack>
struct pop_front_car
{
typedef
iterator_range<
typename result_of::next<
typename Stack::car_type::begin_type
>::type
, typename Stack::car_type::end_type
>
car_type;
typedef
cons<car_type, typename Stack::cdr_type>
type;
static type call(Stack const & stack)
{
return type(
car_type(fusion::next(stack.car.first), stack.car.last),
stack.cdr);
}
};
template <
typename Stack,
typename Next = typename pop_front_car<Stack>::type,
bool IsInvalid = is_invalid<Next>::value,
int StackSize = Stack::size::value>
struct segmented_next_impl_recurse;
// Handle the case where the top of the stack has no usable
//auto segmented_next_impl_recurse3(stack)
//{
// if (size(stack) == 1)
// return cons(iterator_range(end(car(stack)), end(car(stack))), nil);
// else
// return segmented_next_impl_recurse(stack.cdr);
//}
template <
typename Stack,
int StackSize = Stack::size::value>
struct segmented_next_impl_recurse3
{
typedef segmented_next_impl_recurse<typename Stack::cdr_type> impl;
typedef typename impl::type type;
static type call(Stack const & stack)
{
return impl::call(stack.cdr);
}
};
template <typename Stack>
struct segmented_next_impl_recurse3<Stack, 1>
{
typedef typename Stack::car_type::end_type end_type;
typedef iterator_range<end_type, end_type> range_type;
typedef cons<range_type> type;
static type call(Stack const & stack)
{
return type(range_type(stack.car.last, stack.car.last));
}
};
//auto segmented_next_impl_recurse2(stack)
//{
// auto res = segmented_begin_impl(front(car(stack)), stack);
// if (is_invalid(res))
// return segmented_next_impl_recurse3(stack);
// else
// return res;
//}
template <
typename Stack,
typename Sequence =
typename remove_reference<
typename add_const<
typename result_of::deref<
typename Stack::car_type::begin_type
>::type
>::type
>::type,
typename Result =
typename segmented_begin_impl<Sequence, Stack>::type,
bool IsInvalid =
is_invalid<Result>::value>
struct segmented_next_impl_recurse2
{
typedef segmented_next_impl_recurse3<Stack> impl;
typedef typename impl::type type;
static type call(Stack const & stack)
{
return impl::call(stack);
}
};
template <typename Stack, typename Sequence, typename Result>
struct segmented_next_impl_recurse2<Stack, Sequence, Result, false>
{
typedef Result type;
static type call(Stack const & stack)
{
return segmented_begin_impl<Sequence, Stack>::call(*stack.car.first, stack);
}
};
//auto segmented_next_impl_recurse(stack)
//{
// auto next = pop_front_car(stack);
// if (is_invalid(next))
// if (1 == size(stack))
// return next;
// else
// return segmented_next_impl_recurse(cdr(stack));
// else
// return segmented_next_impl_recurse2(next)
//}
template <typename Stack, typename Next, bool IsInvalid, int StackSize>
struct segmented_next_impl_recurse
{
typedef
typename segmented_next_impl_recurse<typename Stack::cdr_type>::type
type;
static type call(Stack const& stack)
{
return segmented_next_impl_recurse<typename Stack::cdr_type>::call(stack.cdr);
}
};
template <typename Stack, typename Next>
struct segmented_next_impl_recurse<Stack, Next, true, 1>
{
typedef Next type;
static type call(Stack const & stack)
{
return pop_front_car<Stack>::call(stack);
}
};
template <typename Stack, typename Next, int StackSize>
struct segmented_next_impl_recurse<Stack, Next, false, StackSize>
{
typedef segmented_next_impl_recurse2<Next> impl;
typedef typename impl::type type;
static type call(Stack const & stack)
{
return impl::call(pop_front_car<Stack>::call(stack));
}
};
//auto segmented_next_impl(stack)
//{
// // car(stack) is a seq of values, not a seq of segments
// auto next = pop_front_car(stack);
// if (is_invalid(next))
// return segmented_next_impl_recurse(cdr(next));
// else
// return next;
//}
template <
typename Stack,
typename Next = typename pop_front_car<Stack>::type,
bool IsInvalid = is_invalid<Next>::value>
struct segmented_next_impl_aux
{
typedef segmented_next_impl_recurse<typename Stack::cdr_type> impl;
typedef typename impl::type type;
static type call(Stack const & stack)
{
return impl::call(stack.cdr);
}
};
template <typename Stack, typename Next>
struct segmented_next_impl_aux<Stack, Next, false>
{
typedef Next type;
static type call(Stack const & stack)
{
return pop_front_car<Stack>::call(stack);
}
};
template <typename Stack>
struct segmented_next_impl
: segmented_next_impl_aux<Stack>
{};
}
}}
#endif

View File

@ -0,0 +1,15 @@
/*=============================================================================
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_SEGMENTED_ITERATOR_HPP_INCLUDED)
#define BOOST_FUSION_SEGMENTED_ITERATOR_HPP_INCLUDED
#include <boost/fusion/iterator/detail/segmented_iterator.hpp>
#include <boost/fusion/iterator/detail/segmented_next_impl.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/container/list/cons.hpp>
#endif

View File

@ -14,6 +14,7 @@
#include <boost/fusion/sequence/intrinsic/end.hpp> #include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/sequence/intrinsic/front.hpp> #include <boost/fusion/sequence/intrinsic/front.hpp>
#include <boost/fusion/sequence/intrinsic/has_key.hpp> #include <boost/fusion/sequence/intrinsic/has_key.hpp>
#include <boost/fusion/sequence/intrinsic/segments.hpp>
#include <boost/fusion/sequence/intrinsic/size.hpp> #include <boost/fusion/sequence/intrinsic/size.hpp>
#include <boost/fusion/sequence/intrinsic/value_at.hpp> #include <boost/fusion/sequence/intrinsic/value_at.hpp>
#include <boost/fusion/sequence/intrinsic/at_key.hpp> #include <boost/fusion/sequence/intrinsic/at_key.hpp>

View File

@ -9,6 +9,7 @@
#include <boost/mpl/int.hpp> #include <boost/mpl/int.hpp>
#include <boost/type_traits/is_const.hpp> #include <boost/type_traits/is_const.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/support/tag_of.hpp> #include <boost/fusion/support/tag_of.hpp>
#include <boost/fusion/support/detail/access.hpp> #include <boost/fusion/support/detail/access.hpp>

View File

@ -9,6 +9,7 @@
#define BOOST_FUSION_AT_KEY_20060304_1755 #define BOOST_FUSION_AT_KEY_20060304_1755
#include <boost/type_traits/is_const.hpp> #include <boost/type_traits/is_const.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/algorithm/query/find.hpp> #include <boost/fusion/algorithm/query/find.hpp>
#include <boost/fusion/iterator/deref_data.hpp> #include <boost/fusion/iterator/deref_data.hpp>
#include <boost/fusion/support/tag_of.hpp> #include <boost/fusion/support/tag_of.hpp>

View File

@ -7,6 +7,7 @@
#if !defined(FUSION_BACK_09162005_0350) #if !defined(FUSION_BACK_09162005_0350)
#define FUSION_BACK_09162005_0350 #define FUSION_BACK_09162005_0350
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp> #include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/iterator/prior.hpp> #include <boost/fusion/iterator/prior.hpp>
#include <boost/fusion/iterator/deref.hpp> #include <boost/fusion/iterator/deref.hpp>

View File

@ -7,9 +7,14 @@
#if !defined(FUSION_BEGIN_04052005_1132) #if !defined(FUSION_BEGIN_04052005_1132)
#define FUSION_BEGIN_04052005_1132 #define FUSION_BEGIN_04052005_1132
#include <boost/blank.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/if.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/support/tag_of.hpp> #include <boost/fusion/support/tag_of.hpp>
#include <boost/fusion/support/is_sequence.hpp> #include <boost/fusion/support/is_sequence.hpp>
#include <boost/utility/enable_if.hpp> #include <boost/fusion/support/is_segmented.hpp>
#include <boost/fusion/sequence/intrinsic/detail/segmented_begin.hpp>
namespace boost { namespace fusion namespace boost { namespace fusion
{ {
@ -26,7 +31,13 @@ namespace boost { namespace fusion
struct begin_impl struct begin_impl
{ {
template <typename Sequence> template <typename Sequence>
struct apply; struct apply
: mpl::if_<
traits::is_segmented<Sequence>
, detail::segmented_begin<Sequence>
, blank
>::type
{};
}; };
template <> template <>

View File

@ -0,0 +1,43 @@
/*=============================================================================
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_SEGMENTED_BEGIN_HPP_INCLUDED)
#define BOOST_FUSION_SEGMENTED_BEGIN_HPP_INCLUDED
#include <boost/fusion/sequence/intrinsic/detail/segmented_begin_impl.hpp>
#include <boost/fusion/iterator/segmented_iterator.hpp>
#include <boost/fusion/view/iterator_range.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/sequence/intrinsic/empty.hpp>
#include <boost/fusion/container/list/cons.hpp>
namespace boost { namespace fusion { namespace detail
{
//auto segmented_begin( seq )
//{
// return make_segmented_iterator( segmented_begin_impl( seq, nil ) );
//}
template <typename Sequence, typename Nil = fusion::nil>
struct segmented_begin
{
typedef
segmented_iterator<
typename segmented_begin_impl<Sequence, Nil>::type
>
type;
static type call(Sequence& seq)
{
return type(
segmented_begin_impl<Sequence, Nil>::call(seq, Nil()));
}
};
}}}
#endif

View File

@ -0,0 +1,92 @@
/*=============================================================================
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_SEGMENTED_BEGIN_IMPL_HPP_INCLUDED)
#define BOOST_FUSION_SEGMENTED_BEGIN_IMPL_HPP_INCLUDED
#include <boost/type_traits/remove_const.hpp>
#include <boost/fusion/container/list/cons_fwd.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/support/is_segmented.hpp>
#include <boost/fusion/sequence/intrinsic/detail/segmented_end_impl.hpp>
#include <boost/fusion/support/detail/segmented_fold_until_impl.hpp>
namespace boost { namespace fusion
{
template <typename First, typename Last>
struct iterator_range;
}}
namespace boost { namespace fusion { namespace detail
{
struct segmented_begin_fun
{
template <typename Sequence, typename State, typename Context>
struct apply
{
typedef
iterator_range<
typename fusion::result_of::begin<Sequence>::type
, typename fusion::result_of::end<Sequence>::type
>
range_type;
typedef cons<range_type, Context> type;
typedef mpl::false_ continue_type;
static type call(Sequence& seq, State const&, Context const& context, segmented_begin_fun)
{
return type(range_type(fusion::begin(seq), fusion::end(seq)), context);
}
};
};
template <typename Sequence, typename Stack, bool IsSegmented = traits::is_segmented<Sequence>::type::value>
struct segmented_begin_impl_aux
{
typedef
segmented_end_impl<Sequence, Stack>
end_impl;
typedef
segmented_fold_until_impl<
Sequence
, typename end_impl::type
, Stack
, segmented_begin_fun
>
fold_impl;
typedef typename fold_impl::type type;
static type call(Sequence& seq, Stack const& stack)
{
return fold_impl::call(seq, end_impl::call(seq, stack), stack, segmented_begin_fun());
}
};
template <typename Sequence, typename Stack>
struct segmented_begin_impl_aux<Sequence, Stack, false>
{
typedef typename result_of::begin<Sequence>::type begin_type;
typedef typename result_of::end<Sequence>::type end_type;
typedef iterator_range<begin_type, end_type> pair_type;
typedef cons<pair_type, Stack> type;
static type call(Sequence& seq, Stack stack)
{
return type(pair_type(fusion::begin(seq), fusion::end(seq)), stack);
}
};
template <typename Sequence, typename Stack>
struct segmented_begin_impl
: segmented_begin_impl_aux<Sequence, Stack>
{};
}}}
#endif

View File

@ -0,0 +1,39 @@
/*=============================================================================
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_SEGMENTED_END_HPP_INCLUDED)
#define BOOST_FUSION_SEGMENTED_END_HPP_INCLUDED
#include <boost/fusion/sequence/intrinsic/detail/segmented_end_impl.hpp>
#include <boost/fusion/iterator/segmented_iterator.hpp>
#include <boost/fusion/container/list/cons.hpp>
namespace boost { namespace fusion { namespace detail
{
//auto segmented_end( seq )
//{
// return make_segmented_iterator( segmented_end_impl( seq ) );
//}
template <typename Sequence, typename Nil = fusion::nil>
struct segmented_end
{
typedef
segmented_iterator<
typename segmented_end_impl<Sequence, Nil>::type
>
type;
static type call(Sequence & seq)
{
return type(
segmented_end_impl<Sequence, Nil>::call(seq, Nil()));
}
};
}}}
#endif

View File

@ -0,0 +1,59 @@
/*=============================================================================
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_SEGMENTED_END_IMPL_HPP_INCLUDED)
#define BOOST_FUSION_SEGMENTED_END_IMPL_HPP_INCLUDED
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/container/list/cons_fwd.hpp>
#include <boost/fusion/support/is_segmented.hpp>
namespace boost { namespace fusion
{
template <typename First, typename Last>
struct iterator_range;
}}
namespace boost { namespace fusion { namespace detail
{
//auto segmented_end_impl( seq, stack )
//{
// assert(is_segmented(seq));
// auto it = end(segments(seq));
// return cons(iterator_range(it, it), stack);
//}
template <typename Sequence, typename Stack>
struct segmented_end_impl
{
BOOST_MPL_ASSERT((traits::is_segmented<Sequence>));
typedef
typename result_of::end<
typename remove_reference<
typename add_const<
typename result_of::segments<Sequence>::type
>::type
>::type
>::type
end_type;
typedef iterator_range<end_type, end_type> pair_type;
typedef cons<pair_type, Stack> type;
static type call(Sequence & seq, Stack stack)
{
end_type end = fusion::end(fusion::segments(seq));
return type(pair_type(end, end), stack);
}
};
}}}
#endif

View File

@ -0,0 +1,54 @@
/*=============================================================================
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_SEGMENTED_SIZE_08112006_1141)
#define BOOST_FUSION_SEGMENTED_SIZE_08112006_1141
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/size_t.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/mpl/begin.hpp>
#include <boost/fusion/mpl/end.hpp>
#include <boost/fusion/support/is_segmented.hpp>
namespace boost { namespace fusion { namespace detail
{
///////////////////////////////////////////////////////////////////////////
// calculates the size of any segmented data structure.
template<typename Sequence>
struct segmented_size;
///////////////////////////////////////////////////////////////////////////
template<typename Sequence, bool IsSegmented = traits::is_segmented<Sequence>::value>
struct segmented_size_impl
: mpl::fold<
typename remove_reference<
typename add_const<
typename result_of::segments<Sequence>::type
>::type
>::type
, mpl::size_t<0>
, mpl::plus<mpl::_1, segmented_size<remove_reference<mpl::_2> > >
>::type
{};
template<typename Sequence>
struct segmented_size_impl<Sequence, false>
: result_of::size<Sequence>::type
{};
template<typename Sequence>
struct segmented_size
: segmented_size_impl<Sequence>
{};
}}}
#endif

View File

@ -7,6 +7,7 @@
#if !defined(FUSION_EMPTY_09162005_0335) #if !defined(FUSION_EMPTY_09162005_0335)
#define FUSION_EMPTY_09162005_0335 #define FUSION_EMPTY_09162005_0335
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/sequence/intrinsic/size.hpp> #include <boost/fusion/sequence/intrinsic/size.hpp>
#include <boost/mpl/bool.hpp> #include <boost/mpl/bool.hpp>
#include <boost/fusion/support/tag_of.hpp> #include <boost/fusion/support/tag_of.hpp>

View File

@ -7,9 +7,14 @@
#if !defined(FUSION_END_04052005_1141) #if !defined(FUSION_END_04052005_1141)
#define FUSION_END_04052005_1141 #define FUSION_END_04052005_1141
#include <boost/blank.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/if.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/support/tag_of.hpp> #include <boost/fusion/support/tag_of.hpp>
#include <boost/fusion/support/is_sequence.hpp> #include <boost/fusion/support/is_sequence.hpp>
#include <boost/utility/enable_if.hpp> #include <boost/fusion/support/is_segmented.hpp>
#include <boost/fusion/sequence/intrinsic/detail/segmented_end.hpp>
namespace boost { namespace fusion namespace boost { namespace fusion
{ {
@ -26,7 +31,13 @@ namespace boost { namespace fusion
struct end_impl struct end_impl
{ {
template <typename Sequence> template <typename Sequence>
struct apply; struct apply
: mpl::if_<
traits::is_segmented<Sequence>
, detail::segmented_end<Sequence>
, blank
>::type
{};
}; };
template <> template <>

View File

@ -1,56 +0,0 @@
/*=============================================================================
Copyright (c) 2006 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(FUSION_SEGMENTS_04052005_1141)
#define FUSION_SEGMENTS_04052005_1141
#include <boost/fusion/support/tag_of.hpp>
namespace boost { namespace fusion
{
// segments: returns a sequence of sequences
namespace extension
{
template <typename Tag>
struct segments_impl
{
template <typename Sequence>
struct apply {};
};
}
namespace result_of
{
template <typename Sequence>
struct segments
{
typedef typename
extension::segments_impl<typename traits::tag_of<Sequence>::type>::
template apply<Sequence>::type
type;
};
}
template <typename Sequence>
typename result_of::segments<Sequence>::type
segments(Sequence & seq)
{
return
extension::segments_impl<typename traits::tag_of<Sequence>::type>::
template apply<Sequence>::call(seq);
}
template <typename Sequence>
typename result_of::segments<Sequence const>::type
segments(Sequence const& seq)
{
return
extension::segments_impl<typename traits::tag_of<Sequence>::type>::
template apply<Sequence const>::call(seq);
}
}}
#endif

View File

@ -1,57 +0,0 @@
/*=============================================================================
Copyright (c) 2006 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(FUSION_SIZE_S_08112006_1141)
#define FUSION_SIZE_S_08112006_1141
#include <boost/mpl/plus.hpp>
#include <boost/mpl/size_t.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/fusion/algorithm/iteration/fold.hpp>
#include <boost/fusion/support/ext_/is_segmented.hpp>
#include <boost/fusion/sequence/intrinsic/ext_/segments.hpp>
namespace boost { namespace fusion
{
///////////////////////////////////////////////////////////////////////////
// calculates the size of any segmented data structure.
template<typename Sequence, bool IsSegmented = traits::is_segmented<Sequence>::value>
struct segmented_size;
namespace detail
{
struct size_plus
{
template<typename Sig>
struct result;
template<typename This, typename State, typename Seq>
struct result<This(State, Seq)>
: mpl::plus<
segmented_size<typename remove_reference<Seq>::type>
, typename remove_reference<State>::type
>
{};
};
}
///////////////////////////////////////////////////////////////////////////
template<typename Sequence, bool IsSegmented>
struct segmented_size
: result_of::fold<
typename result_of::segments<Sequence>::type
, mpl::size_t<0>
, detail::size_plus
>::type
{};
template<typename Sequence>
struct segmented_size<Sequence, false>
: result_of::size<Sequence>
{};
}}
#endif

View File

@ -7,6 +7,7 @@
#if !defined(FUSION_FRONT_09162005_0343) #if !defined(FUSION_FRONT_09162005_0343)
#define FUSION_FRONT_09162005_0343 #define FUSION_FRONT_09162005_0343
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp> #include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/iterator/deref.hpp> #include <boost/fusion/iterator/deref.hpp>
#include <boost/mpl/bool.hpp> #include <boost/mpl/bool.hpp>

View File

@ -7,6 +7,7 @@
#if !defined(FUSION_HAS_KEY_09232005_1454) #if !defined(FUSION_HAS_KEY_09232005_1454)
#define FUSION_HAS_KEY_09232005_1454 #define FUSION_HAS_KEY_09232005_1454
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/support/tag_of.hpp> #include <boost/fusion/support/tag_of.hpp>
#include <boost/fusion/iterator/equal_to.hpp> #include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/algorithm/query/find.hpp> #include <boost/fusion/algorithm/query/find.hpp>

View File

@ -0,0 +1,76 @@
/*=============================================================================
Copyright (c) 2006 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_SEGMENTS_04052005_1141)
#define BOOST_FUSION_SEGMENTS_04052005_1141
#include <boost/type_traits/is_const.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/support/tag_of.hpp>
namespace boost { namespace fusion
{
// Special tags:
struct sequence_facade_tag;
struct iterator_range_tag;
// segments: returns a sequence of sequences
namespace extension
{
template <typename Tag>
struct segments_impl
{
template <typename Sequence>
struct apply {};
};
template <>
struct segments_impl<sequence_facade_tag>
{
template <typename Sequence>
struct apply : Sequence::template segments<Sequence> {};
};
template <>
struct segments_impl<iterator_range_tag>;
}
namespace result_of
{
template <typename Sequence>
struct segments
{
typedef typename traits::tag_of<Sequence>::type tag_type;
typedef typename
extension::segments_impl<tag_type>::template apply<Sequence>::type
type;
};
}
template <typename Sequence>
inline typename
lazy_disable_if<
is_const<Sequence>
, result_of::segments<Sequence>
>::type
segments(Sequence& seq)
{
typedef typename traits::tag_of<Sequence>::type tag_type;
return extension::segments_impl<tag_type>::template apply<Sequence>::call(seq);
}
template <typename Sequence>
inline typename result_of::segments<Sequence const>::type
segments(Sequence const& seq)
{
typedef typename traits::tag_of<Sequence const>::type tag_type;
return extension::segments_impl<tag_type>::template apply<Sequence const>::call(seq);
}
}}
#endif

View File

@ -7,8 +7,13 @@
#if !defined(FUSION_SIZE_05052005_0214) #if !defined(FUSION_SIZE_05052005_0214)
#define FUSION_SIZE_05052005_0214 #define FUSION_SIZE_05052005_0214
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/int.hpp> #include <boost/mpl/int.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/support/tag_of.hpp> #include <boost/fusion/support/tag_of.hpp>
#include <boost/fusion/support/is_segmented.hpp>
#include <boost/fusion/sequence/intrinsic/detail/segmented_size.hpp>
namespace boost { namespace fusion namespace boost { namespace fusion
{ {
@ -25,7 +30,16 @@ namespace boost { namespace fusion
struct size_impl struct size_impl
{ {
template<typename Sequence> template<typename Sequence>
struct apply : Sequence::size {}; struct unsegmented_size : Sequence::size {};
template <typename Sequence>
struct apply
: mpl::if_<
traits::is_segmented<Sequence>
, detail::segmented_size<Sequence>
, unsegmented_size<Sequence>
>::type
{};
}; };
template <> template <>

View File

@ -8,6 +8,7 @@
#define FUSION_VALUE_AT_05052005_0229 #define FUSION_VALUE_AT_05052005_0229
#include <boost/mpl/int.hpp> #include <boost/mpl/int.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/support/tag_of.hpp> #include <boost/fusion/support/tag_of.hpp>
namespace boost { namespace fusion namespace boost { namespace fusion

View File

@ -9,6 +9,7 @@
#define FUSION_VALUE_AT_KEY_05052005_0229 #define FUSION_VALUE_AT_KEY_05052005_0229
#include <boost/mpl/int.hpp> #include <boost/mpl/int.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/iterator/value_of_data.hpp> #include <boost/fusion/iterator/value_of_data.hpp>
#include <boost/fusion/algorithm/query/find.hpp> #include <boost/fusion/algorithm/query/find.hpp>
#include <boost/fusion/support/tag_of.hpp> #include <boost/fusion/support/tag_of.hpp>

View File

@ -0,0 +1,203 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
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_SEQUENCE_INTRINSIC_FWD_HPP_INCLUDED)
#define BOOST_FUSION_SEQUENCE_INTRINSIC_FWD_HPP_INCLUDED
#include <boost/type_traits/is_const.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/fusion/support/is_sequence.hpp>
namespace boost { namespace fusion
{
namespace extension
{
template <typename Tag>
struct at_impl;
template <typename Tag>
struct begin_impl;
template <typename Tag>
struct empty_impl;
template <typename Tag>
struct end_impl;
template <typename Tag>
struct has_key_impl;
template <typename Tag>
struct segments_impl;
template <typename Tag>
struct size_impl;
template <typename Tag>
struct value_at_impl;
template <typename Tag>
struct at_key_impl;
template <typename Tag>
struct value_at_key_impl;
}
namespace result_of
{
template <typename Sequence, typename N>
struct at;
template <typename Sequence, int N>
struct at_c;
template <typename Sequence>
struct back;
template <typename Sequence>
struct begin;
template <typename Sequence>
struct empty;
template <typename Sequence>
struct end;
template <typename Sequence>
struct front;
template <typename Sequence, typename Key>
struct has_key;
template <typename Sequence>
struct segments;
template <typename Sequence>
struct size;
template <typename Sequence, typename N>
struct value_at;
template <typename Sequence, int N>
struct value_at_c;
template <typename Sequence, typename Key>
struct at_key;
template <typename Sequence, typename N>
struct value_at_key;
}
template <typename N, typename Sequence>
typename
lazy_disable_if<
is_const<Sequence>
, result_of::at<Sequence, N>
>::type
at(Sequence& seq);
template <typename N, typename Sequence>
typename result_of::at<Sequence const, N>::type
at(Sequence const& seq);
template <int N, typename Sequence>
typename
lazy_disable_if<
is_const<Sequence>
, result_of::at_c<Sequence, N>
>::type
at_c(Sequence& seq);
template <int N, typename Sequence>
typename result_of::at_c<Sequence const, N>::type
at_c(Sequence const& seq);
template <typename Sequence>
typename result_of::back<Sequence>::type
back(Sequence& seq);
template <typename Sequence>
typename result_of::back<Sequence const>::type
back(Sequence const& seq);
template <typename Sequence>
typename
lazy_enable_if<
traits::is_sequence<Sequence>
, result_of::begin<Sequence>
>::type const
begin(Sequence& seq);
template <typename Sequence>
typename
lazy_enable_if<
traits::is_sequence<Sequence>
, result_of::begin<Sequence const>
>::type const
begin(Sequence const& seq);
template <typename Sequence>
typename result_of::empty<Sequence>::type
empty(Sequence const&);
template <typename Sequence>
typename
lazy_enable_if<
traits::is_sequence<Sequence>
, result_of::end<Sequence>
>::type const
end(Sequence& seq);
template <typename Sequence>
typename
lazy_enable_if<
traits::is_sequence<Sequence>
, result_of::end<Sequence const>
>::type const
end(Sequence const& seq);
template <typename Sequence>
typename result_of::front<Sequence>::type
front(Sequence& seq);
template <typename Sequence>
typename result_of::front<Sequence const>::type
front(Sequence const& seq);
template <typename Key, typename Sequence>
typename result_of::has_key<Sequence, Key>::type
has_key(Sequence const& seq);
template <typename Sequence>
typename
lazy_disable_if<
is_const<Sequence>
, result_of::segments<Sequence>
>::type
segments(Sequence& seq);
template <typename Sequence>
typename result_of::segments<Sequence const>::type
segments(Sequence const& seq);
template <typename Sequence>
typename result_of::size<Sequence>::type
size(Sequence const&);
template <typename Key, typename Sequence>
typename
lazy_disable_if<
is_const<Sequence>
, result_of::at_key<Sequence, Key>
>::type
at_key(Sequence& seq);
template <typename Key, typename Sequence>
typename result_of::at_key<Sequence const, Key>::type
at_key(Sequence const& seq);
}}
#endif

View File

@ -10,6 +10,7 @@
#include <boost/fusion/support/category_of.hpp> #include <boost/fusion/support/category_of.hpp>
#include <boost/fusion/support/is_iterator.hpp> #include <boost/fusion/support/is_iterator.hpp>
#include <boost/fusion/support/is_sequence.hpp> #include <boost/fusion/support/is_sequence.hpp>
#include <boost/fusion/support/is_segmented.hpp>
#include <boost/fusion/support/iterator_base.hpp> #include <boost/fusion/support/iterator_base.hpp>
#include <boost/fusion/support/pair.hpp> #include <boost/fusion/support/pair.hpp>
#include <boost/fusion/support/sequence_base.hpp> #include <boost/fusion/support/sequence_base.hpp>

View File

@ -0,0 +1,389 @@
/*=============================================================================
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_SEGMENTED_FOLD_UNTIL_IMPL_HPP_INCLUDED)
#define BOOST_FUSION_SEGMENTED_FOLD_UNTIL_IMPL_HPP_INCLUDED
#include <boost/mpl/bool.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/fusion/support/void.hpp>
#include <boost/fusion/container/list/cons_fwd.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/iterator/deref.hpp>
#include <boost/fusion/iterator/next.hpp>
#include <boost/fusion/support/is_segmented.hpp>
#include <boost/fusion/sequence/intrinsic/segments.hpp>
// fun(seq, state, context)
// seq: a non-segmented range
// state: the state of the fold so far
// context: the path to the current range
//
// returns: (state', fcontinue)
namespace boost { namespace fusion
{
template <typename First, typename Last>
struct iterator_range;
template <typename Context>
struct segmented_iterator;
namespace result_of
{
template <typename Cur, typename Context>
struct make_segmented_iterator
{
typedef
iterator_range<
Cur
, typename result_of::end<
typename remove_reference<
typename add_const<
typename result_of::deref<
typename Context::car_type::begin_type
>::type
>::type
>::type
>::type
>
range_type;
typedef
segmented_iterator<cons<range_type, Context> >
type;
};
}
template <typename Cur, typename Context>
typename result_of::make_segmented_iterator<Cur, Context>::type
make_segmented_iterator(Cur const& cur, Context const& context)
{
typedef result_of::make_segmented_iterator<Cur, Context> impl_type;
typedef typename impl_type::type type;
typedef typename impl_type::range_type range_type;
return type(cons<range_type, Context>(range_type(cur, fusion::end(*context.car.first)), context));
}
namespace detail
{
template <
typename Begin
, typename End
, typename State
, typename Context
, typename Fun
, bool IsEmpty
>
struct segmented_fold_until_iterate_skip_empty;
template <
typename Begin
, typename End
, typename State
, typename Context
, typename Fun
, bool IsDone = result_of::equal_to<Begin, End>::type::value
>
struct segmented_fold_until_iterate;
template <
typename Sequence
, typename State
, typename Context
, typename Fun
, bool IsSegmented = traits::is_segmented<Sequence>::type::value
>
struct segmented_fold_until_impl;
template <typename Segments, typename State, typename Context, typename Fun>
struct segmented_fold_until_on_segments;
//auto push_context(cur, end, context)
//{
// return push_back(context, segment_sequence(iterator_range(cur, end)));
//}
template <typename Cur, typename End, typename Context>
struct push_context
{
typedef iterator_range<Cur, End> range_type;
typedef cons<range_type, Context> type;
static type call(Cur const& cur, End const& end, Context const& context)
{
return cons<range_type, Context>(range_type(cur, end), context);
}
};
//auto make_segmented_iterator(cur, end, context)
//{
// return segmented_iterator(push_context(cur, end, context));
//}
//
//auto segmented_fold_until_impl(seq, state, context, fun)
//{
// if (is_segmented(seq))
// {
// segmented_fold_until_on_segments(segments(seq), state, context, fun);
// }
// else
// {
// return fun(seq, state, context);
// }
//}
template <
typename Sequence
, typename State
, typename Context
, typename Fun
, bool IsSegmented
>
struct segmented_fold_until_impl
{
typedef
segmented_fold_until_on_segments<
typename remove_reference<
typename add_const<
typename result_of::segments<Sequence>::type
>::type
>::type
, State
, Context
, Fun
>
impl;
typedef typename impl::type type;
typedef typename impl::continue_type continue_type;
static type call(Sequence& seq, State const& state, Context const& context, Fun const& fun)
{
return impl::call(fusion::segments(seq), state, context, fun);
}
};
template <
typename Sequence
, typename State
, typename Context
, typename Fun
>
struct segmented_fold_until_impl<Sequence, State, Context, Fun, false>
{
typedef
typename Fun::template apply<Sequence, State, Context>
apply_type;
typedef typename apply_type::type type;
typedef typename apply_type::continue_type continue_type;
static type call(Sequence& seq, State const& state, Context const& context, Fun const& fun)
{
return apply_type::call(seq, state, context, fun);
}
};
//auto segmented_fold_until_on_segments(segs, state, context, fun)
//{
// auto cur = begin(segs), end = end(segs);
// for (; cur != end; ++cur)
// {
// if (empty(*cur))
// continue;
// auto context` = push_context(cur, end, context);
// state = segmented_fold_until_impl(*cur, state, context`, fun);
// if (!second(state))
// return state;
// }
//}
template <typename Apply>
struct continue_wrap
{
typedef typename Apply::continue_type type;
};
template <typename Begin, typename End, typename State, typename Context, typename Fun, bool IsEmpty>
struct segmented_fold_until_iterate_skip_empty
{
// begin != end and !empty(*begin)
typedef
push_context<Begin, End, Context>
push_context_impl;
typedef
typename push_context_impl::type
next_context_type;
typedef
segmented_fold_until_impl<
typename remove_reference<
typename add_const<
typename result_of::deref<Begin>::type
>::type
>::type
, State
, next_context_type
, Fun
>
fold_recurse_impl;
typedef
typename fold_recurse_impl::type
next_state_type;
typedef
segmented_fold_until_iterate<
typename result_of::next<Begin>::type
, End
, next_state_type
, Context
, Fun
>
next_iteration_impl;
typedef
typename mpl::eval_if<
typename fold_recurse_impl::continue_type
, next_iteration_impl
, mpl::identity<next_state_type>
>::type
type;
typedef
typename mpl::eval_if<
typename fold_recurse_impl::continue_type
, continue_wrap<next_iteration_impl>
, mpl::identity<mpl::false_>
>::type
continue_type;
static type call(Begin const& beg, End const& end, State const& state
, Context const& context, Fun const& fun)
{
return call(beg, end, state, context, fun, typename fold_recurse_impl::continue_type());
}
static type call(Begin const& beg, End const& end, State const& state
, Context const& context, Fun const& fun, mpl::true_) // continue
{
return next_iteration_impl::call(
fusion::next(beg)
, end
, fold_recurse_impl::call(
*beg
, state
, push_context_impl::call(beg, end, context)
, fun)
, context
, fun);
}
static type call(Begin const& beg, End const& end, State const& state
, Context const& context, Fun const& fun, mpl::false_) // break
{
return fold_recurse_impl::call(
*beg
, state
, push_context_impl::call(beg, end, context)
, fun);
}
};
template <typename Begin, typename End, typename State, typename Context, typename Fun>
struct segmented_fold_until_iterate_skip_empty<Begin, End, State, Context, Fun, true>
{
typedef
segmented_fold_until_iterate<
typename result_of::next<Begin>::type
, End
, State
, Context
, Fun
>
impl;
typedef typename impl::type type;
typedef typename impl::continue_type continue_type;
static type call(Begin const& beg, End const& end, State const& state
, Context const& context, Fun const& fun)
{
return impl::call(fusion::next(beg), end, state, context, fun);
}
};
template <typename Begin, typename End, typename State, typename Context, typename Fun, bool IsDone>
struct segmented_fold_until_iterate
{
typedef
typename result_of::empty<
typename remove_reference<
typename result_of::deref<Begin>::type
>::type
>::type
empty_type;
typedef
segmented_fold_until_iterate_skip_empty<Begin, End, State, Context, Fun, empty_type::value>
impl;
typedef typename impl::type type;
typedef typename impl::continue_type continue_type;
static type call(Begin const& beg, End const& end, State const& state
, Context const& context, Fun const& fun)
{
return impl::call(beg, end, state, context, fun);
}
};
template <typename Begin, typename End, typename State, typename Context, typename Fun>
struct segmented_fold_until_iterate<Begin, End, State, Context, Fun, true>
{
typedef State type;
typedef mpl::true_ continue_type;
static type call(Begin const&, End const&, State const& state
, Context const&, Fun const&)
{
return state;
}
};
template <typename Segments, typename State, typename Context, typename Fun>
struct segmented_fold_until_on_segments
{
typedef
segmented_fold_until_iterate<
typename result_of::begin<Segments>::type
, typename result_of::end<Segments>::type
, State
, Context
, Fun
>
impl;
typedef typename impl::type type;
typedef typename impl::continue_type continue_type;
static type call(Segments& segs, State const& state, Context const& context, Fun const& fun)
{
return impl::call(fusion::begin(segs), fusion::end(segs), state, context, fun);
}
};
}
}}
#endif

View File

@ -13,10 +13,6 @@ namespace boost { namespace fusion
{ {
// Special tags: // Special tags:
struct sequence_facade_tag; struct sequence_facade_tag;
struct boost_tuple_tag; // boost::tuples::tuple tag
struct boost_array_tag; // boost::array tag
struct mpl_sequence_tag; // mpl sequence tag
struct std_pair_tag; // std::pair tag
struct iterator_range_tag; struct iterator_range_tag;
namespace extension namespace extension
@ -30,6 +26,13 @@ namespace boost { namespace fusion
{}; {};
}; };
template <>
struct is_segmented_impl<sequence_facade_tag>
{
template <typename Sequence>
struct apply : Sequence::is_segmented {};
};
template <> template <>
struct is_segmented_impl<iterator_range_tag>; struct is_segmented_impl<iterator_range_tag>;
} }

View File

@ -0,0 +1,73 @@
/*=============================================================================
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_SEGMENTED_FOLD_UNTIL_HPP_INCLUDED)
#define BOOST_FUSION_SEGMENTED_FOLD_UNTIL_HPP_INCLUDED
#include <boost/type_traits/is_const.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/fusion/support/detail/segmented_fold_until_impl.hpp>
#include <boost/fusion/view/iterator_range.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/sequence/intrinsic/empty.hpp>
#include <boost/fusion/container/list/cons.hpp>
namespace boost { namespace fusion
{
//auto segmented_fold_until(seq, state, fun)
//{
// return first(segmented_fold_until_impl(seq, state, nil, fun));
//}
namespace result_of
{
template <typename Sequence, typename State, typename Fun>
struct segmented_fold_until
{
typedef
detail::segmented_fold_until_impl<
Sequence
, State
, fusion::nil
, Fun
>
filter;
typedef
typename filter::type
type;
};
}
template <typename Sequence, typename State, typename Fun>
typename
lazy_disable_if<
is_const<Sequence>
, result_of::segmented_fold_until<Sequence, State, Fun>
>::type
segmented_fold_until(Sequence& seq, State const& state, Fun const& fun)
{
typedef
typename result_of::segmented_fold_until<Sequence, State, Fun>::filter
filter;
return filter::call(seq, state, fusion::nil(), fun);
}
template <typename Sequence, typename State, typename Fun>
typename result_of::segmented_fold_until<Sequence const, State, Fun>::type
segmented_fold_until(Sequence const& seq, State const& state, Fun const& fun)
{
typedef
typename result_of::segmented_fold_until<Sequence const, State, Fun>::filter
filter;
return filter::call(seq, state, fusion::nil(), fun);
}
}}
#endif

View File

@ -1,178 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2006 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 FUSION_MULTIPLE_VIEW_05052005_0335
#define FUSION_MULTIPLE_VIEW_05052005_0335
#include <boost/mpl/int.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/next.hpp>
#include <boost/fusion/support/detail/access.hpp>
#include <boost/fusion/support/sequence_base.hpp>
#include <boost/fusion/support/iterator_base.hpp>
#include <boost/fusion/support/detail/as_fusion_element.hpp>
namespace boost { namespace fusion
{
struct multiple_view_tag;
struct forward_traversal_tag;
struct fusion_sequence_tag;
template<typename Size, typename T>
struct multiple_view
: sequence_base<multiple_view<Size, T> >
{
typedef multiple_view_tag fusion_tag;
typedef fusion_sequence_tag tag; // this gets picked up by MPL
typedef forward_traversal_tag category;
typedef mpl::true_ is_view;
typedef mpl::int_<Size::value> size;
typedef T value_type;
multiple_view()
: val()
{}
explicit multiple_view(typename detail::call_param<T>::type val)
: val(val)
{}
value_type val;
};
template<typename Size, typename T>
inline multiple_view<Size, typename detail::as_fusion_element<T>::type>
make_multiple_view(T const& v)
{
return multiple_view<Size, typename detail::as_fusion_element<T>::type>(v);
}
struct multiple_view_iterator_tag;
struct forward_traversal_tag;
template<typename Index, typename MultipleView>
struct multiple_view_iterator
: iterator_base<multiple_view_iterator<Index, MultipleView> >
{
typedef multiple_view_iterator_tag fusion_tag;
typedef forward_traversal_tag category;
typedef typename MultipleView::value_type value_type;
typedef MultipleView multiple_view_type;
typedef Index index;
explicit multiple_view_iterator(multiple_view_type const &view_)
: view(view_)
{}
multiple_view_type view;
};
namespace extension
{
template <typename Tag>
struct next_impl;
template <>
struct next_impl<multiple_view_iterator_tag>
{
template <typename Iterator>
struct apply
{
typedef multiple_view_iterator<
typename mpl::next<typename Iterator::index>::type
, typename Iterator::multiple_view_type
> type;
static type
call(Iterator const &where)
{
return type(where.view);
}
};
};
template <typename Tag>
struct end_impl;
template <>
struct end_impl<multiple_view_tag>
{
template <typename Sequence>
struct apply
{
typedef multiple_view_iterator<
typename Sequence::size
, Sequence
> type;
static type
call(Sequence &seq)
{
return type(seq);
}
};
};
template <typename Tag>
struct deref_impl;
template <>
struct deref_impl<multiple_view_iterator_tag>
{
template <typename Iterator>
struct apply
{
typedef typename Iterator::value_type type;
static type
call(Iterator const& i)
{
return i.view.val;
}
};
};
template <typename Tag>
struct begin_impl;
template <>
struct begin_impl<multiple_view_tag>
{
template <typename Sequence>
struct apply
{
typedef multiple_view_iterator<
mpl::int_<0>
, Sequence
> type;
static type
call(Sequence &seq)
{
return type(seq);
}
};
};
template <typename Tag>
struct value_of_impl;
template <>
struct value_of_impl<multiple_view_iterator_tag>
{
template <typename Iterator>
struct apply
{
typedef typename Iterator::multiple_view_type multiple_view_type;
typedef typename multiple_view_type::value_type type;
};
};
}
}}
#endif

View File

@ -1,448 +0,0 @@
/*=============================================================================
Copyright (c) 2006 Eric Niebler
Use, modification and distribution is subject to 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 FUSION_SEGMENTED_ITERATOR_EAN_05032006_1027
#define FUSION_SEGMENTED_ITERATOR_EAN_05032006_1027
#include <boost/mpl/if.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/next_prior.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/fusion/support/tag_of.hpp>
#include <boost/fusion/support/is_sequence.hpp>
#include <boost/fusion/view/filter_view.hpp>
#include <boost/fusion/container/list/cons.hpp> // for nil
#include <boost/fusion/container/generation/make_cons.hpp>
#include <boost/fusion/iterator/advance.hpp>
#include <boost/fusion/iterator/distance.hpp>
#include <boost/fusion/sequence/intrinsic/ext_/segments.hpp>
#include <boost/fusion/support/ext_/is_segmented.hpp>
namespace boost { namespace fusion
{
struct fusion_sequence_tag;
namespace detail
{
using mpl::_;
using mpl::not_;
////////////////////////////////////////////////////////////////////////////
template<typename Sequence>
struct is_empty
: result_of::equal_to<
typename result_of::begin<Sequence>::type
, typename result_of::end<Sequence>::type
>
{};
template<typename Sequence>
struct is_empty<Sequence &>
: is_empty<Sequence>
{};
////////////////////////////////////////////////////////////////////////////
struct not_is_empty_pred
{
template<typename Sequence>
struct apply
: not_<is_empty<Sequence> >
{};
};
struct segmented_range_tag;
////////////////////////////////////////////////////////////////////////////
template<typename Sequence, typename Index, bool IsSegmented>
struct segmented_range
: sequence_base<segmented_range<Sequence, Index, IsSegmented> >
{
BOOST_MPL_ASSERT_NOT((is_reference<Sequence>));
typedef mpl::bool_<IsSegmented> is_segmented;
typedef segmented_range_tag fusion_tag;
typedef fusion_sequence_tag tag; // this gets picked up by MPL
typedef mpl::true_ is_view;
// If this is a range of segments, skip over the empty ones
typedef typename mpl::if_<
is_segmented
, filter_view<Sequence, not_is_empty_pred>
, Sequence
>::type sequence_non_ref_type;
typedef typename mpl::if_<
traits::is_view<sequence_non_ref_type>
, sequence_non_ref_type
, sequence_non_ref_type &
>::type sequence_type;
typedef
typename fusion::result_of::advance<
typename fusion::result_of::begin<sequence_non_ref_type>::type
, Index
>::type
iterator_type;
typedef typename traits::category_of<sequence_non_ref_type>::type category;
explicit segmented_range(Sequence &sequence_)
: sequence(sequence_type(sequence_))
{}
segmented_range(sequence_type sequence_, int)
: sequence(sequence_)
{}
iterator_type where_() const
{
return fusion::advance<Index>(
fusion::begin(const_cast<sequence_non_ref_type &>(this->sequence))
);
}
sequence_type sequence;
private:
segmented_range &operator =(segmented_range const &);
};
}
namespace extension
{
template<>
struct is_segmented_impl<detail::segmented_range_tag>
{
template<typename Sequence>
struct apply
: Sequence::is_segmented
{};
};
template<>
struct size_impl<detail::segmented_range_tag>
{
template<typename Sequence>
struct apply
: mpl::int_<
result_of::distance<
typename Sequence::iterator_type
, typename result_of::end<typename Sequence::sequence_non_ref_type>::type
>::value
>
{};
};
template<>
struct segments_impl<detail::segmented_range_tag>
{
template<typename Sequence>
struct apply
{
typedef Sequence &type;
static type call(Sequence &seq)
{
return seq;
}
};
};
template<>
struct begin_impl<detail::segmented_range_tag>
{
template<typename Sequence>
struct apply
{
typedef typename Sequence::iterator_type type;
static type call(Sequence &seq)
{
return seq.where_();
}
};
};
template<>
struct end_impl<detail::segmented_range_tag>
{
template<typename Sequence>
struct apply
{
typedef typename Sequence::sequence_non_ref_type sequence;
typedef typename result_of::end<sequence>::type type;
static type call(Sequence &seq)
{
return fusion::end(seq.sequence);
}
};
};
}
namespace detail
{
///////////////////////////////////////////////////////////////////////
template<typename Range>
struct range_next;
template<typename Sequence, typename Index, bool IsSegmented>
struct range_next<segmented_range<Sequence, Index, IsSegmented> >
{
typedef typename mpl::next<Index>::type index_type;
typedef segmented_range<Sequence, index_type, IsSegmented> type;
static type call(segmented_range<Sequence, Index, IsSegmented> const &rng)
{
return type(rng.sequence, 0);
}
};
///////////////////////////////////////////////////////////////////////
template<typename Cons>
struct is_range_next_empty
: is_empty<typename range_next<typename Cons::car_type>::type>
{};
template<>
struct is_range_next_empty<nil>
: mpl::true_
{};
///////////////////////////////////////////////////////////////////////
template<typename Sequence, bool IsSegmented = traits::is_segmented<Sequence>::value>
struct as_segmented_range
{
typedef typename result_of::segments<Sequence>::type segments;
typedef typename remove_reference<segments>::type sequence;
typedef segmented_range<sequence, mpl::int_<0>, true> type;
static type call(Sequence &seq)
{
segments segs(fusion::segments(seq));
return type(segs);
}
};
template<typename Sequence>
struct as_segmented_range<Sequence, false>
{
typedef typename remove_reference<Sequence>::type sequence;
typedef segmented_range<sequence, mpl::int_<0>, false> type;
static type call(Sequence &seq)
{
return type(seq);
}
};
template<typename Sequence, typename Index, bool IsSegmented>
struct as_segmented_range<segmented_range<Sequence, Index, IsSegmented>, IsSegmented>
{
typedef segmented_range<Sequence, Index, IsSegmented> type;
static type &call(type &seq)
{
return seq;
}
};
///////////////////////////////////////////////////////////////////////
template<
typename Sequence
, typename State = nil
, bool IsSegmented = traits::is_segmented<Sequence>::value
>
struct push_segments
{
typedef typename as_segmented_range<Sequence>::type range;
typedef typename result_of::begin<range>::type begin;
typedef typename result_of::deref<begin>::type next_ref;
typedef typename remove_reference<next_ref>::type next;
typedef push_segments<next, cons<range, State> > push;
typedef typename push::type type;
static type call(Sequence &seq, State const &state)
{
range rng(as_segmented_range<Sequence>::call(seq));
next_ref nxt(*fusion::begin(rng));
return push::call(nxt, fusion::make_cons(rng, state));
}
};
template<typename Sequence, typename State>
struct push_segments<Sequence, State, false>
{
typedef typename as_segmented_range<Sequence>::type range;
typedef cons<range, State> type;
static type call(Sequence &seq, State const &state)
{
range rng(as_segmented_range<Sequence>::call(seq));
return fusion::make_cons(rng, state);
}
};
///////////////////////////////////////////////////////////////////////
template<typename State, bool IsEmpty = is_range_next_empty<State>::value>
struct pop_segments
{
typedef range_next<typename State::car_type> next;
typedef push_segments<typename next::type, typename State::cdr_type> push;
typedef typename push::type type;
static type call(State const &state)
{
typename next::type rng(next::call(state.car));
return push::call(rng, state.cdr);
}
};
template<typename State>
struct pop_segments<State, true>
{
typedef pop_segments<typename State::cdr_type> pop;
typedef typename pop::type type;
static type call(State const &state)
{
return pop::call(state.cdr);
}
};
template<>
struct pop_segments<nil, true>
{
typedef nil type;
static type call(nil const &)
{
return nil();
}
};
} // namespace detail
struct segmented_iterator_tag;
////////////////////////////////////////////////////////////////////////////
template<typename Cons>
struct segmented_iterator
: fusion::iterator_base<segmented_iterator<Cons> >
{
typedef segmented_iterator_tag fusion_tag;
typedef fusion::forward_traversal_tag category;
typedef Cons cons_type;
typedef typename Cons::car_type car_type;
typedef typename Cons::cdr_type cdr_type;
explicit segmented_iterator(Cons const &c)
: cons_(c)
{}
cons_type const &cons() const { return this->cons_; };
car_type const &car() const { return this->cons_.car; };
cdr_type const &cdr() const { return this->cons_.cdr; };
private:
Cons cons_;
};
///////////////////////////////////////////////////////////////////////////
template<typename Sequence>
struct segmented_begin
{
typedef typename detail::push_segments<Sequence> push;
typedef segmented_iterator<typename push::type> type;
static type call(Sequence &seq)
{
return type(push::call(seq, nil()));
}
};
///////////////////////////////////////////////////////////////////////////
template<typename Sequence>
struct segmented_end
{
typedef segmented_iterator<nil> type;
static type call(Sequence &)
{
return type(nil());
}
};
namespace extension
{
template<>
struct value_of_impl<segmented_iterator_tag>
{
template<typename Iterator>
struct apply
{
typedef typename result_of::begin<typename Iterator::car_type>::type begin;
typedef typename result_of::value_of<begin>::type type;
};
};
template<>
struct deref_impl<segmented_iterator_tag>
{
template<typename Iterator>
struct apply
{
typedef typename result_of::begin<typename Iterator::car_type>::type begin;
typedef typename result_of::deref<begin>::type type;
static type call(Iterator const &it)
{
return *fusion::begin(it.car());
}
};
};
// discards the old head, expands the right child of the new head
// and pushes the result to the head of the list.
template<>
struct next_impl<segmented_iterator_tag>
{
template<
typename Iterator
, bool IsSegmentDone = detail::is_range_next_empty<Iterator>::value
>
struct apply
{
typedef typename Iterator::cdr_type cdr_type;
typedef detail::range_next<typename Iterator::car_type> next;
typedef segmented_iterator<cons<typename next::type, cdr_type> > type;
static type call(Iterator const &it)
{
return type(fusion::make_cons(next::call(it.car()), it.cdr()));
}
};
template<typename Iterator>
struct apply<Iterator, true> // segment done, move to next segment
{
typedef typename Iterator::cdr_type cdr_type;
typedef typename detail::pop_segments<cdr_type> pop;
typedef segmented_iterator<typename pop::type> type;
static type call(Iterator const &it)
{
return type(pop::call(it.cdr()));
}
};
};
}
}} // namespace boost::fusion
#endif

View File

@ -1,537 +0,0 @@
/*=============================================================================
Copyright (c) 2006 Eric Niebler
Use, modification and distribution is subject to 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 FUSION_SEGMENTED_ITERATOR_RANGE_EAN_05032006_1027
#define FUSION_SEGMENTED_ITERATOR_RANGE_EAN_05032006_1027
#include <boost/mpl/bool.hpp>
#include <boost/mpl/minus.hpp>
#include <boost/mpl/next_prior.hpp>
#include <boost/mpl/and.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/fusion/iterator/mpl/convert_iterator.hpp>
#include <boost/fusion/container/list/cons.hpp>
#include <boost/fusion/view/joint_view.hpp>
#include <boost/fusion/view/single_view.hpp>
#include <boost/fusion/view/transform_view.hpp>
#include <boost/fusion/view/iterator_range.hpp>
#include <boost/fusion/view/ext_/multiple_view.hpp>
#include <boost/fusion/view/ext_/segmented_iterator.hpp>
#include <boost/fusion/adapted/mpl/mpl_iterator.hpp>
namespace boost { namespace fusion
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////
template<typename Cons, typename State = nil>
struct reverse_cons;
template<typename Car, typename Cdr, typename State>
struct reverse_cons<cons<Car, Cdr>, State>
{
typedef reverse_cons<Cdr, cons<Car, State> > reverse;
typedef typename reverse::type type;
static type call(cons<Car, Cdr> const &cons, State const &state = State())
{
return reverse::call(cons.cdr, fusion::make_cons(cons.car, state));
}
};
template<typename State>
struct reverse_cons<nil, State>
{
typedef State type;
static State const &call(nil const &, State const &state = State())
{
return state;
}
};
////////////////////////////////////////////////////////////////////////////
// tags
struct full_view {};
struct left_view {};
struct right_view {};
struct center_view {};
template<typename Tag>
struct segmented_view_tag;
////////////////////////////////////////////////////////////////////////////
// a segmented view of that includes all elements either to the
// right or the left of a segmented iterator.
template<typename Tag, typename Cons1, typename Cons2 = void_>
struct segmented_view
: sequence_base<segmented_view<Tag, Cons1, Cons2> >
{
typedef segmented_view_tag<Tag> fusion_tag;
typedef fusion_sequence_tag tag; // this gets picked up by MPL
typedef mpl::true_ is_view;
typedef forward_traversal_tag category;
explicit segmented_view(Cons1 const &cons)
: cons(cons)
{}
typedef Cons1 cons_type;
cons_type const &cons;
};
// a segmented view that contains all the elements in between
// two segmented iterators
template<typename Cons1, typename Cons2>
struct segmented_view<center_view, Cons1, Cons2>
: sequence_base<segmented_view<center_view, Cons1, Cons2> >
{
typedef segmented_view_tag<center_view> fusion_tag;
typedef fusion_sequence_tag tag; // this gets picked up by MPL
typedef mpl::true_ is_view;
typedef forward_traversal_tag category;
segmented_view(Cons1 const &lcons, Cons2 const &rcons)
: left_cons(lcons)
, right_cons(rcons)
{}
typedef Cons1 left_cons_type;
typedef Cons2 right_cons_type;
left_cons_type const &left_cons;
right_cons_type const &right_cons;
};
////////////////////////////////////////////////////////////////////////////
// Used to transform a sequence of segments. The first segment is
// bounded by RightCons, and the last segment is bounded by LeftCons
// and all the others are passed through unchanged.
template<typename RightCons, typename LeftCons = RightCons>
struct segments_transform
{
explicit segments_transform(RightCons const &cons_)
: right_cons(cons_)
, left_cons(cons_)
{}
segments_transform(RightCons const &right_cons_, LeftCons const &left_cons_)
: right_cons(right_cons_)
, left_cons(left_cons_)
{}
template<typename First, typename Second>
struct result_;
template<typename Second>
struct result_<right_view, Second>
{
typedef segmented_view<right_view, RightCons> type;
};
template<typename Second>
struct result_<left_view, Second>
{
typedef segmented_view<left_view, LeftCons> type;
};
template<typename Second>
struct result_<full_view, Second>
{
typedef Second type;
};
template<typename Sig>
struct result;
template<typename This, typename First, typename Second>
struct result<This(First, Second)>
: result_<
typename remove_cv<typename remove_reference<First>::type>::type
, typename remove_cv<typename remove_reference<Second>::type>::type
>
{};
template<typename Second>
segmented_view<right_view, RightCons> operator ()(right_view, Second &second) const
{
return segmented_view<right_view, RightCons>(this->right_cons);
}
template<typename Second>
segmented_view<left_view, LeftCons> operator ()(left_view, Second &second) const
{
return segmented_view<left_view, LeftCons>(this->left_cons);
}
template<typename Second>
Second &operator ()(full_view, Second &second) const
{
return second;
}
private:
RightCons const &right_cons;
LeftCons const &left_cons;
};
} // namespace detail
namespace extension
{
////////////////////////////////////////////////////////////////////////////
template<typename Tag>
struct is_segmented_impl<detail::segmented_view_tag<Tag> >
{
template<typename Sequence>
struct apply
: mpl::true_
{};
};
////////////////////////////////////////////////////////////////////////////
template<>
struct segments_impl<detail::segmented_view_tag<detail::right_view> >
{
template<
typename Sequence
, typename Cdr = typename Sequence::cons_type::cdr_type
>
struct apply
{
typedef typename Sequence::cons_type::car_type segmented_range;
typedef typename result_of::size<segmented_range>::type size;
typedef typename mpl::prior<size>::type size_minus_1;
typedef detail::segments_transform<Cdr> tfx;
typedef joint_view<
single_view<detail::right_view> const
, multiple_view<size_minus_1, detail::full_view> const
> mask;
typedef transform_view<mask const, segmented_range const, tfx> type;
static type call(Sequence &seq)
{
return type(
mask(
make_single_view(detail::right_view())
, make_multiple_view<size_minus_1>(detail::full_view())
)
, seq.cons.car
, tfx(seq.cons.cdr)
);
}
};
template<typename Sequence>
struct apply<Sequence, nil>
{
typedef typename Sequence::cons_type::car_type segmented_range;
typedef typename segmented_range::iterator_type begin;
typedef typename segmented_range::sequence_non_ref_type sequence_type;
typedef typename result_of::end<sequence_type>::type end;
typedef iterator_range<begin, end> range;
typedef single_view<range> type;
static type call(Sequence &seq)
{
return type(range(seq.cons.car.where_, fusion::end(seq.cons.car.sequence)));
}
};
};
////////////////////////////////////////////////////////////////////////////
template<>
struct segments_impl<detail::segmented_view_tag<detail::left_view> >
{
template<
typename Sequence
, typename Cdr = typename Sequence::cons_type::cdr_type
>
struct apply
{
typedef typename Sequence::cons_type::car_type right_segmented_range;
typedef typename right_segmented_range::sequence_type sequence_type;
typedef typename right_segmented_range::iterator_type iterator_type;
typedef iterator_range<
typename result_of::begin<sequence_type>::type
, typename result_of::next<iterator_type>::type
> segmented_range;
typedef detail::segments_transform<Cdr> tfx;
typedef typename result_of::size<segmented_range>::type size;
typedef typename mpl::prior<size>::type size_minus_1;
typedef joint_view<
multiple_view<size_minus_1, detail::full_view> const
, single_view<detail::left_view> const
> mask;
typedef transform_view<mask const, segmented_range const, tfx> type;
static type call(Sequence &seq)
{
return type(
mask(
make_multiple_view<size_minus_1>(detail::full_view())
, make_single_view(detail::left_view())
)
, segmented_range(fusion::begin(seq.cons.car.sequence), fusion::next(seq.cons.car.where_))
, tfx(seq.cons.cdr)
);
}
};
template<typename Sequence>
struct apply<Sequence, nil>
{
typedef typename Sequence::cons_type::car_type segmented_range;
typedef typename segmented_range::sequence_non_ref_type sequence_type;
typedef typename result_of::begin<sequence_type>::type begin;
typedef typename segmented_range::iterator_type end;
typedef iterator_range<begin, end> range;
typedef single_view<range> type;
static type call(Sequence &seq)
{
return type(range(fusion::begin(seq.cons.car.sequence), seq.cons.car.where_));
}
};
};
////////////////////////////////////////////////////////////////////////////
template<>
struct segments_impl<detail::segmented_view_tag<detail::center_view> >
{
template<typename Sequence>
struct apply
{
typedef typename Sequence::right_cons_type right_cons_type;
typedef typename Sequence::left_cons_type left_cons_type;
typedef typename right_cons_type::car_type right_segmented_range;
typedef typename left_cons_type::car_type left_segmented_range;
typedef iterator_range<
typename result_of::begin<left_segmented_range>::type
, typename result_of::next<typename result_of::begin<right_segmented_range>::type>::type
> segmented_range;
typedef typename mpl::minus<
typename result_of::size<segmented_range>::type
, mpl::int_<2>
>::type size_minus_2;
BOOST_MPL_ASSERT_RELATION(0, <=, size_minus_2::value);
typedef detail::segments_transform<
typename left_cons_type::cdr_type
, typename right_cons_type::cdr_type
> tfx;
typedef joint_view<
multiple_view<size_minus_2, detail::full_view> const
, single_view<detail::left_view> const
> left_mask;
typedef joint_view<
single_view<detail::right_view> const
, left_mask const
> mask;
typedef transform_view<mask const, segmented_range const, tfx> type;
static type call(Sequence &seq)
{
left_mask lmask(
make_multiple_view<size_minus_2>(detail::full_view())
, make_single_view(detail::left_view())
);
return type(
mask(make_single_view(detail::right_view()), lmask)
, segmented_range(fusion::begin(seq.left_cons.car), fusion::next(fusion::begin(seq.right_cons.car)))
, tfx(seq.left_cons.cdr, seq.right_cons.cdr)
);
}
};
};
}
// specialize iterator_range for use with segmented iterators, so that
// it presents a segmented view of the range.
template<typename First, typename Last>
struct iterator_range;
template<typename First, typename Last>
struct iterator_range<segmented_iterator<First>, segmented_iterator<Last> >
: sequence_base<iterator_range<segmented_iterator<First>, segmented_iterator<Last> > >
{
typedef typename convert_iterator<segmented_iterator<First> >::type begin_type;
typedef typename convert_iterator<segmented_iterator<Last> >::type end_type;
typedef typename detail::reverse_cons<First>::type begin_cons_type;
typedef typename detail::reverse_cons<Last>::type end_cons_type;
typedef iterator_range_tag fusion_tag;
typedef fusion_sequence_tag tag; // this gets picked up by MPL
typedef typename traits::category_of<begin_type>::type category;
typedef typename result_of::distance<begin_type, end_type>::type size;
typedef mpl::true_ is_view;
iterator_range(segmented_iterator<First> const& first_, segmented_iterator<Last> const& last_)
: first(convert_iterator<segmented_iterator<First> >::call(first_))
, last(convert_iterator<segmented_iterator<Last> >::call(last_))
, first_cons(detail::reverse_cons<First>::call(first_.cons()))
, last_cons(detail::reverse_cons<Last>::call(last_.cons()))
{}
begin_type first;
end_type last;
begin_cons_type first_cons;
end_cons_type last_cons;
};
namespace detail
{
template<typename Cons1, typename Cons2>
struct same_segment
: mpl::false_
{};
template<typename Car1, typename Cdr1, typename Car2, typename Cdr2>
struct same_segment<cons<Car1, Cdr1>, cons<Car2, Cdr2> >
: mpl::and_<
traits::is_segmented<Car1>
, is_same<Car1, Car2>
>
{};
////////////////////////////////////////////////////////////////////////////
template<typename Cons1, typename Cons2>
struct segments_gen;
////////////////////////////////////////////////////////////////////////////
template<typename Cons1, typename Cons2, bool SameSegment>
struct segments_gen2
{
typedef segments_gen<typename Cons1::cdr_type, typename Cons2::cdr_type> gen;
typedef typename gen::type type;
static type call(Cons1 const &cons1, Cons2 const &cons2)
{
return gen::call(cons1.cdr, cons2.cdr);
}
};
template<typename Cons1, typename Cons2>
struct segments_gen2<Cons1, Cons2, false>
{
typedef segmented_view<center_view, Cons1, Cons2> view;
typedef typename result_of::segments<view>::type type;
static type call(Cons1 const &cons1, Cons2 const &cons2)
{
view v(cons1, cons2);
return fusion::segments(v);
}
};
template<typename Car1, typename Car2>
struct segments_gen2<cons<Car1>, cons<Car2>, false>
{
typedef iterator_range<
typename Car1::iterator_type
, typename Car2::iterator_type
> range;
typedef single_view<range> type;
static type call(cons<Car1> const &cons1, cons<Car2> const &cons2)
{
return type(range(cons1.car.where_, cons2.car.where_));
}
};
////////////////////////////////////////////////////////////////////////////
template<typename Cons1, typename Cons2>
struct segments_gen
: segments_gen2<Cons1, Cons2, same_segment<Cons1, Cons2>::value>
{};
template<typename Car, typename Cdr>
struct segments_gen<cons<Car, Cdr>, nil>
{
typedef segmented_view<right_view, cons<Car, Cdr> > view;
typedef typename result_of::segments<view>::type type;
static type call(cons<Car, Cdr> const &cons, nil const &)
{
view v(cons);
return fusion::segments(v);
}
};
template<>
struct segments_gen<nil, nil>
{
typedef nil type;
static type call(nil const &, nil const &)
{
return nil();
}
};
} // namespace detail
namespace extension
{
template<typename Tag>
struct is_segmented_impl;
// An iterator_range of segmented_iterators is segmented
template<>
struct is_segmented_impl<iterator_range_tag>
{
template<typename Iterator>
struct is_segmented_iterator : mpl::false_ {};
template<typename Cons>
struct is_segmented_iterator<segmented_iterator<Cons> > : mpl::true_ {};
template<typename Sequence>
struct apply
: mpl::and_<
is_segmented_iterator<typename Sequence::begin_type>
, is_segmented_iterator<typename Sequence::end_type>
>
{};
};
template<typename Sequence>
struct segments_impl;
template<>
struct segments_impl<iterator_range_tag>
{
template<typename Sequence>
struct apply
{
typedef typename Sequence::begin_cons_type begin_cons;
typedef typename Sequence::end_cons_type end_cons;
typedef detail::segments_gen<begin_cons, end_cons> gen;
typedef typename gen::type type;
static type call(Sequence &sequence)
{
return gen::call(sequence.first_cons, sequence.last_cons);
}
};
};
}
}}
#endif

View File

@ -65,7 +65,7 @@ namespace boost { namespace fusion
static type static type
call(Iterator const& i) call(Iterator const& i)
{ {
return type(filter::call(i.first)); return type(filter::iter_call(i.first));
} }
}; };
}; };

View File

@ -55,7 +55,7 @@ namespace boost { namespace fusion
typedef Pred pred_type; typedef Pred pred_type;
filter_iterator(First const& in_first) filter_iterator(First const& in_first)
: first(filter::call(first_converter::call(in_first))) {} : first(filter::iter_call(first_converter::call(in_first))) {}
first_type first; first_type first;

View File

@ -0,0 +1,66 @@
/*=============================================================================
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_ITERATOR_RANGE_IS_SEGMENTED_HPP_INCLUDED)
#define BOOST_FUSION_ITERATOR_RANGE_IS_SEGMENTED_HPP_INCLUDED
#include <boost/mpl/assert.hpp>
#include <boost/mpl/bool.hpp>
namespace boost { namespace fusion
{
struct iterator_range_tag;
template <typename Context>
struct segmented_iterator;
namespace extension
{
template <typename Tag>
struct is_segmented_impl;
// An iterator_range of segmented_iterators is segmented
template <>
struct is_segmented_impl<iterator_range_tag>
{
private:
template <typename Iterator>
struct is_segmented_iterator
: mpl::false_
{};
template <typename Iterator>
struct is_segmented_iterator<Iterator &>
: is_segmented_iterator<Iterator>
{};
template <typename Iterator>
struct is_segmented_iterator<Iterator const>
: is_segmented_iterator<Iterator>
{};
template <typename Context>
struct is_segmented_iterator<segmented_iterator<Context> >
: mpl::true_
{};
public:
template <typename Sequence>
struct apply
: is_segmented_iterator<typename Sequence::begin_type>
{
BOOST_MPL_ASSERT_RELATION(
is_segmented_iterator<typename Sequence::begin_type>::value
, ==
, is_segmented_iterator<typename Sequence::end_type>::value);
};
};
}
}}
#endif

View File

@ -0,0 +1,505 @@
/*=============================================================================
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_SEGMENTED_ITERATOR_RANGE_HPP_INCLUDED)
#define BOOST_FUSION_SEGMENTED_ITERATOR_RANGE_HPP_INCLUDED
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/fusion/support/tag_of.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/iterator/next.hpp>
#include <boost/fusion/iterator/deref.hpp>
#include <boost/fusion/sequence/intrinsic/segments.hpp>
#include <boost/fusion/algorithm/transformation/push_back.hpp>
#include <boost/fusion/algorithm/transformation/push_front.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/container/list/detail/reverse_cons.hpp>
#include <boost/fusion/iterator/detail/segment_sequence.hpp>
// Invariants:
// - Each segmented iterator has a stack
// - Each value in the stack is an iterator range
// - The range at the top of the stack points to values
// - All other ranges point to ranges
// - The front of each range in the stack (besides the
// topmost) is the range above it
namespace boost { namespace fusion
{
template <typename First, typename Last>
struct iterator_range;
}}
namespace boost { namespace fusion { namespace detail
{
//auto make_segment_sequence_front(stack_begin)
//{
// switch (size(stack_begin))
// {
// case 1:
// return nil;
// case 2:
// // car(cdr(stack_begin)) is a range over values.
// assert(end(front(car(stack_begin))) == end(car(cdr(stack_begin))));
// return iterator_range(begin(car(cdr(stack_begin))), end(front(car(stack_begin))));
// default:
// // car(cdr(stack_begin)) is a range over segments. We replace the
// // front with a view that is restricted.
// assert(end(segments(front(car(stack_begin)))) == end(car(cdr(stack_begin))));
// return segment_sequence(
// push_front(
// // The following could be a segment_sequence. It then gets wrapped
// // in a single_view, and push_front puts it in a join_view with the
// // following iterator_range.
// iterator_range(next(begin(car(cdr(stack_begin)))), end(segments(front(car(stack_begin))))),
// make_segment_sequence_front(cdr(stack_begin))));
// }
//}
template <typename Stack, std::size_t Size = Stack::size::value>
struct make_segment_sequence_front
{
// assert(end(segments(front(car(stack_begin)))) == end(car(cdr(stack_begin))));
BOOST_MPL_ASSERT((
result_of::equal_to<
typename result_of::end<
typename remove_reference<
typename add_const<
typename result_of::segments<
typename remove_reference<
typename add_const<
typename result_of::deref<
typename Stack::car_type::begin_type
>::type
>::type
>::type
>::type
>::type
>::type
>::type
, typename Stack::cdr_type::car_type::end_type
>));
typedef
iterator_range<
typename result_of::next<
typename Stack::cdr_type::car_type::begin_type
>::type
, typename result_of::end<
typename remove_reference<
typename add_const<
typename result_of::segments<
typename remove_reference<
typename add_const<
typename result_of::deref<
typename Stack::car_type::begin_type
>::type
>::type
>::type
>::type
>::type
>::type
>::type
>
rest_type;
typedef
make_segment_sequence_front<typename Stack::cdr_type>
recurse;
typedef
segment_sequence<
typename result_of::push_front<
rest_type const
, typename recurse::type
>::type
>
type;
static type call(Stack const& stack)
{
//return segment_sequence(
// push_front(
// iterator_range(next(begin(car(cdr(stack_begin)))), end(segments(front(car(stack_begin))))),
// make_segment_sequence_front(cdr(stack_begin))));
return type(
fusion::push_front(
rest_type(fusion::next(stack.cdr.car.first), fusion::end(fusion::segments(*stack.car.first)))
, recurse::call(stack.cdr)));
}
};
template <typename Stack>
struct make_segment_sequence_front<Stack, 2>
{
// assert(end(front(car(stack_begin))) == end(car(cdr(stack_begin))));
BOOST_MPL_ASSERT((
result_of::equal_to<
typename result_of::end<
typename remove_reference<
typename add_const<
typename result_of::deref<
typename Stack::car_type::begin_type
>::type
>::type
>::type
>::type
, typename Stack::cdr_type::car_type::end_type
>));
typedef
iterator_range<
typename Stack::cdr_type::car_type::begin_type
, typename result_of::end<
typename remove_reference<
typename add_const<
typename result_of::deref<
typename Stack::car_type::begin_type
>::type
>::type
>::type
>::type
>
type;
static type call(Stack const& stack)
{
// return iterator_range(begin(car(cdr(stack_begin))), end(front(car(stack_begin))));
return type(stack.cdr.car.first, fusion::end(*stack.car.first));
}
};
template <typename Stack>
struct make_segment_sequence_front<Stack, 1>
{
typedef typename Stack::cdr_type type; // nil
static type call(Stack const &stack)
{
return stack.cdr;
}
};
//auto make_segment_sequence_back(stack_end)
//{
// switch (size(stack_end))
// {
// case 1:
// return nil;
// case 2:
// // car(cdr(stack_back)) is a range over values.
// assert(end(front(car(stack_end))) == end(car(cdr(stack_end))));
// return iterator_range(begin(front(car(stack_end))), begin(car(cdr(stack_end))));
// default:
// // car(cdr(stack_begin)) is a range over segments. We replace the
// // back with a view that is restricted.
// assert(end(segments(front(car(stack_end)))) == end(car(cdr(stack_end))));
// return segment_sequence(
// push_back(
// iterator_range(begin(segments(front(car(stack_end)))), begin(car(cdr(stack_end)))),
// make_segment_sequence_back(cdr(stack_end))));
// }
//}
template <typename Stack, std::size_t Size = Stack::size::value>
struct make_segment_sequence_back
{
// assert(end(segments(front(car(stack_begin)))) == end(car(cdr(stack_begin))));
BOOST_MPL_ASSERT((
result_of::equal_to<
typename result_of::end<
typename remove_reference<
typename add_const<
typename result_of::segments<
typename remove_reference<
typename add_const<
typename result_of::deref<
typename Stack::car_type::begin_type
>::type
>::type
>::type
>::type
>::type
>::type
>::type
, typename Stack::cdr_type::car_type::end_type
>));
typedef
iterator_range<
typename result_of::begin<
typename remove_reference<
typename add_const<
typename result_of::segments<
typename remove_reference<
typename add_const<
typename result_of::deref<
typename Stack::car_type::begin_type
>::type
>::type
>::type
>::type
>::type
>::type
>::type
, typename Stack::cdr_type::car_type::begin_type
>
rest_type;
typedef
make_segment_sequence_back<typename Stack::cdr_type>
recurse;
typedef
segment_sequence<
typename result_of::push_back<
rest_type const
, typename recurse::type
>::type
>
type;
static type call(Stack const& stack)
{
// return segment_sequence(
// push_back(
// iterator_range(begin(segments(front(car(stack_end)))), begin(car(cdr(stack_end)))),
// make_segment_sequence_back(cdr(stack_end))));
return type(
fusion::push_back(
rest_type(fusion::begin(fusion::segments(*stack.car.first)), stack.cdr.car.first)
, recurse::call(stack.cdr)));
}
};
template <typename Stack>
struct make_segment_sequence_back<Stack, 2>
{
// assert(end(front(car(stack_end))) == end(car(cdr(stack_end))));
BOOST_MPL_ASSERT((
result_of::equal_to<
typename result_of::end<
typename remove_reference<
typename add_const<
typename result_of::deref<
typename Stack::car_type::begin_type
>::type
>::type
>::type
>::type
, typename Stack::cdr_type::car_type::end_type
>));
typedef
iterator_range<
typename result_of::begin<
typename remove_reference<
typename add_const<
typename result_of::deref<
typename Stack::car_type::begin_type
>::type
>::type
>::type
>::type
, typename Stack::cdr_type::car_type::begin_type
>
type;
static type call(Stack const& stack)
{
// return iterator_range(begin(front(car(stack_end))), begin(car(cdr(stack_end))));
return type(fusion::begin(*stack.car.first), stack.cdr.car.first);
}
};
template <typename Stack>
struct make_segment_sequence_back<Stack, 1>
{
typedef typename Stack::cdr_type type; // nil
static type call(Stack const& stack)
{
return stack.cdr;
}
};
//auto make_segmented_range_reduce(stack_begin, stack_end)
//{
// if (size(stack_begin) == 1 && size(stack_end) == 1)
// {
// return segment_sequence(
// single_view(
// iterator_range(begin(car(stack_begin)), begin(car(stack_end)))));
// }
// else
// {
// // We are in the case where both begin_stack and/or end_stack have
// // more than one element. Throw away any part of the tree where
// // begin and end refer to the same segment.
// if (begin(car(stack_begin)) == begin(car(stack_end)))
// {
// return make_segmented_range_reduce(cdr(stack_begin), cdr(stack_end));
// }
// else
// {
// // We are in the case where begin_stack and end_stack (a) have
// // more than one element each, and (b) they point to different
// // segments. We must construct a segmented sequence.
// return segment_sequence(
// push_back(
// push_front(
// iterator_range(
// fusion::next(begin(car(stack_begin))),
// begin(car(stack_end))), // a range of (possibly segmented) ranges.
// make_segment_sequence_front(stack_begin)), // should be a (possibly segmented) range.
// make_segment_sequence_back(stack_end))); // should be a (possibly segmented) range.
// }
// }
//}
template <
typename StackBegin
, typename StackEnd
, int StackBeginSize = StackBegin::size::value
, int StackEndSize = StackEnd::size::value>
struct make_segmented_range_reduce;
template <
typename StackBegin
, typename StackEnd
, bool SameSegment =
result_of::equal_to<
typename StackBegin::car_type::begin_type
, typename StackEnd::car_type::begin_type
>::type::value>
struct make_segmented_range_reduce2
{
typedef
iterator_range<
typename result_of::next<
typename StackBegin::car_type::begin_type
>::type
, typename StackEnd::car_type::begin_type
>
rest_type;
typedef
segment_sequence<
typename result_of::push_back<
typename result_of::push_front<
rest_type const
, typename make_segment_sequence_front<StackBegin>::type
>::type const
, typename make_segment_sequence_back<StackEnd>::type
>::type
>
type;
static type call(StackBegin stack_begin, StackEnd stack_end)
{
//return segment_sequence(
// push_back(
// push_front(
// iterator_range(
// fusion::next(begin(car(stack_begin))),
// begin(car(stack_end))), // a range of (possibly segmented) ranges.
// make_segment_sequence_front(stack_begin)), // should be a (possibly segmented) range.
// make_segment_sequence_back(stack_end))); // should be a (possibly segmented) range.
return type(
fusion::push_back(
fusion::push_front(
rest_type(fusion::next(stack_begin.car.first), stack_end.car.first)
, make_segment_sequence_front<StackBegin>::call(stack_begin))
, make_segment_sequence_back<StackEnd>::call(stack_end)));
}
};
template <typename StackBegin, typename StackEnd>
struct make_segmented_range_reduce2<StackBegin, StackEnd, true>
{
typedef
make_segmented_range_reduce<
typename StackBegin::cdr_type
, typename StackEnd::cdr_type
>
impl;
typedef
typename impl::type
type;
static type call(StackBegin stack_begin, StackEnd stack_end)
{
return impl::call(stack_begin.cdr, stack_end.cdr);
}
};
template <typename StackBegin, typename StackEnd, int StackBeginSize, int StackEndSize>
struct make_segmented_range_reduce
: make_segmented_range_reduce2<StackBegin, StackEnd>
{};
template <typename StackBegin, typename StackEnd>
struct make_segmented_range_reduce<StackBegin, StackEnd, 1, 1>
{
typedef
iterator_range<
typename StackBegin::car_type::begin_type
, typename StackEnd::car_type::begin_type
>
range_type;
typedef
single_view<range_type>
segment_type;
typedef
segment_sequence<segment_type>
type;
static type call(StackBegin stack_begin, StackEnd stack_end)
{
//return segment_sequence(
// single_view(
// iterator_range(begin(car(stack_begin)), begin(car(stack_end)))));
return type(segment_type(range_type(stack_begin.car.first, stack_end.car.first)));
}
};
//auto make_segmented_range(begin, end)
//{
// return make_segmented_range_reduce(reverse(begin.context), reverse(end.context));
//}
template <typename Begin, typename End>
struct make_segmented_range
{
typedef reverse_cons<typename Begin::context_type> reverse_begin_cons;
typedef reverse_cons<typename End::context_type> reverse_end_cons;
typedef
make_segmented_range_reduce<
typename reverse_begin_cons::type
, typename reverse_end_cons::type
>
impl;
typedef typename impl::type type;
static type call(Begin const& begin, End const& end)
{
return impl::call(
reverse_begin_cons::call(begin.context)
, reverse_end_cons::call(end.context));
}
};
}}}
#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)
==============================================================================*/
#if !defined(BOOST_FUSION_ITERATOR_RANGE_SEGMENTS_HPP_INCLUDED)
#define BOOST_FUSION_ITERATOR_RANGE_SEGMENTS_HPP_INCLUDED
#include <boost/mpl/assert.hpp>
#include <boost/fusion/sequence/intrinsic/segments.hpp>
#include <boost/fusion/support/is_segmented.hpp>
#include <boost/fusion/view/iterator_range/detail/segmented_iterator_range.hpp>
namespace boost { namespace fusion
{
struct iterator_range_tag;
namespace extension
{
template <typename Tag>
struct segments_impl;
template <>
struct segments_impl<iterator_range_tag>
{
template <typename Sequence>
struct apply
{
typedef
detail::make_segmented_range<
typename Sequence::begin_type
, typename Sequence::end_type
>
impl;
BOOST_MPL_ASSERT((traits::is_segmented<typename impl::type>));
typedef
typename result_of::segments<typename impl::type>::type
type;
static type call(Sequence & seq)
{
return fusion::segments(impl::call(seq.first, seq.last));
}
};
};
}
}}
#endif

View File

@ -0,0 +1,37 @@
/*=============================================================================
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_ITERATOR_RANGE_SIZE_IMPL_HPP_INCLUDED)
#define BOOST_FUSION_ITERATOR_RANGE_SIZE_IMPL_HPP_INCLUDED
#include <boost/fusion/iterator/distance.hpp>
namespace boost { namespace fusion
{
struct iterator_range_tag;
namespace extension
{
template <typename Tag>
struct size_impl;
template <>
struct size_impl<iterator_range_tag>
{
template <typename Seq>
struct apply
: result_of::distance<
typename Seq::begin_type,
typename Seq::end_type
>
{};
};
}
}}
#endif

View File

@ -15,7 +15,10 @@
#include <boost/fusion/view/iterator_range/detail/begin_impl.hpp> #include <boost/fusion/view/iterator_range/detail/begin_impl.hpp>
#include <boost/fusion/view/iterator_range/detail/end_impl.hpp> #include <boost/fusion/view/iterator_range/detail/end_impl.hpp>
#include <boost/fusion/view/iterator_range/detail/at_impl.hpp> #include <boost/fusion/view/iterator_range/detail/at_impl.hpp>
#include <boost/fusion/view/iterator_range/detail/size_impl.hpp>
#include <boost/fusion/view/iterator_range/detail/value_at_impl.hpp> #include <boost/fusion/view/iterator_range/detail/value_at_impl.hpp>
#include <boost/fusion/view/iterator_range/detail/is_segmented_impl.hpp>
#include <boost/fusion/view/iterator_range/detail/segments_impl.hpp>
#include <boost/fusion/adapted/mpl/mpl_iterator.hpp> #include <boost/fusion/adapted/mpl/mpl_iterator.hpp>
#include <boost/config.hpp> #include <boost/config.hpp>
@ -36,7 +39,6 @@ namespace boost { namespace fusion
typedef typename convert_iterator<Last>::type end_type; typedef typename convert_iterator<Last>::type end_type;
typedef iterator_range_tag fusion_tag; typedef iterator_range_tag fusion_tag;
typedef fusion_sequence_tag tag; // this gets picked up by MPL typedef fusion_sequence_tag tag; // this gets picked up by MPL
typedef typename result_of::distance<begin_type, end_type>::type size;
typedef mpl::true_ is_view; typedef mpl::true_ is_view;
typedef typename traits::category_of<begin_type>::type category; typedef typename traits::category_of<begin_type>::type category;

View File

@ -7,6 +7,7 @@
#if !defined(FUSION_JOINT_VIEW_07162005_0140) #if !defined(FUSION_JOINT_VIEW_07162005_0140)
#define FUSION_JOINT_VIEW_07162005_0140 #define FUSION_JOINT_VIEW_07162005_0140
#include <boost/fusion/view/joint_view/joint_view_fwd.hpp>
#include <boost/fusion/support/detail/access.hpp> #include <boost/fusion/support/detail/access.hpp>
#include <boost/fusion/support/is_view.hpp> #include <boost/fusion/support/is_view.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp> #include <boost/fusion/sequence/intrinsic/begin.hpp>
@ -50,7 +51,9 @@ namespace boost { namespace fusion
typedef typename result_of::end<Sequence1>::type last_type; typedef typename result_of::end<Sequence1>::type last_type;
typedef typename result_of::begin<Sequence2>::type concat_type; typedef typename result_of::begin<Sequence2>::type concat_type;
typedef typename result_of::end<Sequence2>::type concat_last_type; typedef typename result_of::end<Sequence2>::type concat_last_type;
typedef typename mpl::plus<result_of::size<Sequence1>, result_of::size<Sequence2> >::type size; typedef typename mpl::int_<
result_of::size<Sequence1>::value + result_of::size<Sequence2>::value>
size;
joint_view(Sequence1& in_seq1, Sequence2& in_seq2) joint_view(Sequence1& in_seq1, Sequence2& in_seq2)
: seq1(in_seq1) : seq1(in_seq1)

View File

@ -0,0 +1,18 @@
/*=============================================================================
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_JOINT_VIEW_FWD_HPP_INCLUDED)
#define BOOST_FUSION_JOINT_VIEW_FWD_HPP_INCLUDED
namespace boost { namespace fusion
{
struct joint_view_tag;
template <typename Sequence1, typename Sequence2>
struct joint_view;
}}
#endif

View File

@ -41,6 +41,10 @@ import testing ;
[ run algorithm/reverse_fold.cpp : : : : ] [ run algorithm/reverse_fold.cpp : : : : ]
[ run algorithm/reverse_iter_fold.cpp : : : : ] [ run algorithm/reverse_iter_fold.cpp : : : : ]
[ run algorithm/reverse.cpp : : : : ] [ run algorithm/reverse.cpp : : : : ]
[ run algorithm/segmented_for_each.cpp : : : : ]
[ run algorithm/segmented_find.cpp : : : : ]
[ run algorithm/segmented_find_if.cpp : : : : ]
[ run algorithm/segmented_fold.cpp : : : : ]
[ run algorithm/transform.cpp : : : : ] [ run algorithm/transform.cpp : : : : ]
[ run algorithm/join.cpp : : : : ] [ run algorithm/join.cpp : : : : ]
[ run algorithm/zip.cpp : : : : ] [ run algorithm/zip.cpp : : : : ]
@ -83,6 +87,7 @@ import testing ;
[ run sequence/map_tie.cpp : : : : ] [ run sequence/map_tie.cpp : : : : ]
[ run sequence/nview.cpp : : : : ] [ run sequence/nview.cpp : : : : ]
[ run sequence/reverse_view.cpp : : : : ] [ run sequence/reverse_view.cpp : : : : ]
[ run sequence/segmented_iterator_range.cpp : : : : ]
[ run sequence/set.cpp : : : : ] [ run sequence/set.cpp : : : : ]
[ run sequence/single_view.cpp : : : : ] [ run sequence/single_view.cpp : : : : ]
[ run sequence/std_pair.cpp : : : : ] [ run sequence/std_pair.cpp : : : : ]
@ -149,17 +154,3 @@ import testing ;
; ;
} }
{
# Text for extension features, must be explicitly specified on the command line to be run
# TODO these are not in a test-suite because currently test-suites cannot be marked "explicit"
run algorithm/ext_/for_each_s.cpp ;
explicit for_each_s ;
run algorithm/ext_/find_if_s.cpp ;
explicit find_if_s ;
run sequence/ext_/iterator_range_s.cpp ;
explicit iterator_range_s ;
}

View File

@ -30,7 +30,7 @@ void test_set(Set const& set)
using namespace boost::fusion; using namespace boost::fusion;
std::cout << set << std::endl; std::cout << set << std::endl;
BOOST_STATIC_ASSERT(result_of::size<Set>::value == 3); BOOST_STATIC_ASSERT(boost::fusion::result_of::size<Set>::value == 3);
BOOST_TEST((*find<int>(set) == 1)); BOOST_TEST((*find<int>(set) == 1));
BOOST_TEST((*find<double>(set) == 1.5)); BOOST_TEST((*find<double>(set) == 1.5));
BOOST_TEST((*find<std::string>(set) == "hello")); BOOST_TEST((*find<std::string>(set) == "hello"));
@ -47,7 +47,7 @@ void test_map(Map const& map)
using namespace boost::fusion; using namespace boost::fusion;
std::cout << map << std::endl; std::cout << map << std::endl;
BOOST_STATIC_ASSERT(result_of::size<Map>::value == 3); BOOST_STATIC_ASSERT(boost::fusion::result_of::size<Map>::value == 3);
BOOST_TEST(((*find<_1>(map)).second == 1)); BOOST_TEST(((*find<_1>(map)).second == 1));
BOOST_TEST(((*find<_3>(map)).second == 1.5)); BOOST_TEST(((*find<_3>(map)).second == 1.5));
BOOST_TEST(((*find<_4>(map)).second == std::string("hello"))); BOOST_TEST(((*find<_4>(map)).second == std::string("hello")));

View File

@ -1,109 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
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/detail/lightweight_test.hpp>
#include <boost/fusion/container/vector/vector.hpp>
#include <boost/fusion/adapted/mpl.hpp>
#include <boost/fusion/sequence/io/out.hpp>
#include <boost/fusion/algorithm/query/ext_/find_if_s.hpp>
#include <boost/fusion/container/ext_/tree.hpp>
#include <boost/fusion/container/generation/make_vector.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/less.hpp>
#include <boost/type_traits/is_same.hpp>
struct X
{
operator int() const
{
return 12345;
}
};
template<typename Tree>
void
process_tree(Tree const &tree)
{
using namespace boost;
using mpl::_;
typedef typename fusion::result_of::find_if_s<Tree const, is_same<_,short> >::type short_iter;
typedef typename fusion::result_of::find_if_s<Tree const, is_same<_,float> >::type float_iter;
// find_if_s of a segmented data structure returns generic
// segmented iterators
short_iter si = fusion::find_if_s<is_same<_,short> >(tree);
float_iter fi = fusion::find_if_s<is_same<_,float> >(tree);
// they behave like ordinary Fusion iterators ...
BOOST_TEST((*si == short('d')));
BOOST_TEST((*fi == float(1)));
}
int
main()
{
using namespace boost::fusion;
{
using boost::is_same;
using boost::mpl::_;
typedef vector<int, char, int, double> vector_type;
vector_type v(12345, 'x', 678910, 3.36);
std::cout << *find_if_s<is_same<_, char> >(v) << std::endl;
BOOST_TEST((*find_if_s<is_same<_, char> >(v) == 'x'));
std::cout << *find_if_s<is_same<_, int> >(v) << std::endl;
BOOST_TEST((*find_if_s<is_same<_, int> >(v) == 12345));
std::cout << *find_if_s<is_same<_, double> >(v) << std::endl;
BOOST_TEST((*find_if_s<is_same<_, double> >(v) == 3.36));
}
{
using boost::mpl::vector;
using boost::is_same;
using boost::mpl::_;
typedef vector<int, char, X, double> mpl_vec;
BOOST_TEST((*find_if_s<is_same<_, X> >(mpl_vec()) == 12345));
}
{
using boost::mpl::vector_c;
using boost::mpl::less;
using boost::mpl::int_;
using boost::is_same;
using boost::mpl::_;
typedef vector_c<int, 1, 2, 3, 4> mpl_vec;
BOOST_TEST((*find_if_s<less<_, int_<3> > >(mpl_vec()) == 1));
}
{
process_tree(
make_tree(
make_vector(double(0),'B')
, make_tree(
make_vector(1,2,long(3))
, make_tree(make_vector('a','b','c'))
, make_tree(make_vector(short('d'),'e','f'))
)
, make_tree(
make_vector(4,5,6)
, make_tree(make_vector(float(1),'h','i'))
, make_tree(make_vector('j','k','l'))
)
)
);
}
return boost::report_errors();
}

View File

@ -59,7 +59,7 @@ struct sum
template<typename Self, typename State, typename T> template<typename Self, typename State, typename T>
struct result<Self(State,T)> struct result<Self(State,T)>
: fusion::result_of::make_pair< : boost::fusion::result_of::make_pair<
mpl::int_< mpl::int_<
boost::remove_reference< boost::remove_reference<
State State
@ -108,7 +108,7 @@ struct meta_sum
#ifdef BOOST_FUSION_TEST_ITER_FOLD #ifdef BOOST_FUSION_TEST_ITER_FOLD
typedef typename typedef typename
fusion::result_of::value_of< boost::fusion::result_of::value_of<
typename boost::remove_reference<T>::type typename boost::remove_reference<T>::type
>::type >::type
t; t;
@ -144,7 +144,7 @@ struct fold_test_n
{ {
mpl::range_c<int, 1, n+1> init_range; mpl::range_c<int, 1, n+1> init_range;
typename fusion::result_of::as_vector< typename boost::fusion::result_of::as_vector<
typename mpl::transform< typename mpl::transform<
range range
, mpl::always<int> , mpl::always<int>
@ -169,20 +169,20 @@ struct fold_test_n
{ {
typedef typename typedef typename
#ifdef BOOST_FUSION_TEST_REVERSE_FOLD #ifdef BOOST_FUSION_TEST_REVERSE_FOLD
fusion::result_of::as_vector< boost::fusion::result_of::as_vector<
typename mpl::copy< typename mpl::copy<
mpl::range_c<int, 1, n+1> mpl::range_c<int, 1, n+1>
, mpl::front_inserter<fusion::vector<> > , mpl::front_inserter<fusion::vector<> >
>::type >::type
>::type >::type
#else #else
fusion::result_of::as_vector<mpl::range_c<int, 1, n+1> >::type boost::fusion::result_of::as_vector<mpl::range_c<int, 1, n+1> >::type
#endif #endif
vec; vec;
typedef typedef
boost::is_same< boost::is_same<
typename fusion::result_of::BOOST_FUSION_TEST_FOLD_NAME< typename boost::fusion::result_of::BOOST_FUSION_TEST_FOLD_NAME<
vec vec
, mpl::vector<mpl::int_<1>, mpl::int_<0> > , mpl::vector<mpl::int_<1>, mpl::int_<0> >
, meta_sum , meta_sum

View File

@ -0,0 +1,62 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
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)
==============================================================================*/
#include <boost/detail/lightweight_test.hpp>
#include <boost/fusion/container/vector/vector.hpp>
#include <boost/fusion/algorithm/query/find.hpp>
#include <boost/fusion/container/generation/make_vector.hpp>
#include "../sequence/tree.hpp"
struct not_there {};
template<typename Tree>
void
process_tree(Tree const &tree)
{
using namespace boost;
typedef typename boost::fusion::result_of::find<Tree const, short>::type short_iter;
typedef typename boost::fusion::result_of::find<Tree const, float>::type float_iter;
typedef typename boost::fusion::result_of::find<Tree const, not_there>::type not_there_iter;
// find_if_s of a segmented data structure returns generic
// segmented iterators
short_iter si = fusion::find<short>(tree);
float_iter fi = fusion::find<float>(tree);
// they behave like ordinary Fusion iterators ...
BOOST_TEST((*si == short('d')));
BOOST_TEST((*fi == float(1)));
// Searching for something that's not there should return the end iterator.
not_there_iter nti = fusion::find<not_there>(tree);
BOOST_TEST((nti == fusion::end(tree)));
}
int
main()
{
using namespace boost::fusion;
process_tree(
make_tree(
make_vector(double(0),'B')
, make_tree(
make_vector(1,2,long(3))
, make_tree(make_vector('a','b','c'))
, make_tree(make_vector(short('d'),'e','f'))
)
, make_tree(
make_vector(4,5,6)
, make_tree(make_vector(float(1),'h','i'))
, make_tree(make_vector('j','k','l'))
)
)
);
return boost::report_errors();
}

View File

@ -0,0 +1,65 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
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)
==============================================================================*/
#include <boost/detail/lightweight_test.hpp>
#include <boost/fusion/container/vector/vector.hpp>
#include <boost/fusion/algorithm/query/find_if.hpp>
#include <boost/fusion/container/generation/make_vector.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/type_traits/is_same.hpp>
#include "../sequence/tree.hpp"
struct not_there {};
template<typename Tree>
void
process_tree(Tree const &tree)
{
using namespace boost;
using mpl::_;
typedef typename boost::fusion::result_of::find_if<Tree const, is_same<_,short> >::type short_iter;
typedef typename boost::fusion::result_of::find_if<Tree const, is_same<_,float> >::type float_iter;
typedef typename boost::fusion::result_of::find_if<Tree const, is_same<_,not_there> >::type not_there_iter;
// find_if of a segmented data structure returns generic
// segmented iterators
short_iter si = fusion::find_if<is_same<_,short> >(tree);
float_iter fi = fusion::find_if<is_same<_,float> >(tree);
// they behave like ordinary Fusion iterators ...
BOOST_TEST((*si == short('d')));
BOOST_TEST((*fi == float(1)));
// Searching for something that's not there should return the end iterator.
not_there_iter nti = fusion::find_if<is_same<_,not_there> >(tree);
BOOST_TEST((nti == fusion::end(tree)));
}
int
main()
{
using namespace boost::fusion;
process_tree(
make_tree(
make_vector(double(0),'B')
, make_tree(
make_vector(1,2,long(3))
, make_tree(make_vector('a','b','c'))
, make_tree(make_vector(short('d'),'e','f'))
)
, make_tree(
make_vector(4,5,6)
, make_tree(make_vector(float(1),'h','i'))
, make_tree(make_vector('j','k','l'))
)
)
);
return boost::report_errors();
}

View File

@ -0,0 +1,63 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
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)
==============================================================================*/
#include <string>
#include <sstream>
#include <iostream>
#include <boost/detail/lightweight_test.hpp>
#include <boost/fusion/container/vector/vector.hpp>
#include <boost/fusion/algorithm/iteration/fold.hpp>
#include <boost/fusion/container/generation/make_vector.hpp>
#include "../sequence/tree.hpp"
struct write_string
{
typedef std::ostream* result_type;
template<typename T>
std::ostream* operator()(std::ostream* sout, T const& t) const
{
return &(*sout << t << " ");
}
};
template<typename Tree>
void
process_tree(Tree const &tree)
{
using namespace boost;
std::stringstream str;
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 ");
}
int
main()
{
using namespace boost::fusion;
process_tree(
make_tree(
make_vector(double(0),'B')
, make_tree(
make_vector(1,2,long(3))
, make_tree(make_vector('a','b','c'))
, make_tree(make_vector(short('d'),'e','f'))
)
, make_tree(
make_vector(4,5,6)
, make_tree(make_vector(float(1),'h','i'))
, make_tree(make_vector('j','k','l'))
)
)
);
return boost::report_errors();
}

View File

@ -1,17 +1,15 @@
/*============================================================================= /*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman, Eric Niebler Copyright (c) 2001-2006 Joel de Guzman
Copyright (c) 2011 Eric Niebler
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) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/ ==============================================================================*/
#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/adapted/mpl.hpp> #include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/sequence/io/out.hpp>
#include <boost/fusion/algorithm/iteration/ext_/for_each_s.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/fusion/container/generation/make_vector.hpp> #include <boost/fusion/container/generation/make_vector.hpp>
#include <boost/fusion/container/ext_/tree.hpp> #include "../sequence/tree.hpp"
struct print struct print
{ {
@ -22,44 +20,13 @@ struct print
} }
}; };
struct increment
{
template <typename T>
void operator()(T& v) const
{
++v;
}
};
int int
main() main()
{ {
using namespace boost::fusion; using namespace boost::fusion;
using boost::mpl::vector_c;
namespace fusion = boost::fusion;
{ {
typedef vector<int, char, double, char const*> vector_type; for_each(
vector_type v(1, 'x', 3.3, "Ruby");
for_each_s(v, print());
std::cout << std::endl;
}
{
typedef vector<int, char, double, char const*> vector_type;
vector_type v(1, 'x', 3.3, "Ruby");
for_each_s(v, increment());
std::cout << v << std::endl;
}
{
typedef vector_c<int, 2, 3, 4, 5, 6> mpl_vec;
fusion::for_each_s(mpl_vec(), print());
std::cout << std::endl;
}
{
fusion::for_each_s(
make_tree( make_tree(
make_vector(double(0),'B') make_vector(double(0),'B')
, make_tree( , make_tree(

View File

@ -109,46 +109,46 @@ main()
{ {
typedef range_c<int, 5, 9> sequence_type; typedef range_c<int, 5, 9> sequence_type;
sequence_type sequence; sequence_type sequence;
std::cout << transform(sequence, square()) << std::endl; std::cout << boost::fusion::transform(sequence, square()) << std::endl;
BOOST_TEST((transform(sequence, square()) == make_vector(25, 36, 49, 64))); BOOST_TEST((boost::fusion::transform(sequence, square()) == make_vector(25, 36, 49, 64)));
} }
{ {
typedef range_c<int, 5, 9> mpl_list1; typedef range_c<int, 5, 9> mpl_list1;
std::cout << transform(mpl_list1(), square()) << std::endl; std::cout << boost::fusion::transform(mpl_list1(), square()) << std::endl;
BOOST_TEST((transform(mpl_list1(), square()) == make_vector(25, 36, 49, 64))); BOOST_TEST((boost::fusion::transform(mpl_list1(), square()) == make_vector(25, 36, 49, 64)));
} }
{ {
vector<int, int, int> tup(1, 2, 3); vector<int, int, int> tup(1, 2, 3);
std::cout << transform(tup, square()) << std::endl; std::cout << boost::fusion::transform(tup, square()) << std::endl;
BOOST_TEST((transform(tup, square()) == make_vector(1, 4, 9))); BOOST_TEST((boost::fusion::transform(tup, square()) == make_vector(1, 4, 9)));
} }
{ {
vector<int, int, int> tup1(1, 2, 3); vector<int, int, int> tup1(1, 2, 3);
vector<int, int, int> tup2(4, 5, 6); vector<int, int, int> tup2(4, 5, 6);
std::cout << transform(tup1, tup2, add()) << std::endl; std::cout << boost::fusion::transform(tup1, tup2, add()) << std::endl;
BOOST_TEST((transform(tup1, tup2, add()) == make_vector(5, 7, 9))); BOOST_TEST((boost::fusion::transform(tup1, tup2, add()) == make_vector(5, 7, 9)));
} }
{ {
// Unary transform that requires lvalues, just check compilation // Unary transform that requires lvalues, just check compilation
vector<int, int, int> tup1(1, 2, 3); vector<int, int, int> tup1(1, 2, 3);
BOOST_TEST(at_c<0>(transform(tup1, unary_lvalue_transform())) == &at_c<0>(tup1)); BOOST_TEST(at_c<0>(boost::fusion::transform(tup1, unary_lvalue_transform())) == &at_c<0>(tup1));
BOOST_TEST(*begin(transform(tup1, unary_lvalue_transform())) == &at_c<0>(tup1)); BOOST_TEST(*begin(boost::fusion::transform(tup1, unary_lvalue_transform())) == &at_c<0>(tup1));
} }
{ {
vector<int, int, int> tup1(1, 2, 3); vector<int, int, int> tup1(1, 2, 3);
vector<int, int, int> tup2(4, 5, 6); vector<int, int, int> tup2(4, 5, 6);
BOOST_TEST(at_c<0>(transform(tup1, tup2, binary_lvalue_transform())) == &at_c<0>(tup1)); BOOST_TEST(at_c<0>(boost::fusion::transform(tup1, tup2, binary_lvalue_transform())) == &at_c<0>(tup1));
BOOST_TEST(*begin(transform(tup1, tup2, binary_lvalue_transform())) == &at_c<0>(tup1)); BOOST_TEST(*begin(boost::fusion::transform(tup1, tup2, binary_lvalue_transform())) == &at_c<0>(tup1));
} }
{ {
vector<int, int, int> tup1(1, 2, 3); vector<int, int, int> tup1(1, 2, 3);
BOOST_TEST(transform(tup1, twice) == make_vector(2,4,6)); BOOST_TEST(boost::fusion::transform(tup1, twice) == make_vector(2,4,6));
} }

View File

@ -38,17 +38,17 @@ namespace
fusion::at_c<8>(v); fusion::at_c<8>(v);
fusion::at_c<9>(v); fusion::at_c<9>(v);
typedef typename fusion::result_of::value_at_c<v_type, 0>::type va0; typedef typename boost::fusion::result_of::value_at_c<v_type, 0>::type va0;
typedef typename fusion::result_of::value_at_c<v_type, 1>::type va1; typedef typename boost::fusion::result_of::value_at_c<v_type, 1>::type va1;
typedef typename fusion::result_of::value_at_c<v_type, 2>::type va2; typedef typename boost::fusion::result_of::value_at_c<v_type, 2>::type va2;
typedef typename fusion::result_of::value_at_c<v_type, 3>::type va3; typedef typename boost::fusion::result_of::value_at_c<v_type, 3>::type va3;
typedef typename fusion::result_of::value_at_c<v_type, 4>::type va4; typedef typename boost::fusion::result_of::value_at_c<v_type, 4>::type va4;
typedef typename fusion::result_of::value_at_c<v_type, 5>::type va5; typedef typename boost::fusion::result_of::value_at_c<v_type, 5>::type va5;
typedef typename fusion::result_of::value_at_c<v_type, 6>::type va6; typedef typename boost::fusion::result_of::value_at_c<v_type, 6>::type va6;
typedef typename fusion::result_of::value_at_c<v_type, 7>::type va7; typedef typename boost::fusion::result_of::value_at_c<v_type, 7>::type va7;
typedef typename fusion::result_of::value_at_c<v_type, 8>::type va8; typedef typename boost::fusion::result_of::value_at_c<v_type, 8>::type va8;
typedef typename fusion::result_of::value_at_c<v_type, 9>::type va9; typedef typename boost::fusion::result_of::value_at_c<v_type, 9>::type va9;
fusion::begin(v); fusion::begin(v);
fusion::end(v); fusion::end(v);

View File

@ -331,7 +331,7 @@ void test_sequence_n(Sequence & seq, mpl::int_<3>)
template <class Sequence> template <class Sequence>
void test_sequence(Sequence & seq) void test_sequence(Sequence & seq)
{ {
test_sequence_n(seq, mpl::int_<fusion::result_of::size<Sequence>::value>()); test_sequence_n(seq, mpl::int_<boost::fusion::result_of::size<Sequence>::value>());
} }
@ -340,18 +340,18 @@ void result_type_tests()
using boost::is_same; using boost::is_same;
BOOST_TEST(( is_same< BOOST_TEST(( is_same<
fusion::result_of::invoke<int (*)(), fusion::vector0<> >::type, int boost::fusion::result_of::invoke<int (*)(), fusion::vector0<> >::type, int
>::value )); >::value ));
// disabled until boost::result_of supports it // disabled until boost::result_of supports it
// BOOST_TEST(( is_same< // BOOST_TEST(( is_same<
// fusion::result_of::invoke<int (*)(...), fusion::vector1<int> >::type, int // boost::fusion::result_of::invoke<int (*)(...), fusion::vector1<int> >::type, int
// >::value )); // >::value ));
BOOST_TEST(( is_same< BOOST_TEST(( is_same<
fusion::result_of::invoke<int (members::*)(), fusion::vector1<members*> >::type, int boost::fusion::result_of::invoke<int (members::*)(), fusion::vector1<members*> >::type, int
>::value )); >::value ));
// disabled until boost::result_of supports it // disabled until boost::result_of supports it
// BOOST_TEST(( is_same< // BOOST_TEST(( is_same<
// fusion::result_of::invoke<int (members::*)(...), fusion::vector2<members*,int> >::type, int // boost::fusion::result_of::invoke<int (members::*)(...), fusion::vector2<members*,int> >::type, int
// >::value )); // >::value ));
} }

View File

@ -182,16 +182,16 @@ void test_sequence_n(Sequence & seq, mpl::int_<3>)
template <class Sequence> template <class Sequence>
void test_sequence(Sequence & seq) void test_sequence(Sequence & seq)
{ {
test_sequence_n(seq, mpl::int_<fusion::result_of::size<Sequence>::value>()); test_sequence_n(seq, mpl::int_<boost::fusion::result_of::size<Sequence>::value>());
} }
void result_type_tests() void result_type_tests()
{ {
using boost::is_same; using boost::is_same;
BOOST_TEST(( is_same< fusion::result_of::invoke_function_object< nullary_fobj, fusion::vector<> >::type, int >::value )); BOOST_TEST(( is_same< boost::fusion::result_of::invoke_function_object< nullary_fobj, fusion::vector<> >::type, int >::value ));
BOOST_TEST(( is_same< fusion::result_of::invoke_function_object< fobj, fusion::vector<element1_type> >::type, int >::value )); BOOST_TEST(( is_same< boost::fusion::result_of::invoke_function_object< fobj, fusion::vector<element1_type> >::type, int >::value ));
BOOST_TEST(( is_same< fusion::result_of::invoke_function_object< fobj, fusion::vector<element1_type,element2_type> >::type, int >::value )); BOOST_TEST(( is_same< boost::fusion::result_of::invoke_function_object< fobj, fusion::vector<element1_type,element2_type> >::type, int >::value ));
} }

View File

@ -244,7 +244,7 @@ void test_sequence_n(Sequence & seq, mpl::int_<3>)
template <class Sequence> template <class Sequence>
void test_sequence(Sequence & seq) void test_sequence(Sequence & seq)
{ {
test_sequence_n(seq, mpl::int_<fusion::result_of::size<Sequence>::value>()); test_sequence_n(seq, mpl::int_<boost::fusion::result_of::size<Sequence>::value>());
} }
int main() int main()

View File

@ -63,7 +63,7 @@ int main()
test_func<> f; test_func<> f;
test_func<noncopyable> f_nc; test_func<noncopyable> f_nc;
fusion::result_of::make_fused< test_func<> >::type fused_func boost::fusion::result_of::make_fused< test_func<> >::type fused_func
= fusion::make_fused(f); = fusion::make_fused(f);
BOOST_TEST(fused_func(lv_vec) == 1); BOOST_TEST(fused_func(lv_vec) == 1);

Some files were not shown because too many files have changed in this diff Show More