Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r57622 - trunk/boost/fusion/view/ext_
From: eric_at_[hidden]
Date: 2009-11-12 21:52:35


Author: eric_niebler
Date: 2009-11-12 21:52:34 EST (Thu, 12 Nov 2009)
New Revision: 57622
URL: http://svn.boost.org/trac/boost/changeset/57622

Log:
avoid iterator invalidation in segmented_range, fixes #3583
Text files modified:
   trunk/boost/fusion/view/ext_/segmented_iterator.hpp | 56 +++++++++++++++++++++++++---------------
   1 files changed, 35 insertions(+), 21 deletions(-)

Modified: trunk/boost/fusion/view/ext_/segmented_iterator.hpp
==============================================================================
--- trunk/boost/fusion/view/ext_/segmented_iterator.hpp (original)
+++ trunk/boost/fusion/view/ext_/segmented_iterator.hpp 2009-11-12 21:52:34 EST (Thu, 12 Nov 2009)
@@ -9,8 +9,10 @@
 #define FUSION_SEGMENTED_ITERATOR_EAN_05032006_1027
 
 #include <boost/mpl/if.hpp>
+#include <boost/mpl/int.hpp>
 #include <boost/mpl/not.hpp>
 #include <boost/mpl/assert.hpp>
+#include <boost/mpl/next_prior.hpp>
 #include <boost/mpl/placeholders.hpp>
 #include <boost/type_traits/is_same.hpp>
 #include <boost/type_traits/is_reference.hpp>
@@ -20,6 +22,7 @@
 #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>
@@ -59,16 +62,15 @@
         struct segmented_range_tag;
 
         ////////////////////////////////////////////////////////////////////////////
- template<typename Sequence, typename Iterator, bool IsSegmented>
+ template<typename Sequence, typename Index, bool IsSegmented>
         struct segmented_range
- : sequence_base<segmented_range<Sequence, Iterator, IsSegmented> >
+ : 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;
- typedef Iterator iterator_type;
 
             // If this is a range of segments, skip over the empty ones
             typedef typename mpl::if_<
@@ -83,20 +85,34 @@
               , 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_))
- , where_(fusion::begin(sequence))
             {}
 
- segmented_range(sequence_type sequence_, iterator_type const &wh)
+ segmented_range(sequence_type sequence_, int)
               : 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;
- iterator_type where_;
+
+ private:
+ segmented_range &operator =(segmented_range const &);
         };
     }
 
@@ -148,7 +164,7 @@
                 typedef typename Sequence::iterator_type type;
                 static type call(Sequence &seq)
                 {
- return seq.where_;
+ return seq.where_();
                 }
             };
         };
@@ -176,15 +192,15 @@
         template<typename Range>
         struct range_next;
 
- template<typename Sequence, typename Iterator, bool IsSegmented>
- struct range_next<segmented_range<Sequence, Iterator, IsSegmented> >
+ template<typename Sequence, typename Index, bool IsSegmented>
+ struct range_next<segmented_range<Sequence, Index, IsSegmented> >
         {
- typedef typename result_of::next<Iterator>::type iterator_type;
- typedef segmented_range<Sequence, iterator_type, IsSegmented> type;
+ typedef typename mpl::next<Index>::type index_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 @@
         {
             typedef typename result_of::segments<Sequence>::type segments;
             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, begin, true> type;
+ typedef segmented_range<sequence, mpl::int_<0>, true> type;
 
             static type call(Sequence &seq)
             {
@@ -219,8 +234,7 @@
         struct as_segmented_range<Sequence, false>
         {
             typedef typename remove_reference<Sequence>::type sequence;
- typedef typename result_of::begin<sequence>::type begin;
- typedef segmented_range<sequence, begin, false> type;
+ typedef segmented_range<sequence, mpl::int_<0>, false> type;
 
             static type call(Sequence &seq)
             {
@@ -228,10 +242,10 @@
             }
         };
 
- template<typename Sequence, typename Iterator, bool IsSegmented>
- struct as_segmented_range<segmented_range<Sequence, Iterator, IsSegmented>, IsSegmented>
+ template<typename Sequence, typename Index, bool 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)
             {
                 return seq;


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk