new cleaner(?) implementation for segmented fusion

[SVN r73644]
This commit is contained in:
Eric Niebler
2011-08-11 04:14:50 +00:00
parent 00b2cfc52e
commit d9c5b32687
28 changed files with 2171 additions and 1496 deletions

View 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

View 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 Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/ ==============================================================================*/
#if !defined(FUSION_FOR_EACH_S_05022006_1027) #if !defined(BOOST_FUSION_FOR_EACH_S_HPP_INCLUDED)
#define FUSION_FOR_EACH_S_05022006_1027 #define BOOST_FUSION_FOR_EACH_S_HPP_INCLUDED
#include <boost/mpl/assert.hpp> #include <boost/fusion/support/void.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp> #include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/sequence/intrinsic/ext_/segments.hpp> #include <boost/fusion/view/ext_/segmented_fold_until.hpp>
#include <boost/fusion/support/ext_/is_segmented.hpp>
// fwd declarations
namespace boost { namespace fusion
{
template <typename Sequence, typename F>
void
for_each_s(Sequence& seq, F const& f);
template <typename Sequence, typename F>
void
for_each_s(Sequence const& seq, F const& f);
}}
namespace boost { namespace fusion { namespace detail namespace boost { namespace fusion { namespace detail
{ {
template<typename F> template<typename Fun>
struct for_each_s_bind struct segmented_for_each_fun
{ {
explicit for_each_s_bind(F const &f) typedef result<void, continue_> result_type;
: f_(f)
explicit segmented_for_each_fun(Fun const& f)
: fun(f)
{} {}
template<typename Sequence> template<typename Range, typename State, typename Context>
void operator ()(Sequence &seq) const 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> Fun const& fun;
void operator ()(Sequence const &seq) const
{
fusion::for_each_s(seq, this->f_);
}
private:
F const &f_;
}; };
template<typename Sequence, typename F>
void for_each_s(Sequence &seq, F const &f, mpl::true_)
{
fusion::for_each_s(fusion::segments(seq), for_each_s_bind<F>(f));
}
template<typename Sequence, typename F>
void for_each_s(Sequence &seq, F const &f, mpl::false_)
{
fusion::for_each(seq, f);
}
}}} }}}
namespace boost { namespace fusion namespace boost { namespace fusion
@ -77,14 +49,14 @@ namespace boost { namespace fusion
inline void inline void
for_each_s(Sequence& seq, F const& f) 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> template <typename Sequence, typename F>
inline void inline void
for_each_s(Sequence const& seq, F const& f) 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));
} }
}} }}

227
include/boost/fusion/algorithm/query/ext_/find_if_s.hpp Executable file → Normal file
View 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 Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/ ==============================================================================*/
#if !defined(FIND_IF_S_05152006_1027) #if !defined(BOOST_FUSION_FIND_IF_S_HPP_INCLUDED)
#define FIND_IF_S_05152006_1027 #define BOOST_FUSION_FIND_IF_S_HPP_INCLUDED
#include <boost/mpl/not.hpp> #include <boost/type_traits/remove_const.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/fusion/algorithm/query/find_if.hpp> #include <boost/fusion/algorithm/query/find_if.hpp>
#include <boost/fusion/container/list/cons.hpp> #include <boost/fusion/view/ext_/segmented_fold_until.hpp>
#include <boost/fusion/sequence/intrinsic/ext_/segments.hpp>
#include <boost/fusion/view/ext_/segmented_iterator.hpp>
#include <boost/fusion/view/ext_/segmented_iterator_range.hpp>
#include <boost/fusion/support/ext_/is_segmented.hpp>
// fwd declarations
namespace boost { namespace fusion
{
namespace detail
{
template<typename Sequence, typename Pred, bool IsSegmented = traits::is_segmented<Sequence>::value>
struct static_find_if_s_recurse;
}
namespace result_of
{
template <typename Sequence, typename Pred>
struct find_if_s;
}
}}
namespace boost { namespace fusion { namespace detail namespace boost { namespace fusion { namespace detail
{ {
template<typename Pred>
template<typename Sequence, typename Where, bool IsSegmented = traits::is_segmented<Sequence>::value> struct segmented_find_if_fun
struct is_found
: mpl::not_<result_of::equal_to<Where, typename result_of::end<Sequence>::type> >
{};
template<typename Sequence, typename Cons>
struct is_found<Sequence, Cons, true>
: mpl::not_<is_same<nil, Cons> >
{};
template<
typename SegmentedRange
, typename Where
, typename Sequence = typename remove_reference<
typename result_of::deref<
typename SegmentedRange::iterator_type
>::type
>::type
, bool IsSegmented = traits::is_segmented<Sequence>::value
>
struct as_segmented_cons
{ {
typedef cons< template<typename Sig>
SegmentedRange struct result;
, cons<segmented_range<Sequence, Where, false> >
> type;
static type call(SegmentedRange const &range, Where const &where) template<typename This, typename Range, typename State, typename Context>
struct result<This(Range&, State&, Context&)>
{ {
return fusion::make_cons( typedef
range typename result_of::find_if<Range, Pred>::type
, fusion::make_cons( iterator_type;
segmented_range<Sequence, Where, false>(*fusion::begin(range), where)
) 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_if_fun(Range&, State const&, Context const&)>::type
operator()(Range& rng, State const&, Context const& context) const
{
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 namespace boost { namespace fusion
@ -191,31 +61,22 @@ namespace boost { namespace fusion
{ {
template <typename Sequence, typename Pred> template <typename Sequence, typename Pred>
struct find_if_s struct find_if_s
{ : result_of::segmented_fold_until<Sequence, void_, detail::segmented_find_if_fun<Pred> >
typedef typename {};
detail::static_find_if_s<
Sequence
, Pred
>::type
type;
};
} }
template <typename Pred, typename Sequence> template <typename Pred, typename Sequence>
typename lazy_disable_if< typename result_of::find_if_s<Sequence, Pred>::type
is_const<Sequence>
, result_of::find_if_s<Sequence, Pred>
>::type
find_if_s(Sequence& seq) 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> template <typename Pred, typename Sequence>
typename result_of::find_if_s<Sequence const, Pred>::type typename result_of::find_if_s<Sequence const, Pred>::type
find_if_s(Sequence const& seq) 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>());
} }
}} }}

View 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
View File

@ -18,26 +18,18 @@
#include <boost/fusion/container/list/cons.hpp> // for nil #include <boost/fusion/container/list/cons.hpp> // for nil
#include <boost/fusion/container/vector/vector10.hpp> #include <boost/fusion/container/vector/vector10.hpp>
#include <boost/fusion/support/sequence_base.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_/segments.hpp>
#include <boost/fusion/sequence/intrinsic/ext_/size_s.hpp>
#include <boost/fusion/support/ext_/is_segmented.hpp> #include <boost/fusion/support/ext_/is_segmented.hpp>
#include <boost/fusion/view/ext_/segmented_iterator.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 namespace boost { namespace fusion
{ {
struct tree_tag; 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> template<typename Data, typename Left = nil, typename Right = nil>
struct tree struct tree
: sequence_base<tree<Data, Left, Right> > : sequence_base<tree<Data, Left, Right> >
@ -46,7 +38,7 @@ namespace boost { namespace fusion
typedef Left left_type; typedef Left left_type;
typedef Right right_type; typedef Right right_type;
typedef tree_tag fusion_tag; typedef tree_tag fusion_tag;
typedef forward_traversal_tag category; typedef bidirectional_traversal_tag category;
typedef mpl::false_ is_view; typedef mpl::false_ is_view;
typedef typename mpl::if_< typedef typename mpl::if_<
@ -124,6 +116,15 @@ namespace boost { namespace fusion
: segmented_end<Sequence> : segmented_end<Sequence>
{}; {};
}; };
template<>
struct size_impl<tree_tag>
{
template<typename Sequence>
struct apply
: segmented_size<Sequence>::type
{};
};
} }
}} }}

View File

@ -4,8 +4,8 @@
Distributed under the Boost Software License, Version 1.0. (See accompanying Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/ ==============================================================================*/
#if !defined(FUSION_SEGMENTS_04052005_1141) #if !defined(BOOST_FUSION_SEGMENTS_04052005_1141)
#define FUSION_SEGMENTS_04052005_1141 #define BOOST_FUSION_SEGMENTS_04052005_1141
#include <boost/fusion/support/tag_of.hpp> #include <boost/fusion/support/tag_of.hpp>
@ -27,9 +27,10 @@ namespace boost { namespace fusion
template <typename Sequence> template <typename Sequence>
struct segments struct segments
{ {
typedef typename traits::tag_of<Sequence>::type tag_type;
typedef typename typedef typename
extension::segments_impl<typename traits::tag_of<Sequence>::type>:: extension::segments_impl<tag_type>::template apply<Sequence>::type
template apply<Sequence>::type
type; type;
}; };
} }
@ -38,18 +39,16 @@ namespace boost { namespace fusion
typename result_of::segments<Sequence>::type typename result_of::segments<Sequence>::type
segments(Sequence & seq) segments(Sequence & seq)
{ {
return typedef typename traits::tag_of<Sequence>::type tag_type;
extension::segments_impl<typename traits::tag_of<Sequence>::type>:: return extension::segments_impl<tag_type>::template apply<Sequence>::call(seq);
template apply<Sequence>::call(seq);
} }
template <typename Sequence> template <typename Sequence>
typename result_of::segments<Sequence const>::type typename result_of::segments<Sequence const>::type
segments(Sequence const& seq) segments(Sequence const& seq)
{ {
return typedef typename traits::tag_of<Sequence const>::type tag_type;
extension::segments_impl<typename traits::tag_of<Sequence>::type>:: return extension::segments_impl<tag_type>::template apply<Sequence const>::call(seq);
template apply<Sequence const>::call(seq);
} }
}} }}

View File

@ -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 Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/ ==============================================================================*/
#if !defined(FUSION_SIZE_S_08112006_1141) #if !defined(BOOST_FUSION_SIZE_S_08112006_1141)
#define 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/plus.hpp>
#include <boost/mpl/size_t.hpp> #include <boost/mpl/size_t.hpp>
#include <boost/type_traits/remove_reference.hpp> #include <boost/mpl/placeholders.hpp>
#include <boost/fusion/algorithm/iteration/fold.hpp> #include <boost/fusion/mpl.hpp>
#include <boost/fusion/support/ext_/is_segmented.hpp> #include <boost/fusion/sequence/intrinsic/size.hpp>
#include <boost/fusion/sequence/intrinsic/ext_/segments.hpp> #include <boost/fusion/sequence/intrinsic/ext_/segments.hpp>
#include <boost/fusion/support/ext_/is_segmented.hpp>
namespace boost { namespace fusion namespace boost { namespace fusion
{ {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// calculates the size of any segmented data structure. // calculates the size of any segmented data structure.
template<typename Sequence, bool IsSegmented = traits::is_segmented<Sequence>::value> template<typename Sequence>
struct segmented_size; struct segmented_size;
namespace detail namespace detail
{ {
struct size_plus ///////////////////////////////////////////////////////////////////////////
{ template<typename Sequence, bool IsSegmented = traits::is_segmented<Sequence>::value>
template<typename Sig> struct segmented_size_impl
struct result; : mpl::fold<
typename remove_reference<
typename add_const<
typename result_of::segments<Sequence>::type
>::type
>::type,
mpl::size_t<0>,
mpl::plus<mpl::_1, segmented_size<mpl::_2> >
>::type
{};
template<typename This, typename State, typename Seq> template<typename Sequence>
struct result<This(State, Seq)> struct segmented_size_impl<Sequence, false>
: mpl::plus< : result_of::size<Sequence>::type
segmented_size<typename remove_reference<Seq>::type> {};
, typename remove_reference<State>::type
>
{};
};
} }
/////////////////////////////////////////////////////////////////////////// template<typename Sequence>
template<typename Sequence, bool IsSegmented>
struct segmented_size struct segmented_size
: result_of::fold< : detail::segmented_size_impl<Sequence>
typename result_of::segments<Sequence>::type
, mpl::size_t<0>
, detail::size_plus
>::type
{}; {};
template<typename Sequence>
struct segmented_size<Sequence, false>
: result_of::size<Sequence>
{};
}} }}
#endif #endif

View 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

View 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

View 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

View 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

View 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

View File

@ -0,0 +1,43 @@
/*=============================================================================
Copyright (c) 2011 Eric Niebler
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_FUSION_REVERSE_CONS_HPP_INCLUDED)
#define BOOST_FUSION_REVERSE_CONS_HPP_INCLUDED
#include <boost/fusion/container/list/cons.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

View 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

View File

@ -1,178 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2006 Eric Niebler
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#ifndef FUSION_MULTIPLE_VIEW_05052005_0335
#define FUSION_MULTIPLE_VIEW_05052005_0335
#include <boost/mpl/int.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/next.hpp>
#include <boost/fusion/support/detail/access.hpp>
#include <boost/fusion/support/sequence_base.hpp>
#include <boost/fusion/support/iterator_base.hpp>
#include <boost/fusion/support/detail/as_fusion_element.hpp>
namespace boost { namespace fusion
{
struct multiple_view_tag;
struct forward_traversal_tag;
struct fusion_sequence_tag;
template<typename Size, typename T>
struct multiple_view
: sequence_base<multiple_view<Size, T> >
{
typedef multiple_view_tag fusion_tag;
typedef fusion_sequence_tag tag; // this gets picked up by MPL
typedef forward_traversal_tag category;
typedef mpl::true_ is_view;
typedef mpl::int_<Size::value> size;
typedef T value_type;
multiple_view()
: val()
{}
explicit multiple_view(typename detail::call_param<T>::type val)
: val(val)
{}
value_type val;
};
template<typename Size, typename T>
inline multiple_view<Size, typename detail::as_fusion_element<T>::type>
make_multiple_view(T const& v)
{
return multiple_view<Size, typename detail::as_fusion_element<T>::type>(v);
}
struct multiple_view_iterator_tag;
struct forward_traversal_tag;
template<typename Index, typename MultipleView>
struct multiple_view_iterator
: iterator_base<multiple_view_iterator<Index, MultipleView> >
{
typedef multiple_view_iterator_tag fusion_tag;
typedef forward_traversal_tag category;
typedef typename MultipleView::value_type value_type;
typedef MultipleView multiple_view_type;
typedef Index index;
explicit multiple_view_iterator(multiple_view_type const &view_)
: view(view_)
{}
multiple_view_type view;
};
namespace extension
{
template <typename Tag>
struct next_impl;
template <>
struct next_impl<multiple_view_iterator_tag>
{
template <typename Iterator>
struct apply
{
typedef multiple_view_iterator<
typename mpl::next<typename Iterator::index>::type
, typename Iterator::multiple_view_type
> type;
static type
call(Iterator const &where)
{
return type(where.view);
}
};
};
template <typename Tag>
struct end_impl;
template <>
struct end_impl<multiple_view_tag>
{
template <typename Sequence>
struct apply
{
typedef multiple_view_iterator<
typename Sequence::size
, Sequence
> type;
static type
call(Sequence &seq)
{
return type(seq);
}
};
};
template <typename Tag>
struct deref_impl;
template <>
struct deref_impl<multiple_view_iterator_tag>
{
template <typename Iterator>
struct apply
{
typedef typename Iterator::value_type type;
static type
call(Iterator const& i)
{
return i.view.val;
}
};
};
template <typename Tag>
struct begin_impl;
template <>
struct begin_impl<multiple_view_tag>
{
template <typename Sequence>
struct apply
{
typedef multiple_view_iterator<
mpl::int_<0>
, Sequence
> type;
static type
call(Sequence &seq)
{
return type(seq);
}
};
};
template <typename Tag>
struct value_of_impl;
template <>
struct value_of_impl<multiple_view_iterator_tag>
{
template <typename Iterator>
struct apply
{
typedef typename Iterator::multiple_view_type multiple_view_type;
typedef typename multiple_view_type::value_type type;
};
};
}
}}
#endif

View File

@ -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

View File

@ -0,0 +1,41 @@
/*=============================================================================
Copyright (c) 2011 Eric Niebler
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_FUSION_SEGMENTED_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

View 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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,37 @@
/*=============================================================================
Copyright (c) 2011 Eric Niebler
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_FUSION_ITERATOR_RANGE_SIZE_IMPL_HPP_INCLUDED)
#define BOOST_FUSION_ITERATOR_RANGE_SIZE_IMPL_HPP_INCLUDED
#include <boost/fusion/iterator/distance.hpp>
namespace boost { namespace fusion
{
struct iterator_range_tag;
namespace extension
{
template <typename Tag>
struct size_impl;
template <>
struct size_impl<iterator_range_tag>
{
template <typename Seq>
struct apply
: result_of::distance<
typename Seq::begin_type,
typename Seq::end_type
>
{};
};
}
}}
#endif

View File

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

View File

@ -157,9 +157,15 @@ import testing ;
run algorithm/ext_/for_each_s.cpp ; run algorithm/ext_/for_each_s.cpp ;
explicit for_each_s ; explicit for_each_s ;
run algorithm/ext_/find_s.cpp ;
explicit find_s ;
run algorithm/ext_/find_if_s.cpp ; run algorithm/ext_/find_if_s.cpp ;
explicit find_if_s ; explicit find_if_s ;
run algorithm/ext_/fold_s.cpp ;
explicit fold_s ;
run sequence/ext_/iterator_range_s.cpp ; run sequence/ext_/iterator_range_s.cpp ;
explicit iterator_range_s ; explicit iterator_range_s ;
} }

83
test/algorithm/ext_/find_if_s.cpp Executable file → Normal file
View File

@ -1,29 +1,18 @@
/*============================================================================= /*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman Copyright (c) 2001-2006 Joel de Guzman
Copyright (c) 2011 Eric Niebler
Distributed under the Boost Software License, Version 1.0. (See accompanying Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/ ==============================================================================*/
#include <boost/detail/lightweight_test.hpp> #include <boost/detail/lightweight_test.hpp>
#include <boost/fusion/container/vector/vector.hpp> #include <boost/fusion/container/vector/vector.hpp>
#include <boost/fusion/adapted/mpl.hpp>
#include <boost/fusion/sequence/io/out.hpp>
#include <boost/fusion/algorithm/query/ext_/find_if_s.hpp> #include <boost/fusion/algorithm/query/ext_/find_if_s.hpp>
#include <boost/fusion/container/ext_/tree.hpp> #include <boost/fusion/container/ext_/tree.hpp>
#include <boost/fusion/container/generation/make_vector.hpp> #include <boost/fusion/container/generation/make_vector.hpp>
#include <boost/mpl/vector.hpp> #include <boost/mpl/placeholders.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/less.hpp>
#include <boost/type_traits/is_same.hpp> #include <boost/type_traits/is_same.hpp>
struct X
{
operator int() const
{
return 12345;
}
};
template<typename Tree> template<typename Tree>
void void
process_tree(Tree const &tree) process_tree(Tree const &tree)
@ -48,61 +37,21 @@ int
main() main()
{ {
using namespace boost::fusion; using namespace boost::fusion;
process_tree(
{ make_tree(
using boost::is_same; make_vector(double(0),'B')
using boost::mpl::_; , make_tree(
make_vector(1,2,long(3))
typedef vector<int, char, int, double> vector_type; , make_tree(make_vector('a','b','c'))
vector_type v(12345, 'x', 678910, 3.36); , make_tree(make_vector(short('d'),'e','f'))
std::cout << *find_if_s<is_same<_, char> >(v) << std::endl;
BOOST_TEST((*find_if_s<is_same<_, char> >(v) == 'x'));
std::cout << *find_if_s<is_same<_, int> >(v) << std::endl;
BOOST_TEST((*find_if_s<is_same<_, int> >(v) == 12345));
std::cout << *find_if_s<is_same<_, double> >(v) << std::endl;
BOOST_TEST((*find_if_s<is_same<_, double> >(v) == 3.36));
}
{
using boost::mpl::vector;
using boost::is_same;
using boost::mpl::_;
typedef vector<int, char, X, double> mpl_vec;
BOOST_TEST((*find_if_s<is_same<_, X> >(mpl_vec()) == 12345));
}
{
using boost::mpl::vector_c;
using boost::mpl::less;
using boost::mpl::int_;
using boost::is_same;
using boost::mpl::_;
typedef vector_c<int, 1, 2, 3, 4> mpl_vec;
BOOST_TEST((*find_if_s<less<_, int_<3> > >(mpl_vec()) == 1));
}
{
process_tree(
make_tree(
make_vector(double(0),'B')
, make_tree(
make_vector(1,2,long(3))
, make_tree(make_vector('a','b','c'))
, make_tree(make_vector(short('d'),'e','f'))
)
, make_tree(
make_vector(4,5,6)
, make_tree(make_vector(float(1),'h','i'))
, make_tree(make_vector('j','k','l'))
)
) )
); , 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(); return boost::report_errors();
} }

View 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();
}

View File

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

1
test/sequence/ext_/iterator_range_s.cpp Executable file → Normal file
View File

@ -1,5 +1,6 @@
/*============================================================================= /*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman Copyright (c) 2001-2006 Joel de Guzman
Copyright (c) 2011 Eric Niebler
Distributed under the Boost Software License, Version 1.0. (See accompanying Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)