File indexing completed on 2025-01-18 09:35:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef BOOST_GEOMETRY_ITERATORS_CLOSING_ITERATOR_HPP
0018 #define BOOST_GEOMETRY_ITERATORS_CLOSING_ITERATOR_HPP
0019
0020
0021 #include <boost/iterator/iterator_facade.hpp>
0022 #include <boost/iterator/iterator_categories.hpp>
0023 #include <boost/range/begin.hpp>
0024 #include <boost/range/end.hpp>
0025 #include <boost/range/difference_type.hpp>
0026 #include <boost/range/reference.hpp>
0027 #include <boost/range/value_type.hpp>
0028
0029 #include <boost/geometry/core/assert.hpp>
0030
0031
0032 namespace boost { namespace geometry
0033 {
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 template <typename Range>
0045 struct closing_iterator
0046 : public boost::iterator_facade
0047 <
0048 closing_iterator<Range>,
0049 typename boost::range_value<Range>::type const,
0050 boost::random_access_traversal_tag,
0051 typename boost::range_reference<Range const>::type,
0052 typename boost::range_difference<Range>::type
0053 >
0054 {
0055 private:
0056 typedef boost::iterator_facade
0057 <
0058 closing_iterator<Range>,
0059 typename boost::range_value<Range>::type const,
0060 boost::random_access_traversal_tag,
0061 typename boost::range_reference<Range const>::type,
0062 typename boost::range_difference<Range>::type
0063 > base_type;
0064
0065 public:
0066 typedef typename base_type::reference reference;
0067 typedef typename base_type::difference_type difference_type;
0068
0069
0070 explicit inline closing_iterator(Range const& range)
0071 : m_iterator(boost::begin(range))
0072 , m_begin(boost::begin(range))
0073 , m_end(boost::end(range))
0074 , m_size(m_end - m_begin)
0075 , m_index(0)
0076 {}
0077
0078
0079 explicit inline closing_iterator(Range const& range, bool)
0080 : m_iterator(boost::end(range))
0081 , m_begin(boost::begin(range))
0082 , m_end(boost::end(range))
0083 , m_size(m_end - m_begin)
0084 , m_index((m_size == 0) ? 0 : m_size + 1)
0085 {}
0086
0087
0088 inline closing_iterator()
0089 : m_size(0)
0090 , m_index(0)
0091 {}
0092
0093 template
0094 <
0095 typename OtherRange,
0096 std::enable_if_t
0097 <
0098 std::is_convertible
0099 <
0100 typename boost::range_iterator<OtherRange const>::type,
0101 typename boost::range_iterator<Range const>::type
0102 >::value,
0103 int
0104 > = 0
0105 >
0106 inline closing_iterator(closing_iterator<OtherRange> const& other)
0107 : m_iterator(other.m_iterator)
0108 , m_begin(other.m_begin)
0109 , m_end(other.m_end)
0110 , m_size(other.m_size)
0111 , m_index(other.m_index)
0112 {}
0113
0114 private:
0115 template <typename OtherRange> friend struct closing_iterator;
0116 friend class boost::iterator_core_access;
0117
0118 inline reference dereference() const
0119 {
0120 return *m_iterator;
0121 }
0122
0123 inline difference_type distance_to(closing_iterator<Range> const& other) const
0124 {
0125 return other.m_index - this->m_index;
0126 }
0127
0128 inline bool equal(closing_iterator<Range> const& other) const
0129 {
0130 BOOST_GEOMETRY_ASSERT(m_begin == other.m_begin && m_end == other.m_end);
0131 return this->m_index == other.m_index;
0132 }
0133
0134 inline void increment()
0135 {
0136 if (++m_index < m_size)
0137 {
0138 ++m_iterator;
0139 }
0140 else
0141 {
0142 update_iterator();
0143 }
0144 }
0145
0146 inline void decrement()
0147 {
0148 if (m_index-- < m_size)
0149 {
0150 --m_iterator;
0151 }
0152 else
0153 {
0154 update_iterator();
0155 }
0156 }
0157
0158 inline void advance(difference_type n)
0159 {
0160 if (m_index < m_size && m_index + n < m_size)
0161 {
0162 m_index += n;
0163 m_iterator += n;
0164 }
0165 else
0166 {
0167 m_index += n;
0168 update_iterator();
0169 }
0170 }
0171
0172 inline void update_iterator()
0173 {
0174 this->m_iterator = m_index <= m_size
0175 ? m_begin + (m_index % m_size)
0176 : m_end
0177 ;
0178 }
0179
0180 typename boost::range_iterator<Range const>::type m_iterator;
0181 typename boost::range_iterator<Range const>::type m_begin;
0182 typename boost::range_iterator<Range const>::type m_end;
0183 difference_type m_size;
0184 difference_type m_index;
0185 };
0186
0187
0188 }}
0189
0190
0191 #endif