summaryrefslogtreecommitdiff
path: root/boost/geometry/iterators/ever_circling_iterator.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/iterators/ever_circling_iterator.hpp')
-rw-r--r--boost/geometry/iterators/ever_circling_iterator.hpp126
1 files changed, 87 insertions, 39 deletions
diff --git a/boost/geometry/iterators/ever_circling_iterator.hpp b/boost/geometry/iterators/ever_circling_iterator.hpp
index 03921096e7..566669e26d 100644
--- a/boost/geometry/iterators/ever_circling_iterator.hpp
+++ b/boost/geometry/iterators/ever_circling_iterator.hpp
@@ -95,67 +95,115 @@ private:
bool m_skip_first;
};
-
-
template <typename Range>
-class ever_circling_range_iterator
- : public boost::iterator_adaptor
- <
- ever_circling_range_iterator<Range>,
- typename boost::range_iterator<Range>::type
- >
+struct ever_circling_range_iterator
+ : public boost::iterator_facade
+ <
+ ever_circling_range_iterator<Range>,
+ typename boost::range_value<Range>::type const,
+ boost::random_access_traversal_tag
+ >
{
-public :
- typedef typename boost::range_iterator<Range>::type iterator_type;
+ /// Constructor including the range it is based on
+ explicit inline ever_circling_range_iterator(Range& range)
+ : m_range(&range)
+ , m_iterator(boost::begin(range))
+ , m_size(boost::size(range))
+ , m_index(0)
+ {}
+
+ /// Default constructor
+ explicit inline ever_circling_range_iterator()
+ : m_range(NULL)
+ , m_size(0)
+ , 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;
+ }
- explicit inline ever_circling_range_iterator(Range& range,
- bool skip_first = false)
- : m_range(range)
- , m_skip_first(skip_first)
+ typedef std::ptrdiff_t difference_type;
+
+private:
+ friend class boost::iterator_core_access;
+
+ inline typename boost::range_value<Range>::type const& dereference() const
{
- this->base_reference() = boost::begin(m_range);
+ return *m_iterator;
}
- explicit inline ever_circling_range_iterator(Range& range, iterator_type start,
- bool skip_first = false)
- : m_range(range)
- , m_skip_first(skip_first)
+ inline difference_type distance_to(ever_circling_range_iterator<Range> const& other) const
{
- this->base_reference() = start;
+ return other.m_index - this->m_index;
}
- /// Navigate to a certain position, should be in [start .. end], if at end
- /// it will circle again.
- inline void moveto(iterator_type it)
+ inline bool equal(ever_circling_range_iterator<Range> const& other) const
{
- this->base_reference() = it;
- check_end();
+ return this->m_range == other.m_range
+ && this->m_index == other.m_index;
}
-private:
+ inline void increment()
+ {
+ ++m_index;
+ if (m_index >= 0 && m_index < m_size)
+ {
+ ++m_iterator;
+ }
+ else
+ {
+ update_iterator();
+ }
+ }
- friend class boost::iterator_core_access;
+ inline void decrement()
+ {
+ --m_index;
+ if (m_index >= 0 && m_index < m_size)
+ {
+ --m_iterator;
+ }
+ else
+ {
+ update_iterator();
+ }
+ }
- inline void increment(bool possibly_skip = true)
+ inline void advance(difference_type n)
{
- (this->base_reference())++;
- check_end(possibly_skip);
+ if (m_index >= 0 && m_index < m_size
+ && m_index + n >= 0 && m_index + n < m_size)
+ {
+ m_index += n;
+ m_iterator += n;
+ }
+ else
+ {
+ m_index += n;
+ update_iterator();
+ }
}
- inline void check_end(bool possibly_skip = true)
+ inline void update_iterator()
{
- if (this->base_reference() == boost::end(m_range))
+ while (m_index < 0)
{
- this->base_reference() = boost::begin(m_range);
- if (m_skip_first && possibly_skip)
- {
- increment(false);
- }
+ m_index += m_size;
}
+ m_index = m_index % m_size;
+ this->m_iterator = boost::begin(*m_range) + m_index;
}
- Range& m_range;
- bool m_skip_first;
+ Range* m_range;
+ typename boost::range_iterator<Range>::type m_iterator;
+ difference_type m_size;
+ difference_type m_index;
};