use iterator_facade to simplify implementation of segmented_iterator

[SVN r73770]
This commit is contained in:
Eric Niebler
2011-08-15 06:20:24 +00:00
parent a339669d05
commit 9ed1f3d606
6 changed files with 97 additions and 147 deletions

View File

@ -13,7 +13,10 @@
#include <boost/mpl/plus.hpp>
#include <boost/mpl/size_t.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/fusion/mpl.hpp>
#include <boost/fusion/mpl/begin.hpp>
#include <boost/fusion/mpl/end.hpp>
#include <boost/fusion/mpl/clear.hpp>
#include <boost/fusion/mpl/push_front.hpp>
#include <boost/fusion/sequence/intrinsic/size.hpp>
#include <boost/fusion/sequence/intrinsic/ext_/segments.hpp>
#include <boost/fusion/support/ext_/is_segmented.hpp>

View File

@ -1,47 +0,0 @@
/*=============================================================================
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

@ -1,51 +0,0 @@
/*=============================================================================
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

@ -17,8 +17,6 @@
namespace boost { namespace fusion
{
struct segmented_iterator_tag;
template<typename Nodes>
struct segmented_iterator;
@ -227,29 +225,6 @@ namespace boost { namespace fusion
}
};
}
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

@ -7,32 +7,83 @@
#if !defined(BOOST_FUSION_SEGMENTED_ITERATOR_HPP_INCLUDED)
#define BOOST_FUSION_SEGMENTED_ITERATOR_HPP_INCLUDED
#include <boost/fusion/support/category_of.hpp>
#include <boost/fusion/support/iterator_base.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/fusion/mpl/begin.hpp>
#include <boost/fusion/mpl/end.hpp>
#include <boost/fusion/mpl/clear.hpp>
#include <boost/fusion/mpl/push_front.hpp>
#include <boost/fusion/iterator/iterator_facade.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/iterator/deref.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/view/ext_/segmented_begin.hpp>
#include <boost/fusion/view/ext_/segmented_end.hpp>
#include <boost/fusion/container/vector/convert.hpp>
namespace boost { namespace fusion
{
struct segmented_iterator_tag {};
// 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<Nodes> >
: iterator_facade<segmented_iterator<Nodes>, forward_traversal_tag>
{
typedef forward_traversal_tag category;
typedef segmented_iterator_tag fusion_tag;
explicit segmented_iterator(Nodes const &ns)
: nodes(ns)
{}
//auto deref(it)
//{
// return deref(begin(car(it.nodes)))
//}
template<typename It>
struct deref
{
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;
}
};
// Compare all the segment iterators in each stack, starting with
// the bottom-most.
template<typename It1, typename It2>
struct equal_to
: 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>
>
{};
template<typename It>
struct next
{
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));
}
};
typedef Nodes nodes_type;
nodes_type nodes;
};

View File

@ -7,22 +7,20 @@
#if !defined(BOOST_FUSION_SEGMENTED_ITERATOR_RANGE_HPP_INCLUDED)
#define BOOST_FUSION_SEGMENTED_ITERATOR_RANGE_HPP_INCLUDED
#include <boost/mpl/and.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/fusion/support/tag_of.hpp>
#include <boost/fusion/include/begin.hpp>
#include <boost/fusion/include/end.hpp>
#include <boost/fusion/include/next.hpp>
#include <boost/fusion/include/deref.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/iterator/next.hpp>
#include <boost/fusion/iterator/deref.hpp>
#include <boost/fusion/sequence/intrinsic/ext_/segments.hpp>
#include <boost/fusion/sequence/intrinsic/ext_/size_s.hpp>
#include <boost/fusion/include/push_back.hpp>
#include <boost/fusion/include/push_front.hpp>
#include <boost/fusion/include/iterator_range.hpp>
#include <boost/fusion/include/equal_to.hpp>
#include <boost/fusion/algorithm/transformation/push_back.hpp>
#include <boost/fusion/algorithm/transformation/push_front.hpp>
#include <boost/fusion/view/iterator_range.hpp>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/fusion/view/ext_/segmented_iterator.hpp>
#include <boost/fusion/view/ext_/detail/reverse_cons.hpp>
#include <boost/fusion/view/ext_/detail/segment_sequence.hpp>
@ -35,6 +33,12 @@
// - The front of each range in the stack (besides the
// topmost) is the range above it
namespace boost { namespace fusion
{
template<typename Context>
struct segmented_iterator;
}}
namespace boost { namespace fusion { namespace detail
{
//auto make_segment_sequence_front(stack_begin)
@ -508,13 +512,28 @@ namespace boost { namespace fusion { namespace extension
template<>
struct is_segmented_impl<iterator_range_tag>
{
private:
template<typename Iterator>
struct is_segmented_iterator
: is_same<
segmented_iterator_tag,
typename traits::tag_of<Iterator>::type>
: mpl::false_
{};
template<typename Iterator>
struct is_segmented_iterator<Iterator &>
: is_segmented_iterator<Iterator>
{};
template<typename Iterator>
struct is_segmented_iterator<Iterator const>
: is_segmented_iterator<Iterator>
{};
template<typename Context>
struct is_segmented_iterator<segmented_iterator<Context> >
: mpl::true_
{};
public:
template<typename Sequence>
struct apply
: is_segmented_iterator<typename Sequence::begin_type>