mirror of
https://github.com/boostorg/fusion.git
synced 2025-07-19 07:12:12 +02:00
new cleaner(?) implementation for segmented fusion
[SVN r73644]
This commit is contained in:
77
include/boost/fusion/algorithm/iteration/ext_/fold_s.hpp
Normal file
77
include/boost/fusion/algorithm/iteration/ext_/fold_s.hpp
Normal file
@ -0,0 +1,77 @@
|
||||
/*=============================================================================
|
||||
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.hpp>
|
||||
#include <boost/fusion/view/ext_/segmented_fold_until.hpp>
|
||||
|
||||
namespace boost { namespace fusion { namespace detail
|
||||
{
|
||||
template<typename Fun>
|
||||
struct segmented_fold_fun
|
||||
{
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename Range, typename State, typename Context>
|
||||
struct result<This(Range&, State&, Context&)>
|
||||
{
|
||||
typedef
|
||||
fusion::result<
|
||||
typename result_of::fold<Range, typename State::value_type, Fun>::type,
|
||||
continue_
|
||||
>
|
||||
type;
|
||||
};
|
||||
|
||||
explicit segmented_fold_fun(Fun const& f)
|
||||
: fun(f)
|
||||
{}
|
||||
|
||||
template<typename Range, typename State, typename Context>
|
||||
typename result<segmented_fold_fun(Range&, State const&, Context const&)>::type
|
||||
operator()(Range& rng, State const& state, Context const&) const
|
||||
{
|
||||
return fusion::fold(rng, state.value, fun);
|
||||
}
|
||||
|
||||
Fun const& fun;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
namespace boost { namespace fusion
|
||||
{
|
||||
namespace result_of
|
||||
{
|
||||
template <typename Sequence, typename State, typename F>
|
||||
struct fold_s
|
||||
: result_of::segmented_fold_until<
|
||||
Sequence,
|
||||
State,
|
||||
detail::segmented_fold_fun<F>
|
||||
>
|
||||
{};
|
||||
}
|
||||
|
||||
template <typename Sequence, typename State, typename F>
|
||||
typename result_of::fold_s<Sequence, State, F>::type
|
||||
fold_s(Sequence& seq, State const& state, F const& f)
|
||||
{
|
||||
return fusion::segmented_fold_until(seq, state, detail::segmented_fold_fun<F>(f));
|
||||
}
|
||||
|
||||
template <typename Sequence, typename State, typename F>
|
||||
typename result_of::fold_s<Sequence const, State, F>::type
|
||||
fold_s(Sequence const& seq, State const& state, F const& f)
|
||||
{
|
||||
return fusion::segmented_fold_until(seq, state, detail::segmented_fold_fun<F>(f));
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
64
include/boost/fusion/algorithm/iteration/ext_/for_each_s.hpp
Executable file → Normal file
64
include/boost/fusion/algorithm/iteration/ext_/for_each_s.hpp
Executable file → Normal file
@ -1,65 +1,37 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2006 Eric Niebler
|
||||
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(FUSION_FOR_EACH_S_05022006_1027)
|
||||
#define FUSION_FOR_EACH_S_05022006_1027
|
||||
#if !defined(BOOST_FUSION_FOR_EACH_S_HPP_INCLUDED)
|
||||
#define BOOST_FUSION_FOR_EACH_S_HPP_INCLUDED
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/fusion/support/void.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);
|
||||
}}
|
||||
#include <boost/fusion/view/ext_/segmented_fold_until.hpp>
|
||||
|
||||
namespace boost { namespace fusion { namespace detail
|
||||
{
|
||||
template<typename F>
|
||||
struct for_each_s_bind
|
||||
template<typename Fun>
|
||||
struct segmented_for_each_fun
|
||||
{
|
||||
explicit for_each_s_bind(F const &f)
|
||||
: f_(f)
|
||||
typedef result<void, continue_> result_type;
|
||||
|
||||
explicit segmented_for_each_fun(Fun const& f)
|
||||
: fun(f)
|
||||
{}
|
||||
|
||||
template<typename Sequence>
|
||||
void operator ()(Sequence &seq) const
|
||||
template<typename Range, typename State, typename Context>
|
||||
result_type operator()(Range& rng, State const&, Context const&) const
|
||||
{
|
||||
fusion::for_each_s(seq, this->f_);
|
||||
fusion::for_each(rng, fun);
|
||||
return void_();
|
||||
}
|
||||
|
||||
template<typename Sequence>
|
||||
void operator ()(Sequence const &seq) const
|
||||
{
|
||||
fusion::for_each_s(seq, this->f_);
|
||||
}
|
||||
private:
|
||||
F const &f_;
|
||||
Fun const& fun;
|
||||
};
|
||||
|
||||
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
|
||||
@ -77,14 +49,14 @@ namespace boost { namespace fusion
|
||||
inline void
|
||||
for_each_s(Sequence& seq, F const& f)
|
||||
{
|
||||
detail::for_each_s(seq, f, traits::is_segmented<Sequence>());
|
||||
fusion::segmented_fold_until(seq, void_(), detail::segmented_for_each_fun<F>(f));
|
||||
}
|
||||
|
||||
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>());
|
||||
fusion::segmented_fold_until(seq, void_(), detail::segmented_for_each_fun<F>(f));
|
||||
}
|
||||
}}
|
||||
|
||||
|
221
include/boost/fusion/algorithm/query/ext_/find_if_s.hpp
Executable file → Normal file
221
include/boost/fusion/algorithm/query/ext_/find_if_s.hpp
Executable file → Normal file
@ -1,188 +1,58 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2006 Eric Niebler
|
||||
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(FIND_IF_S_05152006_1027)
|
||||
#define FIND_IF_S_05152006_1027
|
||||
#if !defined(BOOST_FUSION_FIND_IF_S_HPP_INCLUDED)
|
||||
#define BOOST_FUSION_FIND_IF_S_HPP_INCLUDED
|
||||
|
||||
#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/type_traits/remove_const.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;
|
||||
}
|
||||
}}
|
||||
#include <boost/fusion/view/ext_/segmented_fold_until.hpp>
|
||||
|
||||
namespace boost { namespace fusion { namespace detail
|
||||
{
|
||||
template<typename Pred>
|
||||
struct segmented_find_if_fun
|
||||
{
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
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 This, typename Range, typename State, typename Context>
|
||||
struct result<This(Range&, State&, Context&)>
|
||||
{
|
||||
typedef
|
||||
typename result_of::find_if<Range, Pred>::type
|
||||
iterator_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
|
||||
typedef
|
||||
typename result_of::make_segmented_iterator<
|
||||
iterator_type,
|
||||
typename remove_const<Context>::type
|
||||
>::type
|
||||
segmented_iterator_type;
|
||||
|
||||
typedef
|
||||
typename mpl::if_<
|
||||
result_of::equal_to<
|
||||
iterator_type,
|
||||
typename result_of::end<Range>::type
|
||||
>,
|
||||
fusion::result<segmented_iterator_type, continue_>, // NOT FOUND
|
||||
fusion::result<segmented_iterator_type, break_> // FOUND
|
||||
>::type
|
||||
, bool IsSegmented = traits::is_segmented<Sequence>::value
|
||||
>
|
||||
struct as_segmented_cons
|
||||
{
|
||||
typedef cons<
|
||||
SegmentedRange
|
||||
, cons<segmented_range<Sequence, Where, false> >
|
||||
> type;
|
||||
type;
|
||||
};
|
||||
|
||||
static type call(SegmentedRange const &range, Where const &where)
|
||||
template<typename Range, typename State, typename Context>
|
||||
typename result<segmented_find_if_fun(Range&, State const&, Context const&)>::type
|
||||
operator()(Range& rng, State const&, Context const& context) const
|
||||
{
|
||||
return fusion::make_cons(
|
||||
range
|
||||
, fusion::make_cons(
|
||||
segmented_range<Sequence, Where, false>(*fusion::begin(range), where)
|
||||
)
|
||||
);
|
||||
return fusion::make_segmented_iterator(fusion::find_if<Pred>(rng), context);
|
||||
}
|
||||
};
|
||||
|
||||
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
|
||||
@ -191,31 +61,22 @@ namespace boost { namespace fusion
|
||||
{
|
||||
template <typename Sequence, typename Pred>
|
||||
struct find_if_s
|
||||
{
|
||||
typedef typename
|
||||
detail::static_find_if_s<
|
||||
Sequence
|
||||
, Pred
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
: result_of::segmented_fold_until<Sequence, void_, detail::segmented_find_if_fun<Pred> >
|
||||
{};
|
||||
}
|
||||
|
||||
template <typename Pred, typename Sequence>
|
||||
typename lazy_disable_if<
|
||||
is_const<Sequence>
|
||||
, result_of::find_if_s<Sequence, Pred>
|
||||
>::type
|
||||
typename result_of::find_if_s<Sequence, Pred>::type
|
||||
find_if_s(Sequence& seq)
|
||||
{
|
||||
return detail::static_find_if_s<Sequence, Pred>::call(seq);
|
||||
return fusion::segmented_fold_until(seq, void_(), detail::segmented_find_if_fun<Pred>());
|
||||
}
|
||||
|
||||
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);
|
||||
return fusion::segmented_fold_until(seq, void_(), detail::segmented_find_if_fun<Pred>());
|
||||
}
|
||||
}}
|
||||
|
||||
|
83
include/boost/fusion/algorithm/query/ext_/find_s.hpp
Normal file
83
include/boost/fusion/algorithm/query/ext_/find_s.hpp
Normal file
@ -0,0 +1,83 @@
|
||||
/*=============================================================================
|
||||
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_S_HPP_INCLUDED)
|
||||
#define BOOST_FUSION_FIND_S_HPP_INCLUDED
|
||||
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/fusion/algorithm/query/find.hpp>
|
||||
#include <boost/fusion/view/ext_/segmented_fold_until.hpp>
|
||||
|
||||
namespace boost { namespace fusion { namespace detail
|
||||
{
|
||||
template<typename T>
|
||||
struct segmented_find_fun
|
||||
{
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename Range, typename State, typename Context>
|
||||
struct result<This(Range&, State&, Context&)>
|
||||
{
|
||||
typedef
|
||||
typename result_of::find<Range, T>::type
|
||||
iterator_type;
|
||||
|
||||
typedef
|
||||
typename result_of::make_segmented_iterator<
|
||||
iterator_type,
|
||||
typename remove_const<Context>::type
|
||||
>::type
|
||||
segmented_iterator_type;
|
||||
|
||||
typedef
|
||||
typename mpl::if_<
|
||||
result_of::equal_to<
|
||||
iterator_type,
|
||||
typename result_of::end<Range>::type
|
||||
>,
|
||||
fusion::result<segmented_iterator_type, continue_>, // NOT FOUND
|
||||
fusion::result<segmented_iterator_type, break_> // FOUND
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template<typename Range, typename State, typename Context>
|
||||
typename result<segmented_find_fun(Range&, State const&, Context const&)>::type
|
||||
operator()(Range& rng, State const&, Context const& context) const
|
||||
{
|
||||
return fusion::make_segmented_iterator(fusion::find<T>(rng), context);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
namespace boost { namespace fusion
|
||||
{
|
||||
namespace result_of
|
||||
{
|
||||
template <typename Sequence, typename T>
|
||||
struct find_s
|
||||
: result_of::segmented_fold_until<Sequence, void_, detail::segmented_find_fun<T> >
|
||||
{};
|
||||
}
|
||||
|
||||
template <typename T, typename Sequence>
|
||||
typename result_of::find_s<Sequence, T>::type
|
||||
find_s(Sequence& seq)
|
||||
{
|
||||
return fusion::segmented_fold_until(seq, void_(), detail::segmented_find_fun<T>());
|
||||
}
|
||||
|
||||
template <typename T, typename Sequence>
|
||||
typename result_of::find_s<Sequence const, T>::type
|
||||
find_s(Sequence const& seq)
|
||||
{
|
||||
return fusion::segmented_fold_until(seq, void_(), detail::segmented_find_fun<T>());
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
27
include/boost/fusion/container/ext_/tree.hpp
Executable file → Normal file
27
include/boost/fusion/container/ext_/tree.hpp
Executable file → Normal file
@ -18,26 +18,18 @@
|
||||
#include <boost/fusion/container/list/cons.hpp> // for nil
|
||||
#include <boost/fusion/container/vector/vector10.hpp>
|
||||
#include <boost/fusion/support/sequence_base.hpp>
|
||||
#include <boost/fusion/support/category_of.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/ext_/segments.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/ext_/size_s.hpp>
|
||||
#include <boost/fusion/support/ext_/is_segmented.hpp>
|
||||
#include <boost/fusion/view/ext_/segmented_iterator.hpp>
|
||||
#include <boost/fusion/view/ext_/segmented_begin.hpp>
|
||||
#include <boost/fusion/view/ext_/segmented_end.hpp>
|
||||
|
||||
namespace boost { namespace fusion
|
||||
{
|
||||
struct tree_tag;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename T, bool IsConst>
|
||||
struct reference : add_reference<T> {};
|
||||
|
||||
template<typename T>
|
||||
struct reference<T, true> : reference<typename add_const<T>::type, false> {};
|
||||
|
||||
template<typename T>
|
||||
struct reference<T &, true> : reference<T, false> {};
|
||||
}
|
||||
|
||||
template<typename Data, typename Left = nil, typename Right = nil>
|
||||
struct tree
|
||||
: sequence_base<tree<Data, Left, Right> >
|
||||
@ -46,7 +38,7 @@ namespace boost { namespace fusion
|
||||
typedef Left left_type;
|
||||
typedef Right right_type;
|
||||
typedef tree_tag fusion_tag;
|
||||
typedef forward_traversal_tag category;
|
||||
typedef bidirectional_traversal_tag category;
|
||||
typedef mpl::false_ is_view;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
@ -124,6 +116,15 @@ namespace boost { namespace fusion
|
||||
: segmented_end<Sequence>
|
||||
{};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct size_impl<tree_tag>
|
||||
{
|
||||
template<typename Sequence>
|
||||
struct apply
|
||||
: segmented_size<Sequence>::type
|
||||
{};
|
||||
};
|
||||
}
|
||||
}}
|
||||
|
||||
|
19
include/boost/fusion/sequence/intrinsic/ext_/segments.hpp
Executable file → Normal file
19
include/boost/fusion/sequence/intrinsic/ext_/segments.hpp
Executable file → Normal file
@ -4,8 +4,8 @@
|
||||
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
|
||||
#if !defined(BOOST_FUSION_SEGMENTS_04052005_1141)
|
||||
#define BOOST_FUSION_SEGMENTS_04052005_1141
|
||||
|
||||
#include <boost/fusion/support/tag_of.hpp>
|
||||
|
||||
@ -27,9 +27,10 @@ namespace boost { namespace fusion
|
||||
template <typename Sequence>
|
||||
struct segments
|
||||
{
|
||||
typedef typename traits::tag_of<Sequence>::type tag_type;
|
||||
|
||||
typedef typename
|
||||
extension::segments_impl<typename traits::tag_of<Sequence>::type>::
|
||||
template apply<Sequence>::type
|
||||
extension::segments_impl<tag_type>::template apply<Sequence>::type
|
||||
type;
|
||||
};
|
||||
}
|
||||
@ -38,18 +39,16 @@ namespace boost { namespace fusion
|
||||
typename result_of::segments<Sequence>::type
|
||||
segments(Sequence & seq)
|
||||
{
|
||||
return
|
||||
extension::segments_impl<typename traits::tag_of<Sequence>::type>::
|
||||
template apply<Sequence>::call(seq);
|
||||
typedef typename traits::tag_of<Sequence>::type tag_type;
|
||||
return extension::segments_impl<tag_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);
|
||||
typedef typename traits::tag_of<Sequence const>::type tag_type;
|
||||
return extension::segments_impl<tag_type>::template apply<Sequence const>::call(seq);
|
||||
}
|
||||
}}
|
||||
|
||||
|
@ -1,57 +1,57 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2006 Eric Niebler
|
||||
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(FUSION_SIZE_S_08112006_1141)
|
||||
#define FUSION_SIZE_S_08112006_1141
|
||||
#if !defined(BOOST_FUSION_SIZE_S_08112006_1141)
|
||||
#define BOOST_FUSION_SIZE_S_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/type_traits/remove_reference.hpp>
|
||||
#include <boost/fusion/algorithm/iteration/fold.hpp>
|
||||
#include <boost/fusion/support/ext_/is_segmented.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <boost/fusion/mpl.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/size.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/ext_/segments.hpp>
|
||||
#include <boost/fusion/support/ext_/is_segmented.hpp>
|
||||
|
||||
namespace boost { namespace fusion
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// calculates the size of any segmented data structure.
|
||||
template<typename Sequence, bool IsSegmented = traits::is_segmented<Sequence>::value>
|
||||
template<typename Sequence>
|
||||
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<
|
||||
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
|
||||
, mpl::size_t<0>
|
||||
, detail::size_plus
|
||||
>::type
|
||||
>::type,
|
||||
mpl::size_t<0>,
|
||||
mpl::plus<mpl::_1, segmented_size<mpl::_2> >
|
||||
>::type
|
||||
{};
|
||||
|
||||
template<typename Sequence>
|
||||
struct segmented_size<Sequence, false>
|
||||
: result_of::size<Sequence>
|
||||
struct segmented_size_impl<Sequence, false>
|
||||
: result_of::size<Sequence>::type
|
||||
{};
|
||||
}
|
||||
|
||||
template<typename Sequence>
|
||||
struct segmented_size
|
||||
: detail::segmented_size_impl<Sequence>
|
||||
{};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
100
include/boost/fusion/view/ext_/detail/begin_impl.hpp
Normal file
100
include/boost/fusion/view/ext_/detail/begin_impl.hpp
Normal file
@ -0,0 +1,100 @@
|
||||
/*=============================================================================
|
||||
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/view/iterator_range.hpp>
|
||||
#include <boost/fusion/container/list/cons.hpp>
|
||||
#include <boost/fusion/container/generation/make_cons.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/begin.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/end.hpp>
|
||||
#include <boost/fusion/support/ext_/is_segmented.hpp>
|
||||
#include <boost/fusion/view/ext_/detail/end_impl.hpp>
|
||||
#include <boost/fusion/view/ext_/segmented_fold_until.hpp>
|
||||
|
||||
namespace boost { namespace fusion { namespace detail
|
||||
{
|
||||
struct segmented_begin_fun
|
||||
{
|
||||
template<typename Sig>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename Range, typename State, typename Context>
|
||||
struct result<This(Range&, State&, Context&)>
|
||||
{
|
||||
typedef
|
||||
iterator_range<
|
||||
typename fusion::result_of::begin<Range>::type,
|
||||
typename fusion::result_of::end<Range>::type
|
||||
>
|
||||
range_type;
|
||||
|
||||
typedef
|
||||
fusion::result<
|
||||
cons<range_type, typename remove_const<Context>::type>,
|
||||
fusion::break_
|
||||
>
|
||||
type;
|
||||
};
|
||||
|
||||
template<typename Range, typename State, typename Context>
|
||||
typename result<segmented_begin_fun(Range&, State const&, Context const&)>::type
|
||||
operator()(Range& rng, State const&, Context const& context) const
|
||||
{
|
||||
typedef
|
||||
iterator_range<
|
||||
typename fusion::result_of::begin<Range>::type,
|
||||
typename fusion::result_of::end<Range>::type
|
||||
>
|
||||
range_type;
|
||||
|
||||
return fusion::make_cons(range_type(fusion::begin(rng), fusion::end(rng)), context);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Range, typename Stack, bool IsSegmented = traits::is_segmented<Range>::type::value>
|
||||
struct segmented_begin_impl
|
||||
{
|
||||
typedef
|
||||
segmented_end_impl<Range, Stack>
|
||||
end_impl;
|
||||
|
||||
typedef
|
||||
segmented_fold_until_impl<
|
||||
Range,
|
||||
result<typename end_impl::type, continue_>,
|
||||
Stack,
|
||||
segmented_begin_fun
|
||||
>
|
||||
fold_impl;
|
||||
|
||||
typedef typename fold_impl::type::value_type type;
|
||||
|
||||
static type call(Range& rng, Stack const& stack)
|
||||
{
|
||||
return fold_impl::call(rng, end_impl::call(rng, stack), stack, segmented_begin_fun()).value;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Range, typename Stack>
|
||||
struct segmented_begin_impl<Range, Stack, false>
|
||||
{
|
||||
typedef typename result_of::begin<Range>::type begin_type;
|
||||
typedef typename result_of::end<Range>::type end_type;
|
||||
typedef iterator_range<begin_type, end_type> pair_type;
|
||||
typedef cons<pair_type, Stack> type;
|
||||
|
||||
static type call(Range& rng, Stack stack)
|
||||
{
|
||||
return type(pair_type(fusion::begin(rng), fusion::end(rng)), stack);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
47
include/boost/fusion/view/ext_/detail/deref_impl.hpp
Normal file
47
include/boost/fusion/view/ext_/detail/deref_impl.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
/*=============================================================================
|
||||
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_DEREF_HPP_INCLUDED)
|
||||
#define BOOST_FUSION_SEGMENTED_ITERATOR_DEREF_HPP_INCLUDED
|
||||
|
||||
#include <boost/fusion/iterator/deref.hpp>
|
||||
|
||||
namespace boost { namespace fusion
|
||||
{
|
||||
struct segmented_iterator_tag;
|
||||
|
||||
namespace extension
|
||||
{
|
||||
template<typename Tag>
|
||||
struct deref_impl;
|
||||
|
||||
//auto deref(it)
|
||||
//{
|
||||
// return deref(begin(car(it.nodes)))
|
||||
//}
|
||||
template<>
|
||||
struct deref_impl<segmented_iterator_tag>
|
||||
{
|
||||
template<typename It>
|
||||
struct apply
|
||||
{
|
||||
typedef
|
||||
typename result_of::deref<
|
||||
typename It::nodes_type::car_type::begin_type
|
||||
>::type
|
||||
type;
|
||||
|
||||
static type call(It const& it)
|
||||
{
|
||||
return *it.nodes.car.first;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
55
include/boost/fusion/view/ext_/detail/end_impl.hpp
Normal file
55
include/boost/fusion/view/ext_/detail/end_impl.hpp
Normal file
@ -0,0 +1,55 @@
|
||||
/*=============================================================================
|
||||
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/view/iterator_range.hpp>
|
||||
#include <boost/fusion/container/list/cons.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/end.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/ext_/segments.hpp>
|
||||
#include <boost/fusion/support/ext_/is_segmented.hpp>
|
||||
|
||||
namespace boost { namespace fusion { namespace detail
|
||||
{
|
||||
//auto segmented_end_impl( rng, stack )
|
||||
//{
|
||||
// assert(is_segmented(rng));
|
||||
// auto it = end(segments(rng));
|
||||
// return cons(iterator_range(it, it), stack);
|
||||
//}
|
||||
|
||||
template<typename Range, typename Stack>
|
||||
struct segmented_end_impl
|
||||
{
|
||||
BOOST_MPL_ASSERT((traits::is_segmented<Range>));
|
||||
|
||||
typedef
|
||||
typename result_of::end<
|
||||
typename remove_reference<
|
||||
typename add_const<
|
||||
typename result_of::segments<Range>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
end_type;
|
||||
|
||||
typedef iterator_range<end_type, end_type> pair_type;
|
||||
typedef cons<pair_type, Stack> type;
|
||||
|
||||
static type call(Range & rng, Stack stack)
|
||||
{
|
||||
end_type end = fusion::end(fusion::segments(rng));
|
||||
return type(pair_type(end, end), stack);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
51
include/boost/fusion/view/ext_/detail/equal_to_impl.hpp
Normal file
51
include/boost/fusion/view/ext_/detail/equal_to_impl.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
/*=============================================================================
|
||||
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/equal.hpp>
|
||||
#include <boost/mpl/transform.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <boost/fusion/mpl.hpp>
|
||||
#include <boost/fusion/iterator/equal_to.hpp>
|
||||
#include <boost/fusion/container/vector/convert.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/begin.hpp>
|
||||
|
||||
namespace boost { namespace fusion
|
||||
{
|
||||
struct segmented_iterator_tag;
|
||||
|
||||
namespace extension
|
||||
{
|
||||
template<typename Tag>
|
||||
struct equal_to_impl;
|
||||
|
||||
template<>
|
||||
struct equal_to_impl<segmented_iterator_tag>
|
||||
{
|
||||
// Compare all the segment iterators in each stack, starting with
|
||||
// the bottom-most.
|
||||
template<typename It1, typename It2>
|
||||
struct apply
|
||||
: mpl::equal<
|
||||
typename mpl::reverse_transform<
|
||||
typename result_of::as_vector<typename It1::nodes_type>::type,
|
||||
result_of::begin<mpl::_1>
|
||||
>::type,
|
||||
typename mpl::reverse_transform<
|
||||
typename result_of::as_vector<typename It2::nodes_type>::type,
|
||||
result_of::begin<mpl::_1>
|
||||
>::type,
|
||||
result_of::equal_to<mpl::_1, mpl::_2>
|
||||
>
|
||||
{};
|
||||
};
|
||||
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
252
include/boost/fusion/view/ext_/detail/next_impl.hpp
Normal file
252
include/boost/fusion/view/ext_/detail/next_impl.hpp
Normal file
@ -0,0 +1,252 @@
|
||||
/*=============================================================================
|
||||
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/remove_reference.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/empty.hpp>
|
||||
#include <boost/fusion/container/list/cons.hpp>
|
||||
#include <boost/fusion/iterator/deref.hpp>
|
||||
#include <boost/fusion/algorithm/transformation/pop_front.hpp>
|
||||
#include <boost/fusion/view/ext_/detail/begin_impl.hpp>
|
||||
|
||||
namespace boost { namespace fusion
|
||||
{
|
||||
struct segmented_iterator_tag;
|
||||
|
||||
template<typename Nodes>
|
||||
struct segmented_iterator;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
//bool is_invalid(stack)
|
||||
//{
|
||||
// return empty(car(stack));
|
||||
//}
|
||||
|
||||
template<typename Stack>
|
||||
struct is_invalid
|
||||
: result_of::empty<typename Stack::car_type>
|
||||
{};
|
||||
|
||||
////Advance the first iterator in the range at the
|
||||
////top of a stack of iterator ranges. Return the
|
||||
////new stack.
|
||||
//auto pop_front_car(stack)
|
||||
//{
|
||||
// return cons(pop_front(car(stack)), cdr(stack))
|
||||
//}
|
||||
|
||||
template<typename Stack>
|
||||
struct pop_front_car
|
||||
{
|
||||
typedef typename Stack::car_type car_type;
|
||||
typedef typename result_of::pop_front<car_type>::type new_car_type;
|
||||
typedef cons<new_car_type, typename Stack::cdr_type> type;
|
||||
|
||||
static type call(Stack const & stack)
|
||||
{
|
||||
return type(fusion::pop_front(stack.car), 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 Range =
|
||||
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<Range, 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 Range, typename Result>
|
||||
struct segmented_next_impl_recurse2<Stack, Range, Result, false>
|
||||
{
|
||||
typedef Result type;
|
||||
|
||||
static type call(Stack const & stack)
|
||||
{
|
||||
return segmented_begin_impl<Range, 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 range of values, not a range 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
|
||||
{
|
||||
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<Stack, Next, false>
|
||||
{
|
||||
typedef Next type;
|
||||
|
||||
static type call(Stack const & stack)
|
||||
{
|
||||
return pop_front_car<Stack>::call(stack);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace extension
|
||||
{
|
||||
template<typename Tag>
|
||||
struct next_impl;
|
||||
|
||||
template<>
|
||||
struct next_impl<segmented_iterator_tag>
|
||||
{
|
||||
template<typename It>
|
||||
struct apply
|
||||
{
|
||||
typedef detail::segmented_next_impl<typename It::nodes_type> impl;
|
||||
typedef segmented_iterator<typename impl::type> type;
|
||||
|
||||
static type call(It const& it)
|
||||
{
|
||||
return type(impl::call(it.nodes));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
43
include/boost/fusion/view/ext_/detail/reverse_cons.hpp
Normal file
43
include/boost/fusion/view/ext_/detail/reverse_cons.hpp
Normal 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.hpp>
|
||||
#include <boost/fusion/container/generation/make_cons.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())
|
||||
{
|
||||
return impl::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;
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
112
include/boost/fusion/view/ext_/detail/segment_sequence.hpp
Normal file
112
include/boost/fusion/view/ext_/detail/segment_sequence.hpp
Normal file
@ -0,0 +1,112 @@
|
||||
/*=============================================================================
|
||||
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/ext_/segments.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/ext_/size_s.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;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Tag>
|
||||
struct begin_impl;
|
||||
|
||||
template<>
|
||||
struct begin_impl<detail::segment_sequence_tag>
|
||||
{
|
||||
template<typename Sequence>
|
||||
struct apply
|
||||
: segmented_begin<Sequence>
|
||||
{};
|
||||
};
|
||||
|
||||
template<typename Tag>
|
||||
struct end_impl;
|
||||
|
||||
template<>
|
||||
struct end_impl<detail::segment_sequence_tag>
|
||||
{
|
||||
template<typename Sequence>
|
||||
struct apply
|
||||
: segmented_end<Sequence>
|
||||
{};
|
||||
};
|
||||
|
||||
template<typename Tag>
|
||||
struct size_impl;
|
||||
|
||||
template<>
|
||||
struct size_impl<detail::segment_sequence_tag>
|
||||
{
|
||||
template<typename Sequence>
|
||||
struct apply
|
||||
: segmented_size<Sequence>::type
|
||||
{};
|
||||
};
|
||||
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
@ -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
|
||||
|
||||
|
40
include/boost/fusion/view/ext_/segmented_begin.hpp
Normal file
40
include/boost/fusion/view/ext_/segmented_begin.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
/*=============================================================================
|
||||
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/view/ext_/detail/begin_impl.hpp>
|
||||
|
||||
namespace boost { namespace fusion
|
||||
{
|
||||
template<typename Nodes>
|
||||
struct segmented_iterator;
|
||||
|
||||
//auto segmented_begin( rng )
|
||||
//{
|
||||
// return make_segmented_iterator( segmented_begin_impl( rng, nil ) );
|
||||
//}
|
||||
|
||||
template<typename Range>
|
||||
struct segmented_begin
|
||||
{
|
||||
typedef
|
||||
segmented_iterator<
|
||||
typename detail::segmented_begin_impl<Range, fusion::nil>::type
|
||||
>
|
||||
type;
|
||||
|
||||
static type call(Range & rng)
|
||||
{
|
||||
return type(
|
||||
detail::segmented_begin_impl<Range, fusion::nil>::call(rng, fusion::nil()));
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
41
include/boost/fusion/view/ext_/segmented_end.hpp
Normal file
41
include/boost/fusion/view/ext_/segmented_end.hpp
Normal 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_END_HPP_INCLUDED)
|
||||
#define BOOST_FUSION_SEGMENTED_END_HPP_INCLUDED
|
||||
|
||||
#include <boost/fusion/container/list/cons.hpp>
|
||||
#include <boost/fusion/view/ext_/detail/end_impl.hpp>
|
||||
|
||||
namespace boost { namespace fusion
|
||||
{
|
||||
template<typename Nodes>
|
||||
struct segmented_iterator;
|
||||
|
||||
//auto segmented_end( rng )
|
||||
//{
|
||||
// return make_segmented_iterator( segmented_end_impl( rng ) );
|
||||
//}
|
||||
|
||||
template<typename Range>
|
||||
struct segmented_end
|
||||
{
|
||||
typedef
|
||||
segmented_iterator<
|
||||
typename detail::segmented_end_impl<Range, fusion::nil>::type
|
||||
>
|
||||
type;
|
||||
|
||||
static type call(Range & rng)
|
||||
{
|
||||
return type(
|
||||
detail::segmented_end_impl<Range, fusion::nil>::call(rng, fusion::nil()));
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
436
include/boost/fusion/view/ext_/segmented_fold_until.hpp
Normal file
436
include/boost/fusion/view/ext_/segmented_fold_until.hpp
Normal file
@ -0,0 +1,436 @@
|
||||
/*=============================================================================
|
||||
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/mpl/bool.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
|
||||
#include <boost/fusion/support/void.hpp>
|
||||
#include <boost/fusion/container/list/cons.hpp>
|
||||
#include <boost/fusion/container/generation/make_cons.hpp>
|
||||
#include <boost/fusion/view/iterator_range.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/begin.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/empty.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/end.hpp>
|
||||
#include <boost/fusion/iterator/value_of.hpp>
|
||||
#include <boost/fusion/iterator/equal_to.hpp>
|
||||
#include <boost/fusion/iterator/next.hpp>
|
||||
#include <boost/fusion/support/ext_/is_segmented.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/ext_/segments.hpp>
|
||||
|
||||
// fun(rng, state, context)
|
||||
// rng: 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 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 result_of::deref<
|
||||
typename Context::car_type::begin_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(fusion::make_cons(range_type(cur, fusion::end(*context.car.first)), context));
|
||||
}
|
||||
|
||||
typedef mpl::true_ continue_;
|
||||
typedef mpl::false_ break_;
|
||||
|
||||
template<typename Value, typename Continue>
|
||||
struct result
|
||||
{
|
||||
typedef Value value_type;
|
||||
typedef Continue continue_type;
|
||||
|
||||
result(Value const& val)
|
||||
: value(val)
|
||||
{}
|
||||
|
||||
value_type value;
|
||||
};
|
||||
|
||||
template<typename Continue>
|
||||
struct result<void, Continue>
|
||||
{
|
||||
typedef void_ value_type;
|
||||
typedef Continue continue_type;
|
||||
|
||||
result(void_ const&)
|
||||
{}
|
||||
|
||||
value_type value;
|
||||
};
|
||||
|
||||
template<typename Value>
|
||||
result<Value, continue_> make_result_continue(Value const& val)
|
||||
{
|
||||
return result<Value, continue_>(val);
|
||||
}
|
||||
|
||||
template<typename Value>
|
||||
result<Value, break_> make_result_break(Value const& val)
|
||||
{
|
||||
return result<Value, break_>(val);
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<
|
||||
typename Begin,
|
||||
typename End,
|
||||
typename State,
|
||||
typename Context,
|
||||
typename Fun,
|
||||
bool IsEmpty = result_of::empty<
|
||||
typename result_of::value_of<Begin>::type
|
||||
>::type::value>
|
||||
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 Range,
|
||||
typename State,
|
||||
typename Context,
|
||||
typename Fun,
|
||||
bool IsSegmented = traits::is_segmented<Range>::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 fusion::make_cons(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(rng, state, context, fun)
|
||||
//{
|
||||
// if (is_segmented(rng))
|
||||
// {
|
||||
// segmented_fold_until_on_segments(segments(rng), state, context, fun);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return fun(rng, state, context);
|
||||
// }
|
||||
//}
|
||||
|
||||
template<
|
||||
typename Range,
|
||||
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<Range>::type
|
||||
>::type
|
||||
>::type,
|
||||
State,
|
||||
Context,
|
||||
Fun
|
||||
>
|
||||
impl;
|
||||
|
||||
typedef typename impl::type type;
|
||||
|
||||
static type call(Range& rng, State const& state, Context const& context, Fun const& fun)
|
||||
{
|
||||
return impl::call(fusion::segments(rng), state, context, fun);
|
||||
}
|
||||
};
|
||||
|
||||
template<
|
||||
typename Range,
|
||||
typename State,
|
||||
typename Context,
|
||||
typename Fun>
|
||||
struct segmented_fold_until_impl<Range, State, Context, Fun, false>
|
||||
{
|
||||
typedef
|
||||
typename boost::result_of<Fun(Range&, State const&, Context const&)>::type
|
||||
type;
|
||||
|
||||
static type call(Range& rng, State const& state, Context const& context, Fun const& fun)
|
||||
{
|
||||
return fun(rng, state, context);
|
||||
}
|
||||
};
|
||||
|
||||
//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 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 next_state_type::continue_type,
|
||||
next_iteration_impl,
|
||||
mpl::identity<next_state_type>
|
||||
>::type
|
||||
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 next_state_type::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;
|
||||
|
||||
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
|
||||
segmented_fold_until_iterate_skip_empty<Begin, End, State, Context, Fun>
|
||||
impl;
|
||||
|
||||
typedef typename impl::type 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;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//auto segmented_fold_until(rng, state, fun)
|
||||
//{
|
||||
// return first(segmented_fold_until_impl(rng, state, nil, fun));
|
||||
//}
|
||||
|
||||
namespace result_of
|
||||
{
|
||||
template<typename Range, typename State, typename Fun>
|
||||
struct segmented_fold_until
|
||||
{
|
||||
typedef
|
||||
detail::segmented_fold_until_impl<
|
||||
Range,
|
||||
result<State, continue_>,
|
||||
fusion::nil,
|
||||
Fun
|
||||
>
|
||||
impl;
|
||||
|
||||
typedef
|
||||
typename impl::type::value_type
|
||||
type;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Range, typename State, typename Fun>
|
||||
typename result_of::segmented_fold_until<Range, State, Fun>::type
|
||||
segmented_fold_until(Range& rng, State const& state, Fun const& fun)
|
||||
{
|
||||
typedef typename result_of::segmented_fold_until<Range, State, Fun>::impl impl;
|
||||
return impl::call(rng, state, fusion::nil(), fun).value;
|
||||
}
|
||||
|
||||
template<typename Range, typename State, typename Fun>
|
||||
typename result_of::segmented_fold_until<Range const, State, Fun>::type
|
||||
segmented_fold_until(Range const& rng, State const& state, Fun const& fun)
|
||||
{
|
||||
typedef typename result_of::segmented_fold_until<Range const, State, Fun>::impl impl;
|
||||
return impl::call(rng, state, fusion::nil(), fun).value;
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
@ -1,448 +1,42 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2006 Eric Niebler
|
||||
Copyright (c) 2011 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)
|
||||
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_SEGMENTED_ITERATOR_EAN_05032006_1027
|
||||
#define FUSION_SEGMENTED_ITERATOR_EAN_05032006_1027
|
||||
#if !defined(BOOST_FUSION_SEGMENTED_ITERATOR_HPP_INCLUDED)
|
||||
#define BOOST_FUSION_SEGMENTED_ITERATOR_HPP_INCLUDED
|
||||
|
||||
#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>
|
||||
#include <boost/fusion/support/category_of.hpp>
|
||||
#include <boost/fusion/support/iterator_base.hpp>
|
||||
#include <boost/fusion/view/ext_/detail/next_impl.hpp>
|
||||
#include <boost/fusion/view/ext_/detail/deref_impl.hpp>
|
||||
#include <boost/fusion/view/ext_/detail/equal_to_impl.hpp>
|
||||
#include <boost/fusion/view/ext_/segmented_begin.hpp>
|
||||
#include <boost/fusion/view/ext_/segmented_end.hpp>
|
||||
|
||||
namespace boost { namespace fusion
|
||||
{
|
||||
struct fusion_sequence_tag;
|
||||
struct segmented_iterator_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>
|
||||
// A segmented iterator is a stack of segment nodes.
|
||||
// Note: push_front/pop_front create views. That should
|
||||
// be good enough.
|
||||
template<typename Nodes>
|
||||
struct segmented_iterator
|
||||
: fusion::iterator_base<segmented_iterator<Cons> >
|
||||
: fusion::iterator_base<segmented_iterator<Nodes> >
|
||||
{
|
||||
typedef forward_traversal_tag category;
|
||||
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)
|
||||
explicit segmented_iterator(Nodes const &ns)
|
||||
: nodes(ns)
|
||||
{}
|
||||
|
||||
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_;
|
||||
typedef Nodes nodes_type;
|
||||
nodes_type nodes;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
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
|
||||
|
954
include/boost/fusion/view/ext_/segmented_iterator_range.hpp
Executable file → Normal file
954
include/boost/fusion/view/ext_/segmented_iterator_range.hpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -15,6 +15,7 @@
|
||||
#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/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/adapted/mpl/mpl_iterator.hpp>
|
||||
#include <boost/config.hpp>
|
||||
@ -36,7 +37,6 @@ namespace boost { namespace fusion
|
||||
typedef typename convert_iterator<Last>::type end_type;
|
||||
typedef iterator_range_tag fusion_tag;
|
||||
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 typename traits::category_of<begin_type>::type category;
|
||||
|
@ -157,9 +157,15 @@ import testing ;
|
||||
run algorithm/ext_/for_each_s.cpp ;
|
||||
explicit for_each_s ;
|
||||
|
||||
run algorithm/ext_/find_s.cpp ;
|
||||
explicit find_s ;
|
||||
|
||||
run algorithm/ext_/find_if_s.cpp ;
|
||||
explicit find_if_s ;
|
||||
|
||||
run algorithm/ext_/fold_s.cpp ;
|
||||
explicit fold_s ;
|
||||
|
||||
run sequence/ext_/iterator_range_s.cpp ;
|
||||
explicit iterator_range_s ;
|
||||
}
|
||||
|
55
test/algorithm/ext_/find_if_s.cpp
Executable file → Normal file
55
test/algorithm/ext_/find_if_s.cpp
Executable file → Normal file
@ -1,29 +1,18 @@
|
||||
/*=============================================================================
|
||||
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/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/mpl/placeholders.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
struct X
|
||||
{
|
||||
operator int() const
|
||||
{
|
||||
return 12345;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Tree>
|
||||
void
|
||||
process_tree(Tree const &tree)
|
||||
@ -48,45 +37,6 @@ 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')
|
||||
@ -102,7 +52,6 @@ main()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
55
test/algorithm/ext_/find_s.cpp
Normal file
55
test/algorithm/ext_/find_s.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
/*=============================================================================
|
||||
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/ext_/find_s.hpp>
|
||||
#include <boost/fusion/container/ext_/tree.hpp>
|
||||
#include <boost/fusion/container/generation/make_vector.hpp>
|
||||
|
||||
template<typename Tree>
|
||||
void
|
||||
process_tree(Tree const &tree)
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
typedef typename fusion::result_of::find_s<Tree const, short>::type short_iter;
|
||||
typedef typename fusion::result_of::find_s<Tree const, float>::type float_iter;
|
||||
|
||||
// find_if_s of a segmented data structure returns generic
|
||||
// segmented iterators
|
||||
short_iter si = fusion::find_s<short>(tree);
|
||||
float_iter fi = fusion::find_s<float>(tree);
|
||||
|
||||
// they behave like ordinary Fusion iterators ...
|
||||
BOOST_TEST((*si == short('d')));
|
||||
BOOST_TEST((*fi == float(1)));
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
62
test/algorithm/ext_/fold_s.cpp
Normal file
62
test/algorithm/ext_/fold_s.cpp
Normal 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 <sstream>
|
||||
#include <iostream>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/fusion/container/vector/vector.hpp>
|
||||
#include <boost/fusion/algorithm/iteration/ext_/fold_s.hpp>
|
||||
#include <boost/fusion/container/ext_/tree.hpp>
|
||||
#include <boost/fusion/container/generation/make_vector.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_s(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();
|
||||
}
|
||||
|
39
test/algorithm/ext_/for_each_s.cpp
Executable file → Normal file
39
test/algorithm/ext_/for_each_s.cpp
Executable file → Normal file
@ -1,15 +1,13 @@
|
||||
/*=============================================================================
|
||||
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
|
||||
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/iteration/ext_/for_each_s.hpp>
|
||||
#include <boost/mpl/vector_c.hpp>
|
||||
#include <boost/fusion/container/generation/make_vector.hpp>
|
||||
#include <boost/fusion/container/ext_/tree.hpp>
|
||||
|
||||
@ -22,44 +20,13 @@ struct print
|
||||
}
|
||||
};
|
||||
|
||||
struct increment
|
||||
{
|
||||
template <typename T>
|
||||
void operator()(T& v) const
|
||||
{
|
||||
++v;
|
||||
}
|
||||
};
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
using namespace boost::fusion;
|
||||
using boost::mpl::vector_c;
|
||||
namespace fusion = boost::fusion;
|
||||
|
||||
{
|
||||
typedef vector<int, char, double, char const*> vector_type;
|
||||
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(
|
||||
for_each_s(
|
||||
make_tree(
|
||||
make_vector(double(0),'B')
|
||||
, make_tree(
|
||||
|
1
test/sequence/ext_/iterator_range_s.cpp
Executable file → Normal file
1
test/sequence/ext_/iterator_range_s.cpp
Executable file → Normal file
@ -1,5 +1,6 @@
|
||||
/*=============================================================================
|
||||
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)
|
||||
|
Reference in New Issue
Block a user