1*38fd1498Szrj // Functions used by iterators -*- C++ -*-
2*38fd1498Szrj
3*38fd1498Szrj // Copyright (C) 2001-2018 Free Software Foundation, Inc.
4*38fd1498Szrj //
5*38fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free
6*38fd1498Szrj // software; you can redistribute it and/or modify it under the
7*38fd1498Szrj // terms of the GNU General Public License as published by the
8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
9*38fd1498Szrj // any later version.
10*38fd1498Szrj
11*38fd1498Szrj // This library is distributed in the hope that it will be useful,
12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*38fd1498Szrj // GNU General Public License for more details.
15*38fd1498Szrj
16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
18*38fd1498Szrj // 3.1, as published by the Free Software Foundation.
19*38fd1498Szrj
20*38fd1498Szrj // You should have received a copy of the GNU General Public License and
21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23*38fd1498Szrj // <http://www.gnu.org/licenses/>.
24*38fd1498Szrj
25*38fd1498Szrj /*
26*38fd1498Szrj *
27*38fd1498Szrj * Copyright (c) 1994
28*38fd1498Szrj * Hewlett-Packard Company
29*38fd1498Szrj *
30*38fd1498Szrj * Permission to use, copy, modify, distribute and sell this software
31*38fd1498Szrj * and its documentation for any purpose is hereby granted without fee,
32*38fd1498Szrj * provided that the above copyright notice appear in all copies and
33*38fd1498Szrj * that both that copyright notice and this permission notice appear
34*38fd1498Szrj * in supporting documentation. Hewlett-Packard Company makes no
35*38fd1498Szrj * representations about the suitability of this software for any
36*38fd1498Szrj * purpose. It is provided "as is" without express or implied warranty.
37*38fd1498Szrj *
38*38fd1498Szrj *
39*38fd1498Szrj * Copyright (c) 1996-1998
40*38fd1498Szrj * Silicon Graphics Computer Systems, Inc.
41*38fd1498Szrj *
42*38fd1498Szrj * Permission to use, copy, modify, distribute and sell this software
43*38fd1498Szrj * and its documentation for any purpose is hereby granted without fee,
44*38fd1498Szrj * provided that the above copyright notice appear in all copies and
45*38fd1498Szrj * that both that copyright notice and this permission notice appear
46*38fd1498Szrj * in supporting documentation. Silicon Graphics makes no
47*38fd1498Szrj * representations about the suitability of this software for any
48*38fd1498Szrj * purpose. It is provided "as is" without express or implied warranty.
49*38fd1498Szrj */
50*38fd1498Szrj
51*38fd1498Szrj /** @file bits/stl_iterator_base_funcs.h
52*38fd1498Szrj * This is an internal header file, included by other library headers.
53*38fd1498Szrj * Do not attempt to use it directly. @headername{iterator}
54*38fd1498Szrj *
55*38fd1498Szrj * This file contains all of the general iterator-related utility
56*38fd1498Szrj * functions, such as distance() and advance().
57*38fd1498Szrj */
58*38fd1498Szrj
59*38fd1498Szrj #ifndef _STL_ITERATOR_BASE_FUNCS_H
60*38fd1498Szrj #define _STL_ITERATOR_BASE_FUNCS_H 1
61*38fd1498Szrj
62*38fd1498Szrj #pragma GCC system_header
63*38fd1498Szrj
64*38fd1498Szrj #include <bits/concept_check.h>
65*38fd1498Szrj #include <debug/assertions.h>
66*38fd1498Szrj
_GLIBCXX_VISIBILITY(default)67*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
68*38fd1498Szrj {
69*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
70*38fd1498Szrj
71*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
72*38fd1498Szrj // Forward declaration for the overloads of __distance.
73*38fd1498Szrj template <typename> struct _List_iterator;
74*38fd1498Szrj template <typename> struct _List_const_iterator;
75*38fd1498Szrj _GLIBCXX_END_NAMESPACE_CONTAINER
76*38fd1498Szrj
77*38fd1498Szrj template<typename _InputIterator>
78*38fd1498Szrj inline _GLIBCXX14_CONSTEXPR
79*38fd1498Szrj typename iterator_traits<_InputIterator>::difference_type
80*38fd1498Szrj __distance(_InputIterator __first, _InputIterator __last,
81*38fd1498Szrj input_iterator_tag)
82*38fd1498Szrj {
83*38fd1498Szrj // concept requirements
84*38fd1498Szrj __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
85*38fd1498Szrj
86*38fd1498Szrj typename iterator_traits<_InputIterator>::difference_type __n = 0;
87*38fd1498Szrj while (__first != __last)
88*38fd1498Szrj {
89*38fd1498Szrj ++__first;
90*38fd1498Szrj ++__n;
91*38fd1498Szrj }
92*38fd1498Szrj return __n;
93*38fd1498Szrj }
94*38fd1498Szrj
95*38fd1498Szrj template<typename _RandomAccessIterator>
96*38fd1498Szrj inline _GLIBCXX14_CONSTEXPR
97*38fd1498Szrj typename iterator_traits<_RandomAccessIterator>::difference_type
98*38fd1498Szrj __distance(_RandomAccessIterator __first, _RandomAccessIterator __last,
99*38fd1498Szrj random_access_iterator_tag)
100*38fd1498Szrj {
101*38fd1498Szrj // concept requirements
102*38fd1498Szrj __glibcxx_function_requires(_RandomAccessIteratorConcept<
103*38fd1498Szrj _RandomAccessIterator>)
104*38fd1498Szrj return __last - __first;
105*38fd1498Szrj }
106*38fd1498Szrj
107*38fd1498Szrj #if _GLIBCXX_USE_CXX11_ABI
108*38fd1498Szrj // Forward declaration because of the qualified call in distance.
109*38fd1498Szrj template<typename _Tp>
110*38fd1498Szrj ptrdiff_t
111*38fd1498Szrj __distance(_GLIBCXX_STD_C::_List_iterator<_Tp>,
112*38fd1498Szrj _GLIBCXX_STD_C::_List_iterator<_Tp>,
113*38fd1498Szrj input_iterator_tag);
114*38fd1498Szrj
115*38fd1498Szrj template<typename _Tp>
116*38fd1498Szrj ptrdiff_t
117*38fd1498Szrj __distance(_GLIBCXX_STD_C::_List_const_iterator<_Tp>,
118*38fd1498Szrj _GLIBCXX_STD_C::_List_const_iterator<_Tp>,
119*38fd1498Szrj input_iterator_tag);
120*38fd1498Szrj #endif
121*38fd1498Szrj
122*38fd1498Szrj /**
123*38fd1498Szrj * @brief A generalization of pointer arithmetic.
124*38fd1498Szrj * @param __first An input iterator.
125*38fd1498Szrj * @param __last An input iterator.
126*38fd1498Szrj * @return The distance between them.
127*38fd1498Szrj *
128*38fd1498Szrj * Returns @c n such that __first + n == __last. This requires
129*38fd1498Szrj * that @p __last must be reachable from @p __first. Note that @c
130*38fd1498Szrj * n may be negative.
131*38fd1498Szrj *
132*38fd1498Szrj * For random access iterators, this uses their @c + and @c - operations
133*38fd1498Szrj * and are constant time. For other %iterator classes they are linear time.
134*38fd1498Szrj */
135*38fd1498Szrj template<typename _InputIterator>
136*38fd1498Szrj inline _GLIBCXX17_CONSTEXPR
137*38fd1498Szrj typename iterator_traits<_InputIterator>::difference_type
138*38fd1498Szrj distance(_InputIterator __first, _InputIterator __last)
139*38fd1498Szrj {
140*38fd1498Szrj // concept requirements -- taken care of in __distance
141*38fd1498Szrj return std::__distance(__first, __last,
142*38fd1498Szrj std::__iterator_category(__first));
143*38fd1498Szrj }
144*38fd1498Szrj
145*38fd1498Szrj template<typename _InputIterator, typename _Distance>
146*38fd1498Szrj inline _GLIBCXX14_CONSTEXPR void
147*38fd1498Szrj __advance(_InputIterator& __i, _Distance __n, input_iterator_tag)
148*38fd1498Szrj {
149*38fd1498Szrj // concept requirements
150*38fd1498Szrj __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
151*38fd1498Szrj __glibcxx_assert(__n >= 0);
152*38fd1498Szrj while (__n--)
153*38fd1498Szrj ++__i;
154*38fd1498Szrj }
155*38fd1498Szrj
156*38fd1498Szrj template<typename _BidirectionalIterator, typename _Distance>
157*38fd1498Szrj inline _GLIBCXX14_CONSTEXPR void
158*38fd1498Szrj __advance(_BidirectionalIterator& __i, _Distance __n,
159*38fd1498Szrj bidirectional_iterator_tag)
160*38fd1498Szrj {
161*38fd1498Szrj // concept requirements
162*38fd1498Szrj __glibcxx_function_requires(_BidirectionalIteratorConcept<
163*38fd1498Szrj _BidirectionalIterator>)
164*38fd1498Szrj if (__n > 0)
165*38fd1498Szrj while (__n--)
166*38fd1498Szrj ++__i;
167*38fd1498Szrj else
168*38fd1498Szrj while (__n++)
169*38fd1498Szrj --__i;
170*38fd1498Szrj }
171*38fd1498Szrj
172*38fd1498Szrj template<typename _RandomAccessIterator, typename _Distance>
173*38fd1498Szrj inline _GLIBCXX14_CONSTEXPR void
174*38fd1498Szrj __advance(_RandomAccessIterator& __i, _Distance __n,
175*38fd1498Szrj random_access_iterator_tag)
176*38fd1498Szrj {
177*38fd1498Szrj // concept requirements
178*38fd1498Szrj __glibcxx_function_requires(_RandomAccessIteratorConcept<
179*38fd1498Szrj _RandomAccessIterator>)
180*38fd1498Szrj if (__builtin_constant_p(__n) && __n == 1)
181*38fd1498Szrj ++__i;
182*38fd1498Szrj else if (__builtin_constant_p(__n) && __n == -1)
183*38fd1498Szrj --__i;
184*38fd1498Szrj else
185*38fd1498Szrj __i += __n;
186*38fd1498Szrj }
187*38fd1498Szrj
188*38fd1498Szrj /**
189*38fd1498Szrj * @brief A generalization of pointer arithmetic.
190*38fd1498Szrj * @param __i An input iterator.
191*38fd1498Szrj * @param __n The @a delta by which to change @p __i.
192*38fd1498Szrj * @return Nothing.
193*38fd1498Szrj *
194*38fd1498Szrj * This increments @p i by @p n. For bidirectional and random access
195*38fd1498Szrj * iterators, @p __n may be negative, in which case @p __i is decremented.
196*38fd1498Szrj *
197*38fd1498Szrj * For random access iterators, this uses their @c + and @c - operations
198*38fd1498Szrj * and are constant time. For other %iterator classes they are linear time.
199*38fd1498Szrj */
200*38fd1498Szrj template<typename _InputIterator, typename _Distance>
201*38fd1498Szrj inline _GLIBCXX17_CONSTEXPR void
202*38fd1498Szrj advance(_InputIterator& __i, _Distance __n)
203*38fd1498Szrj {
204*38fd1498Szrj // concept requirements -- taken care of in __advance
205*38fd1498Szrj typename iterator_traits<_InputIterator>::difference_type __d = __n;
206*38fd1498Szrj std::__advance(__i, __d, std::__iterator_category(__i));
207*38fd1498Szrj }
208*38fd1498Szrj
209*38fd1498Szrj #if __cplusplus >= 201103L
210*38fd1498Szrj
211*38fd1498Szrj template<typename _InputIterator>
212*38fd1498Szrj inline _GLIBCXX17_CONSTEXPR _InputIterator
213*38fd1498Szrj next(_InputIterator __x, typename
214*38fd1498Szrj iterator_traits<_InputIterator>::difference_type __n = 1)
215*38fd1498Szrj {
216*38fd1498Szrj // concept requirements
217*38fd1498Szrj __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
218*38fd1498Szrj std::advance(__x, __n);
219*38fd1498Szrj return __x;
220*38fd1498Szrj }
221*38fd1498Szrj
222*38fd1498Szrj template<typename _BidirectionalIterator>
223*38fd1498Szrj inline _GLIBCXX17_CONSTEXPR _BidirectionalIterator
224*38fd1498Szrj prev(_BidirectionalIterator __x, typename
225*38fd1498Szrj iterator_traits<_BidirectionalIterator>::difference_type __n = 1)
226*38fd1498Szrj {
227*38fd1498Szrj // concept requirements
228*38fd1498Szrj __glibcxx_function_requires(_BidirectionalIteratorConcept<
229*38fd1498Szrj _BidirectionalIterator>)
230*38fd1498Szrj std::advance(__x, -__n);
231*38fd1498Szrj return __x;
232*38fd1498Szrj }
233*38fd1498Szrj
234*38fd1498Szrj #endif // C++11
235*38fd1498Szrj
236*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
237*38fd1498Szrj } // namespace
238*38fd1498Szrj
239*38fd1498Szrj #endif /* _STL_ITERATOR_BASE_FUNCS_H */
240