forked from boostorg/fusion
avoid iterator invalidation in segmented_range, fixes #3583
[SVN r57622]
This commit is contained in:
@ -9,8 +9,10 @@
|
|||||||
#define FUSION_SEGMENTED_ITERATOR_EAN_05032006_1027
|
#define FUSION_SEGMENTED_ITERATOR_EAN_05032006_1027
|
||||||
|
|
||||||
#include <boost/mpl/if.hpp>
|
#include <boost/mpl/if.hpp>
|
||||||
|
#include <boost/mpl/int.hpp>
|
||||||
#include <boost/mpl/not.hpp>
|
#include <boost/mpl/not.hpp>
|
||||||
#include <boost/mpl/assert.hpp>
|
#include <boost/mpl/assert.hpp>
|
||||||
|
#include <boost/mpl/next_prior.hpp>
|
||||||
#include <boost/mpl/placeholders.hpp>
|
#include <boost/mpl/placeholders.hpp>
|
||||||
#include <boost/type_traits/is_same.hpp>
|
#include <boost/type_traits/is_same.hpp>
|
||||||
#include <boost/type_traits/is_reference.hpp>
|
#include <boost/type_traits/is_reference.hpp>
|
||||||
@ -20,6 +22,7 @@
|
|||||||
#include <boost/fusion/view/filter_view.hpp>
|
#include <boost/fusion/view/filter_view.hpp>
|
||||||
#include <boost/fusion/container/list/cons.hpp> // for nil
|
#include <boost/fusion/container/list/cons.hpp> // for nil
|
||||||
#include <boost/fusion/container/generation/make_cons.hpp>
|
#include <boost/fusion/container/generation/make_cons.hpp>
|
||||||
|
#include <boost/fusion/iterator/advance.hpp>
|
||||||
#include <boost/fusion/iterator/distance.hpp>
|
#include <boost/fusion/iterator/distance.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>
|
#include <boost/fusion/support/ext_/is_segmented.hpp>
|
||||||
@ -59,16 +62,15 @@ namespace boost { namespace fusion
|
|||||||
struct segmented_range_tag;
|
struct segmented_range_tag;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
template<typename Sequence, typename Iterator, bool IsSegmented>
|
template<typename Sequence, typename Index, bool IsSegmented>
|
||||||
struct segmented_range
|
struct segmented_range
|
||||||
: sequence_base<segmented_range<Sequence, Iterator, IsSegmented> >
|
: sequence_base<segmented_range<Sequence, Index, IsSegmented> >
|
||||||
{
|
{
|
||||||
BOOST_MPL_ASSERT_NOT((is_reference<Sequence>));
|
BOOST_MPL_ASSERT_NOT((is_reference<Sequence>));
|
||||||
typedef mpl::bool_<IsSegmented> is_segmented;
|
typedef mpl::bool_<IsSegmented> is_segmented;
|
||||||
typedef segmented_range_tag fusion_tag;
|
typedef segmented_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 mpl::true_ is_view;
|
typedef mpl::true_ is_view;
|
||||||
typedef Iterator iterator_type;
|
|
||||||
|
|
||||||
// If this is a range of segments, skip over the empty ones
|
// If this is a range of segments, skip over the empty ones
|
||||||
typedef typename mpl::if_<
|
typedef typename mpl::if_<
|
||||||
@ -83,20 +85,34 @@ namespace boost { namespace fusion
|
|||||||
, sequence_non_ref_type &
|
, sequence_non_ref_type &
|
||||||
>::type sequence_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;
|
typedef typename traits::category_of<sequence_non_ref_type>::type category;
|
||||||
|
|
||||||
explicit segmented_range(Sequence &sequence_)
|
explicit segmented_range(Sequence &sequence_)
|
||||||
: sequence(sequence_type(sequence_))
|
: sequence(sequence_type(sequence_))
|
||||||
, where_(fusion::begin(sequence))
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
segmented_range(sequence_type sequence_, iterator_type const &wh)
|
segmented_range(sequence_type sequence_, int)
|
||||||
: sequence(sequence_)
|
: sequence(sequence_)
|
||||||
, where_(wh)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
iterator_type where_() const
|
||||||
|
{
|
||||||
|
return fusion::advance<Index>(
|
||||||
|
fusion::begin(const_cast<sequence_non_ref_type &>(this->sequence))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
sequence_type sequence;
|
sequence_type sequence;
|
||||||
iterator_type where_;
|
|
||||||
|
private:
|
||||||
|
segmented_range &operator =(segmented_range const &);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +164,7 @@ namespace boost { namespace fusion
|
|||||||
typedef typename Sequence::iterator_type type;
|
typedef typename Sequence::iterator_type type;
|
||||||
static type call(Sequence &seq)
|
static type call(Sequence &seq)
|
||||||
{
|
{
|
||||||
return seq.where_;
|
return seq.where_();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -176,15 +192,15 @@ namespace boost { namespace fusion
|
|||||||
template<typename Range>
|
template<typename Range>
|
||||||
struct range_next;
|
struct range_next;
|
||||||
|
|
||||||
template<typename Sequence, typename Iterator, bool IsSegmented>
|
template<typename Sequence, typename Index, bool IsSegmented>
|
||||||
struct range_next<segmented_range<Sequence, Iterator, IsSegmented> >
|
struct range_next<segmented_range<Sequence, Index, IsSegmented> >
|
||||||
{
|
{
|
||||||
typedef typename result_of::next<Iterator>::type iterator_type;
|
typedef typename mpl::next<Index>::type index_type;
|
||||||
typedef segmented_range<Sequence, iterator_type, IsSegmented> type;
|
typedef segmented_range<Sequence, index_type, IsSegmented> type;
|
||||||
|
|
||||||
static type call(segmented_range<Sequence, Iterator, IsSegmented> const &rng)
|
static type call(segmented_range<Sequence, Index, IsSegmented> const &rng)
|
||||||
{
|
{
|
||||||
return type(rng.sequence, fusion::next(rng.where_));
|
return type(rng.sequence, 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -205,8 +221,7 @@ namespace boost { namespace fusion
|
|||||||
{
|
{
|
||||||
typedef typename result_of::segments<Sequence>::type segments;
|
typedef typename result_of::segments<Sequence>::type segments;
|
||||||
typedef typename remove_reference<segments>::type sequence;
|
typedef typename remove_reference<segments>::type sequence;
|
||||||
typedef typename result_of::begin<filter_view<sequence, not_is_empty_pred> >::type begin;
|
typedef segmented_range<sequence, mpl::int_<0>, true> type;
|
||||||
typedef segmented_range<sequence, begin, true> type;
|
|
||||||
|
|
||||||
static type call(Sequence &seq)
|
static type call(Sequence &seq)
|
||||||
{
|
{
|
||||||
@ -219,8 +234,7 @@ namespace boost { namespace fusion
|
|||||||
struct as_segmented_range<Sequence, false>
|
struct as_segmented_range<Sequence, false>
|
||||||
{
|
{
|
||||||
typedef typename remove_reference<Sequence>::type sequence;
|
typedef typename remove_reference<Sequence>::type sequence;
|
||||||
typedef typename result_of::begin<sequence>::type begin;
|
typedef segmented_range<sequence, mpl::int_<0>, false> type;
|
||||||
typedef segmented_range<sequence, begin, false> type;
|
|
||||||
|
|
||||||
static type call(Sequence &seq)
|
static type call(Sequence &seq)
|
||||||
{
|
{
|
||||||
@ -228,10 +242,10 @@ namespace boost { namespace fusion
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Sequence, typename Iterator, bool IsSegmented>
|
template<typename Sequence, typename Index, bool IsSegmented>
|
||||||
struct as_segmented_range<segmented_range<Sequence, Iterator, IsSegmented>, IsSegmented>
|
struct as_segmented_range<segmented_range<Sequence, Index, IsSegmented>, IsSegmented>
|
||||||
{
|
{
|
||||||
typedef segmented_range<Sequence, Iterator, IsSegmented> type;
|
typedef segmented_range<Sequence, Index, IsSegmented> type;
|
||||||
static type &call(type &seq)
|
static type &call(type &seq)
|
||||||
{
|
{
|
||||||
return seq;
|
return seq;
|
||||||
|
Reference in New Issue
Block a user