diff options
Diffstat (limited to 'boost/geometry/iterators/ever_circling_iterator.hpp')
-rw-r--r-- | boost/geometry/iterators/ever_circling_iterator.hpp | 126 |
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; }; |