xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_iterator_base_funcs.h (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
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