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