Chris@16
|
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
|
Chris@16
|
2
|
Chris@16
|
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
Chris@16
|
4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
Chris@16
|
5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
Chris@16
|
6
|
Chris@16
|
7 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
Chris@16
|
8 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
Chris@16
|
9
|
Chris@16
|
10 // Use, modification and distribution is subject to the Boost Software License,
|
Chris@16
|
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
12 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
13
|
Chris@16
|
14 #ifndef BOOST_GEOMETRY_ITERATORS_CLOSING_ITERATOR_HPP
|
Chris@16
|
15 #define BOOST_GEOMETRY_ITERATORS_CLOSING_ITERATOR_HPP
|
Chris@16
|
16
|
Chris@16
|
17 #include <boost/range.hpp>
|
Chris@16
|
18 #include <boost/iterator.hpp>
|
Chris@16
|
19 #include <boost/iterator/iterator_facade.hpp>
|
Chris@16
|
20 #include <boost/iterator/iterator_categories.hpp>
|
Chris@16
|
21
|
Chris@16
|
22
|
Chris@16
|
23
|
Chris@16
|
24 namespace boost { namespace geometry
|
Chris@16
|
25 {
|
Chris@16
|
26
|
Chris@16
|
27 /*!
|
Chris@16
|
28 \brief Iterator which iterates through a range, but adds first element at end of the range
|
Chris@16
|
29 \tparam Range range on which this class is based on
|
Chris@16
|
30 \ingroup iterators
|
Chris@16
|
31 \note Use with "closing_iterator<Range> or "closing_iterator<Range const>
|
Chris@16
|
32 to get non-const / const behaviour
|
Chris@16
|
33 \note This class is normally used from "closeable_view" if Close==true
|
Chris@16
|
34 */
|
Chris@16
|
35 template <typename Range>
|
Chris@16
|
36 struct closing_iterator
|
Chris@16
|
37 : public boost::iterator_facade
|
Chris@16
|
38 <
|
Chris@16
|
39 closing_iterator<Range>,
|
Chris@16
|
40 typename boost::range_value<Range>::type const,
|
Chris@16
|
41 boost::random_access_traversal_tag
|
Chris@16
|
42 >
|
Chris@16
|
43 {
|
Chris@16
|
44 /// Constructor including the range it is based on
|
Chris@16
|
45 explicit inline closing_iterator(Range& range)
|
Chris@16
|
46 : m_range(&range)
|
Chris@16
|
47 , m_iterator(boost::begin(range))
|
Chris@16
|
48 , m_end(boost::end(range))
|
Chris@16
|
49 , m_size(boost::size(range))
|
Chris@16
|
50 , m_index(0)
|
Chris@16
|
51 {}
|
Chris@16
|
52
|
Chris@16
|
53 /// Constructor to indicate the end of a range
|
Chris@16
|
54 explicit inline closing_iterator(Range& range, bool)
|
Chris@16
|
55 : m_range(&range)
|
Chris@16
|
56 , m_iterator(boost::end(range))
|
Chris@16
|
57 , m_end(boost::end(range))
|
Chris@16
|
58 , m_size(boost::size(range))
|
Chris@16
|
59 , m_index(m_size + 1)
|
Chris@16
|
60 {}
|
Chris@16
|
61
|
Chris@16
|
62 /// Default constructor
|
Chris@16
|
63 explicit inline closing_iterator()
|
Chris@16
|
64 : m_range(NULL)
|
Chris@16
|
65 , m_size(0)
|
Chris@16
|
66 , m_index(0)
|
Chris@16
|
67 {}
|
Chris@16
|
68
|
Chris@16
|
69 inline closing_iterator<Range>& operator=(closing_iterator<Range> const& source)
|
Chris@16
|
70 {
|
Chris@16
|
71 m_range = source.m_range;
|
Chris@16
|
72 m_iterator = source.m_iterator;
|
Chris@16
|
73 m_end = source.m_end;
|
Chris@16
|
74 m_size = source.m_size;
|
Chris@16
|
75 m_index = source.m_index;
|
Chris@16
|
76 return *this;
|
Chris@16
|
77 }
|
Chris@16
|
78
|
Chris@16
|
79 typedef std::ptrdiff_t difference_type;
|
Chris@16
|
80
|
Chris@16
|
81 private:
|
Chris@16
|
82 friend class boost::iterator_core_access;
|
Chris@16
|
83
|
Chris@16
|
84 inline typename boost::range_value<Range>::type const& dereference() const
|
Chris@16
|
85 {
|
Chris@16
|
86 return *m_iterator;
|
Chris@16
|
87 }
|
Chris@16
|
88
|
Chris@16
|
89 inline difference_type distance_to(closing_iterator<Range> const& other) const
|
Chris@16
|
90 {
|
Chris@16
|
91 return other.m_index - this->m_index;
|
Chris@16
|
92 }
|
Chris@16
|
93
|
Chris@16
|
94 inline bool equal(closing_iterator<Range> const& other) const
|
Chris@16
|
95 {
|
Chris@16
|
96 return this->m_range == other.m_range
|
Chris@16
|
97 && this->m_index == other.m_index;
|
Chris@16
|
98 }
|
Chris@16
|
99
|
Chris@16
|
100 inline void increment()
|
Chris@16
|
101 {
|
Chris@16
|
102 if (++m_index < m_size)
|
Chris@16
|
103 {
|
Chris@16
|
104 ++m_iterator;
|
Chris@16
|
105 }
|
Chris@16
|
106 else
|
Chris@16
|
107 {
|
Chris@16
|
108 update_iterator();
|
Chris@16
|
109 }
|
Chris@16
|
110 }
|
Chris@16
|
111
|
Chris@16
|
112 inline void decrement()
|
Chris@16
|
113 {
|
Chris@16
|
114 if (m_index-- < m_size)
|
Chris@16
|
115 {
|
Chris@16
|
116 --m_iterator;
|
Chris@16
|
117 }
|
Chris@16
|
118 else
|
Chris@16
|
119 {
|
Chris@16
|
120 update_iterator();
|
Chris@16
|
121 }
|
Chris@16
|
122 }
|
Chris@16
|
123
|
Chris@16
|
124 inline void advance(difference_type n)
|
Chris@16
|
125 {
|
Chris@16
|
126 if (m_index < m_size && m_index + n < m_size)
|
Chris@16
|
127 {
|
Chris@16
|
128 m_index += n;
|
Chris@16
|
129 m_iterator += n;
|
Chris@16
|
130 }
|
Chris@16
|
131 else
|
Chris@16
|
132 {
|
Chris@16
|
133 m_index += n;
|
Chris@16
|
134 update_iterator();
|
Chris@16
|
135 }
|
Chris@16
|
136 }
|
Chris@16
|
137
|
Chris@16
|
138 inline void update_iterator()
|
Chris@16
|
139 {
|
Chris@16
|
140 this->m_iterator = m_index <= m_size
|
Chris@16
|
141 ? boost::begin(*m_range) + (m_index % m_size)
|
Chris@16
|
142 : boost::end(*m_range)
|
Chris@16
|
143 ;
|
Chris@16
|
144 }
|
Chris@16
|
145
|
Chris@16
|
146 Range* m_range;
|
Chris@16
|
147 typename boost::range_iterator<Range>::type m_iterator;
|
Chris@16
|
148 typename boost::range_iterator<Range>::type m_end;
|
Chris@16
|
149 difference_type m_size;
|
Chris@16
|
150 difference_type m_index;
|
Chris@16
|
151 };
|
Chris@16
|
152
|
Chris@16
|
153
|
Chris@16
|
154 }} // namespace boost::geometry
|
Chris@16
|
155
|
Chris@16
|
156
|
Chris@16
|
157 #endif // BOOST_GEOMETRY_ITERATORS_CLOSING_ITERATOR_HPP
|