summaryrefslogtreecommitdiff
path: root/boost/geometry/iterators
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/iterators')
-rw-r--r--boost/geometry/iterators/closing_iterator.hpp20
-rw-r--r--boost/geometry/iterators/concatenate_iterator.hpp30
-rw-r--r--boost/geometry/iterators/detail/segment_iterator/range_segment_iterator.hpp52
-rw-r--r--boost/geometry/iterators/ever_circling_iterator.hpp9
-rw-r--r--boost/geometry/iterators/flatten_iterator.hpp43
-rw-r--r--boost/geometry/iterators/point_iterator.hpp24
-rw-r--r--boost/geometry/iterators/point_reverse_iterator.hpp17
-rw-r--r--boost/geometry/iterators/segment_iterator.hpp36
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;
+ }
};