diff options
Diffstat (limited to 'boost/geometry/iterators')
-rw-r--r-- | boost/geometry/iterators/closing_iterator.hpp | 20 | ||||
-rw-r--r-- | boost/geometry/iterators/concatenate_iterator.hpp | 30 | ||||
-rw-r--r-- | boost/geometry/iterators/detail/segment_iterator/range_segment_iterator.hpp | 52 | ||||
-rw-r--r-- | boost/geometry/iterators/ever_circling_iterator.hpp | 9 | ||||
-rw-r--r-- | boost/geometry/iterators/flatten_iterator.hpp | 43 | ||||
-rw-r--r-- | boost/geometry/iterators/point_iterator.hpp | 24 | ||||
-rw-r--r-- | boost/geometry/iterators/point_reverse_iterator.hpp | 17 | ||||
-rw-r--r-- | boost/geometry/iterators/segment_iterator.hpp | 36 |
8 files changed, 84 insertions, 147 deletions
diff --git a/boost/geometry/iterators/closing_iterator.hpp b/boost/geometry/iterators/closing_iterator.hpp index a9f67d4788..e263f3aafb 100644 --- a/boost/geometry/iterators/closing_iterator.hpp +++ b/boost/geometry/iterators/closing_iterator.hpp @@ -42,12 +42,14 @@ struct closing_iterator boost::random_access_traversal_tag > { + typedef typename boost::range_difference<Range>::type difference_type; + /// Constructor including the range it is based on explicit inline closing_iterator(Range& range) : m_range(&range) , m_iterator(boost::begin(range)) , m_end(boost::end(range)) - , m_size(boost::size(range)) + , m_size(static_cast<difference_type>(boost::size(range))) , m_index(0) {} @@ -56,8 +58,8 @@ struct closing_iterator : m_range(&range) , m_iterator(boost::end(range)) , m_end(boost::end(range)) - , m_size(boost::size(range)) - , m_index(m_size + 1) + , m_size(static_cast<difference_type>(boost::size(range))) + , m_index((m_size == 0) ? 0 : m_size + 1) {} /// Default constructor @@ -67,18 +69,6 @@ struct closing_iterator , m_index(0) {} - inline closing_iterator<Range>& operator=(closing_iterator<Range> const& source) - { - m_range = source.m_range; - m_iterator = source.m_iterator; - m_end = source.m_end; - m_size = source.m_size; - m_index = source.m_index; - return *this; - } - - typedef std::ptrdiff_t difference_type; - private: friend class boost::iterator_core_access; diff --git a/boost/geometry/iterators/concatenate_iterator.hpp b/boost/geometry/iterators/concatenate_iterator.hpp index 20112b4c4c..5c4ae0af1e 100644 --- a/boost/geometry/iterators/concatenate_iterator.hpp +++ b/boost/geometry/iterators/concatenate_iterator.hpp @@ -89,36 +89,6 @@ public: (types<OtherIt1, OtherIt2>)); } - template - < - typename OtherIt1, - typename OtherIt2, - typename OtherValue, - typename OtherReference - > - concatenate_iterator operator=(concatenate_iterator - < - OtherIt1, - OtherIt2, - OtherValue, - OtherReference - > const& other) - { - static const bool are_conv - = boost::is_convertible<OtherIt1, Iterator1>::value - && boost::is_convertible<OtherIt2, Iterator2>::value; - - BOOST_MPL_ASSERT_MSG((are_conv), - NOT_CONVERTIBLE, - (types<OtherIt1, OtherIt2>)); - - m_it1 = other.m_it1; - m_end1 = other.m_end1; - m_begin2 = other.m_begin2; - m_it2 = other.m_it2; - return *this; - } - private: friend class boost::iterator_core_access; diff --git a/boost/geometry/iterators/detail/segment_iterator/range_segment_iterator.hpp b/boost/geometry/iterators/detail/segment_iterator/range_segment_iterator.hpp index d79fda84d9..e65b12b459 100644 --- a/boost/geometry/iterators/detail/segment_iterator/range_segment_iterator.hpp +++ b/boost/geometry/iterators/detail/segment_iterator/range_segment_iterator.hpp @@ -100,23 +100,36 @@ class range_segment_iterator Reference > { + static inline bool has_less_than_two_elements(Range const& r) + { + return boost::size(r) < ((closure<Range>::value == open) ? 1u : 2u); + } + public: typedef typename range_iterator_type<Range>::type iterator_type; // default constructor range_segment_iterator() - : m_it() + : m_it(), m_has_less_than_two_elements(false) {} // for begin range_segment_iterator(Range& r) : m_it(range_iterator_begin<Range>::apply(r)) + , m_has_less_than_two_elements(has_less_than_two_elements(r)) {} // for end range_segment_iterator(Range& r, bool) - : m_it(--range_iterator_end<Range>::apply(r)) - {} + : m_it(range_iterator_end<Range>::apply(r)) + , m_has_less_than_two_elements(has_less_than_two_elements(r)) + { + if (! m_has_less_than_two_elements) + { + // the range consists of at least two items + --m_it; + } + } template < @@ -143,33 +156,6 @@ public: BOOST_MPL_ASSERT_MSG((are_conv), NOT_CONVERTIBLE, (types<OtherRange>)); } - template - < - typename OtherRange, - typename OtherValue, - typename OtherReference - > - range_segment_iterator operator=(range_segment_iterator - < - OtherRange, - OtherValue, - OtherReference - > const& other) - { - typedef typename range_segment_iterator - < - OtherRange, OtherValue, OtherReference - >::iterator_type other_iterator_type; - - static const bool are_conv - = boost::is_convertible<other_iterator_type, iterator_type>::value; - - BOOST_MPL_ASSERT_MSG((are_conv), NOT_CONVERTIBLE, (types<OtherRange>)); - - m_it = other.m_it; - return *this; - } - private: friend class boost::iterator_core_access; @@ -178,6 +164,11 @@ private: inline Reference dereference() const { + if (m_has_less_than_two_elements) + { + return Reference(*m_it, *m_it); + } + iterator_type next(m_it); ++next; return Reference(*m_it, *next); @@ -211,6 +202,7 @@ private: private: iterator_type m_it; + bool m_has_less_than_two_elements; }; diff --git a/boost/geometry/iterators/ever_circling_iterator.hpp b/boost/geometry/iterators/ever_circling_iterator.hpp index 50b20480cd..cfb588b79f 100644 --- a/boost/geometry/iterators/ever_circling_iterator.hpp +++ b/boost/geometry/iterators/ever_circling_iterator.hpp @@ -119,15 +119,6 @@ struct ever_circling_range_iterator , m_index(0) {} - inline ever_circling_range_iterator<Range>& operator=(ever_circling_range_iterator<Range> const& source) - { - m_range = source.m_range; - m_iterator = source.m_iterator; - m_size = source.m_size; - m_index = source.m_index; - return *this; - } - typedef std::ptrdiff_t difference_type; private: diff --git a/boost/geometry/iterators/flatten_iterator.hpp b/boost/geometry/iterators/flatten_iterator.hpp index 078079dc2c..07450afbea 100644 --- a/boost/geometry/iterators/flatten_iterator.hpp +++ b/boost/geometry/iterators/flatten_iterator.hpp @@ -107,42 +107,15 @@ public: (types<OtherOuterIterator, OtherInnerIterator>)); } - template - < - typename OtherOuterIterator, - typename OtherInnerIterator, - typename OtherValue, - typename OtherAccessInnerBegin, - typename OtherAccessInnerEnd, - typename OtherReference - > - flatten_iterator operator=(flatten_iterator - < - OtherOuterIterator, - OtherInnerIterator, - OtherValue, - OtherAccessInnerBegin, - OtherAccessInnerEnd, - OtherReference - > const& other) + flatten_iterator& operator=(flatten_iterator const& other) { - static const bool are_conv - = boost::is_convertible - < - OtherOuterIterator, OuterIterator - >::value - && boost::is_convertible - < - OtherInnerIterator, InnerIterator - >::value; - - BOOST_MPL_ASSERT_MSG((are_conv), - NOT_CONVERTIBLE, - (types<OtherOuterIterator, OtherInnerIterator>)); - m_outer_it = other.m_outer_it; m_outer_end = other.m_outer_end; - m_inner_it = other.m_inner_it; + // avoid assigning an iterator having singular value + if ( other.m_outer_it != other.m_outer_end ) + { + m_inner_it = other.m_inner_it; + } return *this; } @@ -162,8 +135,8 @@ private: static inline bool empty(OuterIterator outer_it) { - return - AccessInnerBegin::apply(*outer_it) == AccessInnerEnd::apply(*outer_it); + return AccessInnerBegin::apply(*outer_it) + == AccessInnerEnd::apply(*outer_it); } inline void advance_through_empty() diff --git a/boost/geometry/iterators/point_iterator.hpp b/boost/geometry/iterators/point_iterator.hpp index 075339aa58..5971cfcef0 100644 --- a/boost/geometry/iterators/point_iterator.hpp +++ b/boost/geometry/iterators/point_iterator.hpp @@ -11,6 +11,7 @@ #define BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP #include <boost/assert.hpp> +#include <boost/iterator/iterator_adaptor.hpp> #include <boost/mpl/assert.hpp> #include <boost/type_traits/is_convertible.hpp> #include <boost/range.hpp> @@ -245,33 +246,26 @@ struct points_end<MultiPolygon, multi_polygon_tag> // MK:: need to add doc here template <typename Geometry> class point_iterator - : public detail::point_iterator::iterator_type<Geometry>::type + : public boost::iterator_adaptor + < + point_iterator<Geometry>, + typename detail::point_iterator::iterator_type<Geometry>::type + > { private: - typedef typename detail::point_iterator::iterator_type<Geometry>::type base; - - inline base* base_ptr() - { - return this; - } - - inline base const* base_ptr() const - { - return this; - } - template <typename OtherGeometry> friend class point_iterator; template <typename G> friend inline point_iterator<G> points_begin(G&); template <typename G> friend inline point_iterator<G> points_end(G&); - inline point_iterator(base const& base_it) : base(base_it) {} + inline point_iterator(typename point_iterator::base_type const& base_it) + : point_iterator::iterator_adaptor_(base_it) {} public: inline point_iterator() {} template <typename OtherGeometry> inline point_iterator(point_iterator<OtherGeometry> const& other) - : base(*other.base_ptr()) + : point_iterator::iterator_adaptor_(other.base()) { static const bool is_conv = boost::is_convertible< diff --git a/boost/geometry/iterators/point_reverse_iterator.hpp b/boost/geometry/iterators/point_reverse_iterator.hpp index 1c2ac0169d..b464c5f22a 100644 --- a/boost/geometry/iterators/point_reverse_iterator.hpp +++ b/boost/geometry/iterators/point_reverse_iterator.hpp @@ -27,17 +27,7 @@ class point_reverse_iterator : public std::reverse_iterator<point_iterator<Geometry> > { private: - typedef std::reverse_iterator<point_iterator<Geometry> > base; - - inline base* base_ptr() - { - return this; - } - - inline base const* base_ptr() const - { - return this; - } + typedef std::reverse_iterator<point_iterator<Geometry> > base_type; template <typename OtherGeometry> friend class point_reverse_iterator; template <typename G> @@ -46,7 +36,8 @@ private: template <typename G> friend inline point_reverse_iterator<G> points_rend(G&); - inline point_reverse_iterator(base const& base_it) : base(base_it) {} + inline point_reverse_iterator(base_type const& base_it) + : base_type(base_it) {} public: inline point_reverse_iterator() {} @@ -54,7 +45,7 @@ public: template <typename OtherGeometry> inline point_reverse_iterator(point_reverse_iterator<OtherGeometry> const& other) - : base(*other.base_ptr()) + : base_type(other.base()) { static const bool is_conv = boost::is_convertible < diff --git a/boost/geometry/iterators/segment_iterator.hpp b/boost/geometry/iterators/segment_iterator.hpp index 206d7fc503..71aff39c43 100644 --- a/boost/geometry/iterators/segment_iterator.hpp +++ b/boost/geometry/iterators/segment_iterator.hpp @@ -272,6 +272,16 @@ private: inline segment_iterator(base const& base_it) : base(base_it) {} public: + // The following typedef is needed for this iterator to be + // bidirectional. + // Normally we would not have to define this. However, due to the + // fact that the value type of the iterator is not a reference, + // the iterator_facade framework (used to define the base class of + // this iterator) degrades automatically the iterator's category + // to input iterator. With the following typedef we recover the + // correct iterator category. + typedef std::bidirectional_iterator_tag iterator_category; + inline segment_iterator() {} template <typename OtherGeometry> @@ -291,6 +301,32 @@ public: NOT_CONVERTIBLE, (segment_iterator<OtherGeometry>)); } + + inline segment_iterator& operator++() // prefix + { + base::operator++(); + return *this; + } + + inline segment_iterator& operator--() // prefix + { + base::operator--(); + return *this; + } + + inline segment_iterator operator++(int) // postfix + { + segment_iterator copy(*this); + base::operator++(); + return copy; + } + + inline segment_iterator operator--(int) // postfix + { + segment_iterator copy(*this); + base::operator--(); + return copy; + } }; |