1e4b17023SJohn Marino // Algorithm implementation -*- C++ -*-
2e4b17023SJohn Marino
3e4b17023SJohn Marino // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
4e4b17023SJohn Marino // 2010, 2011
5e4b17023SJohn Marino // Free Software Foundation, Inc.
6e4b17023SJohn Marino //
7e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library. This library is free
8e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the
9e4b17023SJohn Marino // terms of the GNU General Public License as published by the
10e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option)
11e4b17023SJohn Marino // any later version.
12e4b17023SJohn Marino
13e4b17023SJohn Marino // This library is distributed in the hope that it will be useful,
14e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of
15e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16e4b17023SJohn Marino // GNU General Public License for more details.
17e4b17023SJohn Marino
18e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional
19e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version
20e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation.
21e4b17023SJohn Marino
22e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and
23e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program;
24e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25e4b17023SJohn Marino // <http://www.gnu.org/licenses/>.
26e4b17023SJohn Marino
27e4b17023SJohn Marino /*
28e4b17023SJohn Marino *
29e4b17023SJohn Marino * Copyright (c) 1994
30e4b17023SJohn Marino * Hewlett-Packard Company
31e4b17023SJohn Marino *
32e4b17023SJohn Marino * Permission to use, copy, modify, distribute and sell this software
33e4b17023SJohn Marino * and its documentation for any purpose is hereby granted without fee,
34e4b17023SJohn Marino * provided that the above copyright notice appear in all copies and
35e4b17023SJohn Marino * that both that copyright notice and this permission notice appear
36e4b17023SJohn Marino * in supporting documentation. Hewlett-Packard Company makes no
37e4b17023SJohn Marino * representations about the suitability of this software for any
38e4b17023SJohn Marino * purpose. It is provided "as is" without express or implied warranty.
39e4b17023SJohn Marino *
40e4b17023SJohn Marino *
41e4b17023SJohn Marino * Copyright (c) 1996
42e4b17023SJohn Marino * Silicon Graphics Computer Systems, Inc.
43e4b17023SJohn Marino *
44e4b17023SJohn Marino * Permission to use, copy, modify, distribute and sell this software
45e4b17023SJohn Marino * and its documentation for any purpose is hereby granted without fee,
46e4b17023SJohn Marino * provided that the above copyright notice appear in all copies and
47e4b17023SJohn Marino * that both that copyright notice and this permission notice appear
48e4b17023SJohn Marino * in supporting documentation. Silicon Graphics makes no
49e4b17023SJohn Marino * representations about the suitability of this software for any
50e4b17023SJohn Marino * purpose. It is provided "as is" without express or implied warranty.
51e4b17023SJohn Marino */
52e4b17023SJohn Marino
53e4b17023SJohn Marino /** @file bits/stl_algo.h
54e4b17023SJohn Marino * This is an internal header file, included by other library headers.
55e4b17023SJohn Marino * Do not attempt to use it directly. @headername{algorithm}
56e4b17023SJohn Marino */
57e4b17023SJohn Marino
58e4b17023SJohn Marino #ifndef _STL_ALGO_H
59e4b17023SJohn Marino #define _STL_ALGO_H 1
60e4b17023SJohn Marino
61e4b17023SJohn Marino #include <cstdlib> // for rand
62e4b17023SJohn Marino #include <bits/algorithmfwd.h>
63e4b17023SJohn Marino #include <bits/stl_heap.h>
64e4b17023SJohn Marino #include <bits/stl_tempbuf.h> // for _Temporary_buffer
65e4b17023SJohn Marino
66e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__
67e4b17023SJohn Marino #include <random> // for std::uniform_int_distribution
68e4b17023SJohn Marino #include <functional> // for std::bind
69e4b17023SJohn Marino #endif
70e4b17023SJohn Marino
71e4b17023SJohn Marino // See concept_check.h for the __glibcxx_*_requires macros.
72e4b17023SJohn Marino
_GLIBCXX_VISIBILITY(default)73e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default)
74e4b17023SJohn Marino {
75e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION
76e4b17023SJohn Marino
77*95d28233SJohn Marino /// Swaps the median value of *__a, *__b and *__c to *__result
78e4b17023SJohn Marino template<typename _Iterator>
79e4b17023SJohn Marino void
80*95d28233SJohn Marino __move_median_to_first(_Iterator __result, _Iterator __a,
81*95d28233SJohn Marino _Iterator __b, _Iterator __c)
82e4b17023SJohn Marino {
83e4b17023SJohn Marino // concept requirements
84e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<
85e4b17023SJohn Marino typename iterator_traits<_Iterator>::value_type>)
86e4b17023SJohn Marino
87e4b17023SJohn Marino if (*__a < *__b)
88e4b17023SJohn Marino {
89e4b17023SJohn Marino if (*__b < *__c)
90*95d28233SJohn Marino std::iter_swap(__result, __b);
91e4b17023SJohn Marino else if (*__a < *__c)
92*95d28233SJohn Marino std::iter_swap(__result, __c);
93*95d28233SJohn Marino else
94*95d28233SJohn Marino std::iter_swap(__result, __a);
95e4b17023SJohn Marino }
96e4b17023SJohn Marino else if (*__a < *__c)
97*95d28233SJohn Marino std::iter_swap(__result, __a);
98e4b17023SJohn Marino else if (*__b < *__c)
99*95d28233SJohn Marino std::iter_swap(__result, __c);
100e4b17023SJohn Marino else
101*95d28233SJohn Marino std::iter_swap(__result, __b);
102e4b17023SJohn Marino }
103e4b17023SJohn Marino
104*95d28233SJohn Marino /// Swaps the median value of *__a, *__b and *__c under __comp to *__result
105e4b17023SJohn Marino template<typename _Iterator, typename _Compare>
106e4b17023SJohn Marino void
107*95d28233SJohn Marino __move_median_to_first(_Iterator __result, _Iterator __a,
108*95d28233SJohn Marino _Iterator __b, _Iterator __c,
109e4b17023SJohn Marino _Compare __comp)
110e4b17023SJohn Marino {
111e4b17023SJohn Marino // concept requirements
112e4b17023SJohn Marino __glibcxx_function_requires(_BinaryFunctionConcept<_Compare, bool,
113e4b17023SJohn Marino typename iterator_traits<_Iterator>::value_type,
114e4b17023SJohn Marino typename iterator_traits<_Iterator>::value_type>)
115e4b17023SJohn Marino
116e4b17023SJohn Marino if (__comp(*__a, *__b))
117e4b17023SJohn Marino {
118e4b17023SJohn Marino if (__comp(*__b, *__c))
119*95d28233SJohn Marino std::iter_swap(__result, __b);
120e4b17023SJohn Marino else if (__comp(*__a, *__c))
121*95d28233SJohn Marino std::iter_swap(__result, __c);
122*95d28233SJohn Marino else
123*95d28233SJohn Marino std::iter_swap(__result, __a);
124e4b17023SJohn Marino }
125e4b17023SJohn Marino else if (__comp(*__a, *__c))
126*95d28233SJohn Marino std::iter_swap(__result, __a);
127e4b17023SJohn Marino else if (__comp(*__b, *__c))
128*95d28233SJohn Marino std::iter_swap(__result, __c);
129e4b17023SJohn Marino else
130*95d28233SJohn Marino std::iter_swap(__result, __b);
131e4b17023SJohn Marino }
132e4b17023SJohn Marino
133e4b17023SJohn Marino // for_each
134e4b17023SJohn Marino
135e4b17023SJohn Marino /// This is an overload used by find() for the Input Iterator case.
136e4b17023SJohn Marino template<typename _InputIterator, typename _Tp>
137e4b17023SJohn Marino inline _InputIterator
138e4b17023SJohn Marino __find(_InputIterator __first, _InputIterator __last,
139e4b17023SJohn Marino const _Tp& __val, input_iterator_tag)
140e4b17023SJohn Marino {
141e4b17023SJohn Marino while (__first != __last && !(*__first == __val))
142e4b17023SJohn Marino ++__first;
143e4b17023SJohn Marino return __first;
144e4b17023SJohn Marino }
145e4b17023SJohn Marino
146e4b17023SJohn Marino /// This is an overload used by find_if() for the Input Iterator case.
147e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate>
148e4b17023SJohn Marino inline _InputIterator
149e4b17023SJohn Marino __find_if(_InputIterator __first, _InputIterator __last,
150e4b17023SJohn Marino _Predicate __pred, input_iterator_tag)
151e4b17023SJohn Marino {
152e4b17023SJohn Marino while (__first != __last && !bool(__pred(*__first)))
153e4b17023SJohn Marino ++__first;
154e4b17023SJohn Marino return __first;
155e4b17023SJohn Marino }
156e4b17023SJohn Marino
157e4b17023SJohn Marino /// This is an overload used by find() for the RAI case.
158e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Tp>
159e4b17023SJohn Marino _RandomAccessIterator
160e4b17023SJohn Marino __find(_RandomAccessIterator __first, _RandomAccessIterator __last,
161e4b17023SJohn Marino const _Tp& __val, random_access_iterator_tag)
162e4b17023SJohn Marino {
163e4b17023SJohn Marino typename iterator_traits<_RandomAccessIterator>::difference_type
164e4b17023SJohn Marino __trip_count = (__last - __first) >> 2;
165e4b17023SJohn Marino
166e4b17023SJohn Marino for (; __trip_count > 0; --__trip_count)
167e4b17023SJohn Marino {
168e4b17023SJohn Marino if (*__first == __val)
169e4b17023SJohn Marino return __first;
170e4b17023SJohn Marino ++__first;
171e4b17023SJohn Marino
172e4b17023SJohn Marino if (*__first == __val)
173e4b17023SJohn Marino return __first;
174e4b17023SJohn Marino ++__first;
175e4b17023SJohn Marino
176e4b17023SJohn Marino if (*__first == __val)
177e4b17023SJohn Marino return __first;
178e4b17023SJohn Marino ++__first;
179e4b17023SJohn Marino
180e4b17023SJohn Marino if (*__first == __val)
181e4b17023SJohn Marino return __first;
182e4b17023SJohn Marino ++__first;
183e4b17023SJohn Marino }
184e4b17023SJohn Marino
185e4b17023SJohn Marino switch (__last - __first)
186e4b17023SJohn Marino {
187e4b17023SJohn Marino case 3:
188e4b17023SJohn Marino if (*__first == __val)
189e4b17023SJohn Marino return __first;
190e4b17023SJohn Marino ++__first;
191e4b17023SJohn Marino case 2:
192e4b17023SJohn Marino if (*__first == __val)
193e4b17023SJohn Marino return __first;
194e4b17023SJohn Marino ++__first;
195e4b17023SJohn Marino case 1:
196e4b17023SJohn Marino if (*__first == __val)
197e4b17023SJohn Marino return __first;
198e4b17023SJohn Marino ++__first;
199e4b17023SJohn Marino case 0:
200e4b17023SJohn Marino default:
201e4b17023SJohn Marino return __last;
202e4b17023SJohn Marino }
203e4b17023SJohn Marino }
204e4b17023SJohn Marino
205e4b17023SJohn Marino /// This is an overload used by find_if() for the RAI case.
206e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Predicate>
207e4b17023SJohn Marino _RandomAccessIterator
208e4b17023SJohn Marino __find_if(_RandomAccessIterator __first, _RandomAccessIterator __last,
209e4b17023SJohn Marino _Predicate __pred, random_access_iterator_tag)
210e4b17023SJohn Marino {
211e4b17023SJohn Marino typename iterator_traits<_RandomAccessIterator>::difference_type
212e4b17023SJohn Marino __trip_count = (__last - __first) >> 2;
213e4b17023SJohn Marino
214e4b17023SJohn Marino for (; __trip_count > 0; --__trip_count)
215e4b17023SJohn Marino {
216e4b17023SJohn Marino if (__pred(*__first))
217e4b17023SJohn Marino return __first;
218e4b17023SJohn Marino ++__first;
219e4b17023SJohn Marino
220e4b17023SJohn Marino if (__pred(*__first))
221e4b17023SJohn Marino return __first;
222e4b17023SJohn Marino ++__first;
223e4b17023SJohn Marino
224e4b17023SJohn Marino if (__pred(*__first))
225e4b17023SJohn Marino return __first;
226e4b17023SJohn Marino ++__first;
227e4b17023SJohn Marino
228e4b17023SJohn Marino if (__pred(*__first))
229e4b17023SJohn Marino return __first;
230e4b17023SJohn Marino ++__first;
231e4b17023SJohn Marino }
232e4b17023SJohn Marino
233e4b17023SJohn Marino switch (__last - __first)
234e4b17023SJohn Marino {
235e4b17023SJohn Marino case 3:
236e4b17023SJohn Marino if (__pred(*__first))
237e4b17023SJohn Marino return __first;
238e4b17023SJohn Marino ++__first;
239e4b17023SJohn Marino case 2:
240e4b17023SJohn Marino if (__pred(*__first))
241e4b17023SJohn Marino return __first;
242e4b17023SJohn Marino ++__first;
243e4b17023SJohn Marino case 1:
244e4b17023SJohn Marino if (__pred(*__first))
245e4b17023SJohn Marino return __first;
246e4b17023SJohn Marino ++__first;
247e4b17023SJohn Marino case 0:
248e4b17023SJohn Marino default:
249e4b17023SJohn Marino return __last;
250e4b17023SJohn Marino }
251e4b17023SJohn Marino }
252e4b17023SJohn Marino
253e4b17023SJohn Marino /// This is an overload used by find_if_not() for the Input Iterator case.
254e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate>
255e4b17023SJohn Marino inline _InputIterator
256e4b17023SJohn Marino __find_if_not(_InputIterator __first, _InputIterator __last,
257e4b17023SJohn Marino _Predicate __pred, input_iterator_tag)
258e4b17023SJohn Marino {
259e4b17023SJohn Marino while (__first != __last && bool(__pred(*__first)))
260e4b17023SJohn Marino ++__first;
261e4b17023SJohn Marino return __first;
262e4b17023SJohn Marino }
263e4b17023SJohn Marino
264e4b17023SJohn Marino /// This is an overload used by find_if_not() for the RAI case.
265e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Predicate>
266e4b17023SJohn Marino _RandomAccessIterator
267e4b17023SJohn Marino __find_if_not(_RandomAccessIterator __first, _RandomAccessIterator __last,
268e4b17023SJohn Marino _Predicate __pred, random_access_iterator_tag)
269e4b17023SJohn Marino {
270e4b17023SJohn Marino typename iterator_traits<_RandomAccessIterator>::difference_type
271e4b17023SJohn Marino __trip_count = (__last - __first) >> 2;
272e4b17023SJohn Marino
273e4b17023SJohn Marino for (; __trip_count > 0; --__trip_count)
274e4b17023SJohn Marino {
275e4b17023SJohn Marino if (!bool(__pred(*__first)))
276e4b17023SJohn Marino return __first;
277e4b17023SJohn Marino ++__first;
278e4b17023SJohn Marino
279e4b17023SJohn Marino if (!bool(__pred(*__first)))
280e4b17023SJohn Marino return __first;
281e4b17023SJohn Marino ++__first;
282e4b17023SJohn Marino
283e4b17023SJohn Marino if (!bool(__pred(*__first)))
284e4b17023SJohn Marino return __first;
285e4b17023SJohn Marino ++__first;
286e4b17023SJohn Marino
287e4b17023SJohn Marino if (!bool(__pred(*__first)))
288e4b17023SJohn Marino return __first;
289e4b17023SJohn Marino ++__first;
290e4b17023SJohn Marino }
291e4b17023SJohn Marino
292e4b17023SJohn Marino switch (__last - __first)
293e4b17023SJohn Marino {
294e4b17023SJohn Marino case 3:
295e4b17023SJohn Marino if (!bool(__pred(*__first)))
296e4b17023SJohn Marino return __first;
297e4b17023SJohn Marino ++__first;
298e4b17023SJohn Marino case 2:
299e4b17023SJohn Marino if (!bool(__pred(*__first)))
300e4b17023SJohn Marino return __first;
301e4b17023SJohn Marino ++__first;
302e4b17023SJohn Marino case 1:
303e4b17023SJohn Marino if (!bool(__pred(*__first)))
304e4b17023SJohn Marino return __first;
305e4b17023SJohn Marino ++__first;
306e4b17023SJohn Marino case 0:
307e4b17023SJohn Marino default:
308e4b17023SJohn Marino return __last;
309e4b17023SJohn Marino }
310e4b17023SJohn Marino }
311e4b17023SJohn Marino
312e4b17023SJohn Marino /// Provided for stable_partition to use.
313e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate>
314e4b17023SJohn Marino inline _InputIterator
315e4b17023SJohn Marino __find_if_not(_InputIterator __first, _InputIterator __last,
316e4b17023SJohn Marino _Predicate __pred)
317e4b17023SJohn Marino {
318e4b17023SJohn Marino return std::__find_if_not(__first, __last, __pred,
319e4b17023SJohn Marino std::__iterator_category(__first));
320e4b17023SJohn Marino }
321e4b17023SJohn Marino
322e4b17023SJohn Marino /// Like find_if_not(), but uses and updates a count of the
323e4b17023SJohn Marino /// remaining range length instead of comparing against an end
324e4b17023SJohn Marino /// iterator.
325e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate, typename _Distance>
326e4b17023SJohn Marino _InputIterator
327e4b17023SJohn Marino __find_if_not_n(_InputIterator __first, _Distance& __len, _Predicate __pred)
328e4b17023SJohn Marino {
329e4b17023SJohn Marino for (; __len; --__len, ++__first)
330e4b17023SJohn Marino if (!bool(__pred(*__first)))
331e4b17023SJohn Marino break;
332e4b17023SJohn Marino return __first;
333e4b17023SJohn Marino }
334e4b17023SJohn Marino
335e4b17023SJohn Marino // set_difference
336e4b17023SJohn Marino // set_intersection
337e4b17023SJohn Marino // set_symmetric_difference
338e4b17023SJohn Marino // set_union
339e4b17023SJohn Marino // for_each
340e4b17023SJohn Marino // find
341e4b17023SJohn Marino // find_if
342e4b17023SJohn Marino // find_first_of
343e4b17023SJohn Marino // adjacent_find
344e4b17023SJohn Marino // count
345e4b17023SJohn Marino // count_if
346e4b17023SJohn Marino // search
347e4b17023SJohn Marino
348e4b17023SJohn Marino /**
349e4b17023SJohn Marino * This is an uglified
350e4b17023SJohn Marino * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&)
351e4b17023SJohn Marino * overloaded for forward iterators.
352e4b17023SJohn Marino */
353e4b17023SJohn Marino template<typename _ForwardIterator, typename _Integer, typename _Tp>
354e4b17023SJohn Marino _ForwardIterator
355e4b17023SJohn Marino __search_n(_ForwardIterator __first, _ForwardIterator __last,
356e4b17023SJohn Marino _Integer __count, const _Tp& __val,
357e4b17023SJohn Marino std::forward_iterator_tag)
358e4b17023SJohn Marino {
359e4b17023SJohn Marino __first = _GLIBCXX_STD_A::find(__first, __last, __val);
360e4b17023SJohn Marino while (__first != __last)
361e4b17023SJohn Marino {
362e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::difference_type
363e4b17023SJohn Marino __n = __count;
364e4b17023SJohn Marino _ForwardIterator __i = __first;
365e4b17023SJohn Marino ++__i;
366e4b17023SJohn Marino while (__i != __last && __n != 1 && *__i == __val)
367e4b17023SJohn Marino {
368e4b17023SJohn Marino ++__i;
369e4b17023SJohn Marino --__n;
370e4b17023SJohn Marino }
371e4b17023SJohn Marino if (__n == 1)
372e4b17023SJohn Marino return __first;
373e4b17023SJohn Marino if (__i == __last)
374e4b17023SJohn Marino return __last;
375e4b17023SJohn Marino __first = _GLIBCXX_STD_A::find(++__i, __last, __val);
376e4b17023SJohn Marino }
377e4b17023SJohn Marino return __last;
378e4b17023SJohn Marino }
379e4b17023SJohn Marino
380e4b17023SJohn Marino /**
381e4b17023SJohn Marino * This is an uglified
382e4b17023SJohn Marino * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&)
383e4b17023SJohn Marino * overloaded for random access iterators.
384e4b17023SJohn Marino */
385e4b17023SJohn Marino template<typename _RandomAccessIter, typename _Integer, typename _Tp>
386e4b17023SJohn Marino _RandomAccessIter
387e4b17023SJohn Marino __search_n(_RandomAccessIter __first, _RandomAccessIter __last,
388e4b17023SJohn Marino _Integer __count, const _Tp& __val,
389e4b17023SJohn Marino std::random_access_iterator_tag)
390e4b17023SJohn Marino {
391e4b17023SJohn Marino
392e4b17023SJohn Marino typedef typename std::iterator_traits<_RandomAccessIter>::difference_type
393e4b17023SJohn Marino _DistanceType;
394e4b17023SJohn Marino
395e4b17023SJohn Marino _DistanceType __tailSize = __last - __first;
396e4b17023SJohn Marino const _DistanceType __pattSize = __count;
397e4b17023SJohn Marino
398e4b17023SJohn Marino if (__tailSize < __pattSize)
399e4b17023SJohn Marino return __last;
400e4b17023SJohn Marino
401e4b17023SJohn Marino const _DistanceType __skipOffset = __pattSize - 1;
402e4b17023SJohn Marino _RandomAccessIter __lookAhead = __first + __skipOffset;
403e4b17023SJohn Marino __tailSize -= __pattSize;
404e4b17023SJohn Marino
405e4b17023SJohn Marino while (1) // the main loop...
406e4b17023SJohn Marino {
407e4b17023SJohn Marino // __lookAhead here is always pointing to the last element of next
408e4b17023SJohn Marino // possible match.
409e4b17023SJohn Marino while (!(*__lookAhead == __val)) // the skip loop...
410e4b17023SJohn Marino {
411e4b17023SJohn Marino if (__tailSize < __pattSize)
412e4b17023SJohn Marino return __last; // Failure
413e4b17023SJohn Marino __lookAhead += __pattSize;
414e4b17023SJohn Marino __tailSize -= __pattSize;
415e4b17023SJohn Marino }
416e4b17023SJohn Marino _DistanceType __remainder = __skipOffset;
417e4b17023SJohn Marino for (_RandomAccessIter __backTrack = __lookAhead - 1;
418e4b17023SJohn Marino *__backTrack == __val; --__backTrack)
419e4b17023SJohn Marino {
420e4b17023SJohn Marino if (--__remainder == 0)
421e4b17023SJohn Marino return (__lookAhead - __skipOffset); // Success
422e4b17023SJohn Marino }
423e4b17023SJohn Marino if (__remainder > __tailSize)
424e4b17023SJohn Marino return __last; // Failure
425e4b17023SJohn Marino __lookAhead += __remainder;
426e4b17023SJohn Marino __tailSize -= __remainder;
427e4b17023SJohn Marino }
428e4b17023SJohn Marino }
429e4b17023SJohn Marino
430e4b17023SJohn Marino // search_n
431e4b17023SJohn Marino
432e4b17023SJohn Marino /**
433e4b17023SJohn Marino * This is an uglified
434e4b17023SJohn Marino * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&,
435e4b17023SJohn Marino * _BinaryPredicate)
436e4b17023SJohn Marino * overloaded for forward iterators.
437e4b17023SJohn Marino */
438e4b17023SJohn Marino template<typename _ForwardIterator, typename _Integer, typename _Tp,
439e4b17023SJohn Marino typename _BinaryPredicate>
440e4b17023SJohn Marino _ForwardIterator
441e4b17023SJohn Marino __search_n(_ForwardIterator __first, _ForwardIterator __last,
442e4b17023SJohn Marino _Integer __count, const _Tp& __val,
443e4b17023SJohn Marino _BinaryPredicate __binary_pred, std::forward_iterator_tag)
444e4b17023SJohn Marino {
445e4b17023SJohn Marino while (__first != __last && !bool(__binary_pred(*__first, __val)))
446e4b17023SJohn Marino ++__first;
447e4b17023SJohn Marino
448e4b17023SJohn Marino while (__first != __last)
449e4b17023SJohn Marino {
450e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::difference_type
451e4b17023SJohn Marino __n = __count;
452e4b17023SJohn Marino _ForwardIterator __i = __first;
453e4b17023SJohn Marino ++__i;
454e4b17023SJohn Marino while (__i != __last && __n != 1 && bool(__binary_pred(*__i, __val)))
455e4b17023SJohn Marino {
456e4b17023SJohn Marino ++__i;
457e4b17023SJohn Marino --__n;
458e4b17023SJohn Marino }
459e4b17023SJohn Marino if (__n == 1)
460e4b17023SJohn Marino return __first;
461e4b17023SJohn Marino if (__i == __last)
462e4b17023SJohn Marino return __last;
463e4b17023SJohn Marino __first = ++__i;
464e4b17023SJohn Marino while (__first != __last
465e4b17023SJohn Marino && !bool(__binary_pred(*__first, __val)))
466e4b17023SJohn Marino ++__first;
467e4b17023SJohn Marino }
468e4b17023SJohn Marino return __last;
469e4b17023SJohn Marino }
470e4b17023SJohn Marino
471e4b17023SJohn Marino /**
472e4b17023SJohn Marino * This is an uglified
473e4b17023SJohn Marino * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&,
474e4b17023SJohn Marino * _BinaryPredicate)
475e4b17023SJohn Marino * overloaded for random access iterators.
476e4b17023SJohn Marino */
477e4b17023SJohn Marino template<typename _RandomAccessIter, typename _Integer, typename _Tp,
478e4b17023SJohn Marino typename _BinaryPredicate>
479e4b17023SJohn Marino _RandomAccessIter
480e4b17023SJohn Marino __search_n(_RandomAccessIter __first, _RandomAccessIter __last,
481e4b17023SJohn Marino _Integer __count, const _Tp& __val,
482e4b17023SJohn Marino _BinaryPredicate __binary_pred, std::random_access_iterator_tag)
483e4b17023SJohn Marino {
484e4b17023SJohn Marino
485e4b17023SJohn Marino typedef typename std::iterator_traits<_RandomAccessIter>::difference_type
486e4b17023SJohn Marino _DistanceType;
487e4b17023SJohn Marino
488e4b17023SJohn Marino _DistanceType __tailSize = __last - __first;
489e4b17023SJohn Marino const _DistanceType __pattSize = __count;
490e4b17023SJohn Marino
491e4b17023SJohn Marino if (__tailSize < __pattSize)
492e4b17023SJohn Marino return __last;
493e4b17023SJohn Marino
494e4b17023SJohn Marino const _DistanceType __skipOffset = __pattSize - 1;
495e4b17023SJohn Marino _RandomAccessIter __lookAhead = __first + __skipOffset;
496e4b17023SJohn Marino __tailSize -= __pattSize;
497e4b17023SJohn Marino
498e4b17023SJohn Marino while (1) // the main loop...
499e4b17023SJohn Marino {
500e4b17023SJohn Marino // __lookAhead here is always pointing to the last element of next
501e4b17023SJohn Marino // possible match.
502e4b17023SJohn Marino while (!bool(__binary_pred(*__lookAhead, __val))) // the skip loop...
503e4b17023SJohn Marino {
504e4b17023SJohn Marino if (__tailSize < __pattSize)
505e4b17023SJohn Marino return __last; // Failure
506e4b17023SJohn Marino __lookAhead += __pattSize;
507e4b17023SJohn Marino __tailSize -= __pattSize;
508e4b17023SJohn Marino }
509e4b17023SJohn Marino _DistanceType __remainder = __skipOffset;
510e4b17023SJohn Marino for (_RandomAccessIter __backTrack = __lookAhead - 1;
511e4b17023SJohn Marino __binary_pred(*__backTrack, __val); --__backTrack)
512e4b17023SJohn Marino {
513e4b17023SJohn Marino if (--__remainder == 0)
514e4b17023SJohn Marino return (__lookAhead - __skipOffset); // Success
515e4b17023SJohn Marino }
516e4b17023SJohn Marino if (__remainder > __tailSize)
517e4b17023SJohn Marino return __last; // Failure
518e4b17023SJohn Marino __lookAhead += __remainder;
519e4b17023SJohn Marino __tailSize -= __remainder;
520e4b17023SJohn Marino }
521e4b17023SJohn Marino }
522e4b17023SJohn Marino
523e4b17023SJohn Marino // find_end for forward iterators.
524e4b17023SJohn Marino template<typename _ForwardIterator1, typename _ForwardIterator2>
525e4b17023SJohn Marino _ForwardIterator1
526e4b17023SJohn Marino __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
527e4b17023SJohn Marino _ForwardIterator2 __first2, _ForwardIterator2 __last2,
528e4b17023SJohn Marino forward_iterator_tag, forward_iterator_tag)
529e4b17023SJohn Marino {
530e4b17023SJohn Marino if (__first2 == __last2)
531e4b17023SJohn Marino return __last1;
532e4b17023SJohn Marino else
533e4b17023SJohn Marino {
534e4b17023SJohn Marino _ForwardIterator1 __result = __last1;
535e4b17023SJohn Marino while (1)
536e4b17023SJohn Marino {
537e4b17023SJohn Marino _ForwardIterator1 __new_result
538e4b17023SJohn Marino = _GLIBCXX_STD_A::search(__first1, __last1, __first2, __last2);
539e4b17023SJohn Marino if (__new_result == __last1)
540e4b17023SJohn Marino return __result;
541e4b17023SJohn Marino else
542e4b17023SJohn Marino {
543e4b17023SJohn Marino __result = __new_result;
544e4b17023SJohn Marino __first1 = __new_result;
545e4b17023SJohn Marino ++__first1;
546e4b17023SJohn Marino }
547e4b17023SJohn Marino }
548e4b17023SJohn Marino }
549e4b17023SJohn Marino }
550e4b17023SJohn Marino
551e4b17023SJohn Marino template<typename _ForwardIterator1, typename _ForwardIterator2,
552e4b17023SJohn Marino typename _BinaryPredicate>
553e4b17023SJohn Marino _ForwardIterator1
554e4b17023SJohn Marino __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
555e4b17023SJohn Marino _ForwardIterator2 __first2, _ForwardIterator2 __last2,
556e4b17023SJohn Marino forward_iterator_tag, forward_iterator_tag,
557e4b17023SJohn Marino _BinaryPredicate __comp)
558e4b17023SJohn Marino {
559e4b17023SJohn Marino if (__first2 == __last2)
560e4b17023SJohn Marino return __last1;
561e4b17023SJohn Marino else
562e4b17023SJohn Marino {
563e4b17023SJohn Marino _ForwardIterator1 __result = __last1;
564e4b17023SJohn Marino while (1)
565e4b17023SJohn Marino {
566e4b17023SJohn Marino _ForwardIterator1 __new_result
567e4b17023SJohn Marino = _GLIBCXX_STD_A::search(__first1, __last1, __first2,
568e4b17023SJohn Marino __last2, __comp);
569e4b17023SJohn Marino if (__new_result == __last1)
570e4b17023SJohn Marino return __result;
571e4b17023SJohn Marino else
572e4b17023SJohn Marino {
573e4b17023SJohn Marino __result = __new_result;
574e4b17023SJohn Marino __first1 = __new_result;
575e4b17023SJohn Marino ++__first1;
576e4b17023SJohn Marino }
577e4b17023SJohn Marino }
578e4b17023SJohn Marino }
579e4b17023SJohn Marino }
580e4b17023SJohn Marino
581e4b17023SJohn Marino // find_end for bidirectional iterators (much faster).
582e4b17023SJohn Marino template<typename _BidirectionalIterator1, typename _BidirectionalIterator2>
583e4b17023SJohn Marino _BidirectionalIterator1
584e4b17023SJohn Marino __find_end(_BidirectionalIterator1 __first1,
585e4b17023SJohn Marino _BidirectionalIterator1 __last1,
586e4b17023SJohn Marino _BidirectionalIterator2 __first2,
587e4b17023SJohn Marino _BidirectionalIterator2 __last2,
588e4b17023SJohn Marino bidirectional_iterator_tag, bidirectional_iterator_tag)
589e4b17023SJohn Marino {
590e4b17023SJohn Marino // concept requirements
591e4b17023SJohn Marino __glibcxx_function_requires(_BidirectionalIteratorConcept<
592e4b17023SJohn Marino _BidirectionalIterator1>)
593e4b17023SJohn Marino __glibcxx_function_requires(_BidirectionalIteratorConcept<
594e4b17023SJohn Marino _BidirectionalIterator2>)
595e4b17023SJohn Marino
596e4b17023SJohn Marino typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1;
597e4b17023SJohn Marino typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2;
598e4b17023SJohn Marino
599e4b17023SJohn Marino _RevIterator1 __rlast1(__first1);
600e4b17023SJohn Marino _RevIterator2 __rlast2(__first2);
601e4b17023SJohn Marino _RevIterator1 __rresult = _GLIBCXX_STD_A::search(_RevIterator1(__last1),
602e4b17023SJohn Marino __rlast1,
603e4b17023SJohn Marino _RevIterator2(__last2),
604e4b17023SJohn Marino __rlast2);
605e4b17023SJohn Marino
606e4b17023SJohn Marino if (__rresult == __rlast1)
607e4b17023SJohn Marino return __last1;
608e4b17023SJohn Marino else
609e4b17023SJohn Marino {
610e4b17023SJohn Marino _BidirectionalIterator1 __result = __rresult.base();
611e4b17023SJohn Marino std::advance(__result, -std::distance(__first2, __last2));
612e4b17023SJohn Marino return __result;
613e4b17023SJohn Marino }
614e4b17023SJohn Marino }
615e4b17023SJohn Marino
616e4b17023SJohn Marino template<typename _BidirectionalIterator1, typename _BidirectionalIterator2,
617e4b17023SJohn Marino typename _BinaryPredicate>
618e4b17023SJohn Marino _BidirectionalIterator1
619e4b17023SJohn Marino __find_end(_BidirectionalIterator1 __first1,
620e4b17023SJohn Marino _BidirectionalIterator1 __last1,
621e4b17023SJohn Marino _BidirectionalIterator2 __first2,
622e4b17023SJohn Marino _BidirectionalIterator2 __last2,
623e4b17023SJohn Marino bidirectional_iterator_tag, bidirectional_iterator_tag,
624e4b17023SJohn Marino _BinaryPredicate __comp)
625e4b17023SJohn Marino {
626e4b17023SJohn Marino // concept requirements
627e4b17023SJohn Marino __glibcxx_function_requires(_BidirectionalIteratorConcept<
628e4b17023SJohn Marino _BidirectionalIterator1>)
629e4b17023SJohn Marino __glibcxx_function_requires(_BidirectionalIteratorConcept<
630e4b17023SJohn Marino _BidirectionalIterator2>)
631e4b17023SJohn Marino
632e4b17023SJohn Marino typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1;
633e4b17023SJohn Marino typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2;
634e4b17023SJohn Marino
635e4b17023SJohn Marino _RevIterator1 __rlast1(__first1);
636e4b17023SJohn Marino _RevIterator2 __rlast2(__first2);
637e4b17023SJohn Marino _RevIterator1 __rresult = std::search(_RevIterator1(__last1), __rlast1,
638e4b17023SJohn Marino _RevIterator2(__last2), __rlast2,
639e4b17023SJohn Marino __comp);
640e4b17023SJohn Marino
641e4b17023SJohn Marino if (__rresult == __rlast1)
642e4b17023SJohn Marino return __last1;
643e4b17023SJohn Marino else
644e4b17023SJohn Marino {
645e4b17023SJohn Marino _BidirectionalIterator1 __result = __rresult.base();
646e4b17023SJohn Marino std::advance(__result, -std::distance(__first2, __last2));
647e4b17023SJohn Marino return __result;
648e4b17023SJohn Marino }
649e4b17023SJohn Marino }
650e4b17023SJohn Marino
651e4b17023SJohn Marino /**
652e4b17023SJohn Marino * @brief Find last matching subsequence in a sequence.
653e4b17023SJohn Marino * @ingroup non_mutating_algorithms
654e4b17023SJohn Marino * @param __first1 Start of range to search.
655e4b17023SJohn Marino * @param __last1 End of range to search.
656e4b17023SJohn Marino * @param __first2 Start of sequence to match.
657e4b17023SJohn Marino * @param __last2 End of sequence to match.
658e4b17023SJohn Marino * @return The last iterator @c i in the range
659e4b17023SJohn Marino * @p [__first1,__last1-(__last2-__first2)) such that @c *(i+N) ==
660e4b17023SJohn Marino * @p *(__first2+N) for each @c N in the range @p
661e4b17023SJohn Marino * [0,__last2-__first2), or @p __last1 if no such iterator exists.
662e4b17023SJohn Marino *
663e4b17023SJohn Marino * Searches the range @p [__first1,__last1) for a sub-sequence that
664e4b17023SJohn Marino * compares equal value-by-value with the sequence given by @p
665e4b17023SJohn Marino * [__first2,__last2) and returns an iterator to the __first
666e4b17023SJohn Marino * element of the sub-sequence, or @p __last1 if the sub-sequence
667e4b17023SJohn Marino * is not found. The sub-sequence will be the last such
668e4b17023SJohn Marino * subsequence contained in [__first,__last1).
669e4b17023SJohn Marino *
670e4b17023SJohn Marino * Because the sub-sequence must lie completely within the range @p
671e4b17023SJohn Marino * [__first1,__last1) it must start at a position less than @p
672e4b17023SJohn Marino * __last1-(__last2-__first2) where @p __last2-__first2 is the
673e4b17023SJohn Marino * length of the sub-sequence. This means that the returned
674e4b17023SJohn Marino * iterator @c i will be in the range @p
675e4b17023SJohn Marino * [__first1,__last1-(__last2-__first2))
676e4b17023SJohn Marino */
677e4b17023SJohn Marino template<typename _ForwardIterator1, typename _ForwardIterator2>
678e4b17023SJohn Marino inline _ForwardIterator1
679e4b17023SJohn Marino find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
680e4b17023SJohn Marino _ForwardIterator2 __first2, _ForwardIterator2 __last2)
681e4b17023SJohn Marino {
682e4b17023SJohn Marino // concept requirements
683e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>)
684e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>)
685e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept<
686e4b17023SJohn Marino typename iterator_traits<_ForwardIterator1>::value_type,
687e4b17023SJohn Marino typename iterator_traits<_ForwardIterator2>::value_type>)
688e4b17023SJohn Marino __glibcxx_requires_valid_range(__first1, __last1);
689e4b17023SJohn Marino __glibcxx_requires_valid_range(__first2, __last2);
690e4b17023SJohn Marino
691e4b17023SJohn Marino return std::__find_end(__first1, __last1, __first2, __last2,
692e4b17023SJohn Marino std::__iterator_category(__first1),
693e4b17023SJohn Marino std::__iterator_category(__first2));
694e4b17023SJohn Marino }
695e4b17023SJohn Marino
696e4b17023SJohn Marino /**
697e4b17023SJohn Marino * @brief Find last matching subsequence in a sequence using a predicate.
698e4b17023SJohn Marino * @ingroup non_mutating_algorithms
699e4b17023SJohn Marino * @param __first1 Start of range to search.
700e4b17023SJohn Marino * @param __last1 End of range to search.
701e4b17023SJohn Marino * @param __first2 Start of sequence to match.
702e4b17023SJohn Marino * @param __last2 End of sequence to match.
703e4b17023SJohn Marino * @param __comp The predicate to use.
704e4b17023SJohn Marino * @return The last iterator @c i in the range @p
705e4b17023SJohn Marino * [__first1,__last1-(__last2-__first2)) such that @c
706e4b17023SJohn Marino * predicate(*(i+N), @p (__first2+N)) is true for each @c N in the
707e4b17023SJohn Marino * range @p [0,__last2-__first2), or @p __last1 if no such iterator
708e4b17023SJohn Marino * exists.
709e4b17023SJohn Marino *
710e4b17023SJohn Marino * Searches the range @p [__first1,__last1) for a sub-sequence that
711e4b17023SJohn Marino * compares equal value-by-value with the sequence given by @p
712e4b17023SJohn Marino * [__first2,__last2) using comp as a predicate and returns an
713e4b17023SJohn Marino * iterator to the first element of the sub-sequence, or @p __last1
714e4b17023SJohn Marino * if the sub-sequence is not found. The sub-sequence will be the
715e4b17023SJohn Marino * last such subsequence contained in [__first,__last1).
716e4b17023SJohn Marino *
717e4b17023SJohn Marino * Because the sub-sequence must lie completely within the range @p
718e4b17023SJohn Marino * [__first1,__last1) it must start at a position less than @p
719e4b17023SJohn Marino * __last1-(__last2-__first2) where @p __last2-__first2 is the
720e4b17023SJohn Marino * length of the sub-sequence. This means that the returned
721e4b17023SJohn Marino * iterator @c i will be in the range @p
722e4b17023SJohn Marino * [__first1,__last1-(__last2-__first2))
723e4b17023SJohn Marino */
724e4b17023SJohn Marino template<typename _ForwardIterator1, typename _ForwardIterator2,
725e4b17023SJohn Marino typename _BinaryPredicate>
726e4b17023SJohn Marino inline _ForwardIterator1
727e4b17023SJohn Marino find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
728e4b17023SJohn Marino _ForwardIterator2 __first2, _ForwardIterator2 __last2,
729e4b17023SJohn Marino _BinaryPredicate __comp)
730e4b17023SJohn Marino {
731e4b17023SJohn Marino // concept requirements
732e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>)
733e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>)
734e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
735e4b17023SJohn Marino typename iterator_traits<_ForwardIterator1>::value_type,
736e4b17023SJohn Marino typename iterator_traits<_ForwardIterator2>::value_type>)
737e4b17023SJohn Marino __glibcxx_requires_valid_range(__first1, __last1);
738e4b17023SJohn Marino __glibcxx_requires_valid_range(__first2, __last2);
739e4b17023SJohn Marino
740e4b17023SJohn Marino return std::__find_end(__first1, __last1, __first2, __last2,
741e4b17023SJohn Marino std::__iterator_category(__first1),
742e4b17023SJohn Marino std::__iterator_category(__first2),
743e4b17023SJohn Marino __comp);
744e4b17023SJohn Marino }
745e4b17023SJohn Marino
746e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__
747e4b17023SJohn Marino /**
748e4b17023SJohn Marino * @brief Checks that a predicate is true for all the elements
749e4b17023SJohn Marino * of a sequence.
750e4b17023SJohn Marino * @ingroup non_mutating_algorithms
751e4b17023SJohn Marino * @param __first An input iterator.
752e4b17023SJohn Marino * @param __last An input iterator.
753e4b17023SJohn Marino * @param __pred A predicate.
754e4b17023SJohn Marino * @return True if the check is true, false otherwise.
755e4b17023SJohn Marino *
756e4b17023SJohn Marino * Returns true if @p __pred is true for each element in the range
757e4b17023SJohn Marino * @p [__first,__last), and false otherwise.
758e4b17023SJohn Marino */
759e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate>
760e4b17023SJohn Marino inline bool
761e4b17023SJohn Marino all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
762e4b17023SJohn Marino { return __last == std::find_if_not(__first, __last, __pred); }
763e4b17023SJohn Marino
764e4b17023SJohn Marino /**
765e4b17023SJohn Marino * @brief Checks that a predicate is false for all the elements
766e4b17023SJohn Marino * of a sequence.
767e4b17023SJohn Marino * @ingroup non_mutating_algorithms
768e4b17023SJohn Marino * @param __first An input iterator.
769e4b17023SJohn Marino * @param __last An input iterator.
770e4b17023SJohn Marino * @param __pred A predicate.
771e4b17023SJohn Marino * @return True if the check is true, false otherwise.
772e4b17023SJohn Marino *
773e4b17023SJohn Marino * Returns true if @p __pred is false for each element in the range
774e4b17023SJohn Marino * @p [__first,__last), and false otherwise.
775e4b17023SJohn Marino */
776e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate>
777e4b17023SJohn Marino inline bool
778e4b17023SJohn Marino none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
779e4b17023SJohn Marino { return __last == _GLIBCXX_STD_A::find_if(__first, __last, __pred); }
780e4b17023SJohn Marino
781e4b17023SJohn Marino /**
782e4b17023SJohn Marino * @brief Checks that a predicate is false for at least an element
783e4b17023SJohn Marino * of a sequence.
784e4b17023SJohn Marino * @ingroup non_mutating_algorithms
785e4b17023SJohn Marino * @param __first An input iterator.
786e4b17023SJohn Marino * @param __last An input iterator.
787e4b17023SJohn Marino * @param __pred A predicate.
788e4b17023SJohn Marino * @return True if the check is true, false otherwise.
789e4b17023SJohn Marino *
790e4b17023SJohn Marino * Returns true if an element exists in the range @p
791e4b17023SJohn Marino * [__first,__last) such that @p __pred is true, and false
792e4b17023SJohn Marino * otherwise.
793e4b17023SJohn Marino */
794e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate>
795e4b17023SJohn Marino inline bool
796e4b17023SJohn Marino any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
797e4b17023SJohn Marino { return !std::none_of(__first, __last, __pred); }
798e4b17023SJohn Marino
799e4b17023SJohn Marino /**
800e4b17023SJohn Marino * @brief Find the first element in a sequence for which a
801e4b17023SJohn Marino * predicate is false.
802e4b17023SJohn Marino * @ingroup non_mutating_algorithms
803e4b17023SJohn Marino * @param __first An input iterator.
804e4b17023SJohn Marino * @param __last An input iterator.
805e4b17023SJohn Marino * @param __pred A predicate.
806e4b17023SJohn Marino * @return The first iterator @c i in the range @p [__first,__last)
807e4b17023SJohn Marino * such that @p __pred(*i) is false, or @p __last if no such iterator exists.
808e4b17023SJohn Marino */
809e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate>
810e4b17023SJohn Marino inline _InputIterator
811e4b17023SJohn Marino find_if_not(_InputIterator __first, _InputIterator __last,
812e4b17023SJohn Marino _Predicate __pred)
813e4b17023SJohn Marino {
814e4b17023SJohn Marino // concept requirements
815e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
816e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
817e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
818e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
819e4b17023SJohn Marino return std::__find_if_not(__first, __last, __pred);
820e4b17023SJohn Marino }
821e4b17023SJohn Marino
822e4b17023SJohn Marino /**
823e4b17023SJohn Marino * @brief Checks whether the sequence is partitioned.
824e4b17023SJohn Marino * @ingroup mutating_algorithms
825e4b17023SJohn Marino * @param __first An input iterator.
826e4b17023SJohn Marino * @param __last An input iterator.
827e4b17023SJohn Marino * @param __pred A predicate.
828e4b17023SJohn Marino * @return True if the range @p [__first,__last) is partioned by @p __pred,
829e4b17023SJohn Marino * i.e. if all elements that satisfy @p __pred appear before those that
830e4b17023SJohn Marino * do not.
831e4b17023SJohn Marino */
832e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate>
833e4b17023SJohn Marino inline bool
834e4b17023SJohn Marino is_partitioned(_InputIterator __first, _InputIterator __last,
835e4b17023SJohn Marino _Predicate __pred)
836e4b17023SJohn Marino {
837e4b17023SJohn Marino __first = std::find_if_not(__first, __last, __pred);
838e4b17023SJohn Marino return std::none_of(__first, __last, __pred);
839e4b17023SJohn Marino }
840e4b17023SJohn Marino
841e4b17023SJohn Marino /**
842e4b17023SJohn Marino * @brief Find the partition point of a partitioned range.
843e4b17023SJohn Marino * @ingroup mutating_algorithms
844e4b17023SJohn Marino * @param __first An iterator.
845e4b17023SJohn Marino * @param __last Another iterator.
846e4b17023SJohn Marino * @param __pred A predicate.
847e4b17023SJohn Marino * @return An iterator @p mid such that @p all_of(__first, mid, __pred)
848e4b17023SJohn Marino * and @p none_of(mid, __last, __pred) are both true.
849e4b17023SJohn Marino */
850e4b17023SJohn Marino template<typename _ForwardIterator, typename _Predicate>
851e4b17023SJohn Marino _ForwardIterator
852e4b17023SJohn Marino partition_point(_ForwardIterator __first, _ForwardIterator __last,
853e4b17023SJohn Marino _Predicate __pred)
854e4b17023SJohn Marino {
855e4b17023SJohn Marino // concept requirements
856e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
857e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
858e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
859e4b17023SJohn Marino
860e4b17023SJohn Marino // A specific debug-mode test will be necessary...
861e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
862e4b17023SJohn Marino
863e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::difference_type
864e4b17023SJohn Marino _DistanceType;
865e4b17023SJohn Marino
866e4b17023SJohn Marino _DistanceType __len = std::distance(__first, __last);
867e4b17023SJohn Marino _DistanceType __half;
868e4b17023SJohn Marino _ForwardIterator __middle;
869e4b17023SJohn Marino
870e4b17023SJohn Marino while (__len > 0)
871e4b17023SJohn Marino {
872e4b17023SJohn Marino __half = __len >> 1;
873e4b17023SJohn Marino __middle = __first;
874e4b17023SJohn Marino std::advance(__middle, __half);
875e4b17023SJohn Marino if (__pred(*__middle))
876e4b17023SJohn Marino {
877e4b17023SJohn Marino __first = __middle;
878e4b17023SJohn Marino ++__first;
879e4b17023SJohn Marino __len = __len - __half - 1;
880e4b17023SJohn Marino }
881e4b17023SJohn Marino else
882e4b17023SJohn Marino __len = __half;
883e4b17023SJohn Marino }
884e4b17023SJohn Marino return __first;
885e4b17023SJohn Marino }
886e4b17023SJohn Marino #endif
887e4b17023SJohn Marino
888e4b17023SJohn Marino
889e4b17023SJohn Marino /**
890e4b17023SJohn Marino * @brief Copy a sequence, removing elements of a given value.
891e4b17023SJohn Marino * @ingroup mutating_algorithms
892e4b17023SJohn Marino * @param __first An input iterator.
893e4b17023SJohn Marino * @param __last An input iterator.
894e4b17023SJohn Marino * @param __result An output iterator.
895e4b17023SJohn Marino * @param __value The value to be removed.
896e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence.
897e4b17023SJohn Marino *
898e4b17023SJohn Marino * Copies each element in the range @p [__first,__last) not equal
899e4b17023SJohn Marino * to @p __value to the range beginning at @p __result.
900e4b17023SJohn Marino * remove_copy() is stable, so the relative order of elements that
901e4b17023SJohn Marino * are copied is unchanged.
902e4b17023SJohn Marino */
903e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator, typename _Tp>
904e4b17023SJohn Marino _OutputIterator
905e4b17023SJohn Marino remove_copy(_InputIterator __first, _InputIterator __last,
906e4b17023SJohn Marino _OutputIterator __result, const _Tp& __value)
907e4b17023SJohn Marino {
908e4b17023SJohn Marino // concept requirements
909e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
910e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
911e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
912e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept<
913e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type, _Tp>)
914e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
915e4b17023SJohn Marino
916e4b17023SJohn Marino for (; __first != __last; ++__first)
917e4b17023SJohn Marino if (!(*__first == __value))
918e4b17023SJohn Marino {
919e4b17023SJohn Marino *__result = *__first;
920e4b17023SJohn Marino ++__result;
921e4b17023SJohn Marino }
922e4b17023SJohn Marino return __result;
923e4b17023SJohn Marino }
924e4b17023SJohn Marino
925e4b17023SJohn Marino /**
926e4b17023SJohn Marino * @brief Copy a sequence, removing elements for which a predicate is true.
927e4b17023SJohn Marino * @ingroup mutating_algorithms
928e4b17023SJohn Marino * @param __first An input iterator.
929e4b17023SJohn Marino * @param __last An input iterator.
930e4b17023SJohn Marino * @param __result An output iterator.
931e4b17023SJohn Marino * @param __pred A predicate.
932e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence.
933e4b17023SJohn Marino *
934e4b17023SJohn Marino * Copies each element in the range @p [__first,__last) for which
935e4b17023SJohn Marino * @p __pred returns false to the range beginning at @p __result.
936e4b17023SJohn Marino *
937e4b17023SJohn Marino * remove_copy_if() is stable, so the relative order of elements that are
938e4b17023SJohn Marino * copied is unchanged.
939e4b17023SJohn Marino */
940e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator,
941e4b17023SJohn Marino typename _Predicate>
942e4b17023SJohn Marino _OutputIterator
943e4b17023SJohn Marino remove_copy_if(_InputIterator __first, _InputIterator __last,
944e4b17023SJohn Marino _OutputIterator __result, _Predicate __pred)
945e4b17023SJohn Marino {
946e4b17023SJohn Marino // concept requirements
947e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
948e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
949e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
950e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
951e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
952e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
953e4b17023SJohn Marino
954e4b17023SJohn Marino for (; __first != __last; ++__first)
955e4b17023SJohn Marino if (!bool(__pred(*__first)))
956e4b17023SJohn Marino {
957e4b17023SJohn Marino *__result = *__first;
958e4b17023SJohn Marino ++__result;
959e4b17023SJohn Marino }
960e4b17023SJohn Marino return __result;
961e4b17023SJohn Marino }
962e4b17023SJohn Marino
963e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__
964e4b17023SJohn Marino /**
965e4b17023SJohn Marino * @brief Copy the elements of a sequence for which a predicate is true.
966e4b17023SJohn Marino * @ingroup mutating_algorithms
967e4b17023SJohn Marino * @param __first An input iterator.
968e4b17023SJohn Marino * @param __last An input iterator.
969e4b17023SJohn Marino * @param __result An output iterator.
970e4b17023SJohn Marino * @param __pred A predicate.
971e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence.
972e4b17023SJohn Marino *
973e4b17023SJohn Marino * Copies each element in the range @p [__first,__last) for which
974e4b17023SJohn Marino * @p __pred returns true to the range beginning at @p __result.
975e4b17023SJohn Marino *
976e4b17023SJohn Marino * copy_if() is stable, so the relative order of elements that are
977e4b17023SJohn Marino * copied is unchanged.
978e4b17023SJohn Marino */
979e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator,
980e4b17023SJohn Marino typename _Predicate>
981e4b17023SJohn Marino _OutputIterator
982e4b17023SJohn Marino copy_if(_InputIterator __first, _InputIterator __last,
983e4b17023SJohn Marino _OutputIterator __result, _Predicate __pred)
984e4b17023SJohn Marino {
985e4b17023SJohn Marino // concept requirements
986e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
987e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
988e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
989e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
990e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
991e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
992e4b17023SJohn Marino
993e4b17023SJohn Marino for (; __first != __last; ++__first)
994e4b17023SJohn Marino if (__pred(*__first))
995e4b17023SJohn Marino {
996e4b17023SJohn Marino *__result = *__first;
997e4b17023SJohn Marino ++__result;
998e4b17023SJohn Marino }
999e4b17023SJohn Marino return __result;
1000e4b17023SJohn Marino }
1001e4b17023SJohn Marino
1002e4b17023SJohn Marino
1003e4b17023SJohn Marino template<typename _InputIterator, typename _Size, typename _OutputIterator>
1004e4b17023SJohn Marino _OutputIterator
1005e4b17023SJohn Marino __copy_n(_InputIterator __first, _Size __n,
1006e4b17023SJohn Marino _OutputIterator __result, input_iterator_tag)
1007e4b17023SJohn Marino {
1008e4b17023SJohn Marino if (__n > 0)
1009e4b17023SJohn Marino {
1010e4b17023SJohn Marino while (true)
1011e4b17023SJohn Marino {
1012e4b17023SJohn Marino *__result = *__first;
1013e4b17023SJohn Marino ++__result;
1014e4b17023SJohn Marino if (--__n > 0)
1015e4b17023SJohn Marino ++__first;
1016e4b17023SJohn Marino else
1017e4b17023SJohn Marino break;
1018e4b17023SJohn Marino }
1019e4b17023SJohn Marino }
1020e4b17023SJohn Marino return __result;
1021e4b17023SJohn Marino }
1022e4b17023SJohn Marino
1023e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Size,
1024e4b17023SJohn Marino typename _OutputIterator>
1025e4b17023SJohn Marino inline _OutputIterator
1026e4b17023SJohn Marino __copy_n(_RandomAccessIterator __first, _Size __n,
1027e4b17023SJohn Marino _OutputIterator __result, random_access_iterator_tag)
1028e4b17023SJohn Marino { return std::copy(__first, __first + __n, __result); }
1029e4b17023SJohn Marino
1030e4b17023SJohn Marino /**
1031e4b17023SJohn Marino * @brief Copies the range [first,first+n) into [result,result+n).
1032e4b17023SJohn Marino * @ingroup mutating_algorithms
1033e4b17023SJohn Marino * @param __first An input iterator.
1034e4b17023SJohn Marino * @param __n The number of elements to copy.
1035e4b17023SJohn Marino * @param __result An output iterator.
1036e4b17023SJohn Marino * @return result+n.
1037e4b17023SJohn Marino *
1038e4b17023SJohn Marino * This inline function will boil down to a call to @c memmove whenever
1039e4b17023SJohn Marino * possible. Failing that, if random access iterators are passed, then the
1040e4b17023SJohn Marino * loop count will be known (and therefore a candidate for compiler
1041e4b17023SJohn Marino * optimizations such as unrolling).
1042e4b17023SJohn Marino */
1043e4b17023SJohn Marino template<typename _InputIterator, typename _Size, typename _OutputIterator>
1044e4b17023SJohn Marino inline _OutputIterator
1045e4b17023SJohn Marino copy_n(_InputIterator __first, _Size __n, _OutputIterator __result)
1046e4b17023SJohn Marino {
1047e4b17023SJohn Marino // concept requirements
1048e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
1049e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
1050e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
1051e4b17023SJohn Marino
1052e4b17023SJohn Marino return std::__copy_n(__first, __n, __result,
1053e4b17023SJohn Marino std::__iterator_category(__first));
1054e4b17023SJohn Marino }
1055e4b17023SJohn Marino
1056e4b17023SJohn Marino /**
1057e4b17023SJohn Marino * @brief Copy the elements of a sequence to separate output sequences
1058e4b17023SJohn Marino * depending on the truth value of a predicate.
1059e4b17023SJohn Marino * @ingroup mutating_algorithms
1060e4b17023SJohn Marino * @param __first An input iterator.
1061e4b17023SJohn Marino * @param __last An input iterator.
1062e4b17023SJohn Marino * @param __out_true An output iterator.
1063e4b17023SJohn Marino * @param __out_false An output iterator.
1064e4b17023SJohn Marino * @param __pred A predicate.
1065e4b17023SJohn Marino * @return A pair designating the ends of the resulting sequences.
1066e4b17023SJohn Marino *
1067e4b17023SJohn Marino * Copies each element in the range @p [__first,__last) for which
1068e4b17023SJohn Marino * @p __pred returns true to the range beginning at @p out_true
1069e4b17023SJohn Marino * and each element for which @p __pred returns false to @p __out_false.
1070e4b17023SJohn Marino */
1071e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator1,
1072e4b17023SJohn Marino typename _OutputIterator2, typename _Predicate>
1073e4b17023SJohn Marino pair<_OutputIterator1, _OutputIterator2>
1074e4b17023SJohn Marino partition_copy(_InputIterator __first, _InputIterator __last,
1075e4b17023SJohn Marino _OutputIterator1 __out_true, _OutputIterator2 __out_false,
1076e4b17023SJohn Marino _Predicate __pred)
1077e4b17023SJohn Marino {
1078e4b17023SJohn Marino // concept requirements
1079e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
1080e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator1,
1081e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
1082e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator2,
1083e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
1084e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
1085e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
1086e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
1087e4b17023SJohn Marino
1088e4b17023SJohn Marino for (; __first != __last; ++__first)
1089e4b17023SJohn Marino if (__pred(*__first))
1090e4b17023SJohn Marino {
1091e4b17023SJohn Marino *__out_true = *__first;
1092e4b17023SJohn Marino ++__out_true;
1093e4b17023SJohn Marino }
1094e4b17023SJohn Marino else
1095e4b17023SJohn Marino {
1096e4b17023SJohn Marino *__out_false = *__first;
1097e4b17023SJohn Marino ++__out_false;
1098e4b17023SJohn Marino }
1099e4b17023SJohn Marino
1100e4b17023SJohn Marino return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false);
1101e4b17023SJohn Marino }
1102e4b17023SJohn Marino #endif
1103e4b17023SJohn Marino
1104e4b17023SJohn Marino /**
1105e4b17023SJohn Marino * @brief Remove elements from a sequence.
1106e4b17023SJohn Marino * @ingroup mutating_algorithms
1107e4b17023SJohn Marino * @param __first An input iterator.
1108e4b17023SJohn Marino * @param __last An input iterator.
1109e4b17023SJohn Marino * @param __value The value to be removed.
1110e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence.
1111e4b17023SJohn Marino *
1112e4b17023SJohn Marino * All elements equal to @p __value are removed from the range
1113e4b17023SJohn Marino * @p [__first,__last).
1114e4b17023SJohn Marino *
1115e4b17023SJohn Marino * remove() is stable, so the relative order of elements that are
1116e4b17023SJohn Marino * not removed is unchanged.
1117e4b17023SJohn Marino *
1118e4b17023SJohn Marino * Elements between the end of the resulting sequence and @p __last
1119e4b17023SJohn Marino * are still present, but their value is unspecified.
1120e4b17023SJohn Marino */
1121e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp>
1122e4b17023SJohn Marino _ForwardIterator
1123e4b17023SJohn Marino remove(_ForwardIterator __first, _ForwardIterator __last,
1124e4b17023SJohn Marino const _Tp& __value)
1125e4b17023SJohn Marino {
1126e4b17023SJohn Marino // concept requirements
1127e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
1128e4b17023SJohn Marino _ForwardIterator>)
1129e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept<
1130e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
1131e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
1132e4b17023SJohn Marino
1133e4b17023SJohn Marino __first = _GLIBCXX_STD_A::find(__first, __last, __value);
1134e4b17023SJohn Marino if(__first == __last)
1135e4b17023SJohn Marino return __first;
1136e4b17023SJohn Marino _ForwardIterator __result = __first;
1137e4b17023SJohn Marino ++__first;
1138e4b17023SJohn Marino for(; __first != __last; ++__first)
1139e4b17023SJohn Marino if(!(*__first == __value))
1140e4b17023SJohn Marino {
1141e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first);
1142e4b17023SJohn Marino ++__result;
1143e4b17023SJohn Marino }
1144e4b17023SJohn Marino return __result;
1145e4b17023SJohn Marino }
1146e4b17023SJohn Marino
1147e4b17023SJohn Marino /**
1148e4b17023SJohn Marino * @brief Remove elements from a sequence using a predicate.
1149e4b17023SJohn Marino * @ingroup mutating_algorithms
1150e4b17023SJohn Marino * @param __first A forward iterator.
1151e4b17023SJohn Marino * @param __last A forward iterator.
1152e4b17023SJohn Marino * @param __pred A predicate.
1153e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence.
1154e4b17023SJohn Marino *
1155e4b17023SJohn Marino * All elements for which @p __pred returns true are removed from the range
1156e4b17023SJohn Marino * @p [__first,__last).
1157e4b17023SJohn Marino *
1158e4b17023SJohn Marino * remove_if() is stable, so the relative order of elements that are
1159e4b17023SJohn Marino * not removed is unchanged.
1160e4b17023SJohn Marino *
1161e4b17023SJohn Marino * Elements between the end of the resulting sequence and @p __last
1162e4b17023SJohn Marino * are still present, but their value is unspecified.
1163e4b17023SJohn Marino */
1164e4b17023SJohn Marino template<typename _ForwardIterator, typename _Predicate>
1165e4b17023SJohn Marino _ForwardIterator
1166e4b17023SJohn Marino remove_if(_ForwardIterator __first, _ForwardIterator __last,
1167e4b17023SJohn Marino _Predicate __pred)
1168e4b17023SJohn Marino {
1169e4b17023SJohn Marino // concept requirements
1170e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
1171e4b17023SJohn Marino _ForwardIterator>)
1172e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
1173e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
1174e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
1175e4b17023SJohn Marino
1176e4b17023SJohn Marino __first = _GLIBCXX_STD_A::find_if(__first, __last, __pred);
1177e4b17023SJohn Marino if(__first == __last)
1178e4b17023SJohn Marino return __first;
1179e4b17023SJohn Marino _ForwardIterator __result = __first;
1180e4b17023SJohn Marino ++__first;
1181e4b17023SJohn Marino for(; __first != __last; ++__first)
1182e4b17023SJohn Marino if(!bool(__pred(*__first)))
1183e4b17023SJohn Marino {
1184e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first);
1185e4b17023SJohn Marino ++__result;
1186e4b17023SJohn Marino }
1187e4b17023SJohn Marino return __result;
1188e4b17023SJohn Marino }
1189e4b17023SJohn Marino
1190e4b17023SJohn Marino /**
1191e4b17023SJohn Marino * @brief Remove consecutive duplicate values from a sequence.
1192e4b17023SJohn Marino * @ingroup mutating_algorithms
1193e4b17023SJohn Marino * @param __first A forward iterator.
1194e4b17023SJohn Marino * @param __last A forward iterator.
1195e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence.
1196e4b17023SJohn Marino *
1197e4b17023SJohn Marino * Removes all but the first element from each group of consecutive
1198e4b17023SJohn Marino * values that compare equal.
1199e4b17023SJohn Marino * unique() is stable, so the relative order of elements that are
1200e4b17023SJohn Marino * not removed is unchanged.
1201e4b17023SJohn Marino * Elements between the end of the resulting sequence and @p __last
1202e4b17023SJohn Marino * are still present, but their value is unspecified.
1203e4b17023SJohn Marino */
1204e4b17023SJohn Marino template<typename _ForwardIterator>
1205e4b17023SJohn Marino _ForwardIterator
1206e4b17023SJohn Marino unique(_ForwardIterator __first, _ForwardIterator __last)
1207e4b17023SJohn Marino {
1208e4b17023SJohn Marino // concept requirements
1209e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
1210e4b17023SJohn Marino _ForwardIterator>)
1211e4b17023SJohn Marino __glibcxx_function_requires(_EqualityComparableConcept<
1212e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
1213e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
1214e4b17023SJohn Marino
1215e4b17023SJohn Marino // Skip the beginning, if already unique.
1216e4b17023SJohn Marino __first = _GLIBCXX_STD_A::adjacent_find(__first, __last);
1217e4b17023SJohn Marino if (__first == __last)
1218e4b17023SJohn Marino return __last;
1219e4b17023SJohn Marino
1220e4b17023SJohn Marino // Do the real copy work.
1221e4b17023SJohn Marino _ForwardIterator __dest = __first;
1222e4b17023SJohn Marino ++__first;
1223e4b17023SJohn Marino while (++__first != __last)
1224e4b17023SJohn Marino if (!(*__dest == *__first))
1225e4b17023SJohn Marino *++__dest = _GLIBCXX_MOVE(*__first);
1226e4b17023SJohn Marino return ++__dest;
1227e4b17023SJohn Marino }
1228e4b17023SJohn Marino
1229e4b17023SJohn Marino /**
1230e4b17023SJohn Marino * @brief Remove consecutive values from a sequence using a predicate.
1231e4b17023SJohn Marino * @ingroup mutating_algorithms
1232e4b17023SJohn Marino * @param __first A forward iterator.
1233e4b17023SJohn Marino * @param __last A forward iterator.
1234e4b17023SJohn Marino * @param __binary_pred A binary predicate.
1235e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence.
1236e4b17023SJohn Marino *
1237e4b17023SJohn Marino * Removes all but the first element from each group of consecutive
1238e4b17023SJohn Marino * values for which @p __binary_pred returns true.
1239e4b17023SJohn Marino * unique() is stable, so the relative order of elements that are
1240e4b17023SJohn Marino * not removed is unchanged.
1241e4b17023SJohn Marino * Elements between the end of the resulting sequence and @p __last
1242e4b17023SJohn Marino * are still present, but their value is unspecified.
1243e4b17023SJohn Marino */
1244e4b17023SJohn Marino template<typename _ForwardIterator, typename _BinaryPredicate>
1245e4b17023SJohn Marino _ForwardIterator
1246e4b17023SJohn Marino unique(_ForwardIterator __first, _ForwardIterator __last,
1247e4b17023SJohn Marino _BinaryPredicate __binary_pred)
1248e4b17023SJohn Marino {
1249e4b17023SJohn Marino // concept requirements
1250e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
1251e4b17023SJohn Marino _ForwardIterator>)
1252e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
1253e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type,
1254e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
1255e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
1256e4b17023SJohn Marino
1257e4b17023SJohn Marino // Skip the beginning, if already unique.
1258e4b17023SJohn Marino __first = _GLIBCXX_STD_A::adjacent_find(__first, __last, __binary_pred);
1259e4b17023SJohn Marino if (__first == __last)
1260e4b17023SJohn Marino return __last;
1261e4b17023SJohn Marino
1262e4b17023SJohn Marino // Do the real copy work.
1263e4b17023SJohn Marino _ForwardIterator __dest = __first;
1264e4b17023SJohn Marino ++__first;
1265e4b17023SJohn Marino while (++__first != __last)
1266e4b17023SJohn Marino if (!bool(__binary_pred(*__dest, *__first)))
1267e4b17023SJohn Marino *++__dest = _GLIBCXX_MOVE(*__first);
1268e4b17023SJohn Marino return ++__dest;
1269e4b17023SJohn Marino }
1270e4b17023SJohn Marino
1271e4b17023SJohn Marino /**
1272e4b17023SJohn Marino * This is an uglified unique_copy(_InputIterator, _InputIterator,
1273e4b17023SJohn Marino * _OutputIterator)
1274e4b17023SJohn Marino * overloaded for forward iterators and output iterator as result.
1275e4b17023SJohn Marino */
1276e4b17023SJohn Marino template<typename _ForwardIterator, typename _OutputIterator>
1277e4b17023SJohn Marino _OutputIterator
1278e4b17023SJohn Marino __unique_copy(_ForwardIterator __first, _ForwardIterator __last,
1279e4b17023SJohn Marino _OutputIterator __result,
1280e4b17023SJohn Marino forward_iterator_tag, output_iterator_tag)
1281e4b17023SJohn Marino {
1282e4b17023SJohn Marino // concept requirements -- taken care of in dispatching function
1283e4b17023SJohn Marino _ForwardIterator __next = __first;
1284e4b17023SJohn Marino *__result = *__first;
1285e4b17023SJohn Marino while (++__next != __last)
1286e4b17023SJohn Marino if (!(*__first == *__next))
1287e4b17023SJohn Marino {
1288e4b17023SJohn Marino __first = __next;
1289e4b17023SJohn Marino *++__result = *__first;
1290e4b17023SJohn Marino }
1291e4b17023SJohn Marino return ++__result;
1292e4b17023SJohn Marino }
1293e4b17023SJohn Marino
1294e4b17023SJohn Marino /**
1295e4b17023SJohn Marino * This is an uglified unique_copy(_InputIterator, _InputIterator,
1296e4b17023SJohn Marino * _OutputIterator)
1297e4b17023SJohn Marino * overloaded for input iterators and output iterator as result.
1298e4b17023SJohn Marino */
1299e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator>
1300e4b17023SJohn Marino _OutputIterator
1301e4b17023SJohn Marino __unique_copy(_InputIterator __first, _InputIterator __last,
1302e4b17023SJohn Marino _OutputIterator __result,
1303e4b17023SJohn Marino input_iterator_tag, output_iterator_tag)
1304e4b17023SJohn Marino {
1305e4b17023SJohn Marino // concept requirements -- taken care of in dispatching function
1306e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type __value = *__first;
1307e4b17023SJohn Marino *__result = __value;
1308e4b17023SJohn Marino while (++__first != __last)
1309e4b17023SJohn Marino if (!(__value == *__first))
1310e4b17023SJohn Marino {
1311e4b17023SJohn Marino __value = *__first;
1312e4b17023SJohn Marino *++__result = __value;
1313e4b17023SJohn Marino }
1314e4b17023SJohn Marino return ++__result;
1315e4b17023SJohn Marino }
1316e4b17023SJohn Marino
1317e4b17023SJohn Marino /**
1318e4b17023SJohn Marino * This is an uglified unique_copy(_InputIterator, _InputIterator,
1319e4b17023SJohn Marino * _OutputIterator)
1320e4b17023SJohn Marino * overloaded for input iterators and forward iterator as result.
1321e4b17023SJohn Marino */
1322e4b17023SJohn Marino template<typename _InputIterator, typename _ForwardIterator>
1323e4b17023SJohn Marino _ForwardIterator
1324e4b17023SJohn Marino __unique_copy(_InputIterator __first, _InputIterator __last,
1325e4b17023SJohn Marino _ForwardIterator __result,
1326e4b17023SJohn Marino input_iterator_tag, forward_iterator_tag)
1327e4b17023SJohn Marino {
1328e4b17023SJohn Marino // concept requirements -- taken care of in dispatching function
1329e4b17023SJohn Marino *__result = *__first;
1330e4b17023SJohn Marino while (++__first != __last)
1331e4b17023SJohn Marino if (!(*__result == *__first))
1332e4b17023SJohn Marino *++__result = *__first;
1333e4b17023SJohn Marino return ++__result;
1334e4b17023SJohn Marino }
1335e4b17023SJohn Marino
1336e4b17023SJohn Marino /**
1337e4b17023SJohn Marino * This is an uglified
1338e4b17023SJohn Marino * unique_copy(_InputIterator, _InputIterator, _OutputIterator,
1339e4b17023SJohn Marino * _BinaryPredicate)
1340e4b17023SJohn Marino * overloaded for forward iterators and output iterator as result.
1341e4b17023SJohn Marino */
1342e4b17023SJohn Marino template<typename _ForwardIterator, typename _OutputIterator,
1343e4b17023SJohn Marino typename _BinaryPredicate>
1344e4b17023SJohn Marino _OutputIterator
1345e4b17023SJohn Marino __unique_copy(_ForwardIterator __first, _ForwardIterator __last,
1346e4b17023SJohn Marino _OutputIterator __result, _BinaryPredicate __binary_pred,
1347e4b17023SJohn Marino forward_iterator_tag, output_iterator_tag)
1348e4b17023SJohn Marino {
1349e4b17023SJohn Marino // concept requirements -- iterators already checked
1350e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
1351e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type,
1352e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
1353e4b17023SJohn Marino
1354e4b17023SJohn Marino _ForwardIterator __next = __first;
1355e4b17023SJohn Marino *__result = *__first;
1356e4b17023SJohn Marino while (++__next != __last)
1357e4b17023SJohn Marino if (!bool(__binary_pred(*__first, *__next)))
1358e4b17023SJohn Marino {
1359e4b17023SJohn Marino __first = __next;
1360e4b17023SJohn Marino *++__result = *__first;
1361e4b17023SJohn Marino }
1362e4b17023SJohn Marino return ++__result;
1363e4b17023SJohn Marino }
1364e4b17023SJohn Marino
1365e4b17023SJohn Marino /**
1366e4b17023SJohn Marino * This is an uglified
1367e4b17023SJohn Marino * unique_copy(_InputIterator, _InputIterator, _OutputIterator,
1368e4b17023SJohn Marino * _BinaryPredicate)
1369e4b17023SJohn Marino * overloaded for input iterators and output iterator as result.
1370e4b17023SJohn Marino */
1371e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator,
1372e4b17023SJohn Marino typename _BinaryPredicate>
1373e4b17023SJohn Marino _OutputIterator
1374e4b17023SJohn Marino __unique_copy(_InputIterator __first, _InputIterator __last,
1375e4b17023SJohn Marino _OutputIterator __result, _BinaryPredicate __binary_pred,
1376e4b17023SJohn Marino input_iterator_tag, output_iterator_tag)
1377e4b17023SJohn Marino {
1378e4b17023SJohn Marino // concept requirements -- iterators already checked
1379e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
1380e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type,
1381e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
1382e4b17023SJohn Marino
1383e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type __value = *__first;
1384e4b17023SJohn Marino *__result = __value;
1385e4b17023SJohn Marino while (++__first != __last)
1386e4b17023SJohn Marino if (!bool(__binary_pred(__value, *__first)))
1387e4b17023SJohn Marino {
1388e4b17023SJohn Marino __value = *__first;
1389e4b17023SJohn Marino *++__result = __value;
1390e4b17023SJohn Marino }
1391e4b17023SJohn Marino return ++__result;
1392e4b17023SJohn Marino }
1393e4b17023SJohn Marino
1394e4b17023SJohn Marino /**
1395e4b17023SJohn Marino * This is an uglified
1396e4b17023SJohn Marino * unique_copy(_InputIterator, _InputIterator, _OutputIterator,
1397e4b17023SJohn Marino * _BinaryPredicate)
1398e4b17023SJohn Marino * overloaded for input iterators and forward iterator as result.
1399e4b17023SJohn Marino */
1400e4b17023SJohn Marino template<typename _InputIterator, typename _ForwardIterator,
1401e4b17023SJohn Marino typename _BinaryPredicate>
1402e4b17023SJohn Marino _ForwardIterator
1403e4b17023SJohn Marino __unique_copy(_InputIterator __first, _InputIterator __last,
1404e4b17023SJohn Marino _ForwardIterator __result, _BinaryPredicate __binary_pred,
1405e4b17023SJohn Marino input_iterator_tag, forward_iterator_tag)
1406e4b17023SJohn Marino {
1407e4b17023SJohn Marino // concept requirements -- iterators already checked
1408e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
1409e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type,
1410e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
1411e4b17023SJohn Marino
1412e4b17023SJohn Marino *__result = *__first;
1413e4b17023SJohn Marino while (++__first != __last)
1414e4b17023SJohn Marino if (!bool(__binary_pred(*__result, *__first)))
1415e4b17023SJohn Marino *++__result = *__first;
1416e4b17023SJohn Marino return ++__result;
1417e4b17023SJohn Marino }
1418e4b17023SJohn Marino
1419e4b17023SJohn Marino /**
1420e4b17023SJohn Marino * This is an uglified reverse(_BidirectionalIterator,
1421e4b17023SJohn Marino * _BidirectionalIterator)
1422e4b17023SJohn Marino * overloaded for bidirectional iterators.
1423e4b17023SJohn Marino */
1424e4b17023SJohn Marino template<typename _BidirectionalIterator>
1425e4b17023SJohn Marino void
1426e4b17023SJohn Marino __reverse(_BidirectionalIterator __first, _BidirectionalIterator __last,
1427e4b17023SJohn Marino bidirectional_iterator_tag)
1428e4b17023SJohn Marino {
1429e4b17023SJohn Marino while (true)
1430e4b17023SJohn Marino if (__first == __last || __first == --__last)
1431e4b17023SJohn Marino return;
1432e4b17023SJohn Marino else
1433e4b17023SJohn Marino {
1434e4b17023SJohn Marino std::iter_swap(__first, __last);
1435e4b17023SJohn Marino ++__first;
1436e4b17023SJohn Marino }
1437e4b17023SJohn Marino }
1438e4b17023SJohn Marino
1439e4b17023SJohn Marino /**
1440e4b17023SJohn Marino * This is an uglified reverse(_BidirectionalIterator,
1441e4b17023SJohn Marino * _BidirectionalIterator)
1442e4b17023SJohn Marino * overloaded for random access iterators.
1443e4b17023SJohn Marino */
1444e4b17023SJohn Marino template<typename _RandomAccessIterator>
1445e4b17023SJohn Marino void
1446e4b17023SJohn Marino __reverse(_RandomAccessIterator __first, _RandomAccessIterator __last,
1447e4b17023SJohn Marino random_access_iterator_tag)
1448e4b17023SJohn Marino {
1449e4b17023SJohn Marino if (__first == __last)
1450e4b17023SJohn Marino return;
1451e4b17023SJohn Marino --__last;
1452e4b17023SJohn Marino while (__first < __last)
1453e4b17023SJohn Marino {
1454e4b17023SJohn Marino std::iter_swap(__first, __last);
1455e4b17023SJohn Marino ++__first;
1456e4b17023SJohn Marino --__last;
1457e4b17023SJohn Marino }
1458e4b17023SJohn Marino }
1459e4b17023SJohn Marino
1460e4b17023SJohn Marino /**
1461e4b17023SJohn Marino * @brief Reverse a sequence.
1462e4b17023SJohn Marino * @ingroup mutating_algorithms
1463e4b17023SJohn Marino * @param __first A bidirectional iterator.
1464e4b17023SJohn Marino * @param __last A bidirectional iterator.
1465e4b17023SJohn Marino * @return reverse() returns no value.
1466e4b17023SJohn Marino *
1467e4b17023SJohn Marino * Reverses the order of the elements in the range @p [__first,__last),
1468e4b17023SJohn Marino * so that the first element becomes the last etc.
1469e4b17023SJohn Marino * For every @c i such that @p 0<=i<=(__last-__first)/2), @p reverse()
1470e4b17023SJohn Marino * swaps @p *(__first+i) and @p *(__last-(i+1))
1471e4b17023SJohn Marino */
1472e4b17023SJohn Marino template<typename _BidirectionalIterator>
1473e4b17023SJohn Marino inline void
1474e4b17023SJohn Marino reverse(_BidirectionalIterator __first, _BidirectionalIterator __last)
1475e4b17023SJohn Marino {
1476e4b17023SJohn Marino // concept requirements
1477e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
1478e4b17023SJohn Marino _BidirectionalIterator>)
1479e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
1480e4b17023SJohn Marino std::__reverse(__first, __last, std::__iterator_category(__first));
1481e4b17023SJohn Marino }
1482e4b17023SJohn Marino
1483e4b17023SJohn Marino /**
1484e4b17023SJohn Marino * @brief Copy a sequence, reversing its elements.
1485e4b17023SJohn Marino * @ingroup mutating_algorithms
1486e4b17023SJohn Marino * @param __first A bidirectional iterator.
1487e4b17023SJohn Marino * @param __last A bidirectional iterator.
1488e4b17023SJohn Marino * @param __result An output iterator.
1489e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence.
1490e4b17023SJohn Marino *
1491e4b17023SJohn Marino * Copies the elements in the range @p [__first,__last) to the
1492e4b17023SJohn Marino * range @p [__result,__result+(__last-__first)) such that the
1493e4b17023SJohn Marino * order of the elements is reversed. For every @c i such that @p
1494e4b17023SJohn Marino * 0<=i<=(__last-__first), @p reverse_copy() performs the
1495e4b17023SJohn Marino * assignment @p *(__result+(__last-__first)-i) = *(__first+i).
1496e4b17023SJohn Marino * The ranges @p [__first,__last) and @p
1497e4b17023SJohn Marino * [__result,__result+(__last-__first)) must not overlap.
1498e4b17023SJohn Marino */
1499e4b17023SJohn Marino template<typename _BidirectionalIterator, typename _OutputIterator>
1500e4b17023SJohn Marino _OutputIterator
1501e4b17023SJohn Marino reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last,
1502e4b17023SJohn Marino _OutputIterator __result)
1503e4b17023SJohn Marino {
1504e4b17023SJohn Marino // concept requirements
1505e4b17023SJohn Marino __glibcxx_function_requires(_BidirectionalIteratorConcept<
1506e4b17023SJohn Marino _BidirectionalIterator>)
1507e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
1508e4b17023SJohn Marino typename iterator_traits<_BidirectionalIterator>::value_type>)
1509e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
1510e4b17023SJohn Marino
1511e4b17023SJohn Marino while (__first != __last)
1512e4b17023SJohn Marino {
1513e4b17023SJohn Marino --__last;
1514e4b17023SJohn Marino *__result = *__last;
1515e4b17023SJohn Marino ++__result;
1516e4b17023SJohn Marino }
1517e4b17023SJohn Marino return __result;
1518e4b17023SJohn Marino }
1519e4b17023SJohn Marino
1520e4b17023SJohn Marino /**
1521e4b17023SJohn Marino * This is a helper function for the rotate algorithm specialized on RAIs.
1522e4b17023SJohn Marino * It returns the greatest common divisor of two integer values.
1523e4b17023SJohn Marino */
1524e4b17023SJohn Marino template<typename _EuclideanRingElement>
1525e4b17023SJohn Marino _EuclideanRingElement
1526e4b17023SJohn Marino __gcd(_EuclideanRingElement __m, _EuclideanRingElement __n)
1527e4b17023SJohn Marino {
1528e4b17023SJohn Marino while (__n != 0)
1529e4b17023SJohn Marino {
1530e4b17023SJohn Marino _EuclideanRingElement __t = __m % __n;
1531e4b17023SJohn Marino __m = __n;
1532e4b17023SJohn Marino __n = __t;
1533e4b17023SJohn Marino }
1534e4b17023SJohn Marino return __m;
1535e4b17023SJohn Marino }
1536e4b17023SJohn Marino
1537e4b17023SJohn Marino /// This is a helper function for the rotate algorithm.
1538e4b17023SJohn Marino template<typename _ForwardIterator>
1539e4b17023SJohn Marino void
1540e4b17023SJohn Marino __rotate(_ForwardIterator __first,
1541e4b17023SJohn Marino _ForwardIterator __middle,
1542e4b17023SJohn Marino _ForwardIterator __last,
1543e4b17023SJohn Marino forward_iterator_tag)
1544e4b17023SJohn Marino {
1545e4b17023SJohn Marino if (__first == __middle || __last == __middle)
1546e4b17023SJohn Marino return;
1547e4b17023SJohn Marino
1548e4b17023SJohn Marino _ForwardIterator __first2 = __middle;
1549e4b17023SJohn Marino do
1550e4b17023SJohn Marino {
1551e4b17023SJohn Marino std::iter_swap(__first, __first2);
1552e4b17023SJohn Marino ++__first;
1553e4b17023SJohn Marino ++__first2;
1554e4b17023SJohn Marino if (__first == __middle)
1555e4b17023SJohn Marino __middle = __first2;
1556e4b17023SJohn Marino }
1557e4b17023SJohn Marino while (__first2 != __last);
1558e4b17023SJohn Marino
1559e4b17023SJohn Marino __first2 = __middle;
1560e4b17023SJohn Marino
1561e4b17023SJohn Marino while (__first2 != __last)
1562e4b17023SJohn Marino {
1563e4b17023SJohn Marino std::iter_swap(__first, __first2);
1564e4b17023SJohn Marino ++__first;
1565e4b17023SJohn Marino ++__first2;
1566e4b17023SJohn Marino if (__first == __middle)
1567e4b17023SJohn Marino __middle = __first2;
1568e4b17023SJohn Marino else if (__first2 == __last)
1569e4b17023SJohn Marino __first2 = __middle;
1570e4b17023SJohn Marino }
1571e4b17023SJohn Marino }
1572e4b17023SJohn Marino
1573e4b17023SJohn Marino /// This is a helper function for the rotate algorithm.
1574e4b17023SJohn Marino template<typename _BidirectionalIterator>
1575e4b17023SJohn Marino void
1576e4b17023SJohn Marino __rotate(_BidirectionalIterator __first,
1577e4b17023SJohn Marino _BidirectionalIterator __middle,
1578e4b17023SJohn Marino _BidirectionalIterator __last,
1579e4b17023SJohn Marino bidirectional_iterator_tag)
1580e4b17023SJohn Marino {
1581e4b17023SJohn Marino // concept requirements
1582e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
1583e4b17023SJohn Marino _BidirectionalIterator>)
1584e4b17023SJohn Marino
1585e4b17023SJohn Marino if (__first == __middle || __last == __middle)
1586e4b17023SJohn Marino return;
1587e4b17023SJohn Marino
1588e4b17023SJohn Marino std::__reverse(__first, __middle, bidirectional_iterator_tag());
1589e4b17023SJohn Marino std::__reverse(__middle, __last, bidirectional_iterator_tag());
1590e4b17023SJohn Marino
1591e4b17023SJohn Marino while (__first != __middle && __middle != __last)
1592e4b17023SJohn Marino {
1593e4b17023SJohn Marino std::iter_swap(__first, --__last);
1594e4b17023SJohn Marino ++__first;
1595e4b17023SJohn Marino }
1596e4b17023SJohn Marino
1597e4b17023SJohn Marino if (__first == __middle)
1598e4b17023SJohn Marino std::__reverse(__middle, __last, bidirectional_iterator_tag());
1599e4b17023SJohn Marino else
1600e4b17023SJohn Marino std::__reverse(__first, __middle, bidirectional_iterator_tag());
1601e4b17023SJohn Marino }
1602e4b17023SJohn Marino
1603e4b17023SJohn Marino /// This is a helper function for the rotate algorithm.
1604e4b17023SJohn Marino template<typename _RandomAccessIterator>
1605e4b17023SJohn Marino void
1606e4b17023SJohn Marino __rotate(_RandomAccessIterator __first,
1607e4b17023SJohn Marino _RandomAccessIterator __middle,
1608e4b17023SJohn Marino _RandomAccessIterator __last,
1609e4b17023SJohn Marino random_access_iterator_tag)
1610e4b17023SJohn Marino {
1611e4b17023SJohn Marino // concept requirements
1612e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
1613e4b17023SJohn Marino _RandomAccessIterator>)
1614e4b17023SJohn Marino
1615e4b17023SJohn Marino if (__first == __middle || __last == __middle)
1616e4b17023SJohn Marino return;
1617e4b17023SJohn Marino
1618e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::difference_type
1619e4b17023SJohn Marino _Distance;
1620e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type
1621e4b17023SJohn Marino _ValueType;
1622e4b17023SJohn Marino
1623e4b17023SJohn Marino _Distance __n = __last - __first;
1624e4b17023SJohn Marino _Distance __k = __middle - __first;
1625e4b17023SJohn Marino
1626e4b17023SJohn Marino if (__k == __n - __k)
1627e4b17023SJohn Marino {
1628e4b17023SJohn Marino std::swap_ranges(__first, __middle, __middle);
1629e4b17023SJohn Marino return;
1630e4b17023SJohn Marino }
1631e4b17023SJohn Marino
1632e4b17023SJohn Marino _RandomAccessIterator __p = __first;
1633e4b17023SJohn Marino
1634e4b17023SJohn Marino for (;;)
1635e4b17023SJohn Marino {
1636e4b17023SJohn Marino if (__k < __n - __k)
1637e4b17023SJohn Marino {
1638e4b17023SJohn Marino if (__is_pod(_ValueType) && __k == 1)
1639e4b17023SJohn Marino {
1640e4b17023SJohn Marino _ValueType __t = _GLIBCXX_MOVE(*__p);
1641e4b17023SJohn Marino _GLIBCXX_MOVE3(__p + 1, __p + __n, __p);
1642e4b17023SJohn Marino *(__p + __n - 1) = _GLIBCXX_MOVE(__t);
1643e4b17023SJohn Marino return;
1644e4b17023SJohn Marino }
1645e4b17023SJohn Marino _RandomAccessIterator __q = __p + __k;
1646e4b17023SJohn Marino for (_Distance __i = 0; __i < __n - __k; ++ __i)
1647e4b17023SJohn Marino {
1648e4b17023SJohn Marino std::iter_swap(__p, __q);
1649e4b17023SJohn Marino ++__p;
1650e4b17023SJohn Marino ++__q;
1651e4b17023SJohn Marino }
1652e4b17023SJohn Marino __n %= __k;
1653e4b17023SJohn Marino if (__n == 0)
1654e4b17023SJohn Marino return;
1655e4b17023SJohn Marino std::swap(__n, __k);
1656e4b17023SJohn Marino __k = __n - __k;
1657e4b17023SJohn Marino }
1658e4b17023SJohn Marino else
1659e4b17023SJohn Marino {
1660e4b17023SJohn Marino __k = __n - __k;
1661e4b17023SJohn Marino if (__is_pod(_ValueType) && __k == 1)
1662e4b17023SJohn Marino {
1663e4b17023SJohn Marino _ValueType __t = _GLIBCXX_MOVE(*(__p + __n - 1));
1664e4b17023SJohn Marino _GLIBCXX_MOVE_BACKWARD3(__p, __p + __n - 1, __p + __n);
1665e4b17023SJohn Marino *__p = _GLIBCXX_MOVE(__t);
1666e4b17023SJohn Marino return;
1667e4b17023SJohn Marino }
1668e4b17023SJohn Marino _RandomAccessIterator __q = __p + __n;
1669e4b17023SJohn Marino __p = __q - __k;
1670e4b17023SJohn Marino for (_Distance __i = 0; __i < __n - __k; ++ __i)
1671e4b17023SJohn Marino {
1672e4b17023SJohn Marino --__p;
1673e4b17023SJohn Marino --__q;
1674e4b17023SJohn Marino std::iter_swap(__p, __q);
1675e4b17023SJohn Marino }
1676e4b17023SJohn Marino __n %= __k;
1677e4b17023SJohn Marino if (__n == 0)
1678e4b17023SJohn Marino return;
1679e4b17023SJohn Marino std::swap(__n, __k);
1680e4b17023SJohn Marino }
1681e4b17023SJohn Marino }
1682e4b17023SJohn Marino }
1683e4b17023SJohn Marino
1684e4b17023SJohn Marino /**
1685e4b17023SJohn Marino * @brief Rotate the elements of a sequence.
1686e4b17023SJohn Marino * @ingroup mutating_algorithms
1687e4b17023SJohn Marino * @param __first A forward iterator.
1688e4b17023SJohn Marino * @param __middle A forward iterator.
1689e4b17023SJohn Marino * @param __last A forward iterator.
1690e4b17023SJohn Marino * @return Nothing.
1691e4b17023SJohn Marino *
1692e4b17023SJohn Marino * Rotates the elements of the range @p [__first,__last) by
1693e4b17023SJohn Marino * @p (__middle - __first) positions so that the element at @p __middle
1694e4b17023SJohn Marino * is moved to @p __first, the element at @p __middle+1 is moved to
1695e4b17023SJohn Marino * @p __first+1 and so on for each element in the range
1696e4b17023SJohn Marino * @p [__first,__last).
1697e4b17023SJohn Marino *
1698e4b17023SJohn Marino * This effectively swaps the ranges @p [__first,__middle) and
1699e4b17023SJohn Marino * @p [__middle,__last).
1700e4b17023SJohn Marino *
1701e4b17023SJohn Marino * Performs
1702e4b17023SJohn Marino * @p *(__first+(n+(__last-__middle))%(__last-__first))=*(__first+n)
1703e4b17023SJohn Marino * for each @p n in the range @p [0,__last-__first).
1704e4b17023SJohn Marino */
1705e4b17023SJohn Marino template<typename _ForwardIterator>
1706e4b17023SJohn Marino inline void
1707e4b17023SJohn Marino rotate(_ForwardIterator __first, _ForwardIterator __middle,
1708e4b17023SJohn Marino _ForwardIterator __last)
1709e4b17023SJohn Marino {
1710e4b17023SJohn Marino // concept requirements
1711e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
1712e4b17023SJohn Marino _ForwardIterator>)
1713e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __middle);
1714e4b17023SJohn Marino __glibcxx_requires_valid_range(__middle, __last);
1715e4b17023SJohn Marino
1716e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::iterator_category
1717e4b17023SJohn Marino _IterType;
1718e4b17023SJohn Marino std::__rotate(__first, __middle, __last, _IterType());
1719e4b17023SJohn Marino }
1720e4b17023SJohn Marino
1721e4b17023SJohn Marino /**
1722e4b17023SJohn Marino * @brief Copy a sequence, rotating its elements.
1723e4b17023SJohn Marino * @ingroup mutating_algorithms
1724e4b17023SJohn Marino * @param __first A forward iterator.
1725e4b17023SJohn Marino * @param __middle A forward iterator.
1726e4b17023SJohn Marino * @param __last A forward iterator.
1727e4b17023SJohn Marino * @param __result An output iterator.
1728e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence.
1729e4b17023SJohn Marino *
1730e4b17023SJohn Marino * Copies the elements of the range @p [__first,__last) to the
1731e4b17023SJohn Marino * range beginning at @result, rotating the copied elements by
1732e4b17023SJohn Marino * @p (__middle-__first) positions so that the element at @p __middle
1733e4b17023SJohn Marino * is moved to @p __result, the element at @p __middle+1 is moved
1734e4b17023SJohn Marino * to @p __result+1 and so on for each element in the range @p
1735e4b17023SJohn Marino * [__first,__last).
1736e4b17023SJohn Marino *
1737e4b17023SJohn Marino * Performs
1738e4b17023SJohn Marino * @p *(__result+(n+(__last-__middle))%(__last-__first))=*(__first+n)
1739e4b17023SJohn Marino * for each @p n in the range @p [0,__last-__first).
1740e4b17023SJohn Marino */
1741e4b17023SJohn Marino template<typename _ForwardIterator, typename _OutputIterator>
1742e4b17023SJohn Marino _OutputIterator
1743e4b17023SJohn Marino rotate_copy(_ForwardIterator __first, _ForwardIterator __middle,
1744e4b17023SJohn Marino _ForwardIterator __last, _OutputIterator __result)
1745e4b17023SJohn Marino {
1746e4b17023SJohn Marino // concept requirements
1747e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1748e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
1749e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
1750e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __middle);
1751e4b17023SJohn Marino __glibcxx_requires_valid_range(__middle, __last);
1752e4b17023SJohn Marino
1753e4b17023SJohn Marino return std::copy(__first, __middle,
1754e4b17023SJohn Marino std::copy(__middle, __last, __result));
1755e4b17023SJohn Marino }
1756e4b17023SJohn Marino
1757e4b17023SJohn Marino /// This is a helper function...
1758e4b17023SJohn Marino template<typename _ForwardIterator, typename _Predicate>
1759e4b17023SJohn Marino _ForwardIterator
1760e4b17023SJohn Marino __partition(_ForwardIterator __first, _ForwardIterator __last,
1761e4b17023SJohn Marino _Predicate __pred, forward_iterator_tag)
1762e4b17023SJohn Marino {
1763e4b17023SJohn Marino if (__first == __last)
1764e4b17023SJohn Marino return __first;
1765e4b17023SJohn Marino
1766e4b17023SJohn Marino while (__pred(*__first))
1767e4b17023SJohn Marino if (++__first == __last)
1768e4b17023SJohn Marino return __first;
1769e4b17023SJohn Marino
1770e4b17023SJohn Marino _ForwardIterator __next = __first;
1771e4b17023SJohn Marino
1772e4b17023SJohn Marino while (++__next != __last)
1773e4b17023SJohn Marino if (__pred(*__next))
1774e4b17023SJohn Marino {
1775e4b17023SJohn Marino std::iter_swap(__first, __next);
1776e4b17023SJohn Marino ++__first;
1777e4b17023SJohn Marino }
1778e4b17023SJohn Marino
1779e4b17023SJohn Marino return __first;
1780e4b17023SJohn Marino }
1781e4b17023SJohn Marino
1782e4b17023SJohn Marino /// This is a helper function...
1783e4b17023SJohn Marino template<typename _BidirectionalIterator, typename _Predicate>
1784e4b17023SJohn Marino _BidirectionalIterator
1785e4b17023SJohn Marino __partition(_BidirectionalIterator __first, _BidirectionalIterator __last,
1786e4b17023SJohn Marino _Predicate __pred, bidirectional_iterator_tag)
1787e4b17023SJohn Marino {
1788e4b17023SJohn Marino while (true)
1789e4b17023SJohn Marino {
1790e4b17023SJohn Marino while (true)
1791e4b17023SJohn Marino if (__first == __last)
1792e4b17023SJohn Marino return __first;
1793e4b17023SJohn Marino else if (__pred(*__first))
1794e4b17023SJohn Marino ++__first;
1795e4b17023SJohn Marino else
1796e4b17023SJohn Marino break;
1797e4b17023SJohn Marino --__last;
1798e4b17023SJohn Marino while (true)
1799e4b17023SJohn Marino if (__first == __last)
1800e4b17023SJohn Marino return __first;
1801e4b17023SJohn Marino else if (!bool(__pred(*__last)))
1802e4b17023SJohn Marino --__last;
1803e4b17023SJohn Marino else
1804e4b17023SJohn Marino break;
1805e4b17023SJohn Marino std::iter_swap(__first, __last);
1806e4b17023SJohn Marino ++__first;
1807e4b17023SJohn Marino }
1808e4b17023SJohn Marino }
1809e4b17023SJohn Marino
1810e4b17023SJohn Marino // partition
1811e4b17023SJohn Marino
1812e4b17023SJohn Marino /// This is a helper function...
1813e4b17023SJohn Marino /// Requires __len != 0 and !__pred(*__first),
1814e4b17023SJohn Marino /// same as __stable_partition_adaptive.
1815e4b17023SJohn Marino template<typename _ForwardIterator, typename _Predicate, typename _Distance>
1816e4b17023SJohn Marino _ForwardIterator
1817e4b17023SJohn Marino __inplace_stable_partition(_ForwardIterator __first,
1818e4b17023SJohn Marino _Predicate __pred, _Distance __len)
1819e4b17023SJohn Marino {
1820e4b17023SJohn Marino if (__len == 1)
1821e4b17023SJohn Marino return __first;
1822e4b17023SJohn Marino _ForwardIterator __middle = __first;
1823e4b17023SJohn Marino std::advance(__middle, __len / 2);
1824e4b17023SJohn Marino _ForwardIterator __left_split =
1825e4b17023SJohn Marino std::__inplace_stable_partition(__first, __pred, __len / 2);
1826e4b17023SJohn Marino // Advance past true-predicate values to satisfy this
1827e4b17023SJohn Marino // function's preconditions.
1828e4b17023SJohn Marino _Distance __right_len = __len - __len / 2;
1829e4b17023SJohn Marino _ForwardIterator __right_split =
1830e4b17023SJohn Marino std::__find_if_not_n(__middle, __right_len, __pred);
1831e4b17023SJohn Marino if (__right_len)
1832e4b17023SJohn Marino __right_split = std::__inplace_stable_partition(__middle,
1833e4b17023SJohn Marino __pred,
1834e4b17023SJohn Marino __right_len);
1835e4b17023SJohn Marino std::rotate(__left_split, __middle, __right_split);
1836e4b17023SJohn Marino std::advance(__left_split, std::distance(__middle, __right_split));
1837e4b17023SJohn Marino return __left_split;
1838e4b17023SJohn Marino }
1839e4b17023SJohn Marino
1840e4b17023SJohn Marino /// This is a helper function...
1841e4b17023SJohn Marino /// Requires __first != __last and !__pred(*__first)
1842e4b17023SJohn Marino /// and __len == distance(__first, __last).
1843e4b17023SJohn Marino ///
1844e4b17023SJohn Marino /// !__pred(*__first) allows us to guarantee that we don't
1845e4b17023SJohn Marino /// move-assign an element onto itself.
1846e4b17023SJohn Marino template<typename _ForwardIterator, typename _Pointer, typename _Predicate,
1847e4b17023SJohn Marino typename _Distance>
1848e4b17023SJohn Marino _ForwardIterator
1849e4b17023SJohn Marino __stable_partition_adaptive(_ForwardIterator __first,
1850e4b17023SJohn Marino _ForwardIterator __last,
1851e4b17023SJohn Marino _Predicate __pred, _Distance __len,
1852e4b17023SJohn Marino _Pointer __buffer,
1853e4b17023SJohn Marino _Distance __buffer_size)
1854e4b17023SJohn Marino {
1855e4b17023SJohn Marino if (__len <= __buffer_size)
1856e4b17023SJohn Marino {
1857e4b17023SJohn Marino _ForwardIterator __result1 = __first;
1858e4b17023SJohn Marino _Pointer __result2 = __buffer;
1859e4b17023SJohn Marino // The precondition guarantees that !__pred(*__first), so
1860e4b17023SJohn Marino // move that element to the buffer before starting the loop.
1861e4b17023SJohn Marino // This ensures that we only call __pred once per element.
1862e4b17023SJohn Marino *__result2 = _GLIBCXX_MOVE(*__first);
1863e4b17023SJohn Marino ++__result2;
1864e4b17023SJohn Marino ++__first;
1865e4b17023SJohn Marino for (; __first != __last; ++__first)
1866e4b17023SJohn Marino if (__pred(*__first))
1867e4b17023SJohn Marino {
1868e4b17023SJohn Marino *__result1 = _GLIBCXX_MOVE(*__first);
1869e4b17023SJohn Marino ++__result1;
1870e4b17023SJohn Marino }
1871e4b17023SJohn Marino else
1872e4b17023SJohn Marino {
1873e4b17023SJohn Marino *__result2 = _GLIBCXX_MOVE(*__first);
1874e4b17023SJohn Marino ++__result2;
1875e4b17023SJohn Marino }
1876e4b17023SJohn Marino _GLIBCXX_MOVE3(__buffer, __result2, __result1);
1877e4b17023SJohn Marino return __result1;
1878e4b17023SJohn Marino }
1879e4b17023SJohn Marino else
1880e4b17023SJohn Marino {
1881e4b17023SJohn Marino _ForwardIterator __middle = __first;
1882e4b17023SJohn Marino std::advance(__middle, __len / 2);
1883e4b17023SJohn Marino _ForwardIterator __left_split =
1884e4b17023SJohn Marino std::__stable_partition_adaptive(__first, __middle, __pred,
1885e4b17023SJohn Marino __len / 2, __buffer,
1886e4b17023SJohn Marino __buffer_size);
1887e4b17023SJohn Marino // Advance past true-predicate values to satisfy this
1888e4b17023SJohn Marino // function's preconditions.
1889e4b17023SJohn Marino _Distance __right_len = __len - __len / 2;
1890e4b17023SJohn Marino _ForwardIterator __right_split =
1891e4b17023SJohn Marino std::__find_if_not_n(__middle, __right_len, __pred);
1892e4b17023SJohn Marino if (__right_len)
1893e4b17023SJohn Marino __right_split =
1894e4b17023SJohn Marino std::__stable_partition_adaptive(__right_split, __last, __pred,
1895e4b17023SJohn Marino __right_len,
1896e4b17023SJohn Marino __buffer, __buffer_size);
1897e4b17023SJohn Marino std::rotate(__left_split, __middle, __right_split);
1898e4b17023SJohn Marino std::advance(__left_split, std::distance(__middle, __right_split));
1899e4b17023SJohn Marino return __left_split;
1900e4b17023SJohn Marino }
1901e4b17023SJohn Marino }
1902e4b17023SJohn Marino
1903e4b17023SJohn Marino /**
1904e4b17023SJohn Marino * @brief Move elements for which a predicate is true to the beginning
1905e4b17023SJohn Marino * of a sequence, preserving relative ordering.
1906e4b17023SJohn Marino * @ingroup mutating_algorithms
1907e4b17023SJohn Marino * @param __first A forward iterator.
1908e4b17023SJohn Marino * @param __last A forward iterator.
1909e4b17023SJohn Marino * @param __pred A predicate functor.
1910e4b17023SJohn Marino * @return An iterator @p middle such that @p __pred(i) is true for each
1911e4b17023SJohn Marino * iterator @p i in the range @p [first,middle) and false for each @p i
1912e4b17023SJohn Marino * in the range @p [middle,last).
1913e4b17023SJohn Marino *
1914e4b17023SJohn Marino * Performs the same function as @p partition() with the additional
1915e4b17023SJohn Marino * guarantee that the relative ordering of elements in each group is
1916e4b17023SJohn Marino * preserved, so any two elements @p x and @p y in the range
1917e4b17023SJohn Marino * @p [__first,__last) such that @p __pred(x)==__pred(y) will have the same
1918e4b17023SJohn Marino * relative ordering after calling @p stable_partition().
1919e4b17023SJohn Marino */
1920e4b17023SJohn Marino template<typename _ForwardIterator, typename _Predicate>
1921e4b17023SJohn Marino _ForwardIterator
1922e4b17023SJohn Marino stable_partition(_ForwardIterator __first, _ForwardIterator __last,
1923e4b17023SJohn Marino _Predicate __pred)
1924e4b17023SJohn Marino {
1925e4b17023SJohn Marino // concept requirements
1926e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
1927e4b17023SJohn Marino _ForwardIterator>)
1928e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
1929e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
1930e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
1931e4b17023SJohn Marino
1932e4b17023SJohn Marino __first = std::__find_if_not(__first, __last, __pred);
1933e4b17023SJohn Marino
1934e4b17023SJohn Marino if (__first == __last)
1935e4b17023SJohn Marino return __first;
1936e4b17023SJohn Marino else
1937e4b17023SJohn Marino {
1938e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::value_type
1939e4b17023SJohn Marino _ValueType;
1940e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::difference_type
1941e4b17023SJohn Marino _DistanceType;
1942e4b17023SJohn Marino
1943e4b17023SJohn Marino _Temporary_buffer<_ForwardIterator, _ValueType> __buf(__first,
1944e4b17023SJohn Marino __last);
1945e4b17023SJohn Marino if (__buf.size() > 0)
1946e4b17023SJohn Marino return
1947e4b17023SJohn Marino std::__stable_partition_adaptive(__first, __last, __pred,
1948e4b17023SJohn Marino _DistanceType(__buf.requested_size()),
1949e4b17023SJohn Marino __buf.begin(),
1950e4b17023SJohn Marino _DistanceType(__buf.size()));
1951e4b17023SJohn Marino else
1952e4b17023SJohn Marino return
1953e4b17023SJohn Marino std::__inplace_stable_partition(__first, __pred,
1954e4b17023SJohn Marino _DistanceType(__buf.requested_size()));
1955e4b17023SJohn Marino }
1956e4b17023SJohn Marino }
1957e4b17023SJohn Marino
1958e4b17023SJohn Marino /// This is a helper function for the sort routines.
1959e4b17023SJohn Marino template<typename _RandomAccessIterator>
1960e4b17023SJohn Marino void
1961e4b17023SJohn Marino __heap_select(_RandomAccessIterator __first,
1962e4b17023SJohn Marino _RandomAccessIterator __middle,
1963e4b17023SJohn Marino _RandomAccessIterator __last)
1964e4b17023SJohn Marino {
1965e4b17023SJohn Marino std::make_heap(__first, __middle);
1966e4b17023SJohn Marino for (_RandomAccessIterator __i = __middle; __i < __last; ++__i)
1967e4b17023SJohn Marino if (*__i < *__first)
1968e4b17023SJohn Marino std::__pop_heap(__first, __middle, __i);
1969e4b17023SJohn Marino }
1970e4b17023SJohn Marino
1971e4b17023SJohn Marino /// This is a helper function for the sort routines.
1972e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare>
1973e4b17023SJohn Marino void
1974e4b17023SJohn Marino __heap_select(_RandomAccessIterator __first,
1975e4b17023SJohn Marino _RandomAccessIterator __middle,
1976e4b17023SJohn Marino _RandomAccessIterator __last, _Compare __comp)
1977e4b17023SJohn Marino {
1978e4b17023SJohn Marino std::make_heap(__first, __middle, __comp);
1979e4b17023SJohn Marino for (_RandomAccessIterator __i = __middle; __i < __last; ++__i)
1980e4b17023SJohn Marino if (__comp(*__i, *__first))
1981e4b17023SJohn Marino std::__pop_heap(__first, __middle, __i, __comp);
1982e4b17023SJohn Marino }
1983e4b17023SJohn Marino
1984e4b17023SJohn Marino // partial_sort
1985e4b17023SJohn Marino
1986e4b17023SJohn Marino /**
1987e4b17023SJohn Marino * @brief Copy the smallest elements of a sequence.
1988e4b17023SJohn Marino * @ingroup sorting_algorithms
1989e4b17023SJohn Marino * @param __first An iterator.
1990e4b17023SJohn Marino * @param __last Another iterator.
1991e4b17023SJohn Marino * @param __result_first A random-access iterator.
1992e4b17023SJohn Marino * @param __result_last Another random-access iterator.
1993e4b17023SJohn Marino * @return An iterator indicating the end of the resulting sequence.
1994e4b17023SJohn Marino *
1995e4b17023SJohn Marino * Copies and sorts the smallest N values from the range @p [__first,__last)
1996e4b17023SJohn Marino * to the range beginning at @p __result_first, where the number of
1997e4b17023SJohn Marino * elements to be copied, @p N, is the smaller of @p (__last-__first) and
1998e4b17023SJohn Marino * @p (__result_last-__result_first).
1999e4b17023SJohn Marino * After the sort if @e i and @e j are iterators in the range
2000e4b17023SJohn Marino * @p [__result_first,__result_first+N) such that i precedes j then
2001e4b17023SJohn Marino * *j<*i is false.
2002e4b17023SJohn Marino * The value returned is @p __result_first+N.
2003e4b17023SJohn Marino */
2004e4b17023SJohn Marino template<typename _InputIterator, typename _RandomAccessIterator>
2005e4b17023SJohn Marino _RandomAccessIterator
2006e4b17023SJohn Marino partial_sort_copy(_InputIterator __first, _InputIterator __last,
2007e4b17023SJohn Marino _RandomAccessIterator __result_first,
2008e4b17023SJohn Marino _RandomAccessIterator __result_last)
2009e4b17023SJohn Marino {
2010e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator>::value_type
2011e4b17023SJohn Marino _InputValueType;
2012e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type
2013e4b17023SJohn Marino _OutputValueType;
2014e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::difference_type
2015e4b17023SJohn Marino _DistanceType;
2016e4b17023SJohn Marino
2017e4b17023SJohn Marino // concept requirements
2018e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
2019e4b17023SJohn Marino __glibcxx_function_requires(_ConvertibleConcept<_InputValueType,
2020e4b17023SJohn Marino _OutputValueType>)
2021e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_InputValueType,
2022e4b17023SJohn Marino _OutputValueType>)
2023e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<_OutputValueType>)
2024e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
2025e4b17023SJohn Marino __glibcxx_requires_valid_range(__result_first, __result_last);
2026e4b17023SJohn Marino
2027e4b17023SJohn Marino if (__result_first == __result_last)
2028e4b17023SJohn Marino return __result_last;
2029e4b17023SJohn Marino _RandomAccessIterator __result_real_last = __result_first;
2030e4b17023SJohn Marino while(__first != __last && __result_real_last != __result_last)
2031e4b17023SJohn Marino {
2032e4b17023SJohn Marino *__result_real_last = *__first;
2033e4b17023SJohn Marino ++__result_real_last;
2034e4b17023SJohn Marino ++__first;
2035e4b17023SJohn Marino }
2036e4b17023SJohn Marino std::make_heap(__result_first, __result_real_last);
2037e4b17023SJohn Marino while (__first != __last)
2038e4b17023SJohn Marino {
2039e4b17023SJohn Marino if (*__first < *__result_first)
2040e4b17023SJohn Marino std::__adjust_heap(__result_first, _DistanceType(0),
2041e4b17023SJohn Marino _DistanceType(__result_real_last
2042e4b17023SJohn Marino - __result_first),
2043e4b17023SJohn Marino _InputValueType(*__first));
2044e4b17023SJohn Marino ++__first;
2045e4b17023SJohn Marino }
2046e4b17023SJohn Marino std::sort_heap(__result_first, __result_real_last);
2047e4b17023SJohn Marino return __result_real_last;
2048e4b17023SJohn Marino }
2049e4b17023SJohn Marino
2050e4b17023SJohn Marino /**
2051e4b17023SJohn Marino * @brief Copy the smallest elements of a sequence using a predicate for
2052e4b17023SJohn Marino * comparison.
2053e4b17023SJohn Marino * @ingroup sorting_algorithms
2054e4b17023SJohn Marino * @param __first An input iterator.
2055e4b17023SJohn Marino * @param __last Another input iterator.
2056e4b17023SJohn Marino * @param __result_first A random-access iterator.
2057e4b17023SJohn Marino * @param __result_last Another random-access iterator.
2058e4b17023SJohn Marino * @param __comp A comparison functor.
2059e4b17023SJohn Marino * @return An iterator indicating the end of the resulting sequence.
2060e4b17023SJohn Marino *
2061e4b17023SJohn Marino * Copies and sorts the smallest N values from the range @p [__first,__last)
2062e4b17023SJohn Marino * to the range beginning at @p result_first, where the number of
2063e4b17023SJohn Marino * elements to be copied, @p N, is the smaller of @p (__last-__first) and
2064e4b17023SJohn Marino * @p (__result_last-__result_first).
2065e4b17023SJohn Marino * After the sort if @e i and @e j are iterators in the range
2066e4b17023SJohn Marino * @p [__result_first,__result_first+N) such that i precedes j then
2067e4b17023SJohn Marino * @p __comp(*j,*i) is false.
2068e4b17023SJohn Marino * The value returned is @p __result_first+N.
2069e4b17023SJohn Marino */
2070e4b17023SJohn Marino template<typename _InputIterator, typename _RandomAccessIterator, typename _Compare>
2071e4b17023SJohn Marino _RandomAccessIterator
2072e4b17023SJohn Marino partial_sort_copy(_InputIterator __first, _InputIterator __last,
2073e4b17023SJohn Marino _RandomAccessIterator __result_first,
2074e4b17023SJohn Marino _RandomAccessIterator __result_last,
2075e4b17023SJohn Marino _Compare __comp)
2076e4b17023SJohn Marino {
2077e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator>::value_type
2078e4b17023SJohn Marino _InputValueType;
2079e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type
2080e4b17023SJohn Marino _OutputValueType;
2081e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::difference_type
2082e4b17023SJohn Marino _DistanceType;
2083e4b17023SJohn Marino
2084e4b17023SJohn Marino // concept requirements
2085e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
2086e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
2087e4b17023SJohn Marino _RandomAccessIterator>)
2088e4b17023SJohn Marino __glibcxx_function_requires(_ConvertibleConcept<_InputValueType,
2089e4b17023SJohn Marino _OutputValueType>)
2090e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
2091e4b17023SJohn Marino _InputValueType, _OutputValueType>)
2092e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
2093e4b17023SJohn Marino _OutputValueType, _OutputValueType>)
2094e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
2095e4b17023SJohn Marino __glibcxx_requires_valid_range(__result_first, __result_last);
2096e4b17023SJohn Marino
2097e4b17023SJohn Marino if (__result_first == __result_last)
2098e4b17023SJohn Marino return __result_last;
2099e4b17023SJohn Marino _RandomAccessIterator __result_real_last = __result_first;
2100e4b17023SJohn Marino while(__first != __last && __result_real_last != __result_last)
2101e4b17023SJohn Marino {
2102e4b17023SJohn Marino *__result_real_last = *__first;
2103e4b17023SJohn Marino ++__result_real_last;
2104e4b17023SJohn Marino ++__first;
2105e4b17023SJohn Marino }
2106e4b17023SJohn Marino std::make_heap(__result_first, __result_real_last, __comp);
2107e4b17023SJohn Marino while (__first != __last)
2108e4b17023SJohn Marino {
2109e4b17023SJohn Marino if (__comp(*__first, *__result_first))
2110e4b17023SJohn Marino std::__adjust_heap(__result_first, _DistanceType(0),
2111e4b17023SJohn Marino _DistanceType(__result_real_last
2112e4b17023SJohn Marino - __result_first),
2113e4b17023SJohn Marino _InputValueType(*__first),
2114e4b17023SJohn Marino __comp);
2115e4b17023SJohn Marino ++__first;
2116e4b17023SJohn Marino }
2117e4b17023SJohn Marino std::sort_heap(__result_first, __result_real_last, __comp);
2118e4b17023SJohn Marino return __result_real_last;
2119e4b17023SJohn Marino }
2120e4b17023SJohn Marino
2121e4b17023SJohn Marino /// This is a helper function for the sort routine.
2122e4b17023SJohn Marino template<typename _RandomAccessIterator>
2123e4b17023SJohn Marino void
2124e4b17023SJohn Marino __unguarded_linear_insert(_RandomAccessIterator __last)
2125e4b17023SJohn Marino {
2126e4b17023SJohn Marino typename iterator_traits<_RandomAccessIterator>::value_type
2127e4b17023SJohn Marino __val = _GLIBCXX_MOVE(*__last);
2128e4b17023SJohn Marino _RandomAccessIterator __next = __last;
2129e4b17023SJohn Marino --__next;
2130e4b17023SJohn Marino while (__val < *__next)
2131e4b17023SJohn Marino {
2132e4b17023SJohn Marino *__last = _GLIBCXX_MOVE(*__next);
2133e4b17023SJohn Marino __last = __next;
2134e4b17023SJohn Marino --__next;
2135e4b17023SJohn Marino }
2136e4b17023SJohn Marino *__last = _GLIBCXX_MOVE(__val);
2137e4b17023SJohn Marino }
2138e4b17023SJohn Marino
2139e4b17023SJohn Marino /// This is a helper function for the sort routine.
2140e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare>
2141e4b17023SJohn Marino void
2142e4b17023SJohn Marino __unguarded_linear_insert(_RandomAccessIterator __last,
2143e4b17023SJohn Marino _Compare __comp)
2144e4b17023SJohn Marino {
2145e4b17023SJohn Marino typename iterator_traits<_RandomAccessIterator>::value_type
2146e4b17023SJohn Marino __val = _GLIBCXX_MOVE(*__last);
2147e4b17023SJohn Marino _RandomAccessIterator __next = __last;
2148e4b17023SJohn Marino --__next;
2149e4b17023SJohn Marino while (__comp(__val, *__next))
2150e4b17023SJohn Marino {
2151e4b17023SJohn Marino *__last = _GLIBCXX_MOVE(*__next);
2152e4b17023SJohn Marino __last = __next;
2153e4b17023SJohn Marino --__next;
2154e4b17023SJohn Marino }
2155e4b17023SJohn Marino *__last = _GLIBCXX_MOVE(__val);
2156e4b17023SJohn Marino }
2157e4b17023SJohn Marino
2158e4b17023SJohn Marino /// This is a helper function for the sort routine.
2159e4b17023SJohn Marino template<typename _RandomAccessIterator>
2160e4b17023SJohn Marino void
2161e4b17023SJohn Marino __insertion_sort(_RandomAccessIterator __first,
2162e4b17023SJohn Marino _RandomAccessIterator __last)
2163e4b17023SJohn Marino {
2164e4b17023SJohn Marino if (__first == __last)
2165e4b17023SJohn Marino return;
2166e4b17023SJohn Marino
2167e4b17023SJohn Marino for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
2168e4b17023SJohn Marino {
2169e4b17023SJohn Marino if (*__i < *__first)
2170e4b17023SJohn Marino {
2171e4b17023SJohn Marino typename iterator_traits<_RandomAccessIterator>::value_type
2172e4b17023SJohn Marino __val = _GLIBCXX_MOVE(*__i);
2173e4b17023SJohn Marino _GLIBCXX_MOVE_BACKWARD3(__first, __i, __i + 1);
2174e4b17023SJohn Marino *__first = _GLIBCXX_MOVE(__val);
2175e4b17023SJohn Marino }
2176e4b17023SJohn Marino else
2177e4b17023SJohn Marino std::__unguarded_linear_insert(__i);
2178e4b17023SJohn Marino }
2179e4b17023SJohn Marino }
2180e4b17023SJohn Marino
2181e4b17023SJohn Marino /// This is a helper function for the sort routine.
2182e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare>
2183e4b17023SJohn Marino void
2184e4b17023SJohn Marino __insertion_sort(_RandomAccessIterator __first,
2185e4b17023SJohn Marino _RandomAccessIterator __last, _Compare __comp)
2186e4b17023SJohn Marino {
2187e4b17023SJohn Marino if (__first == __last) return;
2188e4b17023SJohn Marino
2189e4b17023SJohn Marino for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
2190e4b17023SJohn Marino {
2191e4b17023SJohn Marino if (__comp(*__i, *__first))
2192e4b17023SJohn Marino {
2193e4b17023SJohn Marino typename iterator_traits<_RandomAccessIterator>::value_type
2194e4b17023SJohn Marino __val = _GLIBCXX_MOVE(*__i);
2195e4b17023SJohn Marino _GLIBCXX_MOVE_BACKWARD3(__first, __i, __i + 1);
2196e4b17023SJohn Marino *__first = _GLIBCXX_MOVE(__val);
2197e4b17023SJohn Marino }
2198e4b17023SJohn Marino else
2199e4b17023SJohn Marino std::__unguarded_linear_insert(__i, __comp);
2200e4b17023SJohn Marino }
2201e4b17023SJohn Marino }
2202e4b17023SJohn Marino
2203e4b17023SJohn Marino /// This is a helper function for the sort routine.
2204e4b17023SJohn Marino template<typename _RandomAccessIterator>
2205e4b17023SJohn Marino inline void
2206e4b17023SJohn Marino __unguarded_insertion_sort(_RandomAccessIterator __first,
2207e4b17023SJohn Marino _RandomAccessIterator __last)
2208e4b17023SJohn Marino {
2209e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type
2210e4b17023SJohn Marino _ValueType;
2211e4b17023SJohn Marino
2212e4b17023SJohn Marino for (_RandomAccessIterator __i = __first; __i != __last; ++__i)
2213e4b17023SJohn Marino std::__unguarded_linear_insert(__i);
2214e4b17023SJohn Marino }
2215e4b17023SJohn Marino
2216e4b17023SJohn Marino /// This is a helper function for the sort routine.
2217e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare>
2218e4b17023SJohn Marino inline void
2219e4b17023SJohn Marino __unguarded_insertion_sort(_RandomAccessIterator __first,
2220e4b17023SJohn Marino _RandomAccessIterator __last, _Compare __comp)
2221e4b17023SJohn Marino {
2222e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type
2223e4b17023SJohn Marino _ValueType;
2224e4b17023SJohn Marino
2225e4b17023SJohn Marino for (_RandomAccessIterator __i = __first; __i != __last; ++__i)
2226e4b17023SJohn Marino std::__unguarded_linear_insert(__i, __comp);
2227e4b17023SJohn Marino }
2228e4b17023SJohn Marino
2229e4b17023SJohn Marino /**
2230e4b17023SJohn Marino * @doctodo
2231e4b17023SJohn Marino * This controls some aspect of the sort routines.
2232e4b17023SJohn Marino */
2233e4b17023SJohn Marino enum { _S_threshold = 16 };
2234e4b17023SJohn Marino
2235e4b17023SJohn Marino /// This is a helper function for the sort routine.
2236e4b17023SJohn Marino template<typename _RandomAccessIterator>
2237e4b17023SJohn Marino void
2238e4b17023SJohn Marino __final_insertion_sort(_RandomAccessIterator __first,
2239e4b17023SJohn Marino _RandomAccessIterator __last)
2240e4b17023SJohn Marino {
2241e4b17023SJohn Marino if (__last - __first > int(_S_threshold))
2242e4b17023SJohn Marino {
2243e4b17023SJohn Marino std::__insertion_sort(__first, __first + int(_S_threshold));
2244e4b17023SJohn Marino std::__unguarded_insertion_sort(__first + int(_S_threshold), __last);
2245e4b17023SJohn Marino }
2246e4b17023SJohn Marino else
2247e4b17023SJohn Marino std::__insertion_sort(__first, __last);
2248e4b17023SJohn Marino }
2249e4b17023SJohn Marino
2250e4b17023SJohn Marino /// This is a helper function for the sort routine.
2251e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare>
2252e4b17023SJohn Marino void
2253e4b17023SJohn Marino __final_insertion_sort(_RandomAccessIterator __first,
2254e4b17023SJohn Marino _RandomAccessIterator __last, _Compare __comp)
2255e4b17023SJohn Marino {
2256e4b17023SJohn Marino if (__last - __first > int(_S_threshold))
2257e4b17023SJohn Marino {
2258e4b17023SJohn Marino std::__insertion_sort(__first, __first + int(_S_threshold), __comp);
2259e4b17023SJohn Marino std::__unguarded_insertion_sort(__first + int(_S_threshold), __last,
2260e4b17023SJohn Marino __comp);
2261e4b17023SJohn Marino }
2262e4b17023SJohn Marino else
2263e4b17023SJohn Marino std::__insertion_sort(__first, __last, __comp);
2264e4b17023SJohn Marino }
2265e4b17023SJohn Marino
2266e4b17023SJohn Marino /// This is a helper function...
2267e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Tp>
2268e4b17023SJohn Marino _RandomAccessIterator
2269e4b17023SJohn Marino __unguarded_partition(_RandomAccessIterator __first,
2270e4b17023SJohn Marino _RandomAccessIterator __last, const _Tp& __pivot)
2271e4b17023SJohn Marino {
2272e4b17023SJohn Marino while (true)
2273e4b17023SJohn Marino {
2274e4b17023SJohn Marino while (*__first < __pivot)
2275e4b17023SJohn Marino ++__first;
2276e4b17023SJohn Marino --__last;
2277e4b17023SJohn Marino while (__pivot < *__last)
2278e4b17023SJohn Marino --__last;
2279e4b17023SJohn Marino if (!(__first < __last))
2280e4b17023SJohn Marino return __first;
2281e4b17023SJohn Marino std::iter_swap(__first, __last);
2282e4b17023SJohn Marino ++__first;
2283e4b17023SJohn Marino }
2284e4b17023SJohn Marino }
2285e4b17023SJohn Marino
2286e4b17023SJohn Marino /// This is a helper function...
2287e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Tp, typename _Compare>
2288e4b17023SJohn Marino _RandomAccessIterator
2289e4b17023SJohn Marino __unguarded_partition(_RandomAccessIterator __first,
2290e4b17023SJohn Marino _RandomAccessIterator __last,
2291e4b17023SJohn Marino const _Tp& __pivot, _Compare __comp)
2292e4b17023SJohn Marino {
2293e4b17023SJohn Marino while (true)
2294e4b17023SJohn Marino {
2295e4b17023SJohn Marino while (__comp(*__first, __pivot))
2296e4b17023SJohn Marino ++__first;
2297e4b17023SJohn Marino --__last;
2298e4b17023SJohn Marino while (__comp(__pivot, *__last))
2299e4b17023SJohn Marino --__last;
2300e4b17023SJohn Marino if (!(__first < __last))
2301e4b17023SJohn Marino return __first;
2302e4b17023SJohn Marino std::iter_swap(__first, __last);
2303e4b17023SJohn Marino ++__first;
2304e4b17023SJohn Marino }
2305e4b17023SJohn Marino }
2306e4b17023SJohn Marino
2307e4b17023SJohn Marino /// This is a helper function...
2308e4b17023SJohn Marino template<typename _RandomAccessIterator>
2309e4b17023SJohn Marino inline _RandomAccessIterator
2310e4b17023SJohn Marino __unguarded_partition_pivot(_RandomAccessIterator __first,
2311e4b17023SJohn Marino _RandomAccessIterator __last)
2312e4b17023SJohn Marino {
2313e4b17023SJohn Marino _RandomAccessIterator __mid = __first + (__last - __first) / 2;
2314*95d28233SJohn Marino std::__move_median_to_first(__first, __first + 1, __mid, __last - 1);
2315e4b17023SJohn Marino return std::__unguarded_partition(__first + 1, __last, *__first);
2316e4b17023SJohn Marino }
2317e4b17023SJohn Marino
2318e4b17023SJohn Marino
2319e4b17023SJohn Marino /// This is a helper function...
2320e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare>
2321e4b17023SJohn Marino inline _RandomAccessIterator
2322e4b17023SJohn Marino __unguarded_partition_pivot(_RandomAccessIterator __first,
2323e4b17023SJohn Marino _RandomAccessIterator __last, _Compare __comp)
2324e4b17023SJohn Marino {
2325e4b17023SJohn Marino _RandomAccessIterator __mid = __first + (__last - __first) / 2;
2326*95d28233SJohn Marino std::__move_median_to_first(__first, __first + 1, __mid, __last - 1,
2327*95d28233SJohn Marino __comp);
2328e4b17023SJohn Marino return std::__unguarded_partition(__first + 1, __last, *__first, __comp);
2329e4b17023SJohn Marino }
2330e4b17023SJohn Marino
2331e4b17023SJohn Marino /// This is a helper function for the sort routine.
2332e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Size>
2333e4b17023SJohn Marino void
2334e4b17023SJohn Marino __introsort_loop(_RandomAccessIterator __first,
2335e4b17023SJohn Marino _RandomAccessIterator __last,
2336e4b17023SJohn Marino _Size __depth_limit)
2337e4b17023SJohn Marino {
2338e4b17023SJohn Marino while (__last - __first > int(_S_threshold))
2339e4b17023SJohn Marino {
2340e4b17023SJohn Marino if (__depth_limit == 0)
2341e4b17023SJohn Marino {
2342e4b17023SJohn Marino _GLIBCXX_STD_A::partial_sort(__first, __last, __last);
2343e4b17023SJohn Marino return;
2344e4b17023SJohn Marino }
2345e4b17023SJohn Marino --__depth_limit;
2346e4b17023SJohn Marino _RandomAccessIterator __cut =
2347e4b17023SJohn Marino std::__unguarded_partition_pivot(__first, __last);
2348e4b17023SJohn Marino std::__introsort_loop(__cut, __last, __depth_limit);
2349e4b17023SJohn Marino __last = __cut;
2350e4b17023SJohn Marino }
2351e4b17023SJohn Marino }
2352e4b17023SJohn Marino
2353e4b17023SJohn Marino /// This is a helper function for the sort routine.
2354e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Size, typename _Compare>
2355e4b17023SJohn Marino void
2356e4b17023SJohn Marino __introsort_loop(_RandomAccessIterator __first,
2357e4b17023SJohn Marino _RandomAccessIterator __last,
2358e4b17023SJohn Marino _Size __depth_limit, _Compare __comp)
2359e4b17023SJohn Marino {
2360e4b17023SJohn Marino while (__last - __first > int(_S_threshold))
2361e4b17023SJohn Marino {
2362e4b17023SJohn Marino if (__depth_limit == 0)
2363e4b17023SJohn Marino {
2364e4b17023SJohn Marino _GLIBCXX_STD_A::partial_sort(__first, __last, __last, __comp);
2365e4b17023SJohn Marino return;
2366e4b17023SJohn Marino }
2367e4b17023SJohn Marino --__depth_limit;
2368e4b17023SJohn Marino _RandomAccessIterator __cut =
2369e4b17023SJohn Marino std::__unguarded_partition_pivot(__first, __last, __comp);
2370e4b17023SJohn Marino std::__introsort_loop(__cut, __last, __depth_limit, __comp);
2371e4b17023SJohn Marino __last = __cut;
2372e4b17023SJohn Marino }
2373e4b17023SJohn Marino }
2374e4b17023SJohn Marino
2375e4b17023SJohn Marino // sort
2376e4b17023SJohn Marino
2377e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Size>
2378e4b17023SJohn Marino void
2379e4b17023SJohn Marino __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth,
2380e4b17023SJohn Marino _RandomAccessIterator __last, _Size __depth_limit)
2381e4b17023SJohn Marino {
2382e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type
2383e4b17023SJohn Marino _ValueType;
2384e4b17023SJohn Marino
2385e4b17023SJohn Marino while (__last - __first > 3)
2386e4b17023SJohn Marino {
2387e4b17023SJohn Marino if (__depth_limit == 0)
2388e4b17023SJohn Marino {
2389e4b17023SJohn Marino std::__heap_select(__first, __nth + 1, __last);
2390e4b17023SJohn Marino
2391e4b17023SJohn Marino // Place the nth largest element in its final position.
2392e4b17023SJohn Marino std::iter_swap(__first, __nth);
2393e4b17023SJohn Marino return;
2394e4b17023SJohn Marino }
2395e4b17023SJohn Marino --__depth_limit;
2396e4b17023SJohn Marino _RandomAccessIterator __cut =
2397e4b17023SJohn Marino std::__unguarded_partition_pivot(__first, __last);
2398e4b17023SJohn Marino if (__cut <= __nth)
2399e4b17023SJohn Marino __first = __cut;
2400e4b17023SJohn Marino else
2401e4b17023SJohn Marino __last = __cut;
2402e4b17023SJohn Marino }
2403e4b17023SJohn Marino std::__insertion_sort(__first, __last);
2404e4b17023SJohn Marino }
2405e4b17023SJohn Marino
2406e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Size, typename _Compare>
2407e4b17023SJohn Marino void
2408e4b17023SJohn Marino __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth,
2409e4b17023SJohn Marino _RandomAccessIterator __last, _Size __depth_limit,
2410e4b17023SJohn Marino _Compare __comp)
2411e4b17023SJohn Marino {
2412e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type
2413e4b17023SJohn Marino _ValueType;
2414e4b17023SJohn Marino
2415e4b17023SJohn Marino while (__last - __first > 3)
2416e4b17023SJohn Marino {
2417e4b17023SJohn Marino if (__depth_limit == 0)
2418e4b17023SJohn Marino {
2419e4b17023SJohn Marino std::__heap_select(__first, __nth + 1, __last, __comp);
2420e4b17023SJohn Marino // Place the nth largest element in its final position.
2421e4b17023SJohn Marino std::iter_swap(__first, __nth);
2422e4b17023SJohn Marino return;
2423e4b17023SJohn Marino }
2424e4b17023SJohn Marino --__depth_limit;
2425e4b17023SJohn Marino _RandomAccessIterator __cut =
2426e4b17023SJohn Marino std::__unguarded_partition_pivot(__first, __last, __comp);
2427e4b17023SJohn Marino if (__cut <= __nth)
2428e4b17023SJohn Marino __first = __cut;
2429e4b17023SJohn Marino else
2430e4b17023SJohn Marino __last = __cut;
2431e4b17023SJohn Marino }
2432e4b17023SJohn Marino std::__insertion_sort(__first, __last, __comp);
2433e4b17023SJohn Marino }
2434e4b17023SJohn Marino
2435e4b17023SJohn Marino // nth_element
2436e4b17023SJohn Marino
2437e4b17023SJohn Marino // lower_bound moved to stl_algobase.h
2438e4b17023SJohn Marino
2439e4b17023SJohn Marino /**
2440e4b17023SJohn Marino * @brief Finds the first position in which @p __val could be inserted
2441e4b17023SJohn Marino * without changing the ordering.
2442e4b17023SJohn Marino * @ingroup binary_search_algorithms
2443e4b17023SJohn Marino * @param __first An iterator.
2444e4b17023SJohn Marino * @param __last Another iterator.
2445e4b17023SJohn Marino * @param __val The search term.
2446e4b17023SJohn Marino * @param __comp A functor to use for comparisons.
2447e4b17023SJohn Marino * @return An iterator pointing to the first element <em>not less
2448e4b17023SJohn Marino * than</em> @p __val, or end() if every element is less
2449e4b17023SJohn Marino * than @p __val.
2450e4b17023SJohn Marino * @ingroup binary_search_algorithms
2451e4b17023SJohn Marino *
2452e4b17023SJohn Marino * The comparison function should have the same effects on ordering as
2453e4b17023SJohn Marino * the function used for the initial sort.
2454e4b17023SJohn Marino */
2455e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp, typename _Compare>
2456e4b17023SJohn Marino _ForwardIterator
2457e4b17023SJohn Marino lower_bound(_ForwardIterator __first, _ForwardIterator __last,
2458e4b17023SJohn Marino const _Tp& __val, _Compare __comp)
2459e4b17023SJohn Marino {
2460e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::value_type
2461e4b17023SJohn Marino _ValueType;
2462e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::difference_type
2463e4b17023SJohn Marino _DistanceType;
2464e4b17023SJohn Marino
2465e4b17023SJohn Marino // concept requirements
2466e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2467e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
2468e4b17023SJohn Marino _ValueType, _Tp>)
2469e4b17023SJohn Marino __glibcxx_requires_partitioned_lower_pred(__first, __last,
2470e4b17023SJohn Marino __val, __comp);
2471e4b17023SJohn Marino
2472e4b17023SJohn Marino _DistanceType __len = std::distance(__first, __last);
2473e4b17023SJohn Marino
2474e4b17023SJohn Marino while (__len > 0)
2475e4b17023SJohn Marino {
2476e4b17023SJohn Marino _DistanceType __half = __len >> 1;
2477e4b17023SJohn Marino _ForwardIterator __middle = __first;
2478e4b17023SJohn Marino std::advance(__middle, __half);
2479e4b17023SJohn Marino if (__comp(*__middle, __val))
2480e4b17023SJohn Marino {
2481e4b17023SJohn Marino __first = __middle;
2482e4b17023SJohn Marino ++__first;
2483e4b17023SJohn Marino __len = __len - __half - 1;
2484e4b17023SJohn Marino }
2485e4b17023SJohn Marino else
2486e4b17023SJohn Marino __len = __half;
2487e4b17023SJohn Marino }
2488e4b17023SJohn Marino return __first;
2489e4b17023SJohn Marino }
2490e4b17023SJohn Marino
2491e4b17023SJohn Marino /**
2492e4b17023SJohn Marino * @brief Finds the last position in which @p __val could be inserted
2493e4b17023SJohn Marino * without changing the ordering.
2494e4b17023SJohn Marino * @ingroup binary_search_algorithms
2495e4b17023SJohn Marino * @param __first An iterator.
2496e4b17023SJohn Marino * @param __last Another iterator.
2497e4b17023SJohn Marino * @param __val The search term.
2498e4b17023SJohn Marino * @return An iterator pointing to the first element greater than @p __val,
2499e4b17023SJohn Marino * or end() if no elements are greater than @p __val.
2500e4b17023SJohn Marino * @ingroup binary_search_algorithms
2501e4b17023SJohn Marino */
2502e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp>
2503e4b17023SJohn Marino _ForwardIterator
2504e4b17023SJohn Marino upper_bound(_ForwardIterator __first, _ForwardIterator __last,
2505e4b17023SJohn Marino const _Tp& __val)
2506e4b17023SJohn Marino {
2507e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::value_type
2508e4b17023SJohn Marino _ValueType;
2509e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::difference_type
2510e4b17023SJohn Marino _DistanceType;
2511e4b17023SJohn Marino
2512e4b17023SJohn Marino // concept requirements
2513e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2514e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>)
2515e4b17023SJohn Marino __glibcxx_requires_partitioned_upper(__first, __last, __val);
2516e4b17023SJohn Marino
2517e4b17023SJohn Marino _DistanceType __len = std::distance(__first, __last);
2518e4b17023SJohn Marino
2519e4b17023SJohn Marino while (__len > 0)
2520e4b17023SJohn Marino {
2521e4b17023SJohn Marino _DistanceType __half = __len >> 1;
2522e4b17023SJohn Marino _ForwardIterator __middle = __first;
2523e4b17023SJohn Marino std::advance(__middle, __half);
2524e4b17023SJohn Marino if (__val < *__middle)
2525e4b17023SJohn Marino __len = __half;
2526e4b17023SJohn Marino else
2527e4b17023SJohn Marino {
2528e4b17023SJohn Marino __first = __middle;
2529e4b17023SJohn Marino ++__first;
2530e4b17023SJohn Marino __len = __len - __half - 1;
2531e4b17023SJohn Marino }
2532e4b17023SJohn Marino }
2533e4b17023SJohn Marino return __first;
2534e4b17023SJohn Marino }
2535e4b17023SJohn Marino
2536e4b17023SJohn Marino /**
2537e4b17023SJohn Marino * @brief Finds the last position in which @p __val could be inserted
2538e4b17023SJohn Marino * without changing the ordering.
2539e4b17023SJohn Marino * @ingroup binary_search_algorithms
2540e4b17023SJohn Marino * @param __first An iterator.
2541e4b17023SJohn Marino * @param __last Another iterator.
2542e4b17023SJohn Marino * @param __val The search term.
2543e4b17023SJohn Marino * @param __comp A functor to use for comparisons.
2544e4b17023SJohn Marino * @return An iterator pointing to the first element greater than @p __val,
2545e4b17023SJohn Marino * or end() if no elements are greater than @p __val.
2546e4b17023SJohn Marino * @ingroup binary_search_algorithms
2547e4b17023SJohn Marino *
2548e4b17023SJohn Marino * The comparison function should have the same effects on ordering as
2549e4b17023SJohn Marino * the function used for the initial sort.
2550e4b17023SJohn Marino */
2551e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp, typename _Compare>
2552e4b17023SJohn Marino _ForwardIterator
2553e4b17023SJohn Marino upper_bound(_ForwardIterator __first, _ForwardIterator __last,
2554e4b17023SJohn Marino const _Tp& __val, _Compare __comp)
2555e4b17023SJohn Marino {
2556e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::value_type
2557e4b17023SJohn Marino _ValueType;
2558e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::difference_type
2559e4b17023SJohn Marino _DistanceType;
2560e4b17023SJohn Marino
2561e4b17023SJohn Marino // concept requirements
2562e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2563e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
2564e4b17023SJohn Marino _Tp, _ValueType>)
2565e4b17023SJohn Marino __glibcxx_requires_partitioned_upper_pred(__first, __last,
2566e4b17023SJohn Marino __val, __comp);
2567e4b17023SJohn Marino
2568e4b17023SJohn Marino _DistanceType __len = std::distance(__first, __last);
2569e4b17023SJohn Marino
2570e4b17023SJohn Marino while (__len > 0)
2571e4b17023SJohn Marino {
2572e4b17023SJohn Marino _DistanceType __half = __len >> 1;
2573e4b17023SJohn Marino _ForwardIterator __middle = __first;
2574e4b17023SJohn Marino std::advance(__middle, __half);
2575e4b17023SJohn Marino if (__comp(__val, *__middle))
2576e4b17023SJohn Marino __len = __half;
2577e4b17023SJohn Marino else
2578e4b17023SJohn Marino {
2579e4b17023SJohn Marino __first = __middle;
2580e4b17023SJohn Marino ++__first;
2581e4b17023SJohn Marino __len = __len - __half - 1;
2582e4b17023SJohn Marino }
2583e4b17023SJohn Marino }
2584e4b17023SJohn Marino return __first;
2585e4b17023SJohn Marino }
2586e4b17023SJohn Marino
2587e4b17023SJohn Marino /**
2588e4b17023SJohn Marino * @brief Finds the largest subrange in which @p __val could be inserted
2589e4b17023SJohn Marino * at any place in it without changing the ordering.
2590e4b17023SJohn Marino * @ingroup binary_search_algorithms
2591e4b17023SJohn Marino * @param __first An iterator.
2592e4b17023SJohn Marino * @param __last Another iterator.
2593e4b17023SJohn Marino * @param __val The search term.
2594e4b17023SJohn Marino * @return An pair of iterators defining the subrange.
2595e4b17023SJohn Marino * @ingroup binary_search_algorithms
2596e4b17023SJohn Marino *
2597e4b17023SJohn Marino * This is equivalent to
2598e4b17023SJohn Marino * @code
2599e4b17023SJohn Marino * std::make_pair(lower_bound(__first, __last, __val),
2600e4b17023SJohn Marino * upper_bound(__first, __last, __val))
2601e4b17023SJohn Marino * @endcode
2602e4b17023SJohn Marino * but does not actually call those functions.
2603e4b17023SJohn Marino */
2604e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp>
2605e4b17023SJohn Marino pair<_ForwardIterator, _ForwardIterator>
2606e4b17023SJohn Marino equal_range(_ForwardIterator __first, _ForwardIterator __last,
2607e4b17023SJohn Marino const _Tp& __val)
2608e4b17023SJohn Marino {
2609e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::value_type
2610e4b17023SJohn Marino _ValueType;
2611e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::difference_type
2612e4b17023SJohn Marino _DistanceType;
2613e4b17023SJohn Marino
2614e4b17023SJohn Marino // concept requirements
2615e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2616e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>)
2617e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>)
2618e4b17023SJohn Marino __glibcxx_requires_partitioned_lower(__first, __last, __val);
2619e4b17023SJohn Marino __glibcxx_requires_partitioned_upper(__first, __last, __val);
2620e4b17023SJohn Marino
2621e4b17023SJohn Marino _DistanceType __len = std::distance(__first, __last);
2622e4b17023SJohn Marino
2623e4b17023SJohn Marino while (__len > 0)
2624e4b17023SJohn Marino {
2625e4b17023SJohn Marino _DistanceType __half = __len >> 1;
2626e4b17023SJohn Marino _ForwardIterator __middle = __first;
2627e4b17023SJohn Marino std::advance(__middle, __half);
2628e4b17023SJohn Marino if (*__middle < __val)
2629e4b17023SJohn Marino {
2630e4b17023SJohn Marino __first = __middle;
2631e4b17023SJohn Marino ++__first;
2632e4b17023SJohn Marino __len = __len - __half - 1;
2633e4b17023SJohn Marino }
2634e4b17023SJohn Marino else if (__val < *__middle)
2635e4b17023SJohn Marino __len = __half;
2636e4b17023SJohn Marino else
2637e4b17023SJohn Marino {
2638e4b17023SJohn Marino _ForwardIterator __left = std::lower_bound(__first, __middle,
2639e4b17023SJohn Marino __val);
2640e4b17023SJohn Marino std::advance(__first, __len);
2641e4b17023SJohn Marino _ForwardIterator __right = std::upper_bound(++__middle, __first,
2642e4b17023SJohn Marino __val);
2643e4b17023SJohn Marino return pair<_ForwardIterator, _ForwardIterator>(__left, __right);
2644e4b17023SJohn Marino }
2645e4b17023SJohn Marino }
2646e4b17023SJohn Marino return pair<_ForwardIterator, _ForwardIterator>(__first, __first);
2647e4b17023SJohn Marino }
2648e4b17023SJohn Marino
2649e4b17023SJohn Marino /**
2650e4b17023SJohn Marino * @brief Finds the largest subrange in which @p __val could be inserted
2651e4b17023SJohn Marino * at any place in it without changing the ordering.
2652e4b17023SJohn Marino * @param __first An iterator.
2653e4b17023SJohn Marino * @param __last Another iterator.
2654e4b17023SJohn Marino * @param __val The search term.
2655e4b17023SJohn Marino * @param __comp A functor to use for comparisons.
2656e4b17023SJohn Marino * @return An pair of iterators defining the subrange.
2657e4b17023SJohn Marino * @ingroup binary_search_algorithms
2658e4b17023SJohn Marino *
2659e4b17023SJohn Marino * This is equivalent to
2660e4b17023SJohn Marino * @code
2661e4b17023SJohn Marino * std::make_pair(lower_bound(__first, __last, __val, __comp),
2662e4b17023SJohn Marino * upper_bound(__first, __last, __val, __comp))
2663e4b17023SJohn Marino * @endcode
2664e4b17023SJohn Marino * but does not actually call those functions.
2665e4b17023SJohn Marino */
2666e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp, typename _Compare>
2667e4b17023SJohn Marino pair<_ForwardIterator, _ForwardIterator>
2668e4b17023SJohn Marino equal_range(_ForwardIterator __first, _ForwardIterator __last,
2669e4b17023SJohn Marino const _Tp& __val, _Compare __comp)
2670e4b17023SJohn Marino {
2671e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::value_type
2672e4b17023SJohn Marino _ValueType;
2673e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::difference_type
2674e4b17023SJohn Marino _DistanceType;
2675e4b17023SJohn Marino
2676e4b17023SJohn Marino // concept requirements
2677e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2678e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
2679e4b17023SJohn Marino _ValueType, _Tp>)
2680e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
2681e4b17023SJohn Marino _Tp, _ValueType>)
2682e4b17023SJohn Marino __glibcxx_requires_partitioned_lower_pred(__first, __last,
2683e4b17023SJohn Marino __val, __comp);
2684e4b17023SJohn Marino __glibcxx_requires_partitioned_upper_pred(__first, __last,
2685e4b17023SJohn Marino __val, __comp);
2686e4b17023SJohn Marino
2687e4b17023SJohn Marino _DistanceType __len = std::distance(__first, __last);
2688e4b17023SJohn Marino
2689e4b17023SJohn Marino while (__len > 0)
2690e4b17023SJohn Marino {
2691e4b17023SJohn Marino _DistanceType __half = __len >> 1;
2692e4b17023SJohn Marino _ForwardIterator __middle = __first;
2693e4b17023SJohn Marino std::advance(__middle, __half);
2694e4b17023SJohn Marino if (__comp(*__middle, __val))
2695e4b17023SJohn Marino {
2696e4b17023SJohn Marino __first = __middle;
2697e4b17023SJohn Marino ++__first;
2698e4b17023SJohn Marino __len = __len - __half - 1;
2699e4b17023SJohn Marino }
2700e4b17023SJohn Marino else if (__comp(__val, *__middle))
2701e4b17023SJohn Marino __len = __half;
2702e4b17023SJohn Marino else
2703e4b17023SJohn Marino {
2704e4b17023SJohn Marino _ForwardIterator __left = std::lower_bound(__first, __middle,
2705e4b17023SJohn Marino __val, __comp);
2706e4b17023SJohn Marino std::advance(__first, __len);
2707e4b17023SJohn Marino _ForwardIterator __right = std::upper_bound(++__middle, __first,
2708e4b17023SJohn Marino __val, __comp);
2709e4b17023SJohn Marino return pair<_ForwardIterator, _ForwardIterator>(__left, __right);
2710e4b17023SJohn Marino }
2711e4b17023SJohn Marino }
2712e4b17023SJohn Marino return pair<_ForwardIterator, _ForwardIterator>(__first, __first);
2713e4b17023SJohn Marino }
2714e4b17023SJohn Marino
2715e4b17023SJohn Marino /**
2716e4b17023SJohn Marino * @brief Determines whether an element exists in a range.
2717e4b17023SJohn Marino * @ingroup binary_search_algorithms
2718e4b17023SJohn Marino * @param __first An iterator.
2719e4b17023SJohn Marino * @param __last Another iterator.
2720e4b17023SJohn Marino * @param __val The search term.
2721e4b17023SJohn Marino * @return True if @p __val (or its equivalent) is in [@p
2722e4b17023SJohn Marino * __first,@p __last ].
2723e4b17023SJohn Marino *
2724e4b17023SJohn Marino * Note that this does not actually return an iterator to @p __val. For
2725e4b17023SJohn Marino * that, use std::find or a container's specialized find member functions.
2726e4b17023SJohn Marino */
2727e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp>
2728e4b17023SJohn Marino bool
2729e4b17023SJohn Marino binary_search(_ForwardIterator __first, _ForwardIterator __last,
2730e4b17023SJohn Marino const _Tp& __val)
2731e4b17023SJohn Marino {
2732e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::value_type
2733e4b17023SJohn Marino _ValueType;
2734e4b17023SJohn Marino
2735e4b17023SJohn Marino // concept requirements
2736e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2737e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>)
2738e4b17023SJohn Marino __glibcxx_requires_partitioned_lower(__first, __last, __val);
2739e4b17023SJohn Marino __glibcxx_requires_partitioned_upper(__first, __last, __val);
2740e4b17023SJohn Marino
2741e4b17023SJohn Marino _ForwardIterator __i = std::lower_bound(__first, __last, __val);
2742e4b17023SJohn Marino return __i != __last && !(__val < *__i);
2743e4b17023SJohn Marino }
2744e4b17023SJohn Marino
2745e4b17023SJohn Marino /**
2746e4b17023SJohn Marino * @brief Determines whether an element exists in a range.
2747e4b17023SJohn Marino * @ingroup binary_search_algorithms
2748e4b17023SJohn Marino * @param __first An iterator.
2749e4b17023SJohn Marino * @param __last Another iterator.
2750e4b17023SJohn Marino * @param __val The search term.
2751e4b17023SJohn Marino * @param __comp A functor to use for comparisons.
2752e4b17023SJohn Marino * @return True if @p __val (or its equivalent) is in @p [__first,__last].
2753e4b17023SJohn Marino *
2754e4b17023SJohn Marino * Note that this does not actually return an iterator to @p __val. For
2755e4b17023SJohn Marino * that, use std::find or a container's specialized find member functions.
2756e4b17023SJohn Marino *
2757e4b17023SJohn Marino * The comparison function should have the same effects on ordering as
2758e4b17023SJohn Marino * the function used for the initial sort.
2759e4b17023SJohn Marino */
2760e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp, typename _Compare>
2761e4b17023SJohn Marino bool
2762e4b17023SJohn Marino binary_search(_ForwardIterator __first, _ForwardIterator __last,
2763e4b17023SJohn Marino const _Tp& __val, _Compare __comp)
2764e4b17023SJohn Marino {
2765e4b17023SJohn Marino typedef typename iterator_traits<_ForwardIterator>::value_type
2766e4b17023SJohn Marino _ValueType;
2767e4b17023SJohn Marino
2768e4b17023SJohn Marino // concept requirements
2769e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2770e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
2771e4b17023SJohn Marino _Tp, _ValueType>)
2772e4b17023SJohn Marino __glibcxx_requires_partitioned_lower_pred(__first, __last,
2773e4b17023SJohn Marino __val, __comp);
2774e4b17023SJohn Marino __glibcxx_requires_partitioned_upper_pred(__first, __last,
2775e4b17023SJohn Marino __val, __comp);
2776e4b17023SJohn Marino
2777e4b17023SJohn Marino _ForwardIterator __i = std::lower_bound(__first, __last, __val, __comp);
2778e4b17023SJohn Marino return __i != __last && !bool(__comp(__val, *__i));
2779e4b17023SJohn Marino }
2780e4b17023SJohn Marino
2781e4b17023SJohn Marino // merge
2782e4b17023SJohn Marino
2783e4b17023SJohn Marino /// This is a helper function for the __merge_adaptive routines.
2784e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2,
2785e4b17023SJohn Marino typename _OutputIterator>
2786e4b17023SJohn Marino void
2787e4b17023SJohn Marino __move_merge_adaptive(_InputIterator1 __first1, _InputIterator1 __last1,
2788e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2,
2789e4b17023SJohn Marino _OutputIterator __result)
2790e4b17023SJohn Marino {
2791e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2)
2792e4b17023SJohn Marino {
2793e4b17023SJohn Marino if (*__first2 < *__first1)
2794e4b17023SJohn Marino {
2795e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first2);
2796e4b17023SJohn Marino ++__first2;
2797e4b17023SJohn Marino }
2798e4b17023SJohn Marino else
2799e4b17023SJohn Marino {
2800e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first1);
2801e4b17023SJohn Marino ++__first1;
2802e4b17023SJohn Marino }
2803e4b17023SJohn Marino ++__result;
2804e4b17023SJohn Marino }
2805e4b17023SJohn Marino if (__first1 != __last1)
2806e4b17023SJohn Marino _GLIBCXX_MOVE3(__first1, __last1, __result);
2807e4b17023SJohn Marino }
2808e4b17023SJohn Marino
2809e4b17023SJohn Marino /// This is a helper function for the __merge_adaptive routines.
2810e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2,
2811e4b17023SJohn Marino typename _OutputIterator, typename _Compare>
2812e4b17023SJohn Marino void
2813e4b17023SJohn Marino __move_merge_adaptive(_InputIterator1 __first1, _InputIterator1 __last1,
2814e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2,
2815e4b17023SJohn Marino _OutputIterator __result, _Compare __comp)
2816e4b17023SJohn Marino {
2817e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2)
2818e4b17023SJohn Marino {
2819e4b17023SJohn Marino if (__comp(*__first2, *__first1))
2820e4b17023SJohn Marino {
2821e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first2);
2822e4b17023SJohn Marino ++__first2;
2823e4b17023SJohn Marino }
2824e4b17023SJohn Marino else
2825e4b17023SJohn Marino {
2826e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first1);
2827e4b17023SJohn Marino ++__first1;
2828e4b17023SJohn Marino }
2829e4b17023SJohn Marino ++__result;
2830e4b17023SJohn Marino }
2831e4b17023SJohn Marino if (__first1 != __last1)
2832e4b17023SJohn Marino _GLIBCXX_MOVE3(__first1, __last1, __result);
2833e4b17023SJohn Marino }
2834e4b17023SJohn Marino
2835e4b17023SJohn Marino /// This is a helper function for the __merge_adaptive routines.
2836e4b17023SJohn Marino template<typename _BidirectionalIterator1, typename _BidirectionalIterator2,
2837e4b17023SJohn Marino typename _BidirectionalIterator3>
2838e4b17023SJohn Marino void
2839e4b17023SJohn Marino __move_merge_adaptive_backward(_BidirectionalIterator1 __first1,
2840e4b17023SJohn Marino _BidirectionalIterator1 __last1,
2841e4b17023SJohn Marino _BidirectionalIterator2 __first2,
2842e4b17023SJohn Marino _BidirectionalIterator2 __last2,
2843e4b17023SJohn Marino _BidirectionalIterator3 __result)
2844e4b17023SJohn Marino {
2845e4b17023SJohn Marino if (__first1 == __last1)
2846e4b17023SJohn Marino {
2847e4b17023SJohn Marino _GLIBCXX_MOVE_BACKWARD3(__first2, __last2, __result);
2848e4b17023SJohn Marino return;
2849e4b17023SJohn Marino }
2850e4b17023SJohn Marino else if (__first2 == __last2)
2851e4b17023SJohn Marino return;
2852e4b17023SJohn Marino
2853e4b17023SJohn Marino --__last1;
2854e4b17023SJohn Marino --__last2;
2855e4b17023SJohn Marino while (true)
2856e4b17023SJohn Marino {
2857e4b17023SJohn Marino if (*__last2 < *__last1)
2858e4b17023SJohn Marino {
2859e4b17023SJohn Marino *--__result = _GLIBCXX_MOVE(*__last1);
2860e4b17023SJohn Marino if (__first1 == __last1)
2861e4b17023SJohn Marino {
2862e4b17023SJohn Marino _GLIBCXX_MOVE_BACKWARD3(__first2, ++__last2, __result);
2863e4b17023SJohn Marino return;
2864e4b17023SJohn Marino }
2865e4b17023SJohn Marino --__last1;
2866e4b17023SJohn Marino }
2867e4b17023SJohn Marino else
2868e4b17023SJohn Marino {
2869e4b17023SJohn Marino *--__result = _GLIBCXX_MOVE(*__last2);
2870e4b17023SJohn Marino if (__first2 == __last2)
2871e4b17023SJohn Marino return;
2872e4b17023SJohn Marino --__last2;
2873e4b17023SJohn Marino }
2874e4b17023SJohn Marino }
2875e4b17023SJohn Marino }
2876e4b17023SJohn Marino
2877e4b17023SJohn Marino /// This is a helper function for the __merge_adaptive routines.
2878e4b17023SJohn Marino template<typename _BidirectionalIterator1, typename _BidirectionalIterator2,
2879e4b17023SJohn Marino typename _BidirectionalIterator3, typename _Compare>
2880e4b17023SJohn Marino void
2881e4b17023SJohn Marino __move_merge_adaptive_backward(_BidirectionalIterator1 __first1,
2882e4b17023SJohn Marino _BidirectionalIterator1 __last1,
2883e4b17023SJohn Marino _BidirectionalIterator2 __first2,
2884e4b17023SJohn Marino _BidirectionalIterator2 __last2,
2885e4b17023SJohn Marino _BidirectionalIterator3 __result,
2886e4b17023SJohn Marino _Compare __comp)
2887e4b17023SJohn Marino {
2888e4b17023SJohn Marino if (__first1 == __last1)
2889e4b17023SJohn Marino {
2890e4b17023SJohn Marino _GLIBCXX_MOVE_BACKWARD3(__first2, __last2, __result);
2891e4b17023SJohn Marino return;
2892e4b17023SJohn Marino }
2893e4b17023SJohn Marino else if (__first2 == __last2)
2894e4b17023SJohn Marino return;
2895e4b17023SJohn Marino
2896e4b17023SJohn Marino --__last1;
2897e4b17023SJohn Marino --__last2;
2898e4b17023SJohn Marino while (true)
2899e4b17023SJohn Marino {
2900e4b17023SJohn Marino if (__comp(*__last2, *__last1))
2901e4b17023SJohn Marino {
2902e4b17023SJohn Marino *--__result = _GLIBCXX_MOVE(*__last1);
2903e4b17023SJohn Marino if (__first1 == __last1)
2904e4b17023SJohn Marino {
2905e4b17023SJohn Marino _GLIBCXX_MOVE_BACKWARD3(__first2, ++__last2, __result);
2906e4b17023SJohn Marino return;
2907e4b17023SJohn Marino }
2908e4b17023SJohn Marino --__last1;
2909e4b17023SJohn Marino }
2910e4b17023SJohn Marino else
2911e4b17023SJohn Marino {
2912e4b17023SJohn Marino *--__result = _GLIBCXX_MOVE(*__last2);
2913e4b17023SJohn Marino if (__first2 == __last2)
2914e4b17023SJohn Marino return;
2915e4b17023SJohn Marino --__last2;
2916e4b17023SJohn Marino }
2917e4b17023SJohn Marino }
2918e4b17023SJohn Marino }
2919e4b17023SJohn Marino
2920e4b17023SJohn Marino /// This is a helper function for the merge routines.
2921e4b17023SJohn Marino template<typename _BidirectionalIterator1, typename _BidirectionalIterator2,
2922e4b17023SJohn Marino typename _Distance>
2923e4b17023SJohn Marino _BidirectionalIterator1
2924e4b17023SJohn Marino __rotate_adaptive(_BidirectionalIterator1 __first,
2925e4b17023SJohn Marino _BidirectionalIterator1 __middle,
2926e4b17023SJohn Marino _BidirectionalIterator1 __last,
2927e4b17023SJohn Marino _Distance __len1, _Distance __len2,
2928e4b17023SJohn Marino _BidirectionalIterator2 __buffer,
2929e4b17023SJohn Marino _Distance __buffer_size)
2930e4b17023SJohn Marino {
2931e4b17023SJohn Marino _BidirectionalIterator2 __buffer_end;
2932e4b17023SJohn Marino if (__len1 > __len2 && __len2 <= __buffer_size)
2933e4b17023SJohn Marino {
2934e4b17023SJohn Marino if (__len2)
2935e4b17023SJohn Marino {
2936e4b17023SJohn Marino __buffer_end = _GLIBCXX_MOVE3(__middle, __last, __buffer);
2937e4b17023SJohn Marino _GLIBCXX_MOVE_BACKWARD3(__first, __middle, __last);
2938e4b17023SJohn Marino return _GLIBCXX_MOVE3(__buffer, __buffer_end, __first);
2939e4b17023SJohn Marino }
2940e4b17023SJohn Marino else
2941e4b17023SJohn Marino return __first;
2942e4b17023SJohn Marino }
2943e4b17023SJohn Marino else if (__len1 <= __buffer_size)
2944e4b17023SJohn Marino {
2945e4b17023SJohn Marino if (__len1)
2946e4b17023SJohn Marino {
2947e4b17023SJohn Marino __buffer_end = _GLIBCXX_MOVE3(__first, __middle, __buffer);
2948e4b17023SJohn Marino _GLIBCXX_MOVE3(__middle, __last, __first);
2949e4b17023SJohn Marino return _GLIBCXX_MOVE_BACKWARD3(__buffer, __buffer_end, __last);
2950e4b17023SJohn Marino }
2951e4b17023SJohn Marino else
2952e4b17023SJohn Marino return __last;
2953e4b17023SJohn Marino }
2954e4b17023SJohn Marino else
2955e4b17023SJohn Marino {
2956e4b17023SJohn Marino std::rotate(__first, __middle, __last);
2957e4b17023SJohn Marino std::advance(__first, std::distance(__middle, __last));
2958e4b17023SJohn Marino return __first;
2959e4b17023SJohn Marino }
2960e4b17023SJohn Marino }
2961e4b17023SJohn Marino
2962e4b17023SJohn Marino /// This is a helper function for the merge routines.
2963e4b17023SJohn Marino template<typename _BidirectionalIterator, typename _Distance,
2964e4b17023SJohn Marino typename _Pointer>
2965e4b17023SJohn Marino void
2966e4b17023SJohn Marino __merge_adaptive(_BidirectionalIterator __first,
2967e4b17023SJohn Marino _BidirectionalIterator __middle,
2968e4b17023SJohn Marino _BidirectionalIterator __last,
2969e4b17023SJohn Marino _Distance __len1, _Distance __len2,
2970e4b17023SJohn Marino _Pointer __buffer, _Distance __buffer_size)
2971e4b17023SJohn Marino {
2972e4b17023SJohn Marino if (__len1 <= __len2 && __len1 <= __buffer_size)
2973e4b17023SJohn Marino {
2974e4b17023SJohn Marino _Pointer __buffer_end = _GLIBCXX_MOVE3(__first, __middle, __buffer);
2975e4b17023SJohn Marino std::__move_merge_adaptive(__buffer, __buffer_end, __middle, __last,
2976e4b17023SJohn Marino __first);
2977e4b17023SJohn Marino }
2978e4b17023SJohn Marino else if (__len2 <= __buffer_size)
2979e4b17023SJohn Marino {
2980e4b17023SJohn Marino _Pointer __buffer_end = _GLIBCXX_MOVE3(__middle, __last, __buffer);
2981e4b17023SJohn Marino std::__move_merge_adaptive_backward(__first, __middle, __buffer,
2982e4b17023SJohn Marino __buffer_end, __last);
2983e4b17023SJohn Marino }
2984e4b17023SJohn Marino else
2985e4b17023SJohn Marino {
2986e4b17023SJohn Marino _BidirectionalIterator __first_cut = __first;
2987e4b17023SJohn Marino _BidirectionalIterator __second_cut = __middle;
2988e4b17023SJohn Marino _Distance __len11 = 0;
2989e4b17023SJohn Marino _Distance __len22 = 0;
2990e4b17023SJohn Marino if (__len1 > __len2)
2991e4b17023SJohn Marino {
2992e4b17023SJohn Marino __len11 = __len1 / 2;
2993e4b17023SJohn Marino std::advance(__first_cut, __len11);
2994e4b17023SJohn Marino __second_cut = std::lower_bound(__middle, __last,
2995e4b17023SJohn Marino *__first_cut);
2996e4b17023SJohn Marino __len22 = std::distance(__middle, __second_cut);
2997e4b17023SJohn Marino }
2998e4b17023SJohn Marino else
2999e4b17023SJohn Marino {
3000e4b17023SJohn Marino __len22 = __len2 / 2;
3001e4b17023SJohn Marino std::advance(__second_cut, __len22);
3002e4b17023SJohn Marino __first_cut = std::upper_bound(__first, __middle,
3003e4b17023SJohn Marino *__second_cut);
3004e4b17023SJohn Marino __len11 = std::distance(__first, __first_cut);
3005e4b17023SJohn Marino }
3006e4b17023SJohn Marino _BidirectionalIterator __new_middle =
3007e4b17023SJohn Marino std::__rotate_adaptive(__first_cut, __middle, __second_cut,
3008e4b17023SJohn Marino __len1 - __len11, __len22, __buffer,
3009e4b17023SJohn Marino __buffer_size);
3010e4b17023SJohn Marino std::__merge_adaptive(__first, __first_cut, __new_middle, __len11,
3011e4b17023SJohn Marino __len22, __buffer, __buffer_size);
3012e4b17023SJohn Marino std::__merge_adaptive(__new_middle, __second_cut, __last,
3013e4b17023SJohn Marino __len1 - __len11,
3014e4b17023SJohn Marino __len2 - __len22, __buffer, __buffer_size);
3015e4b17023SJohn Marino }
3016e4b17023SJohn Marino }
3017e4b17023SJohn Marino
3018e4b17023SJohn Marino /// This is a helper function for the merge routines.
3019e4b17023SJohn Marino template<typename _BidirectionalIterator, typename _Distance,
3020e4b17023SJohn Marino typename _Pointer, typename _Compare>
3021e4b17023SJohn Marino void
3022e4b17023SJohn Marino __merge_adaptive(_BidirectionalIterator __first,
3023e4b17023SJohn Marino _BidirectionalIterator __middle,
3024e4b17023SJohn Marino _BidirectionalIterator __last,
3025e4b17023SJohn Marino _Distance __len1, _Distance __len2,
3026e4b17023SJohn Marino _Pointer __buffer, _Distance __buffer_size,
3027e4b17023SJohn Marino _Compare __comp)
3028e4b17023SJohn Marino {
3029e4b17023SJohn Marino if (__len1 <= __len2 && __len1 <= __buffer_size)
3030e4b17023SJohn Marino {
3031e4b17023SJohn Marino _Pointer __buffer_end = _GLIBCXX_MOVE3(__first, __middle, __buffer);
3032e4b17023SJohn Marino std::__move_merge_adaptive(__buffer, __buffer_end, __middle, __last,
3033e4b17023SJohn Marino __first, __comp);
3034e4b17023SJohn Marino }
3035e4b17023SJohn Marino else if (__len2 <= __buffer_size)
3036e4b17023SJohn Marino {
3037e4b17023SJohn Marino _Pointer __buffer_end = _GLIBCXX_MOVE3(__middle, __last, __buffer);
3038e4b17023SJohn Marino std::__move_merge_adaptive_backward(__first, __middle, __buffer,
3039e4b17023SJohn Marino __buffer_end, __last, __comp);
3040e4b17023SJohn Marino }
3041e4b17023SJohn Marino else
3042e4b17023SJohn Marino {
3043e4b17023SJohn Marino _BidirectionalIterator __first_cut = __first;
3044e4b17023SJohn Marino _BidirectionalIterator __second_cut = __middle;
3045e4b17023SJohn Marino _Distance __len11 = 0;
3046e4b17023SJohn Marino _Distance __len22 = 0;
3047e4b17023SJohn Marino if (__len1 > __len2)
3048e4b17023SJohn Marino {
3049e4b17023SJohn Marino __len11 = __len1 / 2;
3050e4b17023SJohn Marino std::advance(__first_cut, __len11);
3051e4b17023SJohn Marino __second_cut = std::lower_bound(__middle, __last, *__first_cut,
3052e4b17023SJohn Marino __comp);
3053e4b17023SJohn Marino __len22 = std::distance(__middle, __second_cut);
3054e4b17023SJohn Marino }
3055e4b17023SJohn Marino else
3056e4b17023SJohn Marino {
3057e4b17023SJohn Marino __len22 = __len2 / 2;
3058e4b17023SJohn Marino std::advance(__second_cut, __len22);
3059e4b17023SJohn Marino __first_cut = std::upper_bound(__first, __middle, *__second_cut,
3060e4b17023SJohn Marino __comp);
3061e4b17023SJohn Marino __len11 = std::distance(__first, __first_cut);
3062e4b17023SJohn Marino }
3063e4b17023SJohn Marino _BidirectionalIterator __new_middle =
3064e4b17023SJohn Marino std::__rotate_adaptive(__first_cut, __middle, __second_cut,
3065e4b17023SJohn Marino __len1 - __len11, __len22, __buffer,
3066e4b17023SJohn Marino __buffer_size);
3067e4b17023SJohn Marino std::__merge_adaptive(__first, __first_cut, __new_middle, __len11,
3068e4b17023SJohn Marino __len22, __buffer, __buffer_size, __comp);
3069e4b17023SJohn Marino std::__merge_adaptive(__new_middle, __second_cut, __last,
3070e4b17023SJohn Marino __len1 - __len11,
3071e4b17023SJohn Marino __len2 - __len22, __buffer,
3072e4b17023SJohn Marino __buffer_size, __comp);
3073e4b17023SJohn Marino }
3074e4b17023SJohn Marino }
3075e4b17023SJohn Marino
3076e4b17023SJohn Marino /// This is a helper function for the merge routines.
3077e4b17023SJohn Marino template<typename _BidirectionalIterator, typename _Distance>
3078e4b17023SJohn Marino void
3079e4b17023SJohn Marino __merge_without_buffer(_BidirectionalIterator __first,
3080e4b17023SJohn Marino _BidirectionalIterator __middle,
3081e4b17023SJohn Marino _BidirectionalIterator __last,
3082e4b17023SJohn Marino _Distance __len1, _Distance __len2)
3083e4b17023SJohn Marino {
3084e4b17023SJohn Marino if (__len1 == 0 || __len2 == 0)
3085e4b17023SJohn Marino return;
3086e4b17023SJohn Marino if (__len1 + __len2 == 2)
3087e4b17023SJohn Marino {
3088e4b17023SJohn Marino if (*__middle < *__first)
3089e4b17023SJohn Marino std::iter_swap(__first, __middle);
3090e4b17023SJohn Marino return;
3091e4b17023SJohn Marino }
3092e4b17023SJohn Marino _BidirectionalIterator __first_cut = __first;
3093e4b17023SJohn Marino _BidirectionalIterator __second_cut = __middle;
3094e4b17023SJohn Marino _Distance __len11 = 0;
3095e4b17023SJohn Marino _Distance __len22 = 0;
3096e4b17023SJohn Marino if (__len1 > __len2)
3097e4b17023SJohn Marino {
3098e4b17023SJohn Marino __len11 = __len1 / 2;
3099e4b17023SJohn Marino std::advance(__first_cut, __len11);
3100e4b17023SJohn Marino __second_cut = std::lower_bound(__middle, __last, *__first_cut);
3101e4b17023SJohn Marino __len22 = std::distance(__middle, __second_cut);
3102e4b17023SJohn Marino }
3103e4b17023SJohn Marino else
3104e4b17023SJohn Marino {
3105e4b17023SJohn Marino __len22 = __len2 / 2;
3106e4b17023SJohn Marino std::advance(__second_cut, __len22);
3107e4b17023SJohn Marino __first_cut = std::upper_bound(__first, __middle, *__second_cut);
3108e4b17023SJohn Marino __len11 = std::distance(__first, __first_cut);
3109e4b17023SJohn Marino }
3110e4b17023SJohn Marino std::rotate(__first_cut, __middle, __second_cut);
3111e4b17023SJohn Marino _BidirectionalIterator __new_middle = __first_cut;
3112e4b17023SJohn Marino std::advance(__new_middle, std::distance(__middle, __second_cut));
3113e4b17023SJohn Marino std::__merge_without_buffer(__first, __first_cut, __new_middle,
3114e4b17023SJohn Marino __len11, __len22);
3115e4b17023SJohn Marino std::__merge_without_buffer(__new_middle, __second_cut, __last,
3116e4b17023SJohn Marino __len1 - __len11, __len2 - __len22);
3117e4b17023SJohn Marino }
3118e4b17023SJohn Marino
3119e4b17023SJohn Marino /// This is a helper function for the merge routines.
3120e4b17023SJohn Marino template<typename _BidirectionalIterator, typename _Distance,
3121e4b17023SJohn Marino typename _Compare>
3122e4b17023SJohn Marino void
3123e4b17023SJohn Marino __merge_without_buffer(_BidirectionalIterator __first,
3124e4b17023SJohn Marino _BidirectionalIterator __middle,
3125e4b17023SJohn Marino _BidirectionalIterator __last,
3126e4b17023SJohn Marino _Distance __len1, _Distance __len2,
3127e4b17023SJohn Marino _Compare __comp)
3128e4b17023SJohn Marino {
3129e4b17023SJohn Marino if (__len1 == 0 || __len2 == 0)
3130e4b17023SJohn Marino return;
3131e4b17023SJohn Marino if (__len1 + __len2 == 2)
3132e4b17023SJohn Marino {
3133e4b17023SJohn Marino if (__comp(*__middle, *__first))
3134e4b17023SJohn Marino std::iter_swap(__first, __middle);
3135e4b17023SJohn Marino return;
3136e4b17023SJohn Marino }
3137e4b17023SJohn Marino _BidirectionalIterator __first_cut = __first;
3138e4b17023SJohn Marino _BidirectionalIterator __second_cut = __middle;
3139e4b17023SJohn Marino _Distance __len11 = 0;
3140e4b17023SJohn Marino _Distance __len22 = 0;
3141e4b17023SJohn Marino if (__len1 > __len2)
3142e4b17023SJohn Marino {
3143e4b17023SJohn Marino __len11 = __len1 / 2;
3144e4b17023SJohn Marino std::advance(__first_cut, __len11);
3145e4b17023SJohn Marino __second_cut = std::lower_bound(__middle, __last, *__first_cut,
3146e4b17023SJohn Marino __comp);
3147e4b17023SJohn Marino __len22 = std::distance(__middle, __second_cut);
3148e4b17023SJohn Marino }
3149e4b17023SJohn Marino else
3150e4b17023SJohn Marino {
3151e4b17023SJohn Marino __len22 = __len2 / 2;
3152e4b17023SJohn Marino std::advance(__second_cut, __len22);
3153e4b17023SJohn Marino __first_cut = std::upper_bound(__first, __middle, *__second_cut,
3154e4b17023SJohn Marino __comp);
3155e4b17023SJohn Marino __len11 = std::distance(__first, __first_cut);
3156e4b17023SJohn Marino }
3157e4b17023SJohn Marino std::rotate(__first_cut, __middle, __second_cut);
3158e4b17023SJohn Marino _BidirectionalIterator __new_middle = __first_cut;
3159e4b17023SJohn Marino std::advance(__new_middle, std::distance(__middle, __second_cut));
3160e4b17023SJohn Marino std::__merge_without_buffer(__first, __first_cut, __new_middle,
3161e4b17023SJohn Marino __len11, __len22, __comp);
3162e4b17023SJohn Marino std::__merge_without_buffer(__new_middle, __second_cut, __last,
3163e4b17023SJohn Marino __len1 - __len11, __len2 - __len22, __comp);
3164e4b17023SJohn Marino }
3165e4b17023SJohn Marino
3166e4b17023SJohn Marino /**
3167e4b17023SJohn Marino * @brief Merges two sorted ranges in place.
3168e4b17023SJohn Marino * @ingroup sorting_algorithms
3169e4b17023SJohn Marino * @param __first An iterator.
3170e4b17023SJohn Marino * @param __middle Another iterator.
3171e4b17023SJohn Marino * @param __last Another iterator.
3172e4b17023SJohn Marino * @return Nothing.
3173e4b17023SJohn Marino *
3174e4b17023SJohn Marino * Merges two sorted and consecutive ranges, [__first,__middle) and
3175e4b17023SJohn Marino * [__middle,__last), and puts the result in [__first,__last). The
3176e4b17023SJohn Marino * output will be sorted. The sort is @e stable, that is, for
3177e4b17023SJohn Marino * equivalent elements in the two ranges, elements from the first
3178e4b17023SJohn Marino * range will always come before elements from the second.
3179e4b17023SJohn Marino *
3180e4b17023SJohn Marino * If enough additional memory is available, this takes (__last-__first)-1
3181e4b17023SJohn Marino * comparisons. Otherwise an NlogN algorithm is used, where N is
3182e4b17023SJohn Marino * distance(__first,__last).
3183e4b17023SJohn Marino */
3184e4b17023SJohn Marino template<typename _BidirectionalIterator>
3185e4b17023SJohn Marino void
3186e4b17023SJohn Marino inplace_merge(_BidirectionalIterator __first,
3187e4b17023SJohn Marino _BidirectionalIterator __middle,
3188e4b17023SJohn Marino _BidirectionalIterator __last)
3189e4b17023SJohn Marino {
3190e4b17023SJohn Marino typedef typename iterator_traits<_BidirectionalIterator>::value_type
3191e4b17023SJohn Marino _ValueType;
3192e4b17023SJohn Marino typedef typename iterator_traits<_BidirectionalIterator>::difference_type
3193e4b17023SJohn Marino _DistanceType;
3194e4b17023SJohn Marino
3195e4b17023SJohn Marino // concept requirements
3196e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
3197e4b17023SJohn Marino _BidirectionalIterator>)
3198e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
3199e4b17023SJohn Marino __glibcxx_requires_sorted(__first, __middle);
3200e4b17023SJohn Marino __glibcxx_requires_sorted(__middle, __last);
3201e4b17023SJohn Marino
3202e4b17023SJohn Marino if (__first == __middle || __middle == __last)
3203e4b17023SJohn Marino return;
3204e4b17023SJohn Marino
3205e4b17023SJohn Marino _DistanceType __len1 = std::distance(__first, __middle);
3206e4b17023SJohn Marino _DistanceType __len2 = std::distance(__middle, __last);
3207e4b17023SJohn Marino
3208e4b17023SJohn Marino _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first,
3209e4b17023SJohn Marino __last);
3210e4b17023SJohn Marino if (__buf.begin() == 0)
3211e4b17023SJohn Marino std::__merge_without_buffer(__first, __middle, __last, __len1, __len2);
3212e4b17023SJohn Marino else
3213e4b17023SJohn Marino std::__merge_adaptive(__first, __middle, __last, __len1, __len2,
3214e4b17023SJohn Marino __buf.begin(), _DistanceType(__buf.size()));
3215e4b17023SJohn Marino }
3216e4b17023SJohn Marino
3217e4b17023SJohn Marino /**
3218e4b17023SJohn Marino * @brief Merges two sorted ranges in place.
3219e4b17023SJohn Marino * @ingroup sorting_algorithms
3220e4b17023SJohn Marino * @param __first An iterator.
3221e4b17023SJohn Marino * @param __middle Another iterator.
3222e4b17023SJohn Marino * @param __last Another iterator.
3223e4b17023SJohn Marino * @param __comp A functor to use for comparisons.
3224e4b17023SJohn Marino * @return Nothing.
3225e4b17023SJohn Marino *
3226e4b17023SJohn Marino * Merges two sorted and consecutive ranges, [__first,__middle) and
3227e4b17023SJohn Marino * [middle,last), and puts the result in [__first,__last). The output will
3228e4b17023SJohn Marino * be sorted. The sort is @e stable, that is, for equivalent
3229e4b17023SJohn Marino * elements in the two ranges, elements from the first range will always
3230e4b17023SJohn Marino * come before elements from the second.
3231e4b17023SJohn Marino *
3232e4b17023SJohn Marino * If enough additional memory is available, this takes (__last-__first)-1
3233e4b17023SJohn Marino * comparisons. Otherwise an NlogN algorithm is used, where N is
3234e4b17023SJohn Marino * distance(__first,__last).
3235e4b17023SJohn Marino *
3236e4b17023SJohn Marino * The comparison function should have the same effects on ordering as
3237e4b17023SJohn Marino * the function used for the initial sort.
3238e4b17023SJohn Marino */
3239e4b17023SJohn Marino template<typename _BidirectionalIterator, typename _Compare>
3240e4b17023SJohn Marino void
3241e4b17023SJohn Marino inplace_merge(_BidirectionalIterator __first,
3242e4b17023SJohn Marino _BidirectionalIterator __middle,
3243e4b17023SJohn Marino _BidirectionalIterator __last,
3244e4b17023SJohn Marino _Compare __comp)
3245e4b17023SJohn Marino {
3246e4b17023SJohn Marino typedef typename iterator_traits<_BidirectionalIterator>::value_type
3247e4b17023SJohn Marino _ValueType;
3248e4b17023SJohn Marino typedef typename iterator_traits<_BidirectionalIterator>::difference_type
3249e4b17023SJohn Marino _DistanceType;
3250e4b17023SJohn Marino
3251e4b17023SJohn Marino // concept requirements
3252e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
3253e4b17023SJohn Marino _BidirectionalIterator>)
3254e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
3255e4b17023SJohn Marino _ValueType, _ValueType>)
3256e4b17023SJohn Marino __glibcxx_requires_sorted_pred(__first, __middle, __comp);
3257e4b17023SJohn Marino __glibcxx_requires_sorted_pred(__middle, __last, __comp);
3258e4b17023SJohn Marino
3259e4b17023SJohn Marino if (__first == __middle || __middle == __last)
3260e4b17023SJohn Marino return;
3261e4b17023SJohn Marino
3262e4b17023SJohn Marino const _DistanceType __len1 = std::distance(__first, __middle);
3263e4b17023SJohn Marino const _DistanceType __len2 = std::distance(__middle, __last);
3264e4b17023SJohn Marino
3265e4b17023SJohn Marino _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first,
3266e4b17023SJohn Marino __last);
3267e4b17023SJohn Marino if (__buf.begin() == 0)
3268e4b17023SJohn Marino std::__merge_without_buffer(__first, __middle, __last, __len1,
3269e4b17023SJohn Marino __len2, __comp);
3270e4b17023SJohn Marino else
3271e4b17023SJohn Marino std::__merge_adaptive(__first, __middle, __last, __len1, __len2,
3272e4b17023SJohn Marino __buf.begin(), _DistanceType(__buf.size()),
3273e4b17023SJohn Marino __comp);
3274e4b17023SJohn Marino }
3275e4b17023SJohn Marino
3276e4b17023SJohn Marino
3277e4b17023SJohn Marino /// This is a helper function for the __merge_sort_loop routines.
3278e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2,
3279e4b17023SJohn Marino typename _OutputIterator>
3280e4b17023SJohn Marino _OutputIterator
3281e4b17023SJohn Marino __move_merge(_InputIterator1 __first1, _InputIterator1 __last1,
3282e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2,
3283e4b17023SJohn Marino _OutputIterator __result)
3284e4b17023SJohn Marino {
3285e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2)
3286e4b17023SJohn Marino {
3287e4b17023SJohn Marino if (*__first2 < *__first1)
3288e4b17023SJohn Marino {
3289e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first2);
3290e4b17023SJohn Marino ++__first2;
3291e4b17023SJohn Marino }
3292e4b17023SJohn Marino else
3293e4b17023SJohn Marino {
3294e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first1);
3295e4b17023SJohn Marino ++__first1;
3296e4b17023SJohn Marino }
3297e4b17023SJohn Marino ++__result;
3298e4b17023SJohn Marino }
3299e4b17023SJohn Marino return _GLIBCXX_MOVE3(__first2, __last2,
3300e4b17023SJohn Marino _GLIBCXX_MOVE3(__first1, __last1,
3301e4b17023SJohn Marino __result));
3302e4b17023SJohn Marino }
3303e4b17023SJohn Marino
3304e4b17023SJohn Marino /// This is a helper function for the __merge_sort_loop routines.
3305e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2,
3306e4b17023SJohn Marino typename _OutputIterator, typename _Compare>
3307e4b17023SJohn Marino _OutputIterator
3308e4b17023SJohn Marino __move_merge(_InputIterator1 __first1, _InputIterator1 __last1,
3309e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2,
3310e4b17023SJohn Marino _OutputIterator __result, _Compare __comp)
3311e4b17023SJohn Marino {
3312e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2)
3313e4b17023SJohn Marino {
3314e4b17023SJohn Marino if (__comp(*__first2, *__first1))
3315e4b17023SJohn Marino {
3316e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first2);
3317e4b17023SJohn Marino ++__first2;
3318e4b17023SJohn Marino }
3319e4b17023SJohn Marino else
3320e4b17023SJohn Marino {
3321e4b17023SJohn Marino *__result = _GLIBCXX_MOVE(*__first1);
3322e4b17023SJohn Marino ++__first1;
3323e4b17023SJohn Marino }
3324e4b17023SJohn Marino ++__result;
3325e4b17023SJohn Marino }
3326e4b17023SJohn Marino return _GLIBCXX_MOVE3(__first2, __last2,
3327e4b17023SJohn Marino _GLIBCXX_MOVE3(__first1, __last1,
3328e4b17023SJohn Marino __result));
3329e4b17023SJohn Marino }
3330e4b17023SJohn Marino
3331e4b17023SJohn Marino template<typename _RandomAccessIterator1, typename _RandomAccessIterator2,
3332e4b17023SJohn Marino typename _Distance>
3333e4b17023SJohn Marino void
3334e4b17023SJohn Marino __merge_sort_loop(_RandomAccessIterator1 __first,
3335e4b17023SJohn Marino _RandomAccessIterator1 __last,
3336e4b17023SJohn Marino _RandomAccessIterator2 __result,
3337e4b17023SJohn Marino _Distance __step_size)
3338e4b17023SJohn Marino {
3339e4b17023SJohn Marino const _Distance __two_step = 2 * __step_size;
3340e4b17023SJohn Marino
3341e4b17023SJohn Marino while (__last - __first >= __two_step)
3342e4b17023SJohn Marino {
3343e4b17023SJohn Marino __result = std::__move_merge(__first, __first + __step_size,
3344e4b17023SJohn Marino __first + __step_size,
3345e4b17023SJohn Marino __first + __two_step, __result);
3346e4b17023SJohn Marino __first += __two_step;
3347e4b17023SJohn Marino }
3348e4b17023SJohn Marino
3349e4b17023SJohn Marino __step_size = std::min(_Distance(__last - __first), __step_size);
3350e4b17023SJohn Marino std::__move_merge(__first, __first + __step_size,
3351e4b17023SJohn Marino __first + __step_size, __last, __result);
3352e4b17023SJohn Marino }
3353e4b17023SJohn Marino
3354e4b17023SJohn Marino template<typename _RandomAccessIterator1, typename _RandomAccessIterator2,
3355e4b17023SJohn Marino typename _Distance, typename _Compare>
3356e4b17023SJohn Marino void
3357e4b17023SJohn Marino __merge_sort_loop(_RandomAccessIterator1 __first,
3358e4b17023SJohn Marino _RandomAccessIterator1 __last,
3359e4b17023SJohn Marino _RandomAccessIterator2 __result, _Distance __step_size,
3360e4b17023SJohn Marino _Compare __comp)
3361e4b17023SJohn Marino {
3362e4b17023SJohn Marino const _Distance __two_step = 2 * __step_size;
3363e4b17023SJohn Marino
3364e4b17023SJohn Marino while (__last - __first >= __two_step)
3365e4b17023SJohn Marino {
3366e4b17023SJohn Marino __result = std::__move_merge(__first, __first + __step_size,
3367e4b17023SJohn Marino __first + __step_size,
3368e4b17023SJohn Marino __first + __two_step,
3369e4b17023SJohn Marino __result, __comp);
3370e4b17023SJohn Marino __first += __two_step;
3371e4b17023SJohn Marino }
3372e4b17023SJohn Marino __step_size = std::min(_Distance(__last - __first), __step_size);
3373e4b17023SJohn Marino
3374e4b17023SJohn Marino std::__move_merge(__first,__first + __step_size,
3375e4b17023SJohn Marino __first + __step_size, __last, __result, __comp);
3376e4b17023SJohn Marino }
3377e4b17023SJohn Marino
3378e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Distance>
3379e4b17023SJohn Marino void
3380e4b17023SJohn Marino __chunk_insertion_sort(_RandomAccessIterator __first,
3381e4b17023SJohn Marino _RandomAccessIterator __last,
3382e4b17023SJohn Marino _Distance __chunk_size)
3383e4b17023SJohn Marino {
3384e4b17023SJohn Marino while (__last - __first >= __chunk_size)
3385e4b17023SJohn Marino {
3386e4b17023SJohn Marino std::__insertion_sort(__first, __first + __chunk_size);
3387e4b17023SJohn Marino __first += __chunk_size;
3388e4b17023SJohn Marino }
3389e4b17023SJohn Marino std::__insertion_sort(__first, __last);
3390e4b17023SJohn Marino }
3391e4b17023SJohn Marino
3392e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Distance,
3393e4b17023SJohn Marino typename _Compare>
3394e4b17023SJohn Marino void
3395e4b17023SJohn Marino __chunk_insertion_sort(_RandomAccessIterator __first,
3396e4b17023SJohn Marino _RandomAccessIterator __last,
3397e4b17023SJohn Marino _Distance __chunk_size, _Compare __comp)
3398e4b17023SJohn Marino {
3399e4b17023SJohn Marino while (__last - __first >= __chunk_size)
3400e4b17023SJohn Marino {
3401e4b17023SJohn Marino std::__insertion_sort(__first, __first + __chunk_size, __comp);
3402e4b17023SJohn Marino __first += __chunk_size;
3403e4b17023SJohn Marino }
3404e4b17023SJohn Marino std::__insertion_sort(__first, __last, __comp);
3405e4b17023SJohn Marino }
3406e4b17023SJohn Marino
3407e4b17023SJohn Marino enum { _S_chunk_size = 7 };
3408e4b17023SJohn Marino
3409e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Pointer>
3410e4b17023SJohn Marino void
3411e4b17023SJohn Marino __merge_sort_with_buffer(_RandomAccessIterator __first,
3412e4b17023SJohn Marino _RandomAccessIterator __last,
3413e4b17023SJohn Marino _Pointer __buffer)
3414e4b17023SJohn Marino {
3415e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::difference_type
3416e4b17023SJohn Marino _Distance;
3417e4b17023SJohn Marino
3418e4b17023SJohn Marino const _Distance __len = __last - __first;
3419e4b17023SJohn Marino const _Pointer __buffer_last = __buffer + __len;
3420e4b17023SJohn Marino
3421e4b17023SJohn Marino _Distance __step_size = _S_chunk_size;
3422e4b17023SJohn Marino std::__chunk_insertion_sort(__first, __last, __step_size);
3423e4b17023SJohn Marino
3424e4b17023SJohn Marino while (__step_size < __len)
3425e4b17023SJohn Marino {
3426e4b17023SJohn Marino std::__merge_sort_loop(__first, __last, __buffer, __step_size);
3427e4b17023SJohn Marino __step_size *= 2;
3428e4b17023SJohn Marino std::__merge_sort_loop(__buffer, __buffer_last, __first, __step_size);
3429e4b17023SJohn Marino __step_size *= 2;
3430e4b17023SJohn Marino }
3431e4b17023SJohn Marino }
3432e4b17023SJohn Marino
3433e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Pointer, typename _Compare>
3434e4b17023SJohn Marino void
3435e4b17023SJohn Marino __merge_sort_with_buffer(_RandomAccessIterator __first,
3436e4b17023SJohn Marino _RandomAccessIterator __last,
3437e4b17023SJohn Marino _Pointer __buffer, _Compare __comp)
3438e4b17023SJohn Marino {
3439e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::difference_type
3440e4b17023SJohn Marino _Distance;
3441e4b17023SJohn Marino
3442e4b17023SJohn Marino const _Distance __len = __last - __first;
3443e4b17023SJohn Marino const _Pointer __buffer_last = __buffer + __len;
3444e4b17023SJohn Marino
3445e4b17023SJohn Marino _Distance __step_size = _S_chunk_size;
3446e4b17023SJohn Marino std::__chunk_insertion_sort(__first, __last, __step_size, __comp);
3447e4b17023SJohn Marino
3448e4b17023SJohn Marino while (__step_size < __len)
3449e4b17023SJohn Marino {
3450e4b17023SJohn Marino std::__merge_sort_loop(__first, __last, __buffer,
3451e4b17023SJohn Marino __step_size, __comp);
3452e4b17023SJohn Marino __step_size *= 2;
3453e4b17023SJohn Marino std::__merge_sort_loop(__buffer, __buffer_last, __first,
3454e4b17023SJohn Marino __step_size, __comp);
3455e4b17023SJohn Marino __step_size *= 2;
3456e4b17023SJohn Marino }
3457e4b17023SJohn Marino }
3458e4b17023SJohn Marino
3459e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Pointer,
3460e4b17023SJohn Marino typename _Distance>
3461e4b17023SJohn Marino void
3462e4b17023SJohn Marino __stable_sort_adaptive(_RandomAccessIterator __first,
3463e4b17023SJohn Marino _RandomAccessIterator __last,
3464e4b17023SJohn Marino _Pointer __buffer, _Distance __buffer_size)
3465e4b17023SJohn Marino {
3466e4b17023SJohn Marino const _Distance __len = (__last - __first + 1) / 2;
3467e4b17023SJohn Marino const _RandomAccessIterator __middle = __first + __len;
3468e4b17023SJohn Marino if (__len > __buffer_size)
3469e4b17023SJohn Marino {
3470e4b17023SJohn Marino std::__stable_sort_adaptive(__first, __middle,
3471e4b17023SJohn Marino __buffer, __buffer_size);
3472e4b17023SJohn Marino std::__stable_sort_adaptive(__middle, __last,
3473e4b17023SJohn Marino __buffer, __buffer_size);
3474e4b17023SJohn Marino }
3475e4b17023SJohn Marino else
3476e4b17023SJohn Marino {
3477e4b17023SJohn Marino std::__merge_sort_with_buffer(__first, __middle, __buffer);
3478e4b17023SJohn Marino std::__merge_sort_with_buffer(__middle, __last, __buffer);
3479e4b17023SJohn Marino }
3480e4b17023SJohn Marino std::__merge_adaptive(__first, __middle, __last,
3481e4b17023SJohn Marino _Distance(__middle - __first),
3482e4b17023SJohn Marino _Distance(__last - __middle),
3483e4b17023SJohn Marino __buffer, __buffer_size);
3484e4b17023SJohn Marino }
3485e4b17023SJohn Marino
3486e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Pointer,
3487e4b17023SJohn Marino typename _Distance, typename _Compare>
3488e4b17023SJohn Marino void
3489e4b17023SJohn Marino __stable_sort_adaptive(_RandomAccessIterator __first,
3490e4b17023SJohn Marino _RandomAccessIterator __last,
3491e4b17023SJohn Marino _Pointer __buffer, _Distance __buffer_size,
3492e4b17023SJohn Marino _Compare __comp)
3493e4b17023SJohn Marino {
3494e4b17023SJohn Marino const _Distance __len = (__last - __first + 1) / 2;
3495e4b17023SJohn Marino const _RandomAccessIterator __middle = __first + __len;
3496e4b17023SJohn Marino if (__len > __buffer_size)
3497e4b17023SJohn Marino {
3498e4b17023SJohn Marino std::__stable_sort_adaptive(__first, __middle, __buffer,
3499e4b17023SJohn Marino __buffer_size, __comp);
3500e4b17023SJohn Marino std::__stable_sort_adaptive(__middle, __last, __buffer,
3501e4b17023SJohn Marino __buffer_size, __comp);
3502e4b17023SJohn Marino }
3503e4b17023SJohn Marino else
3504e4b17023SJohn Marino {
3505e4b17023SJohn Marino std::__merge_sort_with_buffer(__first, __middle, __buffer, __comp);
3506e4b17023SJohn Marino std::__merge_sort_with_buffer(__middle, __last, __buffer, __comp);
3507e4b17023SJohn Marino }
3508e4b17023SJohn Marino std::__merge_adaptive(__first, __middle, __last,
3509e4b17023SJohn Marino _Distance(__middle - __first),
3510e4b17023SJohn Marino _Distance(__last - __middle),
3511e4b17023SJohn Marino __buffer, __buffer_size,
3512e4b17023SJohn Marino __comp);
3513e4b17023SJohn Marino }
3514e4b17023SJohn Marino
3515e4b17023SJohn Marino /// This is a helper function for the stable sorting routines.
3516e4b17023SJohn Marino template<typename _RandomAccessIterator>
3517e4b17023SJohn Marino void
3518e4b17023SJohn Marino __inplace_stable_sort(_RandomAccessIterator __first,
3519e4b17023SJohn Marino _RandomAccessIterator __last)
3520e4b17023SJohn Marino {
3521e4b17023SJohn Marino if (__last - __first < 15)
3522e4b17023SJohn Marino {
3523e4b17023SJohn Marino std::__insertion_sort(__first, __last);
3524e4b17023SJohn Marino return;
3525e4b17023SJohn Marino }
3526e4b17023SJohn Marino _RandomAccessIterator __middle = __first + (__last - __first) / 2;
3527e4b17023SJohn Marino std::__inplace_stable_sort(__first, __middle);
3528e4b17023SJohn Marino std::__inplace_stable_sort(__middle, __last);
3529e4b17023SJohn Marino std::__merge_without_buffer(__first, __middle, __last,
3530e4b17023SJohn Marino __middle - __first,
3531e4b17023SJohn Marino __last - __middle);
3532e4b17023SJohn Marino }
3533e4b17023SJohn Marino
3534e4b17023SJohn Marino /// This is a helper function for the stable sorting routines.
3535e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare>
3536e4b17023SJohn Marino void
3537e4b17023SJohn Marino __inplace_stable_sort(_RandomAccessIterator __first,
3538e4b17023SJohn Marino _RandomAccessIterator __last, _Compare __comp)
3539e4b17023SJohn Marino {
3540e4b17023SJohn Marino if (__last - __first < 15)
3541e4b17023SJohn Marino {
3542e4b17023SJohn Marino std::__insertion_sort(__first, __last, __comp);
3543e4b17023SJohn Marino return;
3544e4b17023SJohn Marino }
3545e4b17023SJohn Marino _RandomAccessIterator __middle = __first + (__last - __first) / 2;
3546e4b17023SJohn Marino std::__inplace_stable_sort(__first, __middle, __comp);
3547e4b17023SJohn Marino std::__inplace_stable_sort(__middle, __last, __comp);
3548e4b17023SJohn Marino std::__merge_without_buffer(__first, __middle, __last,
3549e4b17023SJohn Marino __middle - __first,
3550e4b17023SJohn Marino __last - __middle,
3551e4b17023SJohn Marino __comp);
3552e4b17023SJohn Marino }
3553e4b17023SJohn Marino
3554e4b17023SJohn Marino // stable_sort
3555e4b17023SJohn Marino
3556e4b17023SJohn Marino // Set algorithms: includes, set_union, set_intersection, set_difference,
3557e4b17023SJohn Marino // set_symmetric_difference. All of these algorithms have the precondition
3558e4b17023SJohn Marino // that their input ranges are sorted and the postcondition that their output
3559e4b17023SJohn Marino // ranges are sorted.
3560e4b17023SJohn Marino
3561e4b17023SJohn Marino /**
3562e4b17023SJohn Marino * @brief Determines whether all elements of a sequence exists in a range.
3563e4b17023SJohn Marino * @param __first1 Start of search range.
3564e4b17023SJohn Marino * @param __last1 End of search range.
3565e4b17023SJohn Marino * @param __first2 Start of sequence
3566e4b17023SJohn Marino * @param __last2 End of sequence.
3567e4b17023SJohn Marino * @return True if each element in [__first2,__last2) is contained in order
3568e4b17023SJohn Marino * within [__first1,__last1). False otherwise.
3569e4b17023SJohn Marino * @ingroup set_algorithms
3570e4b17023SJohn Marino *
3571e4b17023SJohn Marino * This operation expects both [__first1,__last1) and
3572e4b17023SJohn Marino * [__first2,__last2) to be sorted. Searches for the presence of
3573e4b17023SJohn Marino * each element in [__first2,__last2) within [__first1,__last1).
3574e4b17023SJohn Marino * The iterators over each range only move forward, so this is a
3575e4b17023SJohn Marino * linear algorithm. If an element in [__first2,__last2) is not
3576e4b17023SJohn Marino * found before the search iterator reaches @p __last2, false is
3577e4b17023SJohn Marino * returned.
3578e4b17023SJohn Marino */
3579e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2>
3580e4b17023SJohn Marino bool
3581e4b17023SJohn Marino includes(_InputIterator1 __first1, _InputIterator1 __last1,
3582e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2)
3583e4b17023SJohn Marino {
3584e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type
3585e4b17023SJohn Marino _ValueType1;
3586e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type
3587e4b17023SJohn Marino _ValueType2;
3588e4b17023SJohn Marino
3589e4b17023SJohn Marino // concept requirements
3590e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
3591e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
3592e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
3593e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
3594e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first1, __last1, __first2);
3595e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first2, __last2, __first1);
3596e4b17023SJohn Marino
3597e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2)
3598e4b17023SJohn Marino if (*__first2 < *__first1)
3599e4b17023SJohn Marino return false;
3600e4b17023SJohn Marino else if(*__first1 < *__first2)
3601e4b17023SJohn Marino ++__first1;
3602e4b17023SJohn Marino else
3603e4b17023SJohn Marino ++__first1, ++__first2;
3604e4b17023SJohn Marino
3605e4b17023SJohn Marino return __first2 == __last2;
3606e4b17023SJohn Marino }
3607e4b17023SJohn Marino
3608e4b17023SJohn Marino /**
3609e4b17023SJohn Marino * @brief Determines whether all elements of a sequence exists in a range
3610e4b17023SJohn Marino * using comparison.
3611e4b17023SJohn Marino * @ingroup set_algorithms
3612e4b17023SJohn Marino * @param __first1 Start of search range.
3613e4b17023SJohn Marino * @param __last1 End of search range.
3614e4b17023SJohn Marino * @param __first2 Start of sequence
3615e4b17023SJohn Marino * @param __last2 End of sequence.
3616e4b17023SJohn Marino * @param __comp Comparison function to use.
3617e4b17023SJohn Marino * @return True if each element in [__first2,__last2) is contained
3618e4b17023SJohn Marino * in order within [__first1,__last1) according to comp. False
3619e4b17023SJohn Marino * otherwise. @ingroup set_algorithms
3620e4b17023SJohn Marino *
3621e4b17023SJohn Marino * This operation expects both [__first1,__last1) and
3622e4b17023SJohn Marino * [__first2,__last2) to be sorted. Searches for the presence of
3623e4b17023SJohn Marino * each element in [__first2,__last2) within [__first1,__last1),
3624e4b17023SJohn Marino * using comp to decide. The iterators over each range only move
3625e4b17023SJohn Marino * forward, so this is a linear algorithm. If an element in
3626e4b17023SJohn Marino * [__first2,__last2) is not found before the search iterator
3627e4b17023SJohn Marino * reaches @p __last2, false is returned.
3628e4b17023SJohn Marino */
3629e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2,
3630e4b17023SJohn Marino typename _Compare>
3631e4b17023SJohn Marino bool
3632e4b17023SJohn Marino includes(_InputIterator1 __first1, _InputIterator1 __last1,
3633e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2,
3634e4b17023SJohn Marino _Compare __comp)
3635e4b17023SJohn Marino {
3636e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type
3637e4b17023SJohn Marino _ValueType1;
3638e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type
3639e4b17023SJohn Marino _ValueType2;
3640e4b17023SJohn Marino
3641e4b17023SJohn Marino // concept requirements
3642e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
3643e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
3644e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
3645e4b17023SJohn Marino _ValueType1, _ValueType2>)
3646e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
3647e4b17023SJohn Marino _ValueType2, _ValueType1>)
3648e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
3649e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);
3650e4b17023SJohn Marino
3651e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2)
3652e4b17023SJohn Marino if (__comp(*__first2, *__first1))
3653e4b17023SJohn Marino return false;
3654e4b17023SJohn Marino else if(__comp(*__first1, *__first2))
3655e4b17023SJohn Marino ++__first1;
3656e4b17023SJohn Marino else
3657e4b17023SJohn Marino ++__first1, ++__first2;
3658e4b17023SJohn Marino
3659e4b17023SJohn Marino return __first2 == __last2;
3660e4b17023SJohn Marino }
3661e4b17023SJohn Marino
3662e4b17023SJohn Marino // nth_element
3663e4b17023SJohn Marino // merge
3664e4b17023SJohn Marino // set_difference
3665e4b17023SJohn Marino // set_intersection
3666e4b17023SJohn Marino // set_union
3667e4b17023SJohn Marino // stable_sort
3668e4b17023SJohn Marino // set_symmetric_difference
3669e4b17023SJohn Marino // min_element
3670e4b17023SJohn Marino // max_element
3671e4b17023SJohn Marino
3672e4b17023SJohn Marino /**
3673e4b17023SJohn Marino * @brief Permute range into the next @e dictionary ordering.
3674e4b17023SJohn Marino * @ingroup sorting_algorithms
3675e4b17023SJohn Marino * @param __first Start of range.
3676e4b17023SJohn Marino * @param __last End of range.
3677e4b17023SJohn Marino * @return False if wrapped to first permutation, true otherwise.
3678e4b17023SJohn Marino *
3679e4b17023SJohn Marino * Treats all permutations of the range as a set of @e dictionary sorted
3680e4b17023SJohn Marino * sequences. Permutes the current sequence into the next one of this set.
3681e4b17023SJohn Marino * Returns true if there are more sequences to generate. If the sequence
3682e4b17023SJohn Marino * is the largest of the set, the smallest is generated and false returned.
3683e4b17023SJohn Marino */
3684e4b17023SJohn Marino template<typename _BidirectionalIterator>
3685e4b17023SJohn Marino bool
3686e4b17023SJohn Marino next_permutation(_BidirectionalIterator __first,
3687e4b17023SJohn Marino _BidirectionalIterator __last)
3688e4b17023SJohn Marino {
3689e4b17023SJohn Marino // concept requirements
3690e4b17023SJohn Marino __glibcxx_function_requires(_BidirectionalIteratorConcept<
3691e4b17023SJohn Marino _BidirectionalIterator>)
3692e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<
3693e4b17023SJohn Marino typename iterator_traits<_BidirectionalIterator>::value_type>)
3694e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
3695e4b17023SJohn Marino
3696e4b17023SJohn Marino if (__first == __last)
3697e4b17023SJohn Marino return false;
3698e4b17023SJohn Marino _BidirectionalIterator __i = __first;
3699e4b17023SJohn Marino ++__i;
3700e4b17023SJohn Marino if (__i == __last)
3701e4b17023SJohn Marino return false;
3702e4b17023SJohn Marino __i = __last;
3703e4b17023SJohn Marino --__i;
3704e4b17023SJohn Marino
3705e4b17023SJohn Marino for(;;)
3706e4b17023SJohn Marino {
3707e4b17023SJohn Marino _BidirectionalIterator __ii = __i;
3708e4b17023SJohn Marino --__i;
3709e4b17023SJohn Marino if (*__i < *__ii)
3710e4b17023SJohn Marino {
3711e4b17023SJohn Marino _BidirectionalIterator __j = __last;
3712e4b17023SJohn Marino while (!(*__i < *--__j))
3713e4b17023SJohn Marino {}
3714e4b17023SJohn Marino std::iter_swap(__i, __j);
3715e4b17023SJohn Marino std::reverse(__ii, __last);
3716e4b17023SJohn Marino return true;
3717e4b17023SJohn Marino }
3718e4b17023SJohn Marino if (__i == __first)
3719e4b17023SJohn Marino {
3720e4b17023SJohn Marino std::reverse(__first, __last);
3721e4b17023SJohn Marino return false;
3722e4b17023SJohn Marino }
3723e4b17023SJohn Marino }
3724e4b17023SJohn Marino }
3725e4b17023SJohn Marino
3726e4b17023SJohn Marino /**
3727e4b17023SJohn Marino * @brief Permute range into the next @e dictionary ordering using
3728e4b17023SJohn Marino * comparison functor.
3729e4b17023SJohn Marino * @ingroup sorting_algorithms
3730e4b17023SJohn Marino * @param __first Start of range.
3731e4b17023SJohn Marino * @param __last End of range.
3732e4b17023SJohn Marino * @param __comp A comparison functor.
3733e4b17023SJohn Marino * @return False if wrapped to first permutation, true otherwise.
3734e4b17023SJohn Marino *
3735e4b17023SJohn Marino * Treats all permutations of the range [__first,__last) as a set of
3736e4b17023SJohn Marino * @e dictionary sorted sequences ordered by @p __comp. Permutes the current
3737e4b17023SJohn Marino * sequence into the next one of this set. Returns true if there are more
3738e4b17023SJohn Marino * sequences to generate. If the sequence is the largest of the set, the
3739e4b17023SJohn Marino * smallest is generated and false returned.
3740e4b17023SJohn Marino */
3741e4b17023SJohn Marino template<typename _BidirectionalIterator, typename _Compare>
3742e4b17023SJohn Marino bool
3743e4b17023SJohn Marino next_permutation(_BidirectionalIterator __first,
3744e4b17023SJohn Marino _BidirectionalIterator __last, _Compare __comp)
3745e4b17023SJohn Marino {
3746e4b17023SJohn Marino // concept requirements
3747e4b17023SJohn Marino __glibcxx_function_requires(_BidirectionalIteratorConcept<
3748e4b17023SJohn Marino _BidirectionalIterator>)
3749e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
3750e4b17023SJohn Marino typename iterator_traits<_BidirectionalIterator>::value_type,
3751e4b17023SJohn Marino typename iterator_traits<_BidirectionalIterator>::value_type>)
3752e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
3753e4b17023SJohn Marino
3754e4b17023SJohn Marino if (__first == __last)
3755e4b17023SJohn Marino return false;
3756e4b17023SJohn Marino _BidirectionalIterator __i = __first;
3757e4b17023SJohn Marino ++__i;
3758e4b17023SJohn Marino if (__i == __last)
3759e4b17023SJohn Marino return false;
3760e4b17023SJohn Marino __i = __last;
3761e4b17023SJohn Marino --__i;
3762e4b17023SJohn Marino
3763e4b17023SJohn Marino for(;;)
3764e4b17023SJohn Marino {
3765e4b17023SJohn Marino _BidirectionalIterator __ii = __i;
3766e4b17023SJohn Marino --__i;
3767e4b17023SJohn Marino if (__comp(*__i, *__ii))
3768e4b17023SJohn Marino {
3769e4b17023SJohn Marino _BidirectionalIterator __j = __last;
3770e4b17023SJohn Marino while (!bool(__comp(*__i, *--__j)))
3771e4b17023SJohn Marino {}
3772e4b17023SJohn Marino std::iter_swap(__i, __j);
3773e4b17023SJohn Marino std::reverse(__ii, __last);
3774e4b17023SJohn Marino return true;
3775e4b17023SJohn Marino }
3776e4b17023SJohn Marino if (__i == __first)
3777e4b17023SJohn Marino {
3778e4b17023SJohn Marino std::reverse(__first, __last);
3779e4b17023SJohn Marino return false;
3780e4b17023SJohn Marino }
3781e4b17023SJohn Marino }
3782e4b17023SJohn Marino }
3783e4b17023SJohn Marino
3784e4b17023SJohn Marino /**
3785e4b17023SJohn Marino * @brief Permute range into the previous @e dictionary ordering.
3786e4b17023SJohn Marino * @ingroup sorting_algorithms
3787e4b17023SJohn Marino * @param __first Start of range.
3788e4b17023SJohn Marino * @param __last End of range.
3789e4b17023SJohn Marino * @return False if wrapped to last permutation, true otherwise.
3790e4b17023SJohn Marino *
3791e4b17023SJohn Marino * Treats all permutations of the range as a set of @e dictionary sorted
3792e4b17023SJohn Marino * sequences. Permutes the current sequence into the previous one of this
3793e4b17023SJohn Marino * set. Returns true if there are more sequences to generate. If the
3794e4b17023SJohn Marino * sequence is the smallest of the set, the largest is generated and false
3795e4b17023SJohn Marino * returned.
3796e4b17023SJohn Marino */
3797e4b17023SJohn Marino template<typename _BidirectionalIterator>
3798e4b17023SJohn Marino bool
3799e4b17023SJohn Marino prev_permutation(_BidirectionalIterator __first,
3800e4b17023SJohn Marino _BidirectionalIterator __last)
3801e4b17023SJohn Marino {
3802e4b17023SJohn Marino // concept requirements
3803e4b17023SJohn Marino __glibcxx_function_requires(_BidirectionalIteratorConcept<
3804e4b17023SJohn Marino _BidirectionalIterator>)
3805e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<
3806e4b17023SJohn Marino typename iterator_traits<_BidirectionalIterator>::value_type>)
3807e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
3808e4b17023SJohn Marino
3809e4b17023SJohn Marino if (__first == __last)
3810e4b17023SJohn Marino return false;
3811e4b17023SJohn Marino _BidirectionalIterator __i = __first;
3812e4b17023SJohn Marino ++__i;
3813e4b17023SJohn Marino if (__i == __last)
3814e4b17023SJohn Marino return false;
3815e4b17023SJohn Marino __i = __last;
3816e4b17023SJohn Marino --__i;
3817e4b17023SJohn Marino
3818e4b17023SJohn Marino for(;;)
3819e4b17023SJohn Marino {
3820e4b17023SJohn Marino _BidirectionalIterator __ii = __i;
3821e4b17023SJohn Marino --__i;
3822e4b17023SJohn Marino if (*__ii < *__i)
3823e4b17023SJohn Marino {
3824e4b17023SJohn Marino _BidirectionalIterator __j = __last;
3825e4b17023SJohn Marino while (!(*--__j < *__i))
3826e4b17023SJohn Marino {}
3827e4b17023SJohn Marino std::iter_swap(__i, __j);
3828e4b17023SJohn Marino std::reverse(__ii, __last);
3829e4b17023SJohn Marino return true;
3830e4b17023SJohn Marino }
3831e4b17023SJohn Marino if (__i == __first)
3832e4b17023SJohn Marino {
3833e4b17023SJohn Marino std::reverse(__first, __last);
3834e4b17023SJohn Marino return false;
3835e4b17023SJohn Marino }
3836e4b17023SJohn Marino }
3837e4b17023SJohn Marino }
3838e4b17023SJohn Marino
3839e4b17023SJohn Marino /**
3840e4b17023SJohn Marino * @brief Permute range into the previous @e dictionary ordering using
3841e4b17023SJohn Marino * comparison functor.
3842e4b17023SJohn Marino * @ingroup sorting_algorithms
3843e4b17023SJohn Marino * @param __first Start of range.
3844e4b17023SJohn Marino * @param __last End of range.
3845e4b17023SJohn Marino * @param __comp A comparison functor.
3846e4b17023SJohn Marino * @return False if wrapped to last permutation, true otherwise.
3847e4b17023SJohn Marino *
3848e4b17023SJohn Marino * Treats all permutations of the range [__first,__last) as a set of
3849e4b17023SJohn Marino * @e dictionary sorted sequences ordered by @p __comp. Permutes the current
3850e4b17023SJohn Marino * sequence into the previous one of this set. Returns true if there are
3851e4b17023SJohn Marino * more sequences to generate. If the sequence is the smallest of the set,
3852e4b17023SJohn Marino * the largest is generated and false returned.
3853e4b17023SJohn Marino */
3854e4b17023SJohn Marino template<typename _BidirectionalIterator, typename _Compare>
3855e4b17023SJohn Marino bool
3856e4b17023SJohn Marino prev_permutation(_BidirectionalIterator __first,
3857e4b17023SJohn Marino _BidirectionalIterator __last, _Compare __comp)
3858e4b17023SJohn Marino {
3859e4b17023SJohn Marino // concept requirements
3860e4b17023SJohn Marino __glibcxx_function_requires(_BidirectionalIteratorConcept<
3861e4b17023SJohn Marino _BidirectionalIterator>)
3862e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
3863e4b17023SJohn Marino typename iterator_traits<_BidirectionalIterator>::value_type,
3864e4b17023SJohn Marino typename iterator_traits<_BidirectionalIterator>::value_type>)
3865e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
3866e4b17023SJohn Marino
3867e4b17023SJohn Marino if (__first == __last)
3868e4b17023SJohn Marino return false;
3869e4b17023SJohn Marino _BidirectionalIterator __i = __first;
3870e4b17023SJohn Marino ++__i;
3871e4b17023SJohn Marino if (__i == __last)
3872e4b17023SJohn Marino return false;
3873e4b17023SJohn Marino __i = __last;
3874e4b17023SJohn Marino --__i;
3875e4b17023SJohn Marino
3876e4b17023SJohn Marino for(;;)
3877e4b17023SJohn Marino {
3878e4b17023SJohn Marino _BidirectionalIterator __ii = __i;
3879e4b17023SJohn Marino --__i;
3880e4b17023SJohn Marino if (__comp(*__ii, *__i))
3881e4b17023SJohn Marino {
3882e4b17023SJohn Marino _BidirectionalIterator __j = __last;
3883e4b17023SJohn Marino while (!bool(__comp(*--__j, *__i)))
3884e4b17023SJohn Marino {}
3885e4b17023SJohn Marino std::iter_swap(__i, __j);
3886e4b17023SJohn Marino std::reverse(__ii, __last);
3887e4b17023SJohn Marino return true;
3888e4b17023SJohn Marino }
3889e4b17023SJohn Marino if (__i == __first)
3890e4b17023SJohn Marino {
3891e4b17023SJohn Marino std::reverse(__first, __last);
3892e4b17023SJohn Marino return false;
3893e4b17023SJohn Marino }
3894e4b17023SJohn Marino }
3895e4b17023SJohn Marino }
3896e4b17023SJohn Marino
3897e4b17023SJohn Marino // replace
3898e4b17023SJohn Marino // replace_if
3899e4b17023SJohn Marino
3900e4b17023SJohn Marino /**
3901e4b17023SJohn Marino * @brief Copy a sequence, replacing each element of one value with another
3902e4b17023SJohn Marino * value.
3903e4b17023SJohn Marino * @param __first An input iterator.
3904e4b17023SJohn Marino * @param __last An input iterator.
3905e4b17023SJohn Marino * @param __result An output iterator.
3906e4b17023SJohn Marino * @param __old_value The value to be replaced.
3907e4b17023SJohn Marino * @param __new_value The replacement value.
3908e4b17023SJohn Marino * @return The end of the output sequence, @p result+(last-first).
3909e4b17023SJohn Marino *
3910e4b17023SJohn Marino * Copies each element in the input range @p [__first,__last) to the
3911e4b17023SJohn Marino * output range @p [__result,__result+(__last-__first)) replacing elements
3912e4b17023SJohn Marino * equal to @p __old_value with @p __new_value.
3913e4b17023SJohn Marino */
3914e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator, typename _Tp>
3915e4b17023SJohn Marino _OutputIterator
3916e4b17023SJohn Marino replace_copy(_InputIterator __first, _InputIterator __last,
3917e4b17023SJohn Marino _OutputIterator __result,
3918e4b17023SJohn Marino const _Tp& __old_value, const _Tp& __new_value)
3919e4b17023SJohn Marino {
3920e4b17023SJohn Marino // concept requirements
3921e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
3922e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
3923e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
3924e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept<
3925e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type, _Tp>)
3926e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
3927e4b17023SJohn Marino
3928e4b17023SJohn Marino for (; __first != __last; ++__first, ++__result)
3929e4b17023SJohn Marino if (*__first == __old_value)
3930e4b17023SJohn Marino *__result = __new_value;
3931e4b17023SJohn Marino else
3932e4b17023SJohn Marino *__result = *__first;
3933e4b17023SJohn Marino return __result;
3934e4b17023SJohn Marino }
3935e4b17023SJohn Marino
3936e4b17023SJohn Marino /**
3937e4b17023SJohn Marino * @brief Copy a sequence, replacing each value for which a predicate
3938e4b17023SJohn Marino * returns true with another value.
3939e4b17023SJohn Marino * @ingroup mutating_algorithms
3940e4b17023SJohn Marino * @param __first An input iterator.
3941e4b17023SJohn Marino * @param __last An input iterator.
3942e4b17023SJohn Marino * @param __result An output iterator.
3943e4b17023SJohn Marino * @param __pred A predicate.
3944e4b17023SJohn Marino * @param __new_value The replacement value.
3945e4b17023SJohn Marino * @return The end of the output sequence, @p __result+(__last-__first).
3946e4b17023SJohn Marino *
3947e4b17023SJohn Marino * Copies each element in the range @p [__first,__last) to the range
3948e4b17023SJohn Marino * @p [__result,__result+(__last-__first)) replacing elements for which
3949e4b17023SJohn Marino * @p __pred returns true with @p __new_value.
3950e4b17023SJohn Marino */
3951e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator,
3952e4b17023SJohn Marino typename _Predicate, typename _Tp>
3953e4b17023SJohn Marino _OutputIterator
3954e4b17023SJohn Marino replace_copy_if(_InputIterator __first, _InputIterator __last,
3955e4b17023SJohn Marino _OutputIterator __result,
3956e4b17023SJohn Marino _Predicate __pred, const _Tp& __new_value)
3957e4b17023SJohn Marino {
3958e4b17023SJohn Marino // concept requirements
3959e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
3960e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
3961e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
3962e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
3963e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
3964e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
3965e4b17023SJohn Marino
3966e4b17023SJohn Marino for (; __first != __last; ++__first, ++__result)
3967e4b17023SJohn Marino if (__pred(*__first))
3968e4b17023SJohn Marino *__result = __new_value;
3969e4b17023SJohn Marino else
3970e4b17023SJohn Marino *__result = *__first;
3971e4b17023SJohn Marino return __result;
3972e4b17023SJohn Marino }
3973e4b17023SJohn Marino
3974e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__
3975e4b17023SJohn Marino /**
3976e4b17023SJohn Marino * @brief Determines whether the elements of a sequence are sorted.
3977e4b17023SJohn Marino * @ingroup sorting_algorithms
3978e4b17023SJohn Marino * @param __first An iterator.
3979e4b17023SJohn Marino * @param __last Another iterator.
3980e4b17023SJohn Marino * @return True if the elements are sorted, false otherwise.
3981e4b17023SJohn Marino */
3982e4b17023SJohn Marino template<typename _ForwardIterator>
3983e4b17023SJohn Marino inline bool
3984e4b17023SJohn Marino is_sorted(_ForwardIterator __first, _ForwardIterator __last)
3985e4b17023SJohn Marino { return std::is_sorted_until(__first, __last) == __last; }
3986e4b17023SJohn Marino
3987e4b17023SJohn Marino /**
3988e4b17023SJohn Marino * @brief Determines whether the elements of a sequence are sorted
3989e4b17023SJohn Marino * according to a comparison functor.
3990e4b17023SJohn Marino * @ingroup sorting_algorithms
3991e4b17023SJohn Marino * @param __first An iterator.
3992e4b17023SJohn Marino * @param __last Another iterator.
3993e4b17023SJohn Marino * @param __comp A comparison functor.
3994e4b17023SJohn Marino * @return True if the elements are sorted, false otherwise.
3995e4b17023SJohn Marino */
3996e4b17023SJohn Marino template<typename _ForwardIterator, typename _Compare>
3997e4b17023SJohn Marino inline bool
3998e4b17023SJohn Marino is_sorted(_ForwardIterator __first, _ForwardIterator __last,
3999e4b17023SJohn Marino _Compare __comp)
4000e4b17023SJohn Marino { return std::is_sorted_until(__first, __last, __comp) == __last; }
4001e4b17023SJohn Marino
4002e4b17023SJohn Marino /**
4003e4b17023SJohn Marino * @brief Determines the end of a sorted sequence.
4004e4b17023SJohn Marino * @ingroup sorting_algorithms
4005e4b17023SJohn Marino * @param __first An iterator.
4006e4b17023SJohn Marino * @param __last Another iterator.
4007e4b17023SJohn Marino * @return An iterator pointing to the last iterator i in [__first, __last)
4008e4b17023SJohn Marino * for which the range [__first, i) is sorted.
4009e4b17023SJohn Marino */
4010e4b17023SJohn Marino template<typename _ForwardIterator>
4011e4b17023SJohn Marino _ForwardIterator
4012e4b17023SJohn Marino is_sorted_until(_ForwardIterator __first, _ForwardIterator __last)
4013e4b17023SJohn Marino {
4014e4b17023SJohn Marino // concept requirements
4015e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4016e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<
4017e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
4018e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
4019e4b17023SJohn Marino
4020e4b17023SJohn Marino if (__first == __last)
4021e4b17023SJohn Marino return __last;
4022e4b17023SJohn Marino
4023e4b17023SJohn Marino _ForwardIterator __next = __first;
4024e4b17023SJohn Marino for (++__next; __next != __last; __first = __next, ++__next)
4025e4b17023SJohn Marino if (*__next < *__first)
4026e4b17023SJohn Marino return __next;
4027e4b17023SJohn Marino return __next;
4028e4b17023SJohn Marino }
4029e4b17023SJohn Marino
4030e4b17023SJohn Marino /**
4031e4b17023SJohn Marino * @brief Determines the end of a sorted sequence using comparison functor.
4032e4b17023SJohn Marino * @ingroup sorting_algorithms
4033e4b17023SJohn Marino * @param __first An iterator.
4034e4b17023SJohn Marino * @param __last Another iterator.
4035e4b17023SJohn Marino * @param __comp A comparison functor.
4036e4b17023SJohn Marino * @return An iterator pointing to the last iterator i in [__first, __last)
4037e4b17023SJohn Marino * for which the range [__first, i) is sorted.
4038e4b17023SJohn Marino */
4039e4b17023SJohn Marino template<typename _ForwardIterator, typename _Compare>
4040e4b17023SJohn Marino _ForwardIterator
4041e4b17023SJohn Marino is_sorted_until(_ForwardIterator __first, _ForwardIterator __last,
4042e4b17023SJohn Marino _Compare __comp)
4043e4b17023SJohn Marino {
4044e4b17023SJohn Marino // concept requirements
4045e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4046e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
4047e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type,
4048e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
4049e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
4050e4b17023SJohn Marino
4051e4b17023SJohn Marino if (__first == __last)
4052e4b17023SJohn Marino return __last;
4053e4b17023SJohn Marino
4054e4b17023SJohn Marino _ForwardIterator __next = __first;
4055e4b17023SJohn Marino for (++__next; __next != __last; __first = __next, ++__next)
4056e4b17023SJohn Marino if (__comp(*__next, *__first))
4057e4b17023SJohn Marino return __next;
4058e4b17023SJohn Marino return __next;
4059e4b17023SJohn Marino }
4060e4b17023SJohn Marino
4061e4b17023SJohn Marino /**
4062e4b17023SJohn Marino * @brief Determines min and max at once as an ordered pair.
4063e4b17023SJohn Marino * @ingroup sorting_algorithms
4064e4b17023SJohn Marino * @param __a A thing of arbitrary type.
4065e4b17023SJohn Marino * @param __b Another thing of arbitrary type.
4066e4b17023SJohn Marino * @return A pair(__b, __a) if __b is smaller than __a, pair(__a,
4067e4b17023SJohn Marino * __b) otherwise.
4068e4b17023SJohn Marino */
4069e4b17023SJohn Marino template<typename _Tp>
4070e4b17023SJohn Marino inline pair<const _Tp&, const _Tp&>
4071e4b17023SJohn Marino minmax(const _Tp& __a, const _Tp& __b)
4072e4b17023SJohn Marino {
4073e4b17023SJohn Marino // concept requirements
4074e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<_Tp>)
4075e4b17023SJohn Marino
4076e4b17023SJohn Marino return __b < __a ? pair<const _Tp&, const _Tp&>(__b, __a)
4077e4b17023SJohn Marino : pair<const _Tp&, const _Tp&>(__a, __b);
4078e4b17023SJohn Marino }
4079e4b17023SJohn Marino
4080e4b17023SJohn Marino /**
4081e4b17023SJohn Marino * @brief Determines min and max at once as an ordered pair.
4082e4b17023SJohn Marino * @ingroup sorting_algorithms
4083e4b17023SJohn Marino * @param __a A thing of arbitrary type.
4084e4b17023SJohn Marino * @param __b Another thing of arbitrary type.
4085e4b17023SJohn Marino * @param __comp A @link comparison_functors comparison functor @endlink.
4086e4b17023SJohn Marino * @return A pair(__b, __a) if __b is smaller than __a, pair(__a,
4087e4b17023SJohn Marino * __b) otherwise.
4088e4b17023SJohn Marino */
4089e4b17023SJohn Marino template<typename _Tp, typename _Compare>
4090e4b17023SJohn Marino inline pair<const _Tp&, const _Tp&>
4091e4b17023SJohn Marino minmax(const _Tp& __a, const _Tp& __b, _Compare __comp)
4092e4b17023SJohn Marino {
4093e4b17023SJohn Marino return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a)
4094e4b17023SJohn Marino : pair<const _Tp&, const _Tp&>(__a, __b);
4095e4b17023SJohn Marino }
4096e4b17023SJohn Marino
4097e4b17023SJohn Marino /**
4098e4b17023SJohn Marino * @brief Return a pair of iterators pointing to the minimum and maximum
4099e4b17023SJohn Marino * elements in a range.
4100e4b17023SJohn Marino * @ingroup sorting_algorithms
4101e4b17023SJohn Marino * @param __first Start of range.
4102e4b17023SJohn Marino * @param __last End of range.
4103e4b17023SJohn Marino * @return make_pair(m, M), where m is the first iterator i in
4104e4b17023SJohn Marino * [__first, __last) such that no other element in the range is
4105e4b17023SJohn Marino * smaller, and where M is the last iterator i in [__first, __last)
4106e4b17023SJohn Marino * such that no other element in the range is larger.
4107e4b17023SJohn Marino */
4108e4b17023SJohn Marino template<typename _ForwardIterator>
4109e4b17023SJohn Marino pair<_ForwardIterator, _ForwardIterator>
4110e4b17023SJohn Marino minmax_element(_ForwardIterator __first, _ForwardIterator __last)
4111e4b17023SJohn Marino {
4112e4b17023SJohn Marino // concept requirements
4113e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4114e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<
4115e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
4116e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
4117e4b17023SJohn Marino
4118e4b17023SJohn Marino _ForwardIterator __next = __first;
4119e4b17023SJohn Marino if (__first == __last
4120e4b17023SJohn Marino || ++__next == __last)
4121e4b17023SJohn Marino return std::make_pair(__first, __first);
4122e4b17023SJohn Marino
4123e4b17023SJohn Marino _ForwardIterator __min, __max;
4124e4b17023SJohn Marino if (*__next < *__first)
4125e4b17023SJohn Marino {
4126e4b17023SJohn Marino __min = __next;
4127e4b17023SJohn Marino __max = __first;
4128e4b17023SJohn Marino }
4129e4b17023SJohn Marino else
4130e4b17023SJohn Marino {
4131e4b17023SJohn Marino __min = __first;
4132e4b17023SJohn Marino __max = __next;
4133e4b17023SJohn Marino }
4134e4b17023SJohn Marino
4135e4b17023SJohn Marino __first = __next;
4136e4b17023SJohn Marino ++__first;
4137e4b17023SJohn Marino
4138e4b17023SJohn Marino while (__first != __last)
4139e4b17023SJohn Marino {
4140e4b17023SJohn Marino __next = __first;
4141e4b17023SJohn Marino if (++__next == __last)
4142e4b17023SJohn Marino {
4143e4b17023SJohn Marino if (*__first < *__min)
4144e4b17023SJohn Marino __min = __first;
4145e4b17023SJohn Marino else if (!(*__first < *__max))
4146e4b17023SJohn Marino __max = __first;
4147e4b17023SJohn Marino break;
4148e4b17023SJohn Marino }
4149e4b17023SJohn Marino
4150e4b17023SJohn Marino if (*__next < *__first)
4151e4b17023SJohn Marino {
4152e4b17023SJohn Marino if (*__next < *__min)
4153e4b17023SJohn Marino __min = __next;
4154e4b17023SJohn Marino if (!(*__first < *__max))
4155e4b17023SJohn Marino __max = __first;
4156e4b17023SJohn Marino }
4157e4b17023SJohn Marino else
4158e4b17023SJohn Marino {
4159e4b17023SJohn Marino if (*__first < *__min)
4160e4b17023SJohn Marino __min = __first;
4161e4b17023SJohn Marino if (!(*__next < *__max))
4162e4b17023SJohn Marino __max = __next;
4163e4b17023SJohn Marino }
4164e4b17023SJohn Marino
4165e4b17023SJohn Marino __first = __next;
4166e4b17023SJohn Marino ++__first;
4167e4b17023SJohn Marino }
4168e4b17023SJohn Marino
4169e4b17023SJohn Marino return std::make_pair(__min, __max);
4170e4b17023SJohn Marino }
4171e4b17023SJohn Marino
4172e4b17023SJohn Marino /**
4173e4b17023SJohn Marino * @brief Return a pair of iterators pointing to the minimum and maximum
4174e4b17023SJohn Marino * elements in a range.
4175e4b17023SJohn Marino * @ingroup sorting_algorithms
4176e4b17023SJohn Marino * @param __first Start of range.
4177e4b17023SJohn Marino * @param __last End of range.
4178e4b17023SJohn Marino * @param __comp Comparison functor.
4179e4b17023SJohn Marino * @return make_pair(m, M), where m is the first iterator i in
4180e4b17023SJohn Marino * [__first, __last) such that no other element in the range is
4181e4b17023SJohn Marino * smaller, and where M is the last iterator i in [__first, __last)
4182e4b17023SJohn Marino * such that no other element in the range is larger.
4183e4b17023SJohn Marino */
4184e4b17023SJohn Marino template<typename _ForwardIterator, typename _Compare>
4185e4b17023SJohn Marino pair<_ForwardIterator, _ForwardIterator>
4186e4b17023SJohn Marino minmax_element(_ForwardIterator __first, _ForwardIterator __last,
4187e4b17023SJohn Marino _Compare __comp)
4188e4b17023SJohn Marino {
4189e4b17023SJohn Marino // concept requirements
4190e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4191e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
4192e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type,
4193e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
4194e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
4195e4b17023SJohn Marino
4196e4b17023SJohn Marino _ForwardIterator __next = __first;
4197e4b17023SJohn Marino if (__first == __last
4198e4b17023SJohn Marino || ++__next == __last)
4199e4b17023SJohn Marino return std::make_pair(__first, __first);
4200e4b17023SJohn Marino
4201e4b17023SJohn Marino _ForwardIterator __min, __max;
4202e4b17023SJohn Marino if (__comp(*__next, *__first))
4203e4b17023SJohn Marino {
4204e4b17023SJohn Marino __min = __next;
4205e4b17023SJohn Marino __max = __first;
4206e4b17023SJohn Marino }
4207e4b17023SJohn Marino else
4208e4b17023SJohn Marino {
4209e4b17023SJohn Marino __min = __first;
4210e4b17023SJohn Marino __max = __next;
4211e4b17023SJohn Marino }
4212e4b17023SJohn Marino
4213e4b17023SJohn Marino __first = __next;
4214e4b17023SJohn Marino ++__first;
4215e4b17023SJohn Marino
4216e4b17023SJohn Marino while (__first != __last)
4217e4b17023SJohn Marino {
4218e4b17023SJohn Marino __next = __first;
4219e4b17023SJohn Marino if (++__next == __last)
4220e4b17023SJohn Marino {
4221e4b17023SJohn Marino if (__comp(*__first, *__min))
4222e4b17023SJohn Marino __min = __first;
4223e4b17023SJohn Marino else if (!__comp(*__first, *__max))
4224e4b17023SJohn Marino __max = __first;
4225e4b17023SJohn Marino break;
4226e4b17023SJohn Marino }
4227e4b17023SJohn Marino
4228e4b17023SJohn Marino if (__comp(*__next, *__first))
4229e4b17023SJohn Marino {
4230e4b17023SJohn Marino if (__comp(*__next, *__min))
4231e4b17023SJohn Marino __min = __next;
4232e4b17023SJohn Marino if (!__comp(*__first, *__max))
4233e4b17023SJohn Marino __max = __first;
4234e4b17023SJohn Marino }
4235e4b17023SJohn Marino else
4236e4b17023SJohn Marino {
4237e4b17023SJohn Marino if (__comp(*__first, *__min))
4238e4b17023SJohn Marino __min = __first;
4239e4b17023SJohn Marino if (!__comp(*__next, *__max))
4240e4b17023SJohn Marino __max = __next;
4241e4b17023SJohn Marino }
4242e4b17023SJohn Marino
4243e4b17023SJohn Marino __first = __next;
4244e4b17023SJohn Marino ++__first;
4245e4b17023SJohn Marino }
4246e4b17023SJohn Marino
4247e4b17023SJohn Marino return std::make_pair(__min, __max);
4248e4b17023SJohn Marino }
4249e4b17023SJohn Marino
4250e4b17023SJohn Marino // N2722 + DR 915.
4251e4b17023SJohn Marino template<typename _Tp>
4252e4b17023SJohn Marino inline _Tp
4253e4b17023SJohn Marino min(initializer_list<_Tp> __l)
4254e4b17023SJohn Marino { return *std::min_element(__l.begin(), __l.end()); }
4255e4b17023SJohn Marino
4256e4b17023SJohn Marino template<typename _Tp, typename _Compare>
4257e4b17023SJohn Marino inline _Tp
4258e4b17023SJohn Marino min(initializer_list<_Tp> __l, _Compare __comp)
4259e4b17023SJohn Marino { return *std::min_element(__l.begin(), __l.end(), __comp); }
4260e4b17023SJohn Marino
4261e4b17023SJohn Marino template<typename _Tp>
4262e4b17023SJohn Marino inline _Tp
4263e4b17023SJohn Marino max(initializer_list<_Tp> __l)
4264e4b17023SJohn Marino { return *std::max_element(__l.begin(), __l.end()); }
4265e4b17023SJohn Marino
4266e4b17023SJohn Marino template<typename _Tp, typename _Compare>
4267e4b17023SJohn Marino inline _Tp
4268e4b17023SJohn Marino max(initializer_list<_Tp> __l, _Compare __comp)
4269e4b17023SJohn Marino { return *std::max_element(__l.begin(), __l.end(), __comp); }
4270e4b17023SJohn Marino
4271e4b17023SJohn Marino template<typename _Tp>
4272e4b17023SJohn Marino inline pair<_Tp, _Tp>
4273e4b17023SJohn Marino minmax(initializer_list<_Tp> __l)
4274e4b17023SJohn Marino {
4275e4b17023SJohn Marino pair<const _Tp*, const _Tp*> __p =
4276e4b17023SJohn Marino std::minmax_element(__l.begin(), __l.end());
4277e4b17023SJohn Marino return std::make_pair(*__p.first, *__p.second);
4278e4b17023SJohn Marino }
4279e4b17023SJohn Marino
4280e4b17023SJohn Marino template<typename _Tp, typename _Compare>
4281e4b17023SJohn Marino inline pair<_Tp, _Tp>
4282e4b17023SJohn Marino minmax(initializer_list<_Tp> __l, _Compare __comp)
4283e4b17023SJohn Marino {
4284e4b17023SJohn Marino pair<const _Tp*, const _Tp*> __p =
4285e4b17023SJohn Marino std::minmax_element(__l.begin(), __l.end(), __comp);
4286e4b17023SJohn Marino return std::make_pair(*__p.first, *__p.second);
4287e4b17023SJohn Marino }
4288e4b17023SJohn Marino
4289e4b17023SJohn Marino /**
4290e4b17023SJohn Marino * @brief Checks whether a permutaion of the second sequence is equal
4291e4b17023SJohn Marino * to the first sequence.
4292e4b17023SJohn Marino * @ingroup non_mutating_algorithms
4293e4b17023SJohn Marino * @param __first1 Start of first range.
4294e4b17023SJohn Marino * @param __last1 End of first range.
4295e4b17023SJohn Marino * @param __first2 Start of second range.
4296e4b17023SJohn Marino * @return true if there exists a permutation of the elements in the range
4297e4b17023SJohn Marino * [__first2, __first2 + (__last1 - __first1)), beginning with
4298e4b17023SJohn Marino * ForwardIterator2 begin, such that equal(__first1, __last1, begin)
4299e4b17023SJohn Marino * returns true; otherwise, returns false.
4300e4b17023SJohn Marino */
4301e4b17023SJohn Marino template<typename _ForwardIterator1, typename _ForwardIterator2>
4302e4b17023SJohn Marino bool
4303e4b17023SJohn Marino is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
4304e4b17023SJohn Marino _ForwardIterator2 __first2)
4305e4b17023SJohn Marino {
4306e4b17023SJohn Marino // Efficiently compare identical prefixes: O(N) if sequences
4307e4b17023SJohn Marino // have the same elements in the same order.
4308e4b17023SJohn Marino for (; __first1 != __last1; ++__first1, ++__first2)
4309e4b17023SJohn Marino if (!(*__first1 == *__first2))
4310e4b17023SJohn Marino break;
4311e4b17023SJohn Marino
4312e4b17023SJohn Marino if (__first1 == __last1)
4313e4b17023SJohn Marino return true;
4314e4b17023SJohn Marino
4315e4b17023SJohn Marino // Establish __last2 assuming equal ranges by iterating over the
4316e4b17023SJohn Marino // rest of the list.
4317e4b17023SJohn Marino _ForwardIterator2 __last2 = __first2;
4318e4b17023SJohn Marino std::advance(__last2, std::distance(__first1, __last1));
4319e4b17023SJohn Marino for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan)
4320e4b17023SJohn Marino {
4321e4b17023SJohn Marino if (__scan != _GLIBCXX_STD_A::find(__first1, __scan, *__scan))
4322e4b17023SJohn Marino continue; // We've seen this one before.
4323e4b17023SJohn Marino
4324e4b17023SJohn Marino auto __matches = std::count(__first2, __last2, *__scan);
4325e4b17023SJohn Marino if (0 == __matches
4326e4b17023SJohn Marino || std::count(__scan, __last1, *__scan) != __matches)
4327e4b17023SJohn Marino return false;
4328e4b17023SJohn Marino }
4329e4b17023SJohn Marino return true;
4330e4b17023SJohn Marino }
4331e4b17023SJohn Marino
4332e4b17023SJohn Marino /**
4333e4b17023SJohn Marino * @brief Checks whether a permutation of the second sequence is equal
4334e4b17023SJohn Marino * to the first sequence.
4335e4b17023SJohn Marino * @ingroup non_mutating_algorithms
4336e4b17023SJohn Marino * @param __first1 Start of first range.
4337e4b17023SJohn Marino * @param __last1 End of first range.
4338e4b17023SJohn Marino * @param __first2 Start of second range.
4339e4b17023SJohn Marino * @param __pred A binary predicate.
4340e4b17023SJohn Marino * @return true if there exists a permutation of the elements in
4341e4b17023SJohn Marino * the range [__first2, __first2 + (__last1 - __first1)),
4342e4b17023SJohn Marino * beginning with ForwardIterator2 begin, such that
4343e4b17023SJohn Marino * equal(__first1, __last1, __begin, __pred) returns true;
4344e4b17023SJohn Marino * otherwise, returns false.
4345e4b17023SJohn Marino */
4346e4b17023SJohn Marino template<typename _ForwardIterator1, typename _ForwardIterator2,
4347e4b17023SJohn Marino typename _BinaryPredicate>
4348e4b17023SJohn Marino bool
4349e4b17023SJohn Marino is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
4350e4b17023SJohn Marino _ForwardIterator2 __first2, _BinaryPredicate __pred)
4351e4b17023SJohn Marino {
4352e4b17023SJohn Marino // Efficiently compare identical prefixes: O(N) if sequences
4353e4b17023SJohn Marino // have the same elements in the same order.
4354e4b17023SJohn Marino for (; __first1 != __last1; ++__first1, ++__first2)
4355e4b17023SJohn Marino if (!bool(__pred(*__first1, *__first2)))
4356e4b17023SJohn Marino break;
4357e4b17023SJohn Marino
4358e4b17023SJohn Marino if (__first1 == __last1)
4359e4b17023SJohn Marino return true;
4360e4b17023SJohn Marino
4361e4b17023SJohn Marino // Establish __last2 assuming equal ranges by iterating over the
4362e4b17023SJohn Marino // rest of the list.
4363e4b17023SJohn Marino _ForwardIterator2 __last2 = __first2;
4364e4b17023SJohn Marino std::advance(__last2, std::distance(__first1, __last1));
4365e4b17023SJohn Marino for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan)
4366e4b17023SJohn Marino {
4367e4b17023SJohn Marino using std::placeholders::_1;
4368e4b17023SJohn Marino
4369e4b17023SJohn Marino if (__scan != _GLIBCXX_STD_A::find_if(__first1, __scan,
4370e4b17023SJohn Marino std::bind(__pred, _1, *__scan)))
4371e4b17023SJohn Marino continue; // We've seen this one before.
4372e4b17023SJohn Marino
4373e4b17023SJohn Marino auto __matches = std::count_if(__first2, __last2,
4374e4b17023SJohn Marino std::bind(__pred, _1, *__scan));
4375e4b17023SJohn Marino if (0 == __matches
4376e4b17023SJohn Marino || std::count_if(__scan, __last1,
4377e4b17023SJohn Marino std::bind(__pred, _1, *__scan)) != __matches)
4378e4b17023SJohn Marino return false;
4379e4b17023SJohn Marino }
4380e4b17023SJohn Marino return true;
4381e4b17023SJohn Marino }
4382e4b17023SJohn Marino
4383e4b17023SJohn Marino #ifdef _GLIBCXX_USE_C99_STDINT_TR1
4384e4b17023SJohn Marino /**
4385e4b17023SJohn Marino * @brief Shuffle the elements of a sequence using a uniform random
4386e4b17023SJohn Marino * number generator.
4387e4b17023SJohn Marino * @ingroup mutating_algorithms
4388e4b17023SJohn Marino * @param __first A forward iterator.
4389e4b17023SJohn Marino * @param __last A forward iterator.
4390e4b17023SJohn Marino * @param __g A UniformRandomNumberGenerator (26.5.1.3).
4391e4b17023SJohn Marino * @return Nothing.
4392e4b17023SJohn Marino *
4393e4b17023SJohn Marino * Reorders the elements in the range @p [__first,__last) using @p __g to
4394e4b17023SJohn Marino * provide random numbers.
4395e4b17023SJohn Marino */
4396e4b17023SJohn Marino template<typename _RandomAccessIterator,
4397e4b17023SJohn Marino typename _UniformRandomNumberGenerator>
4398e4b17023SJohn Marino void
4399e4b17023SJohn Marino shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
4400e4b17023SJohn Marino _UniformRandomNumberGenerator&& __g)
4401e4b17023SJohn Marino {
4402e4b17023SJohn Marino // concept requirements
4403e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
4404e4b17023SJohn Marino _RandomAccessIterator>)
4405e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
4406e4b17023SJohn Marino
4407e4b17023SJohn Marino if (__first == __last)
4408e4b17023SJohn Marino return;
4409e4b17023SJohn Marino
4410e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::difference_type
4411e4b17023SJohn Marino _DistanceType;
4412e4b17023SJohn Marino
4413e4b17023SJohn Marino typedef typename std::make_unsigned<_DistanceType>::type __ud_type;
4414e4b17023SJohn Marino typedef typename std::uniform_int_distribution<__ud_type> __distr_type;
4415e4b17023SJohn Marino typedef typename __distr_type::param_type __p_type;
4416e4b17023SJohn Marino __distr_type __d;
4417e4b17023SJohn Marino
4418e4b17023SJohn Marino for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
4419e4b17023SJohn Marino std::iter_swap(__i, __first + __d(__g, __p_type(0, __i - __first)));
4420e4b17023SJohn Marino }
4421e4b17023SJohn Marino #endif
4422e4b17023SJohn Marino
4423e4b17023SJohn Marino #endif // __GXX_EXPERIMENTAL_CXX0X__
4424e4b17023SJohn Marino
4425e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION
4426e4b17023SJohn Marino
4427e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_ALGO
4428e4b17023SJohn Marino
4429e4b17023SJohn Marino /**
4430e4b17023SJohn Marino * @brief Apply a function to every element of a sequence.
4431e4b17023SJohn Marino * @ingroup non_mutating_algorithms
4432e4b17023SJohn Marino * @param __first An input iterator.
4433e4b17023SJohn Marino * @param __last An input iterator.
4434e4b17023SJohn Marino * @param __f A unary function object.
4435e4b17023SJohn Marino * @return @p __f (std::move(@p __f) in C++0x).
4436e4b17023SJohn Marino *
4437e4b17023SJohn Marino * Applies the function object @p __f to each element in the range
4438e4b17023SJohn Marino * @p [first,last). @p __f must not modify the order of the sequence.
4439e4b17023SJohn Marino * If @p __f has a return value it is ignored.
4440e4b17023SJohn Marino */
4441e4b17023SJohn Marino template<typename _InputIterator, typename _Function>
4442e4b17023SJohn Marino _Function
4443e4b17023SJohn Marino for_each(_InputIterator __first, _InputIterator __last, _Function __f)
4444e4b17023SJohn Marino {
4445e4b17023SJohn Marino // concept requirements
4446e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
4447e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
4448e4b17023SJohn Marino for (; __first != __last; ++__first)
4449e4b17023SJohn Marino __f(*__first);
4450e4b17023SJohn Marino return _GLIBCXX_MOVE(__f);
4451e4b17023SJohn Marino }
4452e4b17023SJohn Marino
4453e4b17023SJohn Marino /**
4454e4b17023SJohn Marino * @brief Find the first occurrence of a value in a sequence.
4455e4b17023SJohn Marino * @ingroup non_mutating_algorithms
4456e4b17023SJohn Marino * @param __first An input iterator.
4457e4b17023SJohn Marino * @param __last An input iterator.
4458e4b17023SJohn Marino * @param __val The value to find.
4459e4b17023SJohn Marino * @return The first iterator @c i in the range @p [__first,__last)
4460e4b17023SJohn Marino * such that @c *i == @p __val, or @p __last if no such iterator exists.
4461e4b17023SJohn Marino */
4462e4b17023SJohn Marino template<typename _InputIterator, typename _Tp>
4463e4b17023SJohn Marino inline _InputIterator
4464e4b17023SJohn Marino find(_InputIterator __first, _InputIterator __last,
4465e4b17023SJohn Marino const _Tp& __val)
4466e4b17023SJohn Marino {
4467e4b17023SJohn Marino // concept requirements
4468e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
4469e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept<
4470e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type, _Tp>)
4471e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
4472e4b17023SJohn Marino return std::__find(__first, __last, __val,
4473e4b17023SJohn Marino std::__iterator_category(__first));
4474e4b17023SJohn Marino }
4475e4b17023SJohn Marino
4476e4b17023SJohn Marino /**
4477e4b17023SJohn Marino * @brief Find the first element in a sequence for which a
4478e4b17023SJohn Marino * predicate is true.
4479e4b17023SJohn Marino * @ingroup non_mutating_algorithms
4480e4b17023SJohn Marino * @param __first An input iterator.
4481e4b17023SJohn Marino * @param __last An input iterator.
4482e4b17023SJohn Marino * @param __pred A predicate.
4483e4b17023SJohn Marino * @return The first iterator @c i in the range @p [__first,__last)
4484e4b17023SJohn Marino * such that @p __pred(*i) is true, or @p __last if no such iterator exists.
4485e4b17023SJohn Marino */
4486e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate>
4487e4b17023SJohn Marino inline _InputIterator
4488e4b17023SJohn Marino find_if(_InputIterator __first, _InputIterator __last,
4489e4b17023SJohn Marino _Predicate __pred)
4490e4b17023SJohn Marino {
4491e4b17023SJohn Marino // concept requirements
4492e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
4493e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
4494e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
4495e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
4496e4b17023SJohn Marino return std::__find_if(__first, __last, __pred,
4497e4b17023SJohn Marino std::__iterator_category(__first));
4498e4b17023SJohn Marino }
4499e4b17023SJohn Marino
4500e4b17023SJohn Marino /**
4501e4b17023SJohn Marino * @brief Find element from a set in a sequence.
4502e4b17023SJohn Marino * @ingroup non_mutating_algorithms
4503e4b17023SJohn Marino * @param __first1 Start of range to search.
4504e4b17023SJohn Marino * @param __last1 End of range to search.
4505e4b17023SJohn Marino * @param __first2 Start of match candidates.
4506e4b17023SJohn Marino * @param __last2 End of match candidates.
4507e4b17023SJohn Marino * @return The first iterator @c i in the range
4508e4b17023SJohn Marino * @p [__first1,__last1) such that @c *i == @p *(i2) such that i2 is an
4509e4b17023SJohn Marino * iterator in [__first2,__last2), or @p __last1 if no such iterator exists.
4510e4b17023SJohn Marino *
4511e4b17023SJohn Marino * Searches the range @p [__first1,__last1) for an element that is
4512e4b17023SJohn Marino * equal to some element in the range [__first2,__last2). If
4513e4b17023SJohn Marino * found, returns an iterator in the range [__first1,__last1),
4514e4b17023SJohn Marino * otherwise returns @p __last1.
4515e4b17023SJohn Marino */
4516e4b17023SJohn Marino template<typename _InputIterator, typename _ForwardIterator>
4517e4b17023SJohn Marino _InputIterator
4518e4b17023SJohn Marino find_first_of(_InputIterator __first1, _InputIterator __last1,
4519e4b17023SJohn Marino _ForwardIterator __first2, _ForwardIterator __last2)
4520e4b17023SJohn Marino {
4521e4b17023SJohn Marino // concept requirements
4522e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
4523e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4524e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept<
4525e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type,
4526e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
4527e4b17023SJohn Marino __glibcxx_requires_valid_range(__first1, __last1);
4528e4b17023SJohn Marino __glibcxx_requires_valid_range(__first2, __last2);
4529e4b17023SJohn Marino
4530e4b17023SJohn Marino for (; __first1 != __last1; ++__first1)
4531e4b17023SJohn Marino for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter)
4532e4b17023SJohn Marino if (*__first1 == *__iter)
4533e4b17023SJohn Marino return __first1;
4534e4b17023SJohn Marino return __last1;
4535e4b17023SJohn Marino }
4536e4b17023SJohn Marino
4537e4b17023SJohn Marino /**
4538e4b17023SJohn Marino * @brief Find element from a set in a sequence using a predicate.
4539e4b17023SJohn Marino * @ingroup non_mutating_algorithms
4540e4b17023SJohn Marino * @param __first1 Start of range to search.
4541e4b17023SJohn Marino * @param __last1 End of range to search.
4542e4b17023SJohn Marino * @param __first2 Start of match candidates.
4543e4b17023SJohn Marino * @param __last2 End of match candidates.
4544e4b17023SJohn Marino * @param __comp Predicate to use.
4545e4b17023SJohn Marino * @return The first iterator @c i in the range
4546e4b17023SJohn Marino * @p [__first1,__last1) such that @c comp(*i, @p *(i2)) is true
4547e4b17023SJohn Marino * and i2 is an iterator in [__first2,__last2), or @p __last1 if no
4548e4b17023SJohn Marino * such iterator exists.
4549e4b17023SJohn Marino *
4550e4b17023SJohn Marino
4551e4b17023SJohn Marino * Searches the range @p [__first1,__last1) for an element that is
4552e4b17023SJohn Marino * equal to some element in the range [__first2,__last2). If
4553e4b17023SJohn Marino * found, returns an iterator in the range [__first1,__last1),
4554e4b17023SJohn Marino * otherwise returns @p __last1.
4555e4b17023SJohn Marino */
4556e4b17023SJohn Marino template<typename _InputIterator, typename _ForwardIterator,
4557e4b17023SJohn Marino typename _BinaryPredicate>
4558e4b17023SJohn Marino _InputIterator
4559e4b17023SJohn Marino find_first_of(_InputIterator __first1, _InputIterator __last1,
4560e4b17023SJohn Marino _ForwardIterator __first2, _ForwardIterator __last2,
4561e4b17023SJohn Marino _BinaryPredicate __comp)
4562e4b17023SJohn Marino {
4563e4b17023SJohn Marino // concept requirements
4564e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
4565e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4566e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
4567e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type,
4568e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
4569e4b17023SJohn Marino __glibcxx_requires_valid_range(__first1, __last1);
4570e4b17023SJohn Marino __glibcxx_requires_valid_range(__first2, __last2);
4571e4b17023SJohn Marino
4572e4b17023SJohn Marino for (; __first1 != __last1; ++__first1)
4573e4b17023SJohn Marino for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter)
4574e4b17023SJohn Marino if (__comp(*__first1, *__iter))
4575e4b17023SJohn Marino return __first1;
4576e4b17023SJohn Marino return __last1;
4577e4b17023SJohn Marino }
4578e4b17023SJohn Marino
4579e4b17023SJohn Marino /**
4580e4b17023SJohn Marino * @brief Find two adjacent values in a sequence that are equal.
4581e4b17023SJohn Marino * @ingroup non_mutating_algorithms
4582e4b17023SJohn Marino * @param __first A forward iterator.
4583e4b17023SJohn Marino * @param __last A forward iterator.
4584e4b17023SJohn Marino * @return The first iterator @c i such that @c i and @c i+1 are both
4585e4b17023SJohn Marino * valid iterators in @p [__first,__last) and such that @c *i == @c *(i+1),
4586e4b17023SJohn Marino * or @p __last if no such iterator exists.
4587e4b17023SJohn Marino */
4588e4b17023SJohn Marino template<typename _ForwardIterator>
4589e4b17023SJohn Marino _ForwardIterator
4590e4b17023SJohn Marino adjacent_find(_ForwardIterator __first, _ForwardIterator __last)
4591e4b17023SJohn Marino {
4592e4b17023SJohn Marino // concept requirements
4593e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4594e4b17023SJohn Marino __glibcxx_function_requires(_EqualityComparableConcept<
4595e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
4596e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
4597e4b17023SJohn Marino if (__first == __last)
4598e4b17023SJohn Marino return __last;
4599e4b17023SJohn Marino _ForwardIterator __next = __first;
4600e4b17023SJohn Marino while(++__next != __last)
4601e4b17023SJohn Marino {
4602e4b17023SJohn Marino if (*__first == *__next)
4603e4b17023SJohn Marino return __first;
4604e4b17023SJohn Marino __first = __next;
4605e4b17023SJohn Marino }
4606e4b17023SJohn Marino return __last;
4607e4b17023SJohn Marino }
4608e4b17023SJohn Marino
4609e4b17023SJohn Marino /**
4610e4b17023SJohn Marino * @brief Find two adjacent values in a sequence using a predicate.
4611e4b17023SJohn Marino * @ingroup non_mutating_algorithms
4612e4b17023SJohn Marino * @param __first A forward iterator.
4613e4b17023SJohn Marino * @param __last A forward iterator.
4614e4b17023SJohn Marino * @param __binary_pred A binary predicate.
4615e4b17023SJohn Marino * @return The first iterator @c i such that @c i and @c i+1 are both
4616e4b17023SJohn Marino * valid iterators in @p [__first,__last) and such that
4617e4b17023SJohn Marino * @p __binary_pred(*i,*(i+1)) is true, or @p __last if no such iterator
4618e4b17023SJohn Marino * exists.
4619e4b17023SJohn Marino */
4620e4b17023SJohn Marino template<typename _ForwardIterator, typename _BinaryPredicate>
4621e4b17023SJohn Marino _ForwardIterator
4622e4b17023SJohn Marino adjacent_find(_ForwardIterator __first, _ForwardIterator __last,
4623e4b17023SJohn Marino _BinaryPredicate __binary_pred)
4624e4b17023SJohn Marino {
4625e4b17023SJohn Marino // concept requirements
4626e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4627e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
4628e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type,
4629e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
4630e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
4631e4b17023SJohn Marino if (__first == __last)
4632e4b17023SJohn Marino return __last;
4633e4b17023SJohn Marino _ForwardIterator __next = __first;
4634e4b17023SJohn Marino while(++__next != __last)
4635e4b17023SJohn Marino {
4636e4b17023SJohn Marino if (__binary_pred(*__first, *__next))
4637e4b17023SJohn Marino return __first;
4638e4b17023SJohn Marino __first = __next;
4639e4b17023SJohn Marino }
4640e4b17023SJohn Marino return __last;
4641e4b17023SJohn Marino }
4642e4b17023SJohn Marino
4643e4b17023SJohn Marino /**
4644e4b17023SJohn Marino * @brief Count the number of copies of a value in a sequence.
4645e4b17023SJohn Marino * @ingroup non_mutating_algorithms
4646e4b17023SJohn Marino * @param __first An input iterator.
4647e4b17023SJohn Marino * @param __last An input iterator.
4648e4b17023SJohn Marino * @param __value The value to be counted.
4649e4b17023SJohn Marino * @return The number of iterators @c i in the range @p [__first,__last)
4650e4b17023SJohn Marino * for which @c *i == @p __value
4651e4b17023SJohn Marino */
4652e4b17023SJohn Marino template<typename _InputIterator, typename _Tp>
4653e4b17023SJohn Marino typename iterator_traits<_InputIterator>::difference_type
4654e4b17023SJohn Marino count(_InputIterator __first, _InputIterator __last, const _Tp& __value)
4655e4b17023SJohn Marino {
4656e4b17023SJohn Marino // concept requirements
4657e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
4658e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept<
4659e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type, _Tp>)
4660e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
4661e4b17023SJohn Marino typename iterator_traits<_InputIterator>::difference_type __n = 0;
4662e4b17023SJohn Marino for (; __first != __last; ++__first)
4663e4b17023SJohn Marino if (*__first == __value)
4664e4b17023SJohn Marino ++__n;
4665e4b17023SJohn Marino return __n;
4666e4b17023SJohn Marino }
4667e4b17023SJohn Marino
4668e4b17023SJohn Marino /**
4669e4b17023SJohn Marino * @brief Count the elements of a sequence for which a predicate is true.
4670e4b17023SJohn Marino * @ingroup non_mutating_algorithms
4671e4b17023SJohn Marino * @param __first An input iterator.
4672e4b17023SJohn Marino * @param __last An input iterator.
4673e4b17023SJohn Marino * @param __pred A predicate.
4674e4b17023SJohn Marino * @return The number of iterators @c i in the range @p [__first,__last)
4675e4b17023SJohn Marino * for which @p __pred(*i) is true.
4676e4b17023SJohn Marino */
4677e4b17023SJohn Marino template<typename _InputIterator, typename _Predicate>
4678e4b17023SJohn Marino typename iterator_traits<_InputIterator>::difference_type
4679e4b17023SJohn Marino count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred)
4680e4b17023SJohn Marino {
4681e4b17023SJohn Marino // concept requirements
4682e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
4683e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
4684e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
4685e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
4686e4b17023SJohn Marino typename iterator_traits<_InputIterator>::difference_type __n = 0;
4687e4b17023SJohn Marino for (; __first != __last; ++__first)
4688e4b17023SJohn Marino if (__pred(*__first))
4689e4b17023SJohn Marino ++__n;
4690e4b17023SJohn Marino return __n;
4691e4b17023SJohn Marino }
4692e4b17023SJohn Marino
4693e4b17023SJohn Marino /**
4694e4b17023SJohn Marino * @brief Search a sequence for a matching sub-sequence.
4695e4b17023SJohn Marino * @ingroup non_mutating_algorithms
4696e4b17023SJohn Marino * @param __first1 A forward iterator.
4697e4b17023SJohn Marino * @param __last1 A forward iterator.
4698e4b17023SJohn Marino * @param __first2 A forward iterator.
4699e4b17023SJohn Marino * @param __last2 A forward iterator.
4700e4b17023SJohn Marino * @return The first iterator @c i in the range @p
4701e4b17023SJohn Marino * [__first1,__last1-(__last2-__first2)) such that @c *(i+N) == @p
4702e4b17023SJohn Marino * *(__first2+N) for each @c N in the range @p
4703e4b17023SJohn Marino * [0,__last2-__first2), or @p __last1 if no such iterator exists.
4704e4b17023SJohn Marino *
4705e4b17023SJohn Marino * Searches the range @p [__first1,__last1) for a sub-sequence that
4706e4b17023SJohn Marino * compares equal value-by-value with the sequence given by @p
4707e4b17023SJohn Marino * [__first2,__last2) and returns an iterator to the first element
4708e4b17023SJohn Marino * of the sub-sequence, or @p __last1 if the sub-sequence is not
4709e4b17023SJohn Marino * found.
4710e4b17023SJohn Marino *
4711e4b17023SJohn Marino * Because the sub-sequence must lie completely within the range @p
4712e4b17023SJohn Marino * [__first1,__last1) it must start at a position less than @p
4713e4b17023SJohn Marino * __last1-(__last2-__first2) where @p __last2-__first2 is the
4714e4b17023SJohn Marino * length of the sub-sequence.
4715e4b17023SJohn Marino *
4716e4b17023SJohn Marino * This means that the returned iterator @c i will be in the range
4717e4b17023SJohn Marino * @p [__first1,__last1-(__last2-__first2))
4718e4b17023SJohn Marino */
4719e4b17023SJohn Marino template<typename _ForwardIterator1, typename _ForwardIterator2>
4720e4b17023SJohn Marino _ForwardIterator1
4721e4b17023SJohn Marino search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
4722e4b17023SJohn Marino _ForwardIterator2 __first2, _ForwardIterator2 __last2)
4723e4b17023SJohn Marino {
4724e4b17023SJohn Marino // concept requirements
4725e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>)
4726e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>)
4727e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept<
4728e4b17023SJohn Marino typename iterator_traits<_ForwardIterator1>::value_type,
4729e4b17023SJohn Marino typename iterator_traits<_ForwardIterator2>::value_type>)
4730e4b17023SJohn Marino __glibcxx_requires_valid_range(__first1, __last1);
4731e4b17023SJohn Marino __glibcxx_requires_valid_range(__first2, __last2);
4732e4b17023SJohn Marino
4733e4b17023SJohn Marino // Test for empty ranges
4734e4b17023SJohn Marino if (__first1 == __last1 || __first2 == __last2)
4735e4b17023SJohn Marino return __first1;
4736e4b17023SJohn Marino
4737e4b17023SJohn Marino // Test for a pattern of length 1.
4738e4b17023SJohn Marino _ForwardIterator2 __p1(__first2);
4739e4b17023SJohn Marino if (++__p1 == __last2)
4740e4b17023SJohn Marino return _GLIBCXX_STD_A::find(__first1, __last1, *__first2);
4741e4b17023SJohn Marino
4742e4b17023SJohn Marino // General case.
4743e4b17023SJohn Marino _ForwardIterator2 __p;
4744e4b17023SJohn Marino _ForwardIterator1 __current = __first1;
4745e4b17023SJohn Marino
4746e4b17023SJohn Marino for (;;)
4747e4b17023SJohn Marino {
4748e4b17023SJohn Marino __first1 = _GLIBCXX_STD_A::find(__first1, __last1, *__first2);
4749e4b17023SJohn Marino if (__first1 == __last1)
4750e4b17023SJohn Marino return __last1;
4751e4b17023SJohn Marino
4752e4b17023SJohn Marino __p = __p1;
4753e4b17023SJohn Marino __current = __first1;
4754e4b17023SJohn Marino if (++__current == __last1)
4755e4b17023SJohn Marino return __last1;
4756e4b17023SJohn Marino
4757e4b17023SJohn Marino while (*__current == *__p)
4758e4b17023SJohn Marino {
4759e4b17023SJohn Marino if (++__p == __last2)
4760e4b17023SJohn Marino return __first1;
4761e4b17023SJohn Marino if (++__current == __last1)
4762e4b17023SJohn Marino return __last1;
4763e4b17023SJohn Marino }
4764e4b17023SJohn Marino ++__first1;
4765e4b17023SJohn Marino }
4766e4b17023SJohn Marino return __first1;
4767e4b17023SJohn Marino }
4768e4b17023SJohn Marino
4769e4b17023SJohn Marino /**
4770e4b17023SJohn Marino * @brief Search a sequence for a matching sub-sequence using a predicate.
4771e4b17023SJohn Marino * @ingroup non_mutating_algorithms
4772e4b17023SJohn Marino * @param __first1 A forward iterator.
4773e4b17023SJohn Marino * @param __last1 A forward iterator.
4774e4b17023SJohn Marino * @param __first2 A forward iterator.
4775e4b17023SJohn Marino * @param __last2 A forward iterator.
4776e4b17023SJohn Marino * @param __predicate A binary predicate.
4777e4b17023SJohn Marino * @return The first iterator @c i in the range
4778e4b17023SJohn Marino * @p [__first1,__last1-(__last2-__first2)) such that
4779e4b17023SJohn Marino * @p __predicate(*(i+N),*(__first2+N)) is true for each @c N in the range
4780e4b17023SJohn Marino * @p [0,__last2-__first2), or @p __last1 if no such iterator exists.
4781e4b17023SJohn Marino *
4782e4b17023SJohn Marino * Searches the range @p [__first1,__last1) for a sub-sequence that
4783e4b17023SJohn Marino * compares equal value-by-value with the sequence given by @p
4784e4b17023SJohn Marino * [__first2,__last2), using @p __predicate to determine equality,
4785e4b17023SJohn Marino * and returns an iterator to the first element of the
4786e4b17023SJohn Marino * sub-sequence, or @p __last1 if no such iterator exists.
4787e4b17023SJohn Marino *
4788e4b17023SJohn Marino * @see search(_ForwardIter1, _ForwardIter1, _ForwardIter2, _ForwardIter2)
4789e4b17023SJohn Marino */
4790e4b17023SJohn Marino template<typename _ForwardIterator1, typename _ForwardIterator2,
4791e4b17023SJohn Marino typename _BinaryPredicate>
4792e4b17023SJohn Marino _ForwardIterator1
4793e4b17023SJohn Marino search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
4794e4b17023SJohn Marino _ForwardIterator2 __first2, _ForwardIterator2 __last2,
4795e4b17023SJohn Marino _BinaryPredicate __predicate)
4796e4b17023SJohn Marino {
4797e4b17023SJohn Marino // concept requirements
4798e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>)
4799e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>)
4800e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
4801e4b17023SJohn Marino typename iterator_traits<_ForwardIterator1>::value_type,
4802e4b17023SJohn Marino typename iterator_traits<_ForwardIterator2>::value_type>)
4803e4b17023SJohn Marino __glibcxx_requires_valid_range(__first1, __last1);
4804e4b17023SJohn Marino __glibcxx_requires_valid_range(__first2, __last2);
4805e4b17023SJohn Marino
4806e4b17023SJohn Marino // Test for empty ranges
4807e4b17023SJohn Marino if (__first1 == __last1 || __first2 == __last2)
4808e4b17023SJohn Marino return __first1;
4809e4b17023SJohn Marino
4810e4b17023SJohn Marino // Test for a pattern of length 1.
4811e4b17023SJohn Marino _ForwardIterator2 __p1(__first2);
4812e4b17023SJohn Marino if (++__p1 == __last2)
4813e4b17023SJohn Marino {
4814e4b17023SJohn Marino while (__first1 != __last1
4815e4b17023SJohn Marino && !bool(__predicate(*__first1, *__first2)))
4816e4b17023SJohn Marino ++__first1;
4817e4b17023SJohn Marino return __first1;
4818e4b17023SJohn Marino }
4819e4b17023SJohn Marino
4820e4b17023SJohn Marino // General case.
4821e4b17023SJohn Marino _ForwardIterator2 __p;
4822e4b17023SJohn Marino _ForwardIterator1 __current = __first1;
4823e4b17023SJohn Marino
4824e4b17023SJohn Marino for (;;)
4825e4b17023SJohn Marino {
4826e4b17023SJohn Marino while (__first1 != __last1
4827e4b17023SJohn Marino && !bool(__predicate(*__first1, *__first2)))
4828e4b17023SJohn Marino ++__first1;
4829e4b17023SJohn Marino if (__first1 == __last1)
4830e4b17023SJohn Marino return __last1;
4831e4b17023SJohn Marino
4832e4b17023SJohn Marino __p = __p1;
4833e4b17023SJohn Marino __current = __first1;
4834e4b17023SJohn Marino if (++__current == __last1)
4835e4b17023SJohn Marino return __last1;
4836e4b17023SJohn Marino
4837e4b17023SJohn Marino while (__predicate(*__current, *__p))
4838e4b17023SJohn Marino {
4839e4b17023SJohn Marino if (++__p == __last2)
4840e4b17023SJohn Marino return __first1;
4841e4b17023SJohn Marino if (++__current == __last1)
4842e4b17023SJohn Marino return __last1;
4843e4b17023SJohn Marino }
4844e4b17023SJohn Marino ++__first1;
4845e4b17023SJohn Marino }
4846e4b17023SJohn Marino return __first1;
4847e4b17023SJohn Marino }
4848e4b17023SJohn Marino
4849e4b17023SJohn Marino
4850e4b17023SJohn Marino /**
4851e4b17023SJohn Marino * @brief Search a sequence for a number of consecutive values.
4852e4b17023SJohn Marino * @ingroup non_mutating_algorithms
4853e4b17023SJohn Marino * @param __first A forward iterator.
4854e4b17023SJohn Marino * @param __last A forward iterator.
4855e4b17023SJohn Marino * @param __count The number of consecutive values.
4856e4b17023SJohn Marino * @param __val The value to find.
4857e4b17023SJohn Marino * @return The first iterator @c i in the range @p
4858e4b17023SJohn Marino * [__first,__last-__count) such that @c *(i+N) == @p __val for
4859e4b17023SJohn Marino * each @c N in the range @p [0,__count), or @p __last if no such
4860e4b17023SJohn Marino * iterator exists.
4861e4b17023SJohn Marino *
4862e4b17023SJohn Marino * Searches the range @p [__first,__last) for @p count consecutive elements
4863e4b17023SJohn Marino * equal to @p __val.
4864e4b17023SJohn Marino */
4865e4b17023SJohn Marino template<typename _ForwardIterator, typename _Integer, typename _Tp>
4866e4b17023SJohn Marino _ForwardIterator
4867e4b17023SJohn Marino search_n(_ForwardIterator __first, _ForwardIterator __last,
4868e4b17023SJohn Marino _Integer __count, const _Tp& __val)
4869e4b17023SJohn Marino {
4870e4b17023SJohn Marino // concept requirements
4871e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4872e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept<
4873e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
4874e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
4875e4b17023SJohn Marino
4876e4b17023SJohn Marino if (__count <= 0)
4877e4b17023SJohn Marino return __first;
4878e4b17023SJohn Marino if (__count == 1)
4879e4b17023SJohn Marino return _GLIBCXX_STD_A::find(__first, __last, __val);
4880e4b17023SJohn Marino return std::__search_n(__first, __last, __count, __val,
4881e4b17023SJohn Marino std::__iterator_category(__first));
4882e4b17023SJohn Marino }
4883e4b17023SJohn Marino
4884e4b17023SJohn Marino
4885e4b17023SJohn Marino /**
4886e4b17023SJohn Marino * @brief Search a sequence for a number of consecutive values using a
4887e4b17023SJohn Marino * predicate.
4888e4b17023SJohn Marino * @ingroup non_mutating_algorithms
4889e4b17023SJohn Marino * @param __first A forward iterator.
4890e4b17023SJohn Marino * @param __last A forward iterator.
4891e4b17023SJohn Marino * @param __count The number of consecutive values.
4892e4b17023SJohn Marino * @param __val The value to find.
4893e4b17023SJohn Marino * @param __binary_pred A binary predicate.
4894e4b17023SJohn Marino * @return The first iterator @c i in the range @p
4895e4b17023SJohn Marino * [__first,__last-__count) such that @p
4896e4b17023SJohn Marino * __binary_pred(*(i+N),__val) is true for each @c N in the range
4897e4b17023SJohn Marino * @p [0,__count), or @p __last if no such iterator exists.
4898e4b17023SJohn Marino *
4899e4b17023SJohn Marino * Searches the range @p [__first,__last) for @p __count
4900e4b17023SJohn Marino * consecutive elements for which the predicate returns true.
4901e4b17023SJohn Marino */
4902e4b17023SJohn Marino template<typename _ForwardIterator, typename _Integer, typename _Tp,
4903e4b17023SJohn Marino typename _BinaryPredicate>
4904e4b17023SJohn Marino _ForwardIterator
4905e4b17023SJohn Marino search_n(_ForwardIterator __first, _ForwardIterator __last,
4906e4b17023SJohn Marino _Integer __count, const _Tp& __val,
4907e4b17023SJohn Marino _BinaryPredicate __binary_pred)
4908e4b17023SJohn Marino {
4909e4b17023SJohn Marino // concept requirements
4910e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
4911e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
4912e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
4913e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
4914e4b17023SJohn Marino
4915e4b17023SJohn Marino if (__count <= 0)
4916e4b17023SJohn Marino return __first;
4917e4b17023SJohn Marino if (__count == 1)
4918e4b17023SJohn Marino {
4919e4b17023SJohn Marino while (__first != __last && !bool(__binary_pred(*__first, __val)))
4920e4b17023SJohn Marino ++__first;
4921e4b17023SJohn Marino return __first;
4922e4b17023SJohn Marino }
4923e4b17023SJohn Marino return std::__search_n(__first, __last, __count, __val, __binary_pred,
4924e4b17023SJohn Marino std::__iterator_category(__first));
4925e4b17023SJohn Marino }
4926e4b17023SJohn Marino
4927e4b17023SJohn Marino
4928e4b17023SJohn Marino /**
4929e4b17023SJohn Marino * @brief Perform an operation on a sequence.
4930e4b17023SJohn Marino * @ingroup mutating_algorithms
4931e4b17023SJohn Marino * @param __first An input iterator.
4932e4b17023SJohn Marino * @param __last An input iterator.
4933e4b17023SJohn Marino * @param __result An output iterator.
4934e4b17023SJohn Marino * @param __unary_op A unary operator.
4935e4b17023SJohn Marino * @return An output iterator equal to @p __result+(__last-__first).
4936e4b17023SJohn Marino *
4937e4b17023SJohn Marino * Applies the operator to each element in the input range and assigns
4938e4b17023SJohn Marino * the results to successive elements of the output sequence.
4939e4b17023SJohn Marino * Evaluates @p *(__result+N)=unary_op(*(__first+N)) for each @c N in the
4940e4b17023SJohn Marino * range @p [0,__last-__first).
4941e4b17023SJohn Marino *
4942e4b17023SJohn Marino * @p unary_op must not alter its argument.
4943e4b17023SJohn Marino */
4944e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator,
4945e4b17023SJohn Marino typename _UnaryOperation>
4946e4b17023SJohn Marino _OutputIterator
4947e4b17023SJohn Marino transform(_InputIterator __first, _InputIterator __last,
4948e4b17023SJohn Marino _OutputIterator __result, _UnaryOperation __unary_op)
4949e4b17023SJohn Marino {
4950e4b17023SJohn Marino // concept requirements
4951e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
4952e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
4953e4b17023SJohn Marino // "the type returned by a _UnaryOperation"
4954e4b17023SJohn Marino __typeof__(__unary_op(*__first))>)
4955e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
4956e4b17023SJohn Marino
4957e4b17023SJohn Marino for (; __first != __last; ++__first, ++__result)
4958e4b17023SJohn Marino *__result = __unary_op(*__first);
4959e4b17023SJohn Marino return __result;
4960e4b17023SJohn Marino }
4961e4b17023SJohn Marino
4962e4b17023SJohn Marino /**
4963e4b17023SJohn Marino * @brief Perform an operation on corresponding elements of two sequences.
4964e4b17023SJohn Marino * @ingroup mutating_algorithms
4965e4b17023SJohn Marino * @param __first1 An input iterator.
4966e4b17023SJohn Marino * @param __last1 An input iterator.
4967e4b17023SJohn Marino * @param __first2 An input iterator.
4968e4b17023SJohn Marino * @param __result An output iterator.
4969e4b17023SJohn Marino * @param __binary_op A binary operator.
4970e4b17023SJohn Marino * @return An output iterator equal to @p result+(last-first).
4971e4b17023SJohn Marino *
4972e4b17023SJohn Marino * Applies the operator to the corresponding elements in the two
4973e4b17023SJohn Marino * input ranges and assigns the results to successive elements of the
4974e4b17023SJohn Marino * output sequence.
4975e4b17023SJohn Marino * Evaluates @p
4976e4b17023SJohn Marino * *(__result+N)=__binary_op(*(__first1+N),*(__first2+N)) for each
4977e4b17023SJohn Marino * @c N in the range @p [0,__last1-__first1).
4978e4b17023SJohn Marino *
4979e4b17023SJohn Marino * @p binary_op must not alter either of its arguments.
4980e4b17023SJohn Marino */
4981e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2,
4982e4b17023SJohn Marino typename _OutputIterator, typename _BinaryOperation>
4983e4b17023SJohn Marino _OutputIterator
4984e4b17023SJohn Marino transform(_InputIterator1 __first1, _InputIterator1 __last1,
4985e4b17023SJohn Marino _InputIterator2 __first2, _OutputIterator __result,
4986e4b17023SJohn Marino _BinaryOperation __binary_op)
4987e4b17023SJohn Marino {
4988e4b17023SJohn Marino // concept requirements
4989e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
4990e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
4991e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
4992e4b17023SJohn Marino // "the type returned by a _BinaryOperation"
4993e4b17023SJohn Marino __typeof__(__binary_op(*__first1,*__first2))>)
4994e4b17023SJohn Marino __glibcxx_requires_valid_range(__first1, __last1);
4995e4b17023SJohn Marino
4996e4b17023SJohn Marino for (; __first1 != __last1; ++__first1, ++__first2, ++__result)
4997e4b17023SJohn Marino *__result = __binary_op(*__first1, *__first2);
4998e4b17023SJohn Marino return __result;
4999e4b17023SJohn Marino }
5000e4b17023SJohn Marino
5001e4b17023SJohn Marino /**
5002e4b17023SJohn Marino * @brief Replace each occurrence of one value in a sequence with another
5003e4b17023SJohn Marino * value.
5004e4b17023SJohn Marino * @ingroup mutating_algorithms
5005e4b17023SJohn Marino * @param __first A forward iterator.
5006e4b17023SJohn Marino * @param __last A forward iterator.
5007e4b17023SJohn Marino * @param __old_value The value to be replaced.
5008e4b17023SJohn Marino * @param __new_value The replacement value.
5009e4b17023SJohn Marino * @return replace() returns no value.
5010e4b17023SJohn Marino *
5011e4b17023SJohn Marino * For each iterator @c i in the range @p [__first,__last) if @c *i ==
5012e4b17023SJohn Marino * @p __old_value then the assignment @c *i = @p __new_value is performed.
5013e4b17023SJohn Marino */
5014e4b17023SJohn Marino template<typename _ForwardIterator, typename _Tp>
5015e4b17023SJohn Marino void
5016e4b17023SJohn Marino replace(_ForwardIterator __first, _ForwardIterator __last,
5017e4b17023SJohn Marino const _Tp& __old_value, const _Tp& __new_value)
5018e4b17023SJohn Marino {
5019e4b17023SJohn Marino // concept requirements
5020e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
5021e4b17023SJohn Marino _ForwardIterator>)
5022e4b17023SJohn Marino __glibcxx_function_requires(_EqualOpConcept<
5023e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
5024e4b17023SJohn Marino __glibcxx_function_requires(_ConvertibleConcept<_Tp,
5025e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
5026e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
5027e4b17023SJohn Marino
5028e4b17023SJohn Marino for (; __first != __last; ++__first)
5029e4b17023SJohn Marino if (*__first == __old_value)
5030e4b17023SJohn Marino *__first = __new_value;
5031e4b17023SJohn Marino }
5032e4b17023SJohn Marino
5033e4b17023SJohn Marino /**
5034e4b17023SJohn Marino * @brief Replace each value in a sequence for which a predicate returns
5035e4b17023SJohn Marino * true with another value.
5036e4b17023SJohn Marino * @ingroup mutating_algorithms
5037e4b17023SJohn Marino * @param __first A forward iterator.
5038e4b17023SJohn Marino * @param __last A forward iterator.
5039e4b17023SJohn Marino * @param __pred A predicate.
5040e4b17023SJohn Marino * @param __new_value The replacement value.
5041e4b17023SJohn Marino * @return replace_if() returns no value.
5042e4b17023SJohn Marino *
5043e4b17023SJohn Marino * For each iterator @c i in the range @p [__first,__last) if @p __pred(*i)
5044e4b17023SJohn Marino * is true then the assignment @c *i = @p __new_value is performed.
5045e4b17023SJohn Marino */
5046e4b17023SJohn Marino template<typename _ForwardIterator, typename _Predicate, typename _Tp>
5047e4b17023SJohn Marino void
5048e4b17023SJohn Marino replace_if(_ForwardIterator __first, _ForwardIterator __last,
5049e4b17023SJohn Marino _Predicate __pred, const _Tp& __new_value)
5050e4b17023SJohn Marino {
5051e4b17023SJohn Marino // concept requirements
5052e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
5053e4b17023SJohn Marino _ForwardIterator>)
5054e4b17023SJohn Marino __glibcxx_function_requires(_ConvertibleConcept<_Tp,
5055e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
5056e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
5057e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
5058e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
5059e4b17023SJohn Marino
5060e4b17023SJohn Marino for (; __first != __last; ++__first)
5061e4b17023SJohn Marino if (__pred(*__first))
5062e4b17023SJohn Marino *__first = __new_value;
5063e4b17023SJohn Marino }
5064e4b17023SJohn Marino
5065e4b17023SJohn Marino /**
5066e4b17023SJohn Marino * @brief Assign the result of a function object to each value in a
5067e4b17023SJohn Marino * sequence.
5068e4b17023SJohn Marino * @ingroup mutating_algorithms
5069e4b17023SJohn Marino * @param __first A forward iterator.
5070e4b17023SJohn Marino * @param __last A forward iterator.
5071e4b17023SJohn Marino * @param __gen A function object taking no arguments and returning
5072e4b17023SJohn Marino * std::iterator_traits<_ForwardIterator>::value_type
5073e4b17023SJohn Marino * @return generate() returns no value.
5074e4b17023SJohn Marino *
5075e4b17023SJohn Marino * Performs the assignment @c *i = @p __gen() for each @c i in the range
5076e4b17023SJohn Marino * @p [__first,__last).
5077e4b17023SJohn Marino */
5078e4b17023SJohn Marino template<typename _ForwardIterator, typename _Generator>
5079e4b17023SJohn Marino void
5080e4b17023SJohn Marino generate(_ForwardIterator __first, _ForwardIterator __last,
5081e4b17023SJohn Marino _Generator __gen)
5082e4b17023SJohn Marino {
5083e4b17023SJohn Marino // concept requirements
5084e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
5085e4b17023SJohn Marino __glibcxx_function_requires(_GeneratorConcept<_Generator,
5086e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
5087e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
5088e4b17023SJohn Marino
5089e4b17023SJohn Marino for (; __first != __last; ++__first)
5090e4b17023SJohn Marino *__first = __gen();
5091e4b17023SJohn Marino }
5092e4b17023SJohn Marino
5093e4b17023SJohn Marino /**
5094e4b17023SJohn Marino * @brief Assign the result of a function object to each value in a
5095e4b17023SJohn Marino * sequence.
5096e4b17023SJohn Marino * @ingroup mutating_algorithms
5097e4b17023SJohn Marino * @param __first A forward iterator.
5098e4b17023SJohn Marino * @param __n The length of the sequence.
5099e4b17023SJohn Marino * @param __gen A function object taking no arguments and returning
5100e4b17023SJohn Marino * std::iterator_traits<_ForwardIterator>::value_type
5101e4b17023SJohn Marino * @return The end of the sequence, @p __first+__n
5102e4b17023SJohn Marino *
5103e4b17023SJohn Marino * Performs the assignment @c *i = @p __gen() for each @c i in the range
5104e4b17023SJohn Marino * @p [__first,__first+__n).
5105e4b17023SJohn Marino *
5106e4b17023SJohn Marino * _GLIBCXX_RESOLVE_LIB_DEFECTS
5107e4b17023SJohn Marino * DR 865. More algorithms that throw away information
5108e4b17023SJohn Marino */
5109e4b17023SJohn Marino template<typename _OutputIterator, typename _Size, typename _Generator>
5110e4b17023SJohn Marino _OutputIterator
5111e4b17023SJohn Marino generate_n(_OutputIterator __first, _Size __n, _Generator __gen)
5112e4b17023SJohn Marino {
5113e4b17023SJohn Marino // concept requirements
5114e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5115e4b17023SJohn Marino // "the type returned by a _Generator"
5116e4b17023SJohn Marino __typeof__(__gen())>)
5117e4b17023SJohn Marino
5118e4b17023SJohn Marino for (__decltype(__n + 0) __niter = __n;
5119e4b17023SJohn Marino __niter > 0; --__niter, ++__first)
5120e4b17023SJohn Marino *__first = __gen();
5121e4b17023SJohn Marino return __first;
5122e4b17023SJohn Marino }
5123e4b17023SJohn Marino
5124e4b17023SJohn Marino
5125e4b17023SJohn Marino /**
5126e4b17023SJohn Marino * @brief Copy a sequence, removing consecutive duplicate values.
5127e4b17023SJohn Marino * @ingroup mutating_algorithms
5128e4b17023SJohn Marino * @param __first An input iterator.
5129e4b17023SJohn Marino * @param __last An input iterator.
5130e4b17023SJohn Marino * @param __result An output iterator.
5131e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence.
5132e4b17023SJohn Marino *
5133e4b17023SJohn Marino * Copies each element in the range @p [__first,__last) to the range
5134e4b17023SJohn Marino * beginning at @p __result, except that only the first element is copied
5135e4b17023SJohn Marino * from groups of consecutive elements that compare equal.
5136e4b17023SJohn Marino * unique_copy() is stable, so the relative order of elements that are
5137e4b17023SJohn Marino * copied is unchanged.
5138e4b17023SJohn Marino *
5139e4b17023SJohn Marino * _GLIBCXX_RESOLVE_LIB_DEFECTS
5140e4b17023SJohn Marino * DR 241. Does unique_copy() require CopyConstructible and Assignable?
5141e4b17023SJohn Marino *
5142e4b17023SJohn Marino * _GLIBCXX_RESOLVE_LIB_DEFECTS
5143e4b17023SJohn Marino * DR 538. 241 again: Does unique_copy() require CopyConstructible and
5144e4b17023SJohn Marino * Assignable?
5145e4b17023SJohn Marino */
5146e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator>
5147e4b17023SJohn Marino inline _OutputIterator
5148e4b17023SJohn Marino unique_copy(_InputIterator __first, _InputIterator __last,
5149e4b17023SJohn Marino _OutputIterator __result)
5150e4b17023SJohn Marino {
5151e4b17023SJohn Marino // concept requirements
5152e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
5153e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5154e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
5155e4b17023SJohn Marino __glibcxx_function_requires(_EqualityComparableConcept<
5156e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
5157e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
5158e4b17023SJohn Marino
5159e4b17023SJohn Marino if (__first == __last)
5160e4b17023SJohn Marino return __result;
5161e4b17023SJohn Marino return std::__unique_copy(__first, __last, __result,
5162e4b17023SJohn Marino std::__iterator_category(__first),
5163e4b17023SJohn Marino std::__iterator_category(__result));
5164e4b17023SJohn Marino }
5165e4b17023SJohn Marino
5166e4b17023SJohn Marino /**
5167e4b17023SJohn Marino * @brief Copy a sequence, removing consecutive values using a predicate.
5168e4b17023SJohn Marino * @ingroup mutating_algorithms
5169e4b17023SJohn Marino * @param __first An input iterator.
5170e4b17023SJohn Marino * @param __last An input iterator.
5171e4b17023SJohn Marino * @param __result An output iterator.
5172e4b17023SJohn Marino * @param __binary_pred A binary predicate.
5173e4b17023SJohn Marino * @return An iterator designating the end of the resulting sequence.
5174e4b17023SJohn Marino *
5175e4b17023SJohn Marino * Copies each element in the range @p [__first,__last) to the range
5176e4b17023SJohn Marino * beginning at @p __result, except that only the first element is copied
5177e4b17023SJohn Marino * from groups of consecutive elements for which @p __binary_pred returns
5178e4b17023SJohn Marino * true.
5179e4b17023SJohn Marino * unique_copy() is stable, so the relative order of elements that are
5180e4b17023SJohn Marino * copied is unchanged.
5181e4b17023SJohn Marino *
5182e4b17023SJohn Marino * _GLIBCXX_RESOLVE_LIB_DEFECTS
5183e4b17023SJohn Marino * DR 241. Does unique_copy() require CopyConstructible and Assignable?
5184e4b17023SJohn Marino */
5185e4b17023SJohn Marino template<typename _InputIterator, typename _OutputIterator,
5186e4b17023SJohn Marino typename _BinaryPredicate>
5187e4b17023SJohn Marino inline _OutputIterator
5188e4b17023SJohn Marino unique_copy(_InputIterator __first, _InputIterator __last,
5189e4b17023SJohn Marino _OutputIterator __result,
5190e4b17023SJohn Marino _BinaryPredicate __binary_pred)
5191e4b17023SJohn Marino {
5192e4b17023SJohn Marino // concept requirements -- predicates checked later
5193e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
5194e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5195e4b17023SJohn Marino typename iterator_traits<_InputIterator>::value_type>)
5196e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
5197e4b17023SJohn Marino
5198e4b17023SJohn Marino if (__first == __last)
5199e4b17023SJohn Marino return __result;
5200e4b17023SJohn Marino return std::__unique_copy(__first, __last, __result, __binary_pred,
5201e4b17023SJohn Marino std::__iterator_category(__first),
5202e4b17023SJohn Marino std::__iterator_category(__result));
5203e4b17023SJohn Marino }
5204e4b17023SJohn Marino
5205e4b17023SJohn Marino
5206e4b17023SJohn Marino /**
5207e4b17023SJohn Marino * @brief Randomly shuffle the elements of a sequence.
5208e4b17023SJohn Marino * @ingroup mutating_algorithms
5209e4b17023SJohn Marino * @param __first A forward iterator.
5210e4b17023SJohn Marino * @param __last A forward iterator.
5211e4b17023SJohn Marino * @return Nothing.
5212e4b17023SJohn Marino *
5213e4b17023SJohn Marino * Reorder the elements in the range @p [__first,__last) using a random
5214e4b17023SJohn Marino * distribution, so that every possible ordering of the sequence is
5215e4b17023SJohn Marino * equally likely.
5216e4b17023SJohn Marino */
5217e4b17023SJohn Marino template<typename _RandomAccessIterator>
5218e4b17023SJohn Marino inline void
5219e4b17023SJohn Marino random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
5220e4b17023SJohn Marino {
5221e4b17023SJohn Marino // concept requirements
5222e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5223e4b17023SJohn Marino _RandomAccessIterator>)
5224e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
5225e4b17023SJohn Marino
5226e4b17023SJohn Marino if (__first != __last)
5227e4b17023SJohn Marino for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
5228e4b17023SJohn Marino std::iter_swap(__i, __first + (std::rand() % ((__i - __first) + 1)));
5229e4b17023SJohn Marino }
5230e4b17023SJohn Marino
5231e4b17023SJohn Marino /**
5232e4b17023SJohn Marino * @brief Shuffle the elements of a sequence using a random number
5233e4b17023SJohn Marino * generator.
5234e4b17023SJohn Marino * @ingroup mutating_algorithms
5235e4b17023SJohn Marino * @param __first A forward iterator.
5236e4b17023SJohn Marino * @param __last A forward iterator.
5237e4b17023SJohn Marino * @param __rand The RNG functor or function.
5238e4b17023SJohn Marino * @return Nothing.
5239e4b17023SJohn Marino *
5240e4b17023SJohn Marino * Reorders the elements in the range @p [__first,__last) using @p __rand to
5241e4b17023SJohn Marino * provide a random distribution. Calling @p __rand(N) for a positive
5242e4b17023SJohn Marino * integer @p N should return a randomly chosen integer from the
5243e4b17023SJohn Marino * range [0,N).
5244e4b17023SJohn Marino */
5245e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _RandomNumberGenerator>
5246e4b17023SJohn Marino void
5247e4b17023SJohn Marino random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
5248e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__
5249e4b17023SJohn Marino _RandomNumberGenerator&& __rand)
5250e4b17023SJohn Marino #else
5251e4b17023SJohn Marino _RandomNumberGenerator& __rand)
5252e4b17023SJohn Marino #endif
5253e4b17023SJohn Marino {
5254e4b17023SJohn Marino // concept requirements
5255e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5256e4b17023SJohn Marino _RandomAccessIterator>)
5257e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
5258e4b17023SJohn Marino
5259e4b17023SJohn Marino if (__first == __last)
5260e4b17023SJohn Marino return;
5261e4b17023SJohn Marino for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
5262e4b17023SJohn Marino std::iter_swap(__i, __first + __rand((__i - __first) + 1));
5263e4b17023SJohn Marino }
5264e4b17023SJohn Marino
5265e4b17023SJohn Marino
5266e4b17023SJohn Marino /**
5267e4b17023SJohn Marino * @brief Move elements for which a predicate is true to the beginning
5268e4b17023SJohn Marino * of a sequence.
5269e4b17023SJohn Marino * @ingroup mutating_algorithms
5270e4b17023SJohn Marino * @param __first A forward iterator.
5271e4b17023SJohn Marino * @param __last A forward iterator.
5272e4b17023SJohn Marino * @param __pred A predicate functor.
5273e4b17023SJohn Marino * @return An iterator @p middle such that @p __pred(i) is true for each
5274e4b17023SJohn Marino * iterator @p i in the range @p [__first,middle) and false for each @p i
5275e4b17023SJohn Marino * in the range @p [middle,__last).
5276e4b17023SJohn Marino *
5277e4b17023SJohn Marino * @p __pred must not modify its operand. @p partition() does not preserve
5278e4b17023SJohn Marino * the relative ordering of elements in each group, use
5279e4b17023SJohn Marino * @p stable_partition() if this is needed.
5280e4b17023SJohn Marino */
5281e4b17023SJohn Marino template<typename _ForwardIterator, typename _Predicate>
5282e4b17023SJohn Marino inline _ForwardIterator
5283e4b17023SJohn Marino partition(_ForwardIterator __first, _ForwardIterator __last,
5284e4b17023SJohn Marino _Predicate __pred)
5285e4b17023SJohn Marino {
5286e4b17023SJohn Marino // concept requirements
5287e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
5288e4b17023SJohn Marino _ForwardIterator>)
5289e4b17023SJohn Marino __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
5290e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
5291e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
5292e4b17023SJohn Marino
5293e4b17023SJohn Marino return std::__partition(__first, __last, __pred,
5294e4b17023SJohn Marino std::__iterator_category(__first));
5295e4b17023SJohn Marino }
5296e4b17023SJohn Marino
5297e4b17023SJohn Marino
5298e4b17023SJohn Marino
5299e4b17023SJohn Marino /**
5300e4b17023SJohn Marino * @brief Sort the smallest elements of a sequence.
5301e4b17023SJohn Marino * @ingroup sorting_algorithms
5302e4b17023SJohn Marino * @param __first An iterator.
5303e4b17023SJohn Marino * @param __middle Another iterator.
5304e4b17023SJohn Marino * @param __last Another iterator.
5305e4b17023SJohn Marino * @return Nothing.
5306e4b17023SJohn Marino *
5307e4b17023SJohn Marino * Sorts the smallest @p (__middle-__first) elements in the range
5308e4b17023SJohn Marino * @p [first,last) and moves them to the range @p [__first,__middle). The
5309e4b17023SJohn Marino * order of the remaining elements in the range @p [__middle,__last) is
5310e4b17023SJohn Marino * undefined.
5311e4b17023SJohn Marino * After the sort if @e i and @e j are iterators in the range
5312e4b17023SJohn Marino * @p [__first,__middle) such that i precedes j and @e k is an iterator in
5313e4b17023SJohn Marino * the range @p [__middle,__last) then *j<*i and *k<*i are both false.
5314e4b17023SJohn Marino */
5315e4b17023SJohn Marino template<typename _RandomAccessIterator>
5316e4b17023SJohn Marino inline void
5317e4b17023SJohn Marino partial_sort(_RandomAccessIterator __first,
5318e4b17023SJohn Marino _RandomAccessIterator __middle,
5319e4b17023SJohn Marino _RandomAccessIterator __last)
5320e4b17023SJohn Marino {
5321e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type
5322e4b17023SJohn Marino _ValueType;
5323e4b17023SJohn Marino
5324e4b17023SJohn Marino // concept requirements
5325e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5326e4b17023SJohn Marino _RandomAccessIterator>)
5327e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
5328e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __middle);
5329e4b17023SJohn Marino __glibcxx_requires_valid_range(__middle, __last);
5330e4b17023SJohn Marino
5331e4b17023SJohn Marino std::__heap_select(__first, __middle, __last);
5332e4b17023SJohn Marino std::sort_heap(__first, __middle);
5333e4b17023SJohn Marino }
5334e4b17023SJohn Marino
5335e4b17023SJohn Marino /**
5336e4b17023SJohn Marino * @brief Sort the smallest elements of a sequence using a predicate
5337e4b17023SJohn Marino * for comparison.
5338e4b17023SJohn Marino * @ingroup sorting_algorithms
5339e4b17023SJohn Marino * @param __first An iterator.
5340e4b17023SJohn Marino * @param __middle Another iterator.
5341e4b17023SJohn Marino * @param __last Another iterator.
5342e4b17023SJohn Marino * @param __comp A comparison functor.
5343e4b17023SJohn Marino * @return Nothing.
5344e4b17023SJohn Marino *
5345e4b17023SJohn Marino * Sorts the smallest @p (__middle-__first) elements in the range
5346e4b17023SJohn Marino * @p [__first,__last) and moves them to the range @p [__first,__middle). The
5347e4b17023SJohn Marino * order of the remaining elements in the range @p [__middle,__last) is
5348e4b17023SJohn Marino * undefined.
5349e4b17023SJohn Marino * After the sort if @e i and @e j are iterators in the range
5350e4b17023SJohn Marino * @p [__first,__middle) such that i precedes j and @e k is an iterator in
5351e4b17023SJohn Marino * the range @p [__middle,__last) then @p *__comp(j,*i) and @p __comp(*k,*i)
5352e4b17023SJohn Marino * are both false.
5353e4b17023SJohn Marino */
5354e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare>
5355e4b17023SJohn Marino inline void
5356e4b17023SJohn Marino partial_sort(_RandomAccessIterator __first,
5357e4b17023SJohn Marino _RandomAccessIterator __middle,
5358e4b17023SJohn Marino _RandomAccessIterator __last,
5359e4b17023SJohn Marino _Compare __comp)
5360e4b17023SJohn Marino {
5361e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type
5362e4b17023SJohn Marino _ValueType;
5363e4b17023SJohn Marino
5364e4b17023SJohn Marino // concept requirements
5365e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5366e4b17023SJohn Marino _RandomAccessIterator>)
5367e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
5368e4b17023SJohn Marino _ValueType, _ValueType>)
5369e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __middle);
5370e4b17023SJohn Marino __glibcxx_requires_valid_range(__middle, __last);
5371e4b17023SJohn Marino
5372e4b17023SJohn Marino std::__heap_select(__first, __middle, __last, __comp);
5373e4b17023SJohn Marino std::sort_heap(__first, __middle, __comp);
5374e4b17023SJohn Marino }
5375e4b17023SJohn Marino
5376e4b17023SJohn Marino /**
5377e4b17023SJohn Marino * @brief Sort a sequence just enough to find a particular position.
5378e4b17023SJohn Marino * @ingroup sorting_algorithms
5379e4b17023SJohn Marino * @param __first An iterator.
5380e4b17023SJohn Marino * @param __nth Another iterator.
5381e4b17023SJohn Marino * @param __last Another iterator.
5382e4b17023SJohn Marino * @return Nothing.
5383e4b17023SJohn Marino *
5384e4b17023SJohn Marino * Rearranges the elements in the range @p [__first,__last) so that @p *__nth
5385e4b17023SJohn Marino * is the same element that would have been in that position had the
5386e4b17023SJohn Marino * whole sequence been sorted. The elements either side of @p *__nth are
5387e4b17023SJohn Marino * not completely sorted, but for any iterator @e i in the range
5388e4b17023SJohn Marino * @p [__first,__nth) and any iterator @e j in the range @p [__nth,__last) it
5389e4b17023SJohn Marino * holds that *j < *i is false.
5390e4b17023SJohn Marino */
5391e4b17023SJohn Marino template<typename _RandomAccessIterator>
5392e4b17023SJohn Marino inline void
5393e4b17023SJohn Marino nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth,
5394e4b17023SJohn Marino _RandomAccessIterator __last)
5395e4b17023SJohn Marino {
5396e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type
5397e4b17023SJohn Marino _ValueType;
5398e4b17023SJohn Marino
5399e4b17023SJohn Marino // concept requirements
5400e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5401e4b17023SJohn Marino _RandomAccessIterator>)
5402e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
5403e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __nth);
5404e4b17023SJohn Marino __glibcxx_requires_valid_range(__nth, __last);
5405e4b17023SJohn Marino
5406e4b17023SJohn Marino if (__first == __last || __nth == __last)
5407e4b17023SJohn Marino return;
5408e4b17023SJohn Marino
5409e4b17023SJohn Marino std::__introselect(__first, __nth, __last,
5410e4b17023SJohn Marino std::__lg(__last - __first) * 2);
5411e4b17023SJohn Marino }
5412e4b17023SJohn Marino
5413e4b17023SJohn Marino /**
5414e4b17023SJohn Marino * @brief Sort a sequence just enough to find a particular position
5415e4b17023SJohn Marino * using a predicate for comparison.
5416e4b17023SJohn Marino * @ingroup sorting_algorithms
5417e4b17023SJohn Marino * @param __first An iterator.
5418e4b17023SJohn Marino * @param __nth Another iterator.
5419e4b17023SJohn Marino * @param __last Another iterator.
5420e4b17023SJohn Marino * @param __comp A comparison functor.
5421e4b17023SJohn Marino * @return Nothing.
5422e4b17023SJohn Marino *
5423e4b17023SJohn Marino * Rearranges the elements in the range @p [__first,__last) so that @p *__nth
5424e4b17023SJohn Marino * is the same element that would have been in that position had the
5425e4b17023SJohn Marino * whole sequence been sorted. The elements either side of @p *__nth are
5426e4b17023SJohn Marino * not completely sorted, but for any iterator @e i in the range
5427e4b17023SJohn Marino * @p [__first,__nth) and any iterator @e j in the range @p [__nth,__last) it
5428e4b17023SJohn Marino * holds that @p __comp(*j,*i) is false.
5429e4b17023SJohn Marino */
5430e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare>
5431e4b17023SJohn Marino inline void
5432e4b17023SJohn Marino nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth,
5433e4b17023SJohn Marino _RandomAccessIterator __last, _Compare __comp)
5434e4b17023SJohn Marino {
5435e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type
5436e4b17023SJohn Marino _ValueType;
5437e4b17023SJohn Marino
5438e4b17023SJohn Marino // concept requirements
5439e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5440e4b17023SJohn Marino _RandomAccessIterator>)
5441e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
5442e4b17023SJohn Marino _ValueType, _ValueType>)
5443e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __nth);
5444e4b17023SJohn Marino __glibcxx_requires_valid_range(__nth, __last);
5445e4b17023SJohn Marino
5446e4b17023SJohn Marino if (__first == __last || __nth == __last)
5447e4b17023SJohn Marino return;
5448e4b17023SJohn Marino
5449e4b17023SJohn Marino std::__introselect(__first, __nth, __last,
5450e4b17023SJohn Marino std::__lg(__last - __first) * 2, __comp);
5451e4b17023SJohn Marino }
5452e4b17023SJohn Marino
5453e4b17023SJohn Marino
5454e4b17023SJohn Marino /**
5455e4b17023SJohn Marino * @brief Sort the elements of a sequence.
5456e4b17023SJohn Marino * @ingroup sorting_algorithms
5457e4b17023SJohn Marino * @param __first An iterator.
5458e4b17023SJohn Marino * @param __last Another iterator.
5459e4b17023SJohn Marino * @return Nothing.
5460e4b17023SJohn Marino *
5461e4b17023SJohn Marino * Sorts the elements in the range @p [__first,__last) in ascending order,
5462e4b17023SJohn Marino * such that for each iterator @e i in the range @p [__first,__last-1),
5463e4b17023SJohn Marino * *(i+1)<*i is false.
5464e4b17023SJohn Marino *
5465e4b17023SJohn Marino * The relative ordering of equivalent elements is not preserved, use
5466e4b17023SJohn Marino * @p stable_sort() if this is needed.
5467e4b17023SJohn Marino */
5468e4b17023SJohn Marino template<typename _RandomAccessIterator>
5469e4b17023SJohn Marino inline void
5470e4b17023SJohn Marino sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
5471e4b17023SJohn Marino {
5472e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type
5473e4b17023SJohn Marino _ValueType;
5474e4b17023SJohn Marino
5475e4b17023SJohn Marino // concept requirements
5476e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5477e4b17023SJohn Marino _RandomAccessIterator>)
5478e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
5479e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
5480e4b17023SJohn Marino
5481e4b17023SJohn Marino if (__first != __last)
5482e4b17023SJohn Marino {
5483e4b17023SJohn Marino std::__introsort_loop(__first, __last,
5484e4b17023SJohn Marino std::__lg(__last - __first) * 2);
5485e4b17023SJohn Marino std::__final_insertion_sort(__first, __last);
5486e4b17023SJohn Marino }
5487e4b17023SJohn Marino }
5488e4b17023SJohn Marino
5489e4b17023SJohn Marino /**
5490e4b17023SJohn Marino * @brief Sort the elements of a sequence using a predicate for comparison.
5491e4b17023SJohn Marino * @ingroup sorting_algorithms
5492e4b17023SJohn Marino * @param __first An iterator.
5493e4b17023SJohn Marino * @param __last Another iterator.
5494e4b17023SJohn Marino * @param __comp A comparison functor.
5495e4b17023SJohn Marino * @return Nothing.
5496e4b17023SJohn Marino *
5497e4b17023SJohn Marino * Sorts the elements in the range @p [__first,__last) in ascending order,
5498e4b17023SJohn Marino * such that @p __comp(*(i+1),*i) is false for every iterator @e i in the
5499e4b17023SJohn Marino * range @p [__first,__last-1).
5500e4b17023SJohn Marino *
5501e4b17023SJohn Marino * The relative ordering of equivalent elements is not preserved, use
5502e4b17023SJohn Marino * @p stable_sort() if this is needed.
5503e4b17023SJohn Marino */
5504e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare>
5505e4b17023SJohn Marino inline void
5506e4b17023SJohn Marino sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
5507e4b17023SJohn Marino _Compare __comp)
5508e4b17023SJohn Marino {
5509e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type
5510e4b17023SJohn Marino _ValueType;
5511e4b17023SJohn Marino
5512e4b17023SJohn Marino // concept requirements
5513e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5514e4b17023SJohn Marino _RandomAccessIterator>)
5515e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType,
5516e4b17023SJohn Marino _ValueType>)
5517e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
5518e4b17023SJohn Marino
5519e4b17023SJohn Marino if (__first != __last)
5520e4b17023SJohn Marino {
5521e4b17023SJohn Marino std::__introsort_loop(__first, __last,
5522e4b17023SJohn Marino std::__lg(__last - __first) * 2, __comp);
5523e4b17023SJohn Marino std::__final_insertion_sort(__first, __last, __comp);
5524e4b17023SJohn Marino }
5525e4b17023SJohn Marino }
5526e4b17023SJohn Marino
5527e4b17023SJohn Marino /**
5528e4b17023SJohn Marino * @brief Merges two sorted ranges.
5529e4b17023SJohn Marino * @ingroup sorting_algorithms
5530e4b17023SJohn Marino * @param __first1 An iterator.
5531e4b17023SJohn Marino * @param __first2 Another iterator.
5532e4b17023SJohn Marino * @param __last1 Another iterator.
5533e4b17023SJohn Marino * @param __last2 Another iterator.
5534e4b17023SJohn Marino * @param __result An iterator pointing to the end of the merged range.
5535e4b17023SJohn Marino * @return An iterator pointing to the first element <em>not less
5536e4b17023SJohn Marino * than</em> @e val.
5537e4b17023SJohn Marino *
5538e4b17023SJohn Marino * Merges the ranges @p [__first1,__last1) and @p [__first2,__last2) into
5539e4b17023SJohn Marino * the sorted range @p [__result, __result + (__last1-__first1) +
5540e4b17023SJohn Marino * (__last2-__first2)). Both input ranges must be sorted, and the
5541e4b17023SJohn Marino * output range must not overlap with either of the input ranges.
5542e4b17023SJohn Marino * The sort is @e stable, that is, for equivalent elements in the
5543e4b17023SJohn Marino * two ranges, elements from the first range will always come
5544e4b17023SJohn Marino * before elements from the second.
5545e4b17023SJohn Marino */
5546e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2,
5547e4b17023SJohn Marino typename _OutputIterator>
5548e4b17023SJohn Marino _OutputIterator
5549e4b17023SJohn Marino merge(_InputIterator1 __first1, _InputIterator1 __last1,
5550e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2,
5551e4b17023SJohn Marino _OutputIterator __result)
5552e4b17023SJohn Marino {
5553e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type
5554e4b17023SJohn Marino _ValueType1;
5555e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type
5556e4b17023SJohn Marino _ValueType2;
5557e4b17023SJohn Marino
5558e4b17023SJohn Marino // concept requirements
5559e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
5560e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
5561e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5562e4b17023SJohn Marino _ValueType1>)
5563e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5564e4b17023SJohn Marino _ValueType2>)
5565e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
5566e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first1, __last1, __first2);
5567e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first2, __last2, __first1);
5568e4b17023SJohn Marino
5569e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2)
5570e4b17023SJohn Marino {
5571e4b17023SJohn Marino if (*__first2 < *__first1)
5572e4b17023SJohn Marino {
5573e4b17023SJohn Marino *__result = *__first2;
5574e4b17023SJohn Marino ++__first2;
5575e4b17023SJohn Marino }
5576e4b17023SJohn Marino else
5577e4b17023SJohn Marino {
5578e4b17023SJohn Marino *__result = *__first1;
5579e4b17023SJohn Marino ++__first1;
5580e4b17023SJohn Marino }
5581e4b17023SJohn Marino ++__result;
5582e4b17023SJohn Marino }
5583e4b17023SJohn Marino return std::copy(__first2, __last2, std::copy(__first1, __last1,
5584e4b17023SJohn Marino __result));
5585e4b17023SJohn Marino }
5586e4b17023SJohn Marino
5587e4b17023SJohn Marino /**
5588e4b17023SJohn Marino * @brief Merges two sorted ranges.
5589e4b17023SJohn Marino * @ingroup sorting_algorithms
5590e4b17023SJohn Marino * @param __first1 An iterator.
5591e4b17023SJohn Marino * @param __first2 Another iterator.
5592e4b17023SJohn Marino * @param __last1 Another iterator.
5593e4b17023SJohn Marino * @param __last2 Another iterator.
5594e4b17023SJohn Marino * @param __result An iterator pointing to the end of the merged range.
5595e4b17023SJohn Marino * @param __comp A functor to use for comparisons.
5596e4b17023SJohn Marino * @return An iterator pointing to the first element "not less
5597e4b17023SJohn Marino * than" @e val.
5598e4b17023SJohn Marino *
5599e4b17023SJohn Marino * Merges the ranges @p [__first1,__last1) and @p [__first2,__last2) into
5600e4b17023SJohn Marino * the sorted range @p [__result, __result + (__last1-__first1) +
5601e4b17023SJohn Marino * (__last2-__first2)). Both input ranges must be sorted, and the
5602e4b17023SJohn Marino * output range must not overlap with either of the input ranges.
5603e4b17023SJohn Marino * The sort is @e stable, that is, for equivalent elements in the
5604e4b17023SJohn Marino * two ranges, elements from the first range will always come
5605e4b17023SJohn Marino * before elements from the second.
5606e4b17023SJohn Marino *
5607e4b17023SJohn Marino * The comparison function should have the same effects on ordering as
5608e4b17023SJohn Marino * the function used for the initial sort.
5609e4b17023SJohn Marino */
5610e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2,
5611e4b17023SJohn Marino typename _OutputIterator, typename _Compare>
5612e4b17023SJohn Marino _OutputIterator
5613e4b17023SJohn Marino merge(_InputIterator1 __first1, _InputIterator1 __last1,
5614e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2,
5615e4b17023SJohn Marino _OutputIterator __result, _Compare __comp)
5616e4b17023SJohn Marino {
5617e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type
5618e4b17023SJohn Marino _ValueType1;
5619e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type
5620e4b17023SJohn Marino _ValueType2;
5621e4b17023SJohn Marino
5622e4b17023SJohn Marino // concept requirements
5623e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
5624e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
5625e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5626e4b17023SJohn Marino _ValueType1>)
5627e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5628e4b17023SJohn Marino _ValueType2>)
5629e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
5630e4b17023SJohn Marino _ValueType2, _ValueType1>)
5631e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
5632e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);
5633e4b17023SJohn Marino
5634e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2)
5635e4b17023SJohn Marino {
5636e4b17023SJohn Marino if (__comp(*__first2, *__first1))
5637e4b17023SJohn Marino {
5638e4b17023SJohn Marino *__result = *__first2;
5639e4b17023SJohn Marino ++__first2;
5640e4b17023SJohn Marino }
5641e4b17023SJohn Marino else
5642e4b17023SJohn Marino {
5643e4b17023SJohn Marino *__result = *__first1;
5644e4b17023SJohn Marino ++__first1;
5645e4b17023SJohn Marino }
5646e4b17023SJohn Marino ++__result;
5647e4b17023SJohn Marino }
5648e4b17023SJohn Marino return std::copy(__first2, __last2, std::copy(__first1, __last1,
5649e4b17023SJohn Marino __result));
5650e4b17023SJohn Marino }
5651e4b17023SJohn Marino
5652e4b17023SJohn Marino
5653e4b17023SJohn Marino /**
5654e4b17023SJohn Marino * @brief Sort the elements of a sequence, preserving the relative order
5655e4b17023SJohn Marino * of equivalent elements.
5656e4b17023SJohn Marino * @ingroup sorting_algorithms
5657e4b17023SJohn Marino * @param __first An iterator.
5658e4b17023SJohn Marino * @param __last Another iterator.
5659e4b17023SJohn Marino * @return Nothing.
5660e4b17023SJohn Marino *
5661e4b17023SJohn Marino * Sorts the elements in the range @p [__first,__last) in ascending order,
5662e4b17023SJohn Marino * such that for each iterator @p i in the range @p [__first,__last-1),
5663e4b17023SJohn Marino * @p *(i+1)<*i is false.
5664e4b17023SJohn Marino *
5665e4b17023SJohn Marino * The relative ordering of equivalent elements is preserved, so any two
5666e4b17023SJohn Marino * elements @p x and @p y in the range @p [__first,__last) such that
5667e4b17023SJohn Marino * @p x<y is false and @p y<x is false will have the same relative
5668e4b17023SJohn Marino * ordering after calling @p stable_sort().
5669e4b17023SJohn Marino */
5670e4b17023SJohn Marino template<typename _RandomAccessIterator>
5671e4b17023SJohn Marino inline void
5672e4b17023SJohn Marino stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
5673e4b17023SJohn Marino {
5674e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type
5675e4b17023SJohn Marino _ValueType;
5676e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::difference_type
5677e4b17023SJohn Marino _DistanceType;
5678e4b17023SJohn Marino
5679e4b17023SJohn Marino // concept requirements
5680e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5681e4b17023SJohn Marino _RandomAccessIterator>)
5682e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
5683e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
5684e4b17023SJohn Marino
5685e4b17023SJohn Marino _Temporary_buffer<_RandomAccessIterator, _ValueType> __buf(__first,
5686e4b17023SJohn Marino __last);
5687e4b17023SJohn Marino if (__buf.begin() == 0)
5688e4b17023SJohn Marino std::__inplace_stable_sort(__first, __last);
5689e4b17023SJohn Marino else
5690e4b17023SJohn Marino std::__stable_sort_adaptive(__first, __last, __buf.begin(),
5691e4b17023SJohn Marino _DistanceType(__buf.size()));
5692e4b17023SJohn Marino }
5693e4b17023SJohn Marino
5694e4b17023SJohn Marino /**
5695e4b17023SJohn Marino * @brief Sort the elements of a sequence using a predicate for comparison,
5696e4b17023SJohn Marino * preserving the relative order of equivalent elements.
5697e4b17023SJohn Marino * @ingroup sorting_algorithms
5698e4b17023SJohn Marino * @param __first An iterator.
5699e4b17023SJohn Marino * @param __last Another iterator.
5700e4b17023SJohn Marino * @param __comp A comparison functor.
5701e4b17023SJohn Marino * @return Nothing.
5702e4b17023SJohn Marino *
5703e4b17023SJohn Marino * Sorts the elements in the range @p [__first,__last) in ascending order,
5704e4b17023SJohn Marino * such that for each iterator @p i in the range @p [__first,__last-1),
5705e4b17023SJohn Marino * @p __comp(*(i+1),*i) is false.
5706e4b17023SJohn Marino *
5707e4b17023SJohn Marino * The relative ordering of equivalent elements is preserved, so any two
5708e4b17023SJohn Marino * elements @p x and @p y in the range @p [__first,__last) such that
5709e4b17023SJohn Marino * @p __comp(x,y) is false and @p __comp(y,x) is false will have the same
5710e4b17023SJohn Marino * relative ordering after calling @p stable_sort().
5711e4b17023SJohn Marino */
5712e4b17023SJohn Marino template<typename _RandomAccessIterator, typename _Compare>
5713e4b17023SJohn Marino inline void
5714e4b17023SJohn Marino stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
5715e4b17023SJohn Marino _Compare __comp)
5716e4b17023SJohn Marino {
5717e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::value_type
5718e4b17023SJohn Marino _ValueType;
5719e4b17023SJohn Marino typedef typename iterator_traits<_RandomAccessIterator>::difference_type
5720e4b17023SJohn Marino _DistanceType;
5721e4b17023SJohn Marino
5722e4b17023SJohn Marino // concept requirements
5723e4b17023SJohn Marino __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
5724e4b17023SJohn Marino _RandomAccessIterator>)
5725e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
5726e4b17023SJohn Marino _ValueType,
5727e4b17023SJohn Marino _ValueType>)
5728e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
5729e4b17023SJohn Marino
5730e4b17023SJohn Marino _Temporary_buffer<_RandomAccessIterator, _ValueType> __buf(__first,
5731e4b17023SJohn Marino __last);
5732e4b17023SJohn Marino if (__buf.begin() == 0)
5733e4b17023SJohn Marino std::__inplace_stable_sort(__first, __last, __comp);
5734e4b17023SJohn Marino else
5735e4b17023SJohn Marino std::__stable_sort_adaptive(__first, __last, __buf.begin(),
5736e4b17023SJohn Marino _DistanceType(__buf.size()), __comp);
5737e4b17023SJohn Marino }
5738e4b17023SJohn Marino
5739e4b17023SJohn Marino
5740e4b17023SJohn Marino /**
5741e4b17023SJohn Marino * @brief Return the union of two sorted ranges.
5742e4b17023SJohn Marino * @ingroup set_algorithms
5743e4b17023SJohn Marino * @param __first1 Start of first range.
5744e4b17023SJohn Marino * @param __last1 End of first range.
5745e4b17023SJohn Marino * @param __first2 Start of second range.
5746e4b17023SJohn Marino * @param __last2 End of second range.
5747e4b17023SJohn Marino * @return End of the output range.
5748e4b17023SJohn Marino * @ingroup set_algorithms
5749e4b17023SJohn Marino *
5750e4b17023SJohn Marino * This operation iterates over both ranges, copying elements present in
5751e4b17023SJohn Marino * each range in order to the output range. Iterators increment for each
5752e4b17023SJohn Marino * range. When the current element of one range is less than the other,
5753e4b17023SJohn Marino * that element is copied and the iterator advanced. If an element is
5754e4b17023SJohn Marino * contained in both ranges, the element from the first range is copied and
5755e4b17023SJohn Marino * both ranges advance. The output range may not overlap either input
5756e4b17023SJohn Marino * range.
5757e4b17023SJohn Marino */
5758e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2,
5759e4b17023SJohn Marino typename _OutputIterator>
5760e4b17023SJohn Marino _OutputIterator
5761e4b17023SJohn Marino set_union(_InputIterator1 __first1, _InputIterator1 __last1,
5762e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2,
5763e4b17023SJohn Marino _OutputIterator __result)
5764e4b17023SJohn Marino {
5765e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type
5766e4b17023SJohn Marino _ValueType1;
5767e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type
5768e4b17023SJohn Marino _ValueType2;
5769e4b17023SJohn Marino
5770e4b17023SJohn Marino // concept requirements
5771e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
5772e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
5773e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5774e4b17023SJohn Marino _ValueType1>)
5775e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5776e4b17023SJohn Marino _ValueType2>)
5777e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
5778e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
5779e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first1, __last1, __first2);
5780e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first2, __last2, __first1);
5781e4b17023SJohn Marino
5782e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2)
5783e4b17023SJohn Marino {
5784e4b17023SJohn Marino if (*__first1 < *__first2)
5785e4b17023SJohn Marino {
5786e4b17023SJohn Marino *__result = *__first1;
5787e4b17023SJohn Marino ++__first1;
5788e4b17023SJohn Marino }
5789e4b17023SJohn Marino else if (*__first2 < *__first1)
5790e4b17023SJohn Marino {
5791e4b17023SJohn Marino *__result = *__first2;
5792e4b17023SJohn Marino ++__first2;
5793e4b17023SJohn Marino }
5794e4b17023SJohn Marino else
5795e4b17023SJohn Marino {
5796e4b17023SJohn Marino *__result = *__first1;
5797e4b17023SJohn Marino ++__first1;
5798e4b17023SJohn Marino ++__first2;
5799e4b17023SJohn Marino }
5800e4b17023SJohn Marino ++__result;
5801e4b17023SJohn Marino }
5802e4b17023SJohn Marino return std::copy(__first2, __last2, std::copy(__first1, __last1,
5803e4b17023SJohn Marino __result));
5804e4b17023SJohn Marino }
5805e4b17023SJohn Marino
5806e4b17023SJohn Marino /**
5807e4b17023SJohn Marino * @brief Return the union of two sorted ranges using a comparison functor.
5808e4b17023SJohn Marino * @ingroup set_algorithms
5809e4b17023SJohn Marino * @param __first1 Start of first range.
5810e4b17023SJohn Marino * @param __last1 End of first range.
5811e4b17023SJohn Marino * @param __first2 Start of second range.
5812e4b17023SJohn Marino * @param __last2 End of second range.
5813e4b17023SJohn Marino * @param __comp The comparison functor.
5814e4b17023SJohn Marino * @return End of the output range.
5815e4b17023SJohn Marino * @ingroup set_algorithms
5816e4b17023SJohn Marino *
5817e4b17023SJohn Marino * This operation iterates over both ranges, copying elements present in
5818e4b17023SJohn Marino * each range in order to the output range. Iterators increment for each
5819e4b17023SJohn Marino * range. When the current element of one range is less than the other
5820e4b17023SJohn Marino * according to @p __comp, that element is copied and the iterator advanced.
5821e4b17023SJohn Marino * If an equivalent element according to @p __comp is contained in both
5822e4b17023SJohn Marino * ranges, the element from the first range is copied and both ranges
5823e4b17023SJohn Marino * advance. The output range may not overlap either input range.
5824e4b17023SJohn Marino */
5825e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2,
5826e4b17023SJohn Marino typename _OutputIterator, typename _Compare>
5827e4b17023SJohn Marino _OutputIterator
5828e4b17023SJohn Marino set_union(_InputIterator1 __first1, _InputIterator1 __last1,
5829e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2,
5830e4b17023SJohn Marino _OutputIterator __result, _Compare __comp)
5831e4b17023SJohn Marino {
5832e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type
5833e4b17023SJohn Marino _ValueType1;
5834e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type
5835e4b17023SJohn Marino _ValueType2;
5836e4b17023SJohn Marino
5837e4b17023SJohn Marino // concept requirements
5838e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
5839e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
5840e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5841e4b17023SJohn Marino _ValueType1>)
5842e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5843e4b17023SJohn Marino _ValueType2>)
5844e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
5845e4b17023SJohn Marino _ValueType1, _ValueType2>)
5846e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
5847e4b17023SJohn Marino _ValueType2, _ValueType1>)
5848e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
5849e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);
5850e4b17023SJohn Marino
5851e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2)
5852e4b17023SJohn Marino {
5853e4b17023SJohn Marino if (__comp(*__first1, *__first2))
5854e4b17023SJohn Marino {
5855e4b17023SJohn Marino *__result = *__first1;
5856e4b17023SJohn Marino ++__first1;
5857e4b17023SJohn Marino }
5858e4b17023SJohn Marino else if (__comp(*__first2, *__first1))
5859e4b17023SJohn Marino {
5860e4b17023SJohn Marino *__result = *__first2;
5861e4b17023SJohn Marino ++__first2;
5862e4b17023SJohn Marino }
5863e4b17023SJohn Marino else
5864e4b17023SJohn Marino {
5865e4b17023SJohn Marino *__result = *__first1;
5866e4b17023SJohn Marino ++__first1;
5867e4b17023SJohn Marino ++__first2;
5868e4b17023SJohn Marino }
5869e4b17023SJohn Marino ++__result;
5870e4b17023SJohn Marino }
5871e4b17023SJohn Marino return std::copy(__first2, __last2, std::copy(__first1, __last1,
5872e4b17023SJohn Marino __result));
5873e4b17023SJohn Marino }
5874e4b17023SJohn Marino
5875e4b17023SJohn Marino /**
5876e4b17023SJohn Marino * @brief Return the intersection of two sorted ranges.
5877e4b17023SJohn Marino * @ingroup set_algorithms
5878e4b17023SJohn Marino * @param __first1 Start of first range.
5879e4b17023SJohn Marino * @param __last1 End of first range.
5880e4b17023SJohn Marino * @param __first2 Start of second range.
5881e4b17023SJohn Marino * @param __last2 End of second range.
5882e4b17023SJohn Marino * @return End of the output range.
5883e4b17023SJohn Marino * @ingroup set_algorithms
5884e4b17023SJohn Marino *
5885e4b17023SJohn Marino * This operation iterates over both ranges, copying elements present in
5886e4b17023SJohn Marino * both ranges in order to the output range. Iterators increment for each
5887e4b17023SJohn Marino * range. When the current element of one range is less than the other,
5888e4b17023SJohn Marino * that iterator advances. If an element is contained in both ranges, the
5889e4b17023SJohn Marino * element from the first range is copied and both ranges advance. The
5890e4b17023SJohn Marino * output range may not overlap either input range.
5891e4b17023SJohn Marino */
5892e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2,
5893e4b17023SJohn Marino typename _OutputIterator>
5894e4b17023SJohn Marino _OutputIterator
5895e4b17023SJohn Marino set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
5896e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2,
5897e4b17023SJohn Marino _OutputIterator __result)
5898e4b17023SJohn Marino {
5899e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type
5900e4b17023SJohn Marino _ValueType1;
5901e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type
5902e4b17023SJohn Marino _ValueType2;
5903e4b17023SJohn Marino
5904e4b17023SJohn Marino // concept requirements
5905e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
5906e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
5907e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5908e4b17023SJohn Marino _ValueType1>)
5909e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
5910e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
5911e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first1, __last1, __first2);
5912e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first2, __last2, __first1);
5913e4b17023SJohn Marino
5914e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2)
5915e4b17023SJohn Marino if (*__first1 < *__first2)
5916e4b17023SJohn Marino ++__first1;
5917e4b17023SJohn Marino else if (*__first2 < *__first1)
5918e4b17023SJohn Marino ++__first2;
5919e4b17023SJohn Marino else
5920e4b17023SJohn Marino {
5921e4b17023SJohn Marino *__result = *__first1;
5922e4b17023SJohn Marino ++__first1;
5923e4b17023SJohn Marino ++__first2;
5924e4b17023SJohn Marino ++__result;
5925e4b17023SJohn Marino }
5926e4b17023SJohn Marino return __result;
5927e4b17023SJohn Marino }
5928e4b17023SJohn Marino
5929e4b17023SJohn Marino /**
5930e4b17023SJohn Marino * @brief Return the intersection of two sorted ranges using comparison
5931e4b17023SJohn Marino * functor.
5932e4b17023SJohn Marino * @ingroup set_algorithms
5933e4b17023SJohn Marino * @param __first1 Start of first range.
5934e4b17023SJohn Marino * @param __last1 End of first range.
5935e4b17023SJohn Marino * @param __first2 Start of second range.
5936e4b17023SJohn Marino * @param __last2 End of second range.
5937e4b17023SJohn Marino * @param __comp The comparison functor.
5938e4b17023SJohn Marino * @return End of the output range.
5939e4b17023SJohn Marino * @ingroup set_algorithms
5940e4b17023SJohn Marino *
5941e4b17023SJohn Marino * This operation iterates over both ranges, copying elements present in
5942e4b17023SJohn Marino * both ranges in order to the output range. Iterators increment for each
5943e4b17023SJohn Marino * range. When the current element of one range is less than the other
5944e4b17023SJohn Marino * according to @p __comp, that iterator advances. If an element is
5945e4b17023SJohn Marino * contained in both ranges according to @p __comp, the element from the
5946e4b17023SJohn Marino * first range is copied and both ranges advance. The output range may not
5947e4b17023SJohn Marino * overlap either input range.
5948e4b17023SJohn Marino */
5949e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2,
5950e4b17023SJohn Marino typename _OutputIterator, typename _Compare>
5951e4b17023SJohn Marino _OutputIterator
5952e4b17023SJohn Marino set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
5953e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2,
5954e4b17023SJohn Marino _OutputIterator __result, _Compare __comp)
5955e4b17023SJohn Marino {
5956e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type
5957e4b17023SJohn Marino _ValueType1;
5958e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type
5959e4b17023SJohn Marino _ValueType2;
5960e4b17023SJohn Marino
5961e4b17023SJohn Marino // concept requirements
5962e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
5963e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
5964e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
5965e4b17023SJohn Marino _ValueType1>)
5966e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
5967e4b17023SJohn Marino _ValueType1, _ValueType2>)
5968e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
5969e4b17023SJohn Marino _ValueType2, _ValueType1>)
5970e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
5971e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);
5972e4b17023SJohn Marino
5973e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2)
5974e4b17023SJohn Marino if (__comp(*__first1, *__first2))
5975e4b17023SJohn Marino ++__first1;
5976e4b17023SJohn Marino else if (__comp(*__first2, *__first1))
5977e4b17023SJohn Marino ++__first2;
5978e4b17023SJohn Marino else
5979e4b17023SJohn Marino {
5980e4b17023SJohn Marino *__result = *__first1;
5981e4b17023SJohn Marino ++__first1;
5982e4b17023SJohn Marino ++__first2;
5983e4b17023SJohn Marino ++__result;
5984e4b17023SJohn Marino }
5985e4b17023SJohn Marino return __result;
5986e4b17023SJohn Marino }
5987e4b17023SJohn Marino
5988e4b17023SJohn Marino /**
5989e4b17023SJohn Marino * @brief Return the difference of two sorted ranges.
5990e4b17023SJohn Marino * @ingroup set_algorithms
5991e4b17023SJohn Marino * @param __first1 Start of first range.
5992e4b17023SJohn Marino * @param __last1 End of first range.
5993e4b17023SJohn Marino * @param __first2 Start of second range.
5994e4b17023SJohn Marino * @param __last2 End of second range.
5995e4b17023SJohn Marino * @return End of the output range.
5996e4b17023SJohn Marino * @ingroup set_algorithms
5997e4b17023SJohn Marino *
5998e4b17023SJohn Marino * This operation iterates over both ranges, copying elements present in
5999e4b17023SJohn Marino * the first range but not the second in order to the output range.
6000e4b17023SJohn Marino * Iterators increment for each range. When the current element of the
6001e4b17023SJohn Marino * first range is less than the second, that element is copied and the
6002e4b17023SJohn Marino * iterator advances. If the current element of the second range is less,
6003e4b17023SJohn Marino * the iterator advances, but no element is copied. If an element is
6004e4b17023SJohn Marino * contained in both ranges, no elements are copied and both ranges
6005e4b17023SJohn Marino * advance. The output range may not overlap either input range.
6006e4b17023SJohn Marino */
6007e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2,
6008e4b17023SJohn Marino typename _OutputIterator>
6009e4b17023SJohn Marino _OutputIterator
6010e4b17023SJohn Marino set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
6011e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2,
6012e4b17023SJohn Marino _OutputIterator __result)
6013e4b17023SJohn Marino {
6014e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type
6015e4b17023SJohn Marino _ValueType1;
6016e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type
6017e4b17023SJohn Marino _ValueType2;
6018e4b17023SJohn Marino
6019e4b17023SJohn Marino // concept requirements
6020e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
6021e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
6022e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
6023e4b17023SJohn Marino _ValueType1>)
6024e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
6025e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
6026e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first1, __last1, __first2);
6027e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first2, __last2, __first1);
6028e4b17023SJohn Marino
6029e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2)
6030e4b17023SJohn Marino if (*__first1 < *__first2)
6031e4b17023SJohn Marino {
6032e4b17023SJohn Marino *__result = *__first1;
6033e4b17023SJohn Marino ++__first1;
6034e4b17023SJohn Marino ++__result;
6035e4b17023SJohn Marino }
6036e4b17023SJohn Marino else if (*__first2 < *__first1)
6037e4b17023SJohn Marino ++__first2;
6038e4b17023SJohn Marino else
6039e4b17023SJohn Marino {
6040e4b17023SJohn Marino ++__first1;
6041e4b17023SJohn Marino ++__first2;
6042e4b17023SJohn Marino }
6043e4b17023SJohn Marino return std::copy(__first1, __last1, __result);
6044e4b17023SJohn Marino }
6045e4b17023SJohn Marino
6046e4b17023SJohn Marino /**
6047e4b17023SJohn Marino * @brief Return the difference of two sorted ranges using comparison
6048e4b17023SJohn Marino * functor.
6049e4b17023SJohn Marino * @ingroup set_algorithms
6050e4b17023SJohn Marino * @param __first1 Start of first range.
6051e4b17023SJohn Marino * @param __last1 End of first range.
6052e4b17023SJohn Marino * @param __first2 Start of second range.
6053e4b17023SJohn Marino * @param __last2 End of second range.
6054e4b17023SJohn Marino * @param __comp The comparison functor.
6055e4b17023SJohn Marino * @return End of the output range.
6056e4b17023SJohn Marino * @ingroup set_algorithms
6057e4b17023SJohn Marino *
6058e4b17023SJohn Marino * This operation iterates over both ranges, copying elements present in
6059e4b17023SJohn Marino * the first range but not the second in order to the output range.
6060e4b17023SJohn Marino * Iterators increment for each range. When the current element of the
6061e4b17023SJohn Marino * first range is less than the second according to @p __comp, that element
6062e4b17023SJohn Marino * is copied and the iterator advances. If the current element of the
6063e4b17023SJohn Marino * second range is less, no element is copied and the iterator advances.
6064e4b17023SJohn Marino * If an element is contained in both ranges according to @p __comp, no
6065e4b17023SJohn Marino * elements are copied and both ranges advance. The output range may not
6066e4b17023SJohn Marino * overlap either input range.
6067e4b17023SJohn Marino */
6068e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2,
6069e4b17023SJohn Marino typename _OutputIterator, typename _Compare>
6070e4b17023SJohn Marino _OutputIterator
6071e4b17023SJohn Marino set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
6072e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2,
6073e4b17023SJohn Marino _OutputIterator __result, _Compare __comp)
6074e4b17023SJohn Marino {
6075e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type
6076e4b17023SJohn Marino _ValueType1;
6077e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type
6078e4b17023SJohn Marino _ValueType2;
6079e4b17023SJohn Marino
6080e4b17023SJohn Marino // concept requirements
6081e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
6082e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
6083e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
6084e4b17023SJohn Marino _ValueType1>)
6085e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
6086e4b17023SJohn Marino _ValueType1, _ValueType2>)
6087e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
6088e4b17023SJohn Marino _ValueType2, _ValueType1>)
6089e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
6090e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);
6091e4b17023SJohn Marino
6092e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2)
6093e4b17023SJohn Marino if (__comp(*__first1, *__first2))
6094e4b17023SJohn Marino {
6095e4b17023SJohn Marino *__result = *__first1;
6096e4b17023SJohn Marino ++__first1;
6097e4b17023SJohn Marino ++__result;
6098e4b17023SJohn Marino }
6099e4b17023SJohn Marino else if (__comp(*__first2, *__first1))
6100e4b17023SJohn Marino ++__first2;
6101e4b17023SJohn Marino else
6102e4b17023SJohn Marino {
6103e4b17023SJohn Marino ++__first1;
6104e4b17023SJohn Marino ++__first2;
6105e4b17023SJohn Marino }
6106e4b17023SJohn Marino return std::copy(__first1, __last1, __result);
6107e4b17023SJohn Marino }
6108e4b17023SJohn Marino
6109e4b17023SJohn Marino /**
6110e4b17023SJohn Marino * @brief Return the symmetric difference of two sorted ranges.
6111e4b17023SJohn Marino * @ingroup set_algorithms
6112e4b17023SJohn Marino * @param __first1 Start of first range.
6113e4b17023SJohn Marino * @param __last1 End of first range.
6114e4b17023SJohn Marino * @param __first2 Start of second range.
6115e4b17023SJohn Marino * @param __last2 End of second range.
6116e4b17023SJohn Marino * @return End of the output range.
6117e4b17023SJohn Marino * @ingroup set_algorithms
6118e4b17023SJohn Marino *
6119e4b17023SJohn Marino * This operation iterates over both ranges, copying elements present in
6120e4b17023SJohn Marino * one range but not the other in order to the output range. Iterators
6121e4b17023SJohn Marino * increment for each range. When the current element of one range is less
6122e4b17023SJohn Marino * than the other, that element is copied and the iterator advances. If an
6123e4b17023SJohn Marino * element is contained in both ranges, no elements are copied and both
6124e4b17023SJohn Marino * ranges advance. The output range may not overlap either input range.
6125e4b17023SJohn Marino */
6126e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2,
6127e4b17023SJohn Marino typename _OutputIterator>
6128e4b17023SJohn Marino _OutputIterator
6129e4b17023SJohn Marino set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
6130e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2,
6131e4b17023SJohn Marino _OutputIterator __result)
6132e4b17023SJohn Marino {
6133e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type
6134e4b17023SJohn Marino _ValueType1;
6135e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type
6136e4b17023SJohn Marino _ValueType2;
6137e4b17023SJohn Marino
6138e4b17023SJohn Marino // concept requirements
6139e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
6140e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
6141e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
6142e4b17023SJohn Marino _ValueType1>)
6143e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
6144e4b17023SJohn Marino _ValueType2>)
6145e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
6146e4b17023SJohn Marino __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
6147e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first1, __last1, __first2);
6148e4b17023SJohn Marino __glibcxx_requires_sorted_set(__first2, __last2, __first1);
6149e4b17023SJohn Marino
6150e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2)
6151e4b17023SJohn Marino if (*__first1 < *__first2)
6152e4b17023SJohn Marino {
6153e4b17023SJohn Marino *__result = *__first1;
6154e4b17023SJohn Marino ++__first1;
6155e4b17023SJohn Marino ++__result;
6156e4b17023SJohn Marino }
6157e4b17023SJohn Marino else if (*__first2 < *__first1)
6158e4b17023SJohn Marino {
6159e4b17023SJohn Marino *__result = *__first2;
6160e4b17023SJohn Marino ++__first2;
6161e4b17023SJohn Marino ++__result;
6162e4b17023SJohn Marino }
6163e4b17023SJohn Marino else
6164e4b17023SJohn Marino {
6165e4b17023SJohn Marino ++__first1;
6166e4b17023SJohn Marino ++__first2;
6167e4b17023SJohn Marino }
6168e4b17023SJohn Marino return std::copy(__first2, __last2, std::copy(__first1,
6169e4b17023SJohn Marino __last1, __result));
6170e4b17023SJohn Marino }
6171e4b17023SJohn Marino
6172e4b17023SJohn Marino /**
6173e4b17023SJohn Marino * @brief Return the symmetric difference of two sorted ranges using
6174e4b17023SJohn Marino * comparison functor.
6175e4b17023SJohn Marino * @ingroup set_algorithms
6176e4b17023SJohn Marino * @param __first1 Start of first range.
6177e4b17023SJohn Marino * @param __last1 End of first range.
6178e4b17023SJohn Marino * @param __first2 Start of second range.
6179e4b17023SJohn Marino * @param __last2 End of second range.
6180e4b17023SJohn Marino * @param __comp The comparison functor.
6181e4b17023SJohn Marino * @return End of the output range.
6182e4b17023SJohn Marino * @ingroup set_algorithms
6183e4b17023SJohn Marino *
6184e4b17023SJohn Marino * This operation iterates over both ranges, copying elements present in
6185e4b17023SJohn Marino * one range but not the other in order to the output range. Iterators
6186e4b17023SJohn Marino * increment for each range. When the current element of one range is less
6187e4b17023SJohn Marino * than the other according to @p comp, that element is copied and the
6188e4b17023SJohn Marino * iterator advances. If an element is contained in both ranges according
6189e4b17023SJohn Marino * to @p __comp, no elements are copied and both ranges advance. The output
6190e4b17023SJohn Marino * range may not overlap either input range.
6191e4b17023SJohn Marino */
6192e4b17023SJohn Marino template<typename _InputIterator1, typename _InputIterator2,
6193e4b17023SJohn Marino typename _OutputIterator, typename _Compare>
6194e4b17023SJohn Marino _OutputIterator
6195e4b17023SJohn Marino set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
6196e4b17023SJohn Marino _InputIterator2 __first2, _InputIterator2 __last2,
6197e4b17023SJohn Marino _OutputIterator __result,
6198e4b17023SJohn Marino _Compare __comp)
6199e4b17023SJohn Marino {
6200e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator1>::value_type
6201e4b17023SJohn Marino _ValueType1;
6202e4b17023SJohn Marino typedef typename iterator_traits<_InputIterator2>::value_type
6203e4b17023SJohn Marino _ValueType2;
6204e4b17023SJohn Marino
6205e4b17023SJohn Marino // concept requirements
6206e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
6207e4b17023SJohn Marino __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
6208e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
6209e4b17023SJohn Marino _ValueType1>)
6210e4b17023SJohn Marino __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
6211e4b17023SJohn Marino _ValueType2>)
6212e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
6213e4b17023SJohn Marino _ValueType1, _ValueType2>)
6214e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
6215e4b17023SJohn Marino _ValueType2, _ValueType1>)
6216e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
6217e4b17023SJohn Marino __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);
6218e4b17023SJohn Marino
6219e4b17023SJohn Marino while (__first1 != __last1 && __first2 != __last2)
6220e4b17023SJohn Marino if (__comp(*__first1, *__first2))
6221e4b17023SJohn Marino {
6222e4b17023SJohn Marino *__result = *__first1;
6223e4b17023SJohn Marino ++__first1;
6224e4b17023SJohn Marino ++__result;
6225e4b17023SJohn Marino }
6226e4b17023SJohn Marino else if (__comp(*__first2, *__first1))
6227e4b17023SJohn Marino {
6228e4b17023SJohn Marino *__result = *__first2;
6229e4b17023SJohn Marino ++__first2;
6230e4b17023SJohn Marino ++__result;
6231e4b17023SJohn Marino }
6232e4b17023SJohn Marino else
6233e4b17023SJohn Marino {
6234e4b17023SJohn Marino ++__first1;
6235e4b17023SJohn Marino ++__first2;
6236e4b17023SJohn Marino }
6237e4b17023SJohn Marino return std::copy(__first2, __last2,
6238e4b17023SJohn Marino std::copy(__first1, __last1, __result));
6239e4b17023SJohn Marino }
6240e4b17023SJohn Marino
6241e4b17023SJohn Marino
6242e4b17023SJohn Marino /**
6243e4b17023SJohn Marino * @brief Return the minimum element in a range.
6244e4b17023SJohn Marino * @ingroup sorting_algorithms
6245e4b17023SJohn Marino * @param __first Start of range.
6246e4b17023SJohn Marino * @param __last End of range.
6247e4b17023SJohn Marino * @return Iterator referencing the first instance of the smallest value.
6248e4b17023SJohn Marino */
6249e4b17023SJohn Marino template<typename _ForwardIterator>
6250e4b17023SJohn Marino _ForwardIterator
6251e4b17023SJohn Marino min_element(_ForwardIterator __first, _ForwardIterator __last)
6252e4b17023SJohn Marino {
6253e4b17023SJohn Marino // concept requirements
6254e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
6255e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<
6256e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
6257e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
6258e4b17023SJohn Marino
6259e4b17023SJohn Marino if (__first == __last)
6260e4b17023SJohn Marino return __first;
6261e4b17023SJohn Marino _ForwardIterator __result = __first;
6262e4b17023SJohn Marino while (++__first != __last)
6263e4b17023SJohn Marino if (*__first < *__result)
6264e4b17023SJohn Marino __result = __first;
6265e4b17023SJohn Marino return __result;
6266e4b17023SJohn Marino }
6267e4b17023SJohn Marino
6268e4b17023SJohn Marino /**
6269e4b17023SJohn Marino * @brief Return the minimum element in a range using comparison functor.
6270e4b17023SJohn Marino * @ingroup sorting_algorithms
6271e4b17023SJohn Marino * @param __first Start of range.
6272e4b17023SJohn Marino * @param __last End of range.
6273e4b17023SJohn Marino * @param __comp Comparison functor.
6274e4b17023SJohn Marino * @return Iterator referencing the first instance of the smallest value
6275e4b17023SJohn Marino * according to __comp.
6276e4b17023SJohn Marino */
6277e4b17023SJohn Marino template<typename _ForwardIterator, typename _Compare>
6278e4b17023SJohn Marino _ForwardIterator
6279e4b17023SJohn Marino min_element(_ForwardIterator __first, _ForwardIterator __last,
6280e4b17023SJohn Marino _Compare __comp)
6281e4b17023SJohn Marino {
6282e4b17023SJohn Marino // concept requirements
6283e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
6284e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
6285e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type,
6286e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
6287e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
6288e4b17023SJohn Marino
6289e4b17023SJohn Marino if (__first == __last)
6290e4b17023SJohn Marino return __first;
6291e4b17023SJohn Marino _ForwardIterator __result = __first;
6292e4b17023SJohn Marino while (++__first != __last)
6293e4b17023SJohn Marino if (__comp(*__first, *__result))
6294e4b17023SJohn Marino __result = __first;
6295e4b17023SJohn Marino return __result;
6296e4b17023SJohn Marino }
6297e4b17023SJohn Marino
6298e4b17023SJohn Marino /**
6299e4b17023SJohn Marino * @brief Return the maximum element in a range.
6300e4b17023SJohn Marino * @ingroup sorting_algorithms
6301e4b17023SJohn Marino * @param __first Start of range.
6302e4b17023SJohn Marino * @param __last End of range.
6303e4b17023SJohn Marino * @return Iterator referencing the first instance of the largest value.
6304e4b17023SJohn Marino */
6305e4b17023SJohn Marino template<typename _ForwardIterator>
6306e4b17023SJohn Marino _ForwardIterator
6307e4b17023SJohn Marino max_element(_ForwardIterator __first, _ForwardIterator __last)
6308e4b17023SJohn Marino {
6309e4b17023SJohn Marino // concept requirements
6310e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
6311e4b17023SJohn Marino __glibcxx_function_requires(_LessThanComparableConcept<
6312e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
6313e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
6314e4b17023SJohn Marino
6315e4b17023SJohn Marino if (__first == __last)
6316e4b17023SJohn Marino return __first;
6317e4b17023SJohn Marino _ForwardIterator __result = __first;
6318e4b17023SJohn Marino while (++__first != __last)
6319e4b17023SJohn Marino if (*__result < *__first)
6320e4b17023SJohn Marino __result = __first;
6321e4b17023SJohn Marino return __result;
6322e4b17023SJohn Marino }
6323e4b17023SJohn Marino
6324e4b17023SJohn Marino /**
6325e4b17023SJohn Marino * @brief Return the maximum element in a range using comparison functor.
6326e4b17023SJohn Marino * @ingroup sorting_algorithms
6327e4b17023SJohn Marino * @param __first Start of range.
6328e4b17023SJohn Marino * @param __last End of range.
6329e4b17023SJohn Marino * @param __comp Comparison functor.
6330e4b17023SJohn Marino * @return Iterator referencing the first instance of the largest value
6331e4b17023SJohn Marino * according to __comp.
6332e4b17023SJohn Marino */
6333e4b17023SJohn Marino template<typename _ForwardIterator, typename _Compare>
6334e4b17023SJohn Marino _ForwardIterator
6335e4b17023SJohn Marino max_element(_ForwardIterator __first, _ForwardIterator __last,
6336e4b17023SJohn Marino _Compare __comp)
6337e4b17023SJohn Marino {
6338e4b17023SJohn Marino // concept requirements
6339e4b17023SJohn Marino __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
6340e4b17023SJohn Marino __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
6341e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type,
6342e4b17023SJohn Marino typename iterator_traits<_ForwardIterator>::value_type>)
6343e4b17023SJohn Marino __glibcxx_requires_valid_range(__first, __last);
6344e4b17023SJohn Marino
6345e4b17023SJohn Marino if (__first == __last) return __first;
6346e4b17023SJohn Marino _ForwardIterator __result = __first;
6347e4b17023SJohn Marino while (++__first != __last)
6348e4b17023SJohn Marino if (__comp(*__result, *__first))
6349e4b17023SJohn Marino __result = __first;
6350e4b17023SJohn Marino return __result;
6351e4b17023SJohn Marino }
6352e4b17023SJohn Marino
6353e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_ALGO
6354e4b17023SJohn Marino } // namespace std
6355e4b17023SJohn Marino
6356e4b17023SJohn Marino #endif /* _STL_ALGO_H */
6357