02d92e3b70
2001-07-17 Stephen M. Webb <stephen@bregmasoft.com>r All occurrences of the __value_type() and __distance_type() functions, which were required to support the HP STL, have been removed along with all the auxiliary forwarding functions that were required to support their use. The __iterator_category() function was pretty much left alone because there was no benefit to removing it and its use made code just a little more readable. Incidences of distance() with nonstandard argument list were replaced by calls to the standard function (only in the files affected by the removal of the other HP functions). The signature of the rotate() algorithm was changed to match the standard. Headers were reformatted under C++STYLE guidelines (indentation, linebreaks, typename keyword). * include/bits/stl_algo.h: replaced __value_type() and __distance_type() with iterator_traits, eliminated auxiliary support functions required to support said function usage. Changed nonstandard distance() call to standard call. * include/bits/stl_algobase.h: Same. * include/bits/stl_heap.h: Same. * include/bits/stl_numeric.h: Same. * include/bits/stl_uninitialized.h: Same. * include/bits/stl_iterator_base_types.h (__value_type()): Removed. (__distance_type()): Removed. (value_type()): Gone. (distance_type()): Done in. (iterator_category()): Hasta la vista, baby. * include/bits/stl_iterator_base_funcs.h (iterator_category()): Replaced with __iterator_category(). * include/backward/iterator.h: moved definition of value_type(), distance_type(), and iterator_category() out of std:: and into here. * testsuite/23_containers/vector_ctor.cc (test03): New testcases. * testsuite/23_containers/vector_modifiers.cc (test03): New testcases. * testsuite/25_algorithms/rotate.cc: New testcase. * testsuite/25_algorithms/copy.cc: New testcase. * testsuite/25_algorithms/sort.cc: Same. * testsuite/25_algorithms/heap.cc: Same. * testsuite/25_algorithms/partition.cc: Same. * testsuite/25_algorithms/binary_search.cc: Same. * testsuite/26_numerics/sum_diff.cc: Ditto. From-SVN: r44117
3607 lines
114 KiB
C++
3607 lines
114 KiB
C++
// Algorithm implimentation -*- C++ -*-
|
|
|
|
// Copyright (C) 2001 Free Software Foundation, Inc.
|
|
//
|
|
// This file is part of the GNU ISO C++ Library. This library is free
|
|
// software; you can redistribute it and/or modify it under the
|
|
// terms of the GNU General Public License as published by the
|
|
// Free Software Foundation; either version 2, or (at your option)
|
|
// any later version.
|
|
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// You should have received a copy of the GNU General Public License along
|
|
// with this library; see the file COPYING. If not, write to the Free
|
|
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
// USA.
|
|
|
|
// As a special exception, you may use this file as part of a free software
|
|
// library without restriction. Specifically, if other files instantiate
|
|
// templates or use macros or inline functions from this file, or you compile
|
|
// this file and link it with other files to produce an executable, this
|
|
// file does not by itself cause the resulting executable to be covered by
|
|
// the GNU General Public License. This exception does not however
|
|
// invalidate any other reasons why the executable file might be covered by
|
|
// the GNU General Public License.
|
|
|
|
/*
|
|
*
|
|
* Copyright (c) 1994
|
|
* Hewlett-Packard Company
|
|
*
|
|
* Permission to use, copy, modify, distribute and sell this software
|
|
* and its documentation for any purpose is hereby granted without fee,
|
|
* provided that the above copyright notice appear in all copies and
|
|
* that both that copyright notice and this permission notice appear
|
|
* in supporting documentation. Hewlett-Packard Company makes no
|
|
* representations about the suitability of this software for any
|
|
* purpose. It is provided "as is" without express or implied warranty.
|
|
*
|
|
*
|
|
* Copyright (c) 1996
|
|
* Silicon Graphics Computer Systems, Inc.
|
|
*
|
|
* Permission to use, copy, modify, distribute and sell this software
|
|
* and its documentation for any purpose is hereby granted without fee,
|
|
* provided that the above copyright notice appear in all copies and
|
|
* that both that copyright notice and this permission notice appear
|
|
* in supporting documentation. Silicon Graphics makes no
|
|
* representations about the suitability of this software for any
|
|
* purpose. It is provided "as is" without express or implied warranty.
|
|
*/
|
|
|
|
/* NOTE: This is an internal header file, included by other STL headers.
|
|
* You should not attempt to use it directly.
|
|
*/
|
|
|
|
#ifndef __SGI_STL_INTERNAL_ALGO_H
|
|
#define __SGI_STL_INTERNAL_ALGO_H
|
|
|
|
#include <bits/stl_heap.h>
|
|
|
|
// See concept_check.h for the __glibcpp_*_requires macros.
|
|
|
|
namespace std
|
|
{
|
|
|
|
// __median (an extension, not present in the C++ standard).
|
|
|
|
template<typename _Tp>
|
|
inline const _Tp&
|
|
__median(const _Tp& __a, const _Tp& __b, const _Tp& __c)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_LessThanComparableConcept<_Tp>);
|
|
if (__a < __b)
|
|
if (__b < __c)
|
|
return __b;
|
|
else if (__a < __c)
|
|
return __c;
|
|
else
|
|
return __a;
|
|
else if (__a < __c)
|
|
return __a;
|
|
else if (__b < __c)
|
|
return __c;
|
|
else
|
|
return __b;
|
|
}
|
|
|
|
template<typename _Tp, typename _Compare>
|
|
inline const _Tp&
|
|
__median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_BinaryFunctionConcept<_Compare, bool, _Tp, _Tp>);
|
|
if (__comp(__a, __b))
|
|
if (__comp(__b, __c))
|
|
return __b;
|
|
else if (__comp(__a, __c))
|
|
return __c;
|
|
else
|
|
return __a;
|
|
else if (__comp(__a, __c))
|
|
return __a;
|
|
else if (__comp(__b, __c))
|
|
return __c;
|
|
else
|
|
return __b;
|
|
}
|
|
|
|
// for_each. Apply a function to every element of a range.
|
|
template<typename _InputIter, typename _Function>
|
|
_Function
|
|
for_each(_InputIter __first, _InputIter __last, _Function __f)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
for ( ; __first != __last; ++__first)
|
|
__f(*__first);
|
|
return __f;
|
|
}
|
|
|
|
// find and find_if.
|
|
|
|
template<typename _InputIter, typename _Tp>
|
|
inline _InputIter
|
|
find(_InputIter __first, _InputIter __last,
|
|
const _Tp& __val,
|
|
input_iterator_tag)
|
|
{
|
|
while (__first != __last && !(*__first == __val))
|
|
++__first;
|
|
return __first;
|
|
}
|
|
|
|
template<typename _InputIter, typename _Predicate>
|
|
inline _InputIter
|
|
find_if(_InputIter __first, _InputIter __last,
|
|
_Predicate __pred,
|
|
input_iterator_tag)
|
|
{
|
|
while (__first != __last && !__pred(*__first))
|
|
++__first;
|
|
return __first;
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Tp>
|
|
_RandomAccessIter
|
|
find(_RandomAccessIter __first, _RandomAccessIter __last,
|
|
const _Tp& __val,
|
|
random_access_iterator_tag)
|
|
{
|
|
typename iterator_traits<_RandomAccessIter>::difference_type __trip_count
|
|
= (__last - __first) >> 2;
|
|
|
|
for ( ; __trip_count > 0 ; --__trip_count) {
|
|
if (*__first == __val) return __first;
|
|
++__first;
|
|
|
|
if (*__first == __val) return __first;
|
|
++__first;
|
|
|
|
if (*__first == __val) return __first;
|
|
++__first;
|
|
|
|
if (*__first == __val) return __first;
|
|
++__first;
|
|
}
|
|
|
|
switch(__last - __first) {
|
|
case 3:
|
|
if (*__first == __val) return __first;
|
|
++__first;
|
|
case 2:
|
|
if (*__first == __val) return __first;
|
|
++__first;
|
|
case 1:
|
|
if (*__first == __val) return __first;
|
|
++__first;
|
|
case 0:
|
|
default:
|
|
return __last;
|
|
}
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Predicate>
|
|
_RandomAccessIter
|
|
find_if(_RandomAccessIter __first, _RandomAccessIter __last,
|
|
_Predicate __pred,
|
|
random_access_iterator_tag)
|
|
{
|
|
typename iterator_traits<_RandomAccessIter>::difference_type __trip_count
|
|
= (__last - __first) >> 2;
|
|
|
|
for ( ; __trip_count > 0 ; --__trip_count) {
|
|
if (__pred(*__first)) return __first;
|
|
++__first;
|
|
|
|
if (__pred(*__first)) return __first;
|
|
++__first;
|
|
|
|
if (__pred(*__first)) return __first;
|
|
++__first;
|
|
|
|
if (__pred(*__first)) return __first;
|
|
++__first;
|
|
}
|
|
|
|
switch(__last - __first) {
|
|
case 3:
|
|
if (__pred(*__first)) return __first;
|
|
++__first;
|
|
case 2:
|
|
if (__pred(*__first)) return __first;
|
|
++__first;
|
|
case 1:
|
|
if (__pred(*__first)) return __first;
|
|
++__first;
|
|
case 0:
|
|
default:
|
|
return __last;
|
|
}
|
|
}
|
|
|
|
template<typename _InputIter, typename _Tp>
|
|
inline _InputIter
|
|
find(_InputIter __first, _InputIter __last,
|
|
const _Tp& __val)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
__glibcpp_function_requires(_EqualOpConcept<
|
|
typename iterator_traits<_InputIter>::value_type, _Tp>);
|
|
return find(__first, __last, __val, __iterator_category(__first));
|
|
}
|
|
|
|
template<typename _InputIter, typename _Predicate>
|
|
inline _InputIter
|
|
find_if(_InputIter __first, _InputIter __last,
|
|
_Predicate __pred)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
__glibcpp_function_requires(_UnaryPredicateConcept<_Predicate,
|
|
typename iterator_traits<_InputIter>::value_type>);
|
|
return find_if(__first, __last, __pred, __iterator_category(__first));
|
|
}
|
|
|
|
// adjacent_find.
|
|
|
|
template<typename _ForwardIter>
|
|
_ForwardIter
|
|
adjacent_find(_ForwardIter __first, _ForwardIter __last)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_EqualityComparableConcept<
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
if (__first == __last)
|
|
return __last;
|
|
_ForwardIter __next = __first;
|
|
while(++__next != __last) {
|
|
if (*__first == *__next)
|
|
return __first;
|
|
__first = __next;
|
|
}
|
|
return __last;
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _BinaryPredicate>
|
|
_ForwardIter
|
|
adjacent_find(_ForwardIter __first, _ForwardIter __last,
|
|
_BinaryPredicate __binary_pred)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
|
|
typename iterator_traits<_ForwardIter>::value_type,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
if (__first == __last)
|
|
return __last;
|
|
_ForwardIter __next = __first;
|
|
while(++__next != __last) {
|
|
if (__binary_pred(*__first, *__next))
|
|
return __first;
|
|
__first = __next;
|
|
}
|
|
return __last;
|
|
}
|
|
|
|
// count and count_if. There are two version of each, one whose return type
|
|
// type is void and one (present only if we have partial specialization)
|
|
// whose return type is iterator_traits<_InputIter>::difference_type. The
|
|
// C++ standard only has the latter version, but the former, which was present
|
|
// in the HP STL, is retained for backward compatibility.
|
|
|
|
template<typename _InputIter, typename _Tp, typename _Size>
|
|
void
|
|
count(_InputIter __first, _InputIter __last,
|
|
const _Tp& __value,
|
|
_Size& __n)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
__glibcpp_function_requires(_EqualityComparableConcept<
|
|
typename iterator_traits<_InputIter>::value_type >);
|
|
__glibcpp_function_requires(_EqualityComparableConcept<_Tp>);
|
|
for ( ; __first != __last; ++__first)
|
|
if (*__first == __value)
|
|
++__n;
|
|
}
|
|
|
|
template<typename _InputIter, typename _Predicate, typename _Size>
|
|
void
|
|
count_if(_InputIter __first, _InputIter __last,
|
|
_Predicate __pred,
|
|
_Size& __n)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
__glibcpp_function_requires(_UnaryPredicateConcept<_Predicate,
|
|
typename iterator_traits<_InputIter>::value_type>);
|
|
for ( ; __first != __last; ++__first)
|
|
if (__pred(*__first))
|
|
++__n;
|
|
}
|
|
|
|
template<typename _InputIter, typename _Tp>
|
|
typename iterator_traits<_InputIter>::difference_type
|
|
count(_InputIter __first, _InputIter __last, const _Tp& __value)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
__glibcpp_function_requires(_EqualityComparableConcept<
|
|
typename iterator_traits<_InputIter>::value_type >);
|
|
__glibcpp_function_requires(_EqualityComparableConcept<_Tp>);
|
|
typename iterator_traits<_InputIter>::difference_type __n = 0;
|
|
for ( ; __first != __last; ++__first)
|
|
if (*__first == __value)
|
|
++__n;
|
|
return __n;
|
|
}
|
|
|
|
template<typename _InputIter, typename _Predicate>
|
|
typename iterator_traits<_InputIter>::difference_type
|
|
count_if(_InputIter __first, _InputIter __last, _Predicate __pred)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
__glibcpp_function_requires(_UnaryPredicateConcept<_Predicate,
|
|
typename iterator_traits<_InputIter>::value_type>);
|
|
typename iterator_traits<_InputIter>::difference_type __n = 0;
|
|
for ( ; __first != __last; ++__first)
|
|
if (__pred(*__first))
|
|
++__n;
|
|
return __n;
|
|
}
|
|
|
|
|
|
// search.
|
|
|
|
template<typename _ForwardIter1, typename _ForwardIter2>
|
|
_ForwardIter1
|
|
search(_ForwardIter1 __first1, _ForwardIter1 __last1,
|
|
_ForwardIter2 __first2, _ForwardIter2 __last2)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter1>);
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter2>);
|
|
__glibcpp_function_requires(_EqualOpConcept<
|
|
typename iterator_traits<_ForwardIter1>::value_type,
|
|
typename iterator_traits<_ForwardIter2>::value_type>);
|
|
|
|
// Test for empty ranges
|
|
if (__first1 == __last1 || __first2 == __last2)
|
|
return __first1;
|
|
|
|
// Test for a pattern of length 1.
|
|
_ForwardIter2 __tmp(__first2);
|
|
++__tmp;
|
|
if (__tmp == __last2)
|
|
return find(__first1, __last1, *__first2);
|
|
|
|
// General case.
|
|
|
|
_ForwardIter2 __p1, __p;
|
|
|
|
__p1 = __first2; ++__p1;
|
|
|
|
_ForwardIter1 __current = __first1;
|
|
|
|
while (__first1 != __last1) {
|
|
__first1 = find(__first1, __last1, *__first2);
|
|
if (__first1 == __last1)
|
|
return __last1;
|
|
|
|
__p = __p1;
|
|
__current = __first1;
|
|
if (++__current == __last1)
|
|
return __last1;
|
|
|
|
while (*__current == *__p) {
|
|
if (++__p == __last2)
|
|
return __first1;
|
|
if (++__current == __last1)
|
|
return __last1;
|
|
}
|
|
|
|
++__first1;
|
|
}
|
|
return __first1;
|
|
}
|
|
|
|
template<typename _ForwardIter1, typename _ForwardIter2, typename _BinaryPred>
|
|
_ForwardIter1
|
|
search(_ForwardIter1 __first1, _ForwardIter1 __last1,
|
|
_ForwardIter2 __first2, _ForwardIter2 __last2,
|
|
_BinaryPred __predicate)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter1>);
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter2>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPred,
|
|
typename iterator_traits<_ForwardIter1>::value_type,
|
|
typename iterator_traits<_ForwardIter2>::value_type>);
|
|
|
|
// Test for empty ranges
|
|
if (__first1 == __last1 || __first2 == __last2)
|
|
return __first1;
|
|
|
|
// Test for a pattern of length 1.
|
|
_ForwardIter2 __tmp(__first2);
|
|
++__tmp;
|
|
if (__tmp == __last2) {
|
|
while (__first1 != __last1 && !__predicate(*__first1, *__first2))
|
|
++__first1;
|
|
return __first1;
|
|
}
|
|
|
|
// General case.
|
|
|
|
_ForwardIter2 __p1, __p;
|
|
|
|
__p1 = __first2; ++__p1;
|
|
|
|
_ForwardIter1 __current = __first1;
|
|
|
|
while (__first1 != __last1) {
|
|
while (__first1 != __last1) {
|
|
if (__predicate(*__first1, *__first2))
|
|
break;
|
|
++__first1;
|
|
}
|
|
while (__first1 != __last1 && !__predicate(*__first1, *__first2))
|
|
++__first1;
|
|
if (__first1 == __last1)
|
|
return __last1;
|
|
|
|
__p = __p1;
|
|
__current = __first1;
|
|
if (++__current == __last1) return __last1;
|
|
|
|
while (__predicate(*__current, *__p)) {
|
|
if (++__p == __last2)
|
|
return __first1;
|
|
if (++__current == __last1)
|
|
return __last1;
|
|
}
|
|
|
|
++__first1;
|
|
}
|
|
return __first1;
|
|
}
|
|
|
|
// search_n. Search for __count consecutive copies of __val.
|
|
|
|
template<typename _ForwardIter, typename _Integer, typename _Tp>
|
|
_ForwardIter
|
|
search_n(_ForwardIter __first, _ForwardIter __last,
|
|
_Integer __count, const _Tp& __val)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_EqualityComparableConcept<
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
__glibcpp_function_requires(_EqualityComparableConcept<_Tp>);
|
|
|
|
if (__count <= 0)
|
|
return __first;
|
|
else {
|
|
__first = find(__first, __last, __val);
|
|
while (__first != __last) {
|
|
_Integer __n = __count - 1;
|
|
_ForwardIter __i = __first;
|
|
++__i;
|
|
while (__i != __last && __n != 0 && *__i == __val) {
|
|
++__i;
|
|
--__n;
|
|
}
|
|
if (__n == 0)
|
|
return __first;
|
|
else
|
|
__first = find(__i, __last, __val);
|
|
}
|
|
return __last;
|
|
}
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _Integer, typename _Tp,
|
|
typename _BinaryPred>
|
|
_ForwardIter
|
|
search_n(_ForwardIter __first, _ForwardIter __last,
|
|
_Integer __count, const _Tp& __val,
|
|
_BinaryPred __binary_pred)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPred,
|
|
typename iterator_traits<_ForwardIter>::value_type, _Tp>);
|
|
|
|
if (__count <= 0)
|
|
return __first;
|
|
else {
|
|
while (__first != __last) {
|
|
if (__binary_pred(*__first, __val))
|
|
break;
|
|
++__first;
|
|
}
|
|
while (__first != __last) {
|
|
_Integer __n = __count - 1;
|
|
_ForwardIter __i = __first;
|
|
++__i;
|
|
while (__i != __last && __n != 0 && __binary_pred(*__i, __val)) {
|
|
++__i;
|
|
--__n;
|
|
}
|
|
if (__n == 0)
|
|
return __first;
|
|
else {
|
|
while (__i != __last) {
|
|
if (__binary_pred(*__i, __val))
|
|
break;
|
|
++__i;
|
|
}
|
|
__first = __i;
|
|
}
|
|
}
|
|
return __last;
|
|
}
|
|
}
|
|
|
|
// swap_ranges
|
|
|
|
template<typename _ForwardIter1, typename _ForwardIter2>
|
|
_ForwardIter2
|
|
swap_ranges(_ForwardIter1 __first1, _ForwardIter1 __last1,
|
|
_ForwardIter2 __first2)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter1>);
|
|
__glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter2>);
|
|
__glibcpp_function_requires(_ConvertibleConcept<
|
|
typename iterator_traits<_ForwardIter1>::value_type,
|
|
typename iterator_traits<_ForwardIter2>::value_type>);
|
|
__glibcpp_function_requires(_ConvertibleConcept<
|
|
typename iterator_traits<_ForwardIter2>::value_type,
|
|
typename iterator_traits<_ForwardIter1>::value_type>);
|
|
|
|
for ( ; __first1 != __last1; ++__first1, ++__first2)
|
|
iter_swap(__first1, __first2);
|
|
return __first2;
|
|
}
|
|
|
|
// transform
|
|
|
|
template<typename _InputIter, typename _OutputIter, typename _UnaryOperation>
|
|
_OutputIter
|
|
transform(_InputIter __first, _InputIter __last,
|
|
_OutputIter __result, _UnaryOperation __unary_op)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
/* XXX
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
// should be "the type returned by _UnaryOperation"
|
|
typename iterator_traits<_InputIter>::value_type>);
|
|
*/
|
|
|
|
for ( ; __first != __last; ++__first, ++__result)
|
|
*__result = __unary_op(*__first);
|
|
return __result;
|
|
}
|
|
|
|
template<typename _InputIter1, typename _InputIter2, typename _OutputIter,
|
|
typename _BinaryOperation>
|
|
_OutputIter
|
|
transform(_InputIter1 __first1, _InputIter1 __last1,
|
|
_InputIter2 __first2, _OutputIter __result,
|
|
_BinaryOperation __binary_op)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter1>);
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter2>);
|
|
/* XXX
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
// should be "the type returned by _BinaryOperation"
|
|
typename iterator_traits<_InputIter1>::value_type>);
|
|
*/
|
|
|
|
for ( ; __first1 != __last1; ++__first1, ++__first2, ++__result)
|
|
*__result = __binary_op(*__first1, *__first2);
|
|
return __result;
|
|
}
|
|
|
|
// replace, replace_if, replace_copy, replace_copy_if
|
|
|
|
template<typename _ForwardIter, typename _Tp>
|
|
void
|
|
replace(_ForwardIter __first, _ForwardIter __last,
|
|
const _Tp& __old_value, const _Tp& __new_value)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_EqualOpConcept<
|
|
typename iterator_traits<_ForwardIter>::value_type, _Tp>);
|
|
__glibcpp_function_requires(_ConvertibleConcept<_Tp,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
|
|
for ( ; __first != __last; ++__first)
|
|
if (*__first == __old_value)
|
|
*__first = __new_value;
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _Predicate, typename _Tp>
|
|
void
|
|
replace_if(_ForwardIter __first, _ForwardIter __last,
|
|
_Predicate __pred, const _Tp& __new_value)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_ConvertibleConcept<_Tp,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
__glibcpp_function_requires(_UnaryPredicateConcept<_Predicate,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
|
|
for ( ; __first != __last; ++__first)
|
|
if (__pred(*__first))
|
|
*__first = __new_value;
|
|
}
|
|
|
|
template<typename _InputIter, typename _OutputIter, typename _Tp>
|
|
_OutputIter
|
|
replace_copy(_InputIter __first, _InputIter __last,
|
|
_OutputIter __result,
|
|
const _Tp& __old_value, const _Tp& __new_value)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_InputIter>::value_type>);
|
|
__glibcpp_function_requires(_EqualOpConcept<
|
|
typename iterator_traits<_InputIter>::value_type, _Tp>);
|
|
|
|
for ( ; __first != __last; ++__first, ++__result)
|
|
*__result = *__first == __old_value ? __new_value : *__first;
|
|
return __result;
|
|
}
|
|
|
|
template<typename _InputIter, typename _OutputIter, typename _Predicate,
|
|
typename _Tp>
|
|
_OutputIter
|
|
replace_copy_if(_InputIter __first, _InputIter __last,
|
|
_OutputIter __result,
|
|
_Predicate __pred, const _Tp& __new_value)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_InputIter>::value_type>);
|
|
__glibcpp_function_requires(_UnaryPredicateConcept<_Predicate,
|
|
typename iterator_traits<_InputIter>::value_type>);
|
|
|
|
for ( ; __first != __last; ++__first, ++__result)
|
|
*__result = __pred(*__first) ? __new_value : *__first;
|
|
return __result;
|
|
}
|
|
|
|
// generate and generate_n
|
|
|
|
template<typename _ForwardIter, typename _Generator>
|
|
void
|
|
generate(_ForwardIter __first, _ForwardIter __last, _Generator __gen)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_GeneratorConcept<_Generator,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
|
|
for ( ; __first != __last; ++__first)
|
|
*__first = __gen();
|
|
}
|
|
|
|
template<typename _OutputIter, typename _Size, typename _Generator>
|
|
_OutputIter
|
|
generate_n(_OutputIter __first, _Size __n, _Generator __gen)
|
|
{
|
|
/*
|
|
// XXX concept requirements
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
"the return type of _Generator" ?? >);
|
|
*/
|
|
|
|
for ( ; __n > 0; --__n, ++__first)
|
|
*__first = __gen();
|
|
return __first;
|
|
}
|
|
|
|
// remove, remove_if, remove_copy, remove_copy_if
|
|
|
|
template<typename _InputIter, typename _OutputIter, typename _Tp>
|
|
_OutputIter
|
|
remove_copy(_InputIter __first, _InputIter __last,
|
|
_OutputIter __result, const _Tp& __value)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_InputIter>::value_type>);
|
|
__glibcpp_function_requires(_EqualOpConcept<
|
|
typename iterator_traits<_InputIter>::value_type, _Tp>);
|
|
|
|
for ( ; __first != __last; ++__first)
|
|
if (!(*__first == __value)) {
|
|
*__result = *__first;
|
|
++__result;
|
|
}
|
|
return __result;
|
|
}
|
|
|
|
template<typename _InputIter, typename _OutputIter, typename _Predicate>
|
|
_OutputIter
|
|
remove_copy_if(_InputIter __first, _InputIter __last,
|
|
_OutputIter __result, _Predicate __pred)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_InputIter>::value_type>);
|
|
__glibcpp_function_requires(_UnaryPredicateConcept<_Predicate,
|
|
typename iterator_traits<_InputIter>::value_type>);
|
|
|
|
for ( ; __first != __last; ++__first)
|
|
if (!__pred(*__first)) {
|
|
*__result = *__first;
|
|
++__result;
|
|
}
|
|
return __result;
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _Tp>
|
|
_ForwardIter
|
|
remove(_ForwardIter __first, _ForwardIter __last,
|
|
const _Tp& __value)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_ConvertibleConcept<_Tp,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
__glibcpp_function_requires(_EqualOpConcept<
|
|
typename iterator_traits<_ForwardIter>::value_type, _Tp>);
|
|
|
|
__first = find(__first, __last, __value);
|
|
_ForwardIter __i = __first;
|
|
return __first == __last ? __first
|
|
: remove_copy(++__i, __last, __first, __value);
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _Predicate>
|
|
_ForwardIter
|
|
remove_if(_ForwardIter __first, _ForwardIter __last,
|
|
_Predicate __pred)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_UnaryPredicateConcept<_Predicate,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
|
|
__first = find_if(__first, __last, __pred);
|
|
_ForwardIter __i = __first;
|
|
return __first == __last ? __first
|
|
: remove_copy_if(++__i, __last, __first, __pred);
|
|
}
|
|
|
|
template<typename _InputIter, typename _OutputIter>
|
|
_OutputIter
|
|
__unique_copy(_InputIter __first, _InputIter __last,
|
|
_OutputIter __result,
|
|
output_iterator_tag)
|
|
{
|
|
// concept requirements -- taken care of in dispatching function
|
|
typename iterator_traits<_InputIter>::value_type __value = *__first;
|
|
*__result = __value;
|
|
while (++__first != __last)
|
|
if (!(__value == *__first)) {
|
|
__value = *__first;
|
|
*++__result = __value;
|
|
}
|
|
return ++__result;
|
|
}
|
|
|
|
template<typename _InputIter, typename _ForwardIter>
|
|
_ForwardIter
|
|
__unique_copy(_InputIter __first, _InputIter __last,
|
|
_ForwardIter __result,
|
|
forward_iterator_tag)
|
|
{
|
|
// concept requirements -- taken care of in dispatching function
|
|
*__result = *__first;
|
|
while (++__first != __last)
|
|
if (!(*__result == *__first))
|
|
*++__result = *__first;
|
|
return ++__result;
|
|
}
|
|
|
|
template<typename _InputIter, typename _OutputIter>
|
|
inline _OutputIter
|
|
unique_copy(_InputIter __first, _InputIter __last,
|
|
_OutputIter __result)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_InputIter>::value_type>);
|
|
__glibcpp_function_requires(_EqualityComparableConcept<
|
|
typename iterator_traits<_InputIter>::value_type>);
|
|
|
|
typedef typename iterator_traits<_OutputIter>::iterator_catgeory _IterType;
|
|
|
|
if (__first == __last) return __result;
|
|
return __unique_copy(__first, __last, __result, _IterType());
|
|
}
|
|
|
|
template<typename _InputIter, typename _OutputIter, typename _BinaryPredicate>
|
|
_OutputIter
|
|
__unique_copy(_InputIter __first, _InputIter __last,
|
|
_OutputIter __result,
|
|
_BinaryPredicate __binary_pred,
|
|
output_iterator_tag)
|
|
{
|
|
// concept requirements -- iterators already checked
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
|
|
typename iterator_traits<_InputIter>::value_type,
|
|
typename iterator_traits<_InputIter>::value_type>);
|
|
|
|
typename iterator_traits<_InputIter>::value_type __value = *__first;
|
|
*__result = __value;
|
|
while (++__first != __last)
|
|
if (!__binary_pred(__value, *__first)) {
|
|
__value = *__first;
|
|
*++__result = __value;
|
|
}
|
|
return ++__result;
|
|
}
|
|
|
|
template<typename _InputIter, typename _ForwardIter, typename _BinaryPredicate>
|
|
_ForwardIter
|
|
__unique_copy(_InputIter __first, _InputIter __last,
|
|
_ForwardIter __result,
|
|
_BinaryPredicate __binary_pred,
|
|
forward_iterator_tag)
|
|
{
|
|
// concept requirements -- iterators already checked
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
|
|
typename iterator_traits<_ForwardIter>::value_type,
|
|
typename iterator_traits<_InputIter>::value_type>);
|
|
|
|
*__result = *__first;
|
|
while (++__first != __last)
|
|
if (!__binary_pred(*__result, *__first)) *++__result = *__first;
|
|
return ++__result;
|
|
}
|
|
|
|
template<typename _InputIter, typename _OutputIter, typename _BinaryPredicate>
|
|
inline _OutputIter
|
|
unique_copy(_InputIter __first, _InputIter __last,
|
|
_OutputIter __result,
|
|
_BinaryPredicate __binary_pred)
|
|
{
|
|
// concept requirements -- predicates checked later
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_InputIter>::value_type>);
|
|
|
|
typedef typename iterator_traits<_OutputIter>::iterator_catgeory _IterType;
|
|
|
|
if (__first == __last) return __result;
|
|
return __unique_copy(__first, __last, __result, __binary_pred, _IterType());
|
|
}
|
|
|
|
template<typename _ForwardIter>
|
|
_ForwardIter
|
|
unique(_ForwardIter __first, _ForwardIter __last)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_EqualityComparableConcept<
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
|
|
__first = adjacent_find(__first, __last);
|
|
return unique_copy(__first, __last, __first);
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _BinaryPredicate>
|
|
_ForwardIter
|
|
unique(_ForwardIter __first, _ForwardIter __last,
|
|
_BinaryPredicate __binary_pred)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
|
|
typename iterator_traits<_ForwardIter>::value_type,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
|
|
__first = adjacent_find(__first, __last, __binary_pred);
|
|
return unique_copy(__first, __last, __first, __binary_pred);
|
|
}
|
|
|
|
template<typename _BidirectionalIter>
|
|
void
|
|
__reverse(_BidirectionalIter __first, _BidirectionalIter __last,
|
|
bidirectional_iterator_tag)
|
|
{
|
|
while (true)
|
|
if (__first == __last || __first == --__last)
|
|
return;
|
|
else
|
|
iter_swap(__first++, __last);
|
|
}
|
|
|
|
template<typename _RandomAccessIter>
|
|
void
|
|
__reverse(_RandomAccessIter __first, _RandomAccessIter __last,
|
|
random_access_iterator_tag)
|
|
{
|
|
while (__first < __last)
|
|
iter_swap(__first++, --__last);
|
|
}
|
|
|
|
template<typename _BidirectionalIter>
|
|
inline void
|
|
reverse(_BidirectionalIter __first, _BidirectionalIter __last)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_BidirectionalIteratorConcept<
|
|
_BidirectionalIter>);
|
|
__reverse(__first, __last, __iterator_category(__first));
|
|
}
|
|
|
|
template<typename _BidirectionalIter, typename _OutputIter>
|
|
_OutputIter
|
|
reverse_copy(_BidirectionalIter __first, _BidirectionalIter __last,
|
|
_OutputIter __result)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_BidirectionalIter>::value_type>);
|
|
|
|
while (__first != __last) {
|
|
--__last;
|
|
*__result = *__last;
|
|
++__result;
|
|
}
|
|
return __result;
|
|
}
|
|
|
|
/// This is a helper function for the rotate algorithm specialized on RAIs.
|
|
|
|
template<typename _EuclideanRingElement>
|
|
_EuclideanRingElement
|
|
__gcd(_EuclideanRingElement __m, _EuclideanRingElement __n)
|
|
{
|
|
while (__n != 0) {
|
|
_EuclideanRingElement __t = __m % __n;
|
|
__m = __n;
|
|
__n = __t;
|
|
}
|
|
return __m;
|
|
}
|
|
|
|
template<typename _ForwardIter>
|
|
void
|
|
__rotate(_ForwardIter __first,
|
|
_ForwardIter __middle,
|
|
_ForwardIter __last,
|
|
forward_iterator_tag)
|
|
{
|
|
if ((__first == __middle) || (__last == __middle))
|
|
return;
|
|
|
|
_ForwardIter __first2 = __middle;
|
|
do {
|
|
swap(*__first++, *__first2++);
|
|
if (__first == __middle)
|
|
__middle = __first2;
|
|
} while (__first2 != __last);
|
|
|
|
__first2 = __middle;
|
|
|
|
while (__first2 != __last) {
|
|
swap(*__first++, *__first2++);
|
|
if (__first == __middle)
|
|
__middle = __first2;
|
|
else if (__first2 == __last)
|
|
__first2 = __middle;
|
|
}
|
|
}
|
|
|
|
template<typename _BidirectionalIter>
|
|
void
|
|
__rotate(_BidirectionalIter __first,
|
|
_BidirectionalIter __middle,
|
|
_BidirectionalIter __last,
|
|
bidirectional_iterator_tag)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_BidirectionalIteratorConcept<
|
|
_BidirectionalIter>);
|
|
|
|
if ((__first == __middle) || (__last == __middle))
|
|
return;
|
|
|
|
__reverse(__first, __middle, bidirectional_iterator_tag());
|
|
__reverse(__middle, __last, bidirectional_iterator_tag());
|
|
|
|
while (__first != __middle && __middle != __last)
|
|
swap (*__first++, *--__last);
|
|
|
|
if (__first == __middle) {
|
|
__reverse(__middle, __last, bidirectional_iterator_tag());
|
|
}
|
|
else {
|
|
__reverse(__first, __middle, bidirectional_iterator_tag());
|
|
}
|
|
}
|
|
|
|
template<typename _RandomAccessIter>
|
|
void
|
|
__rotate(_RandomAccessIter __first,
|
|
_RandomAccessIter __middle,
|
|
_RandomAccessIter __last,
|
|
random_access_iterator_tag)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
|
|
_RandomAccessIter>);
|
|
|
|
if ((__first == __middle) || (__last == __middle))
|
|
return;
|
|
|
|
typedef typename iterator_traits<_RandomAccessIter>::difference_type _Distance;
|
|
typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
|
|
|
|
_Distance __n = __last - __first;
|
|
_Distance __k = __middle - __first;
|
|
_Distance __l = __n - __k;
|
|
|
|
if (__k == __l) {
|
|
swap_ranges(__first, __middle, __middle);
|
|
return;
|
|
}
|
|
|
|
_Distance __d = __gcd(__n, __k);
|
|
|
|
for (_Distance __i = 0; __i < __d; __i++) {
|
|
_ValueType __tmp = *__first;
|
|
_RandomAccessIter __p = __first;
|
|
|
|
if (__k < __l) {
|
|
for (_Distance __j = 0; __j < __l/__d; __j++) {
|
|
if (__p > __first + __l) {
|
|
*__p = *(__p - __l);
|
|
__p -= __l;
|
|
}
|
|
|
|
*__p = *(__p + __k);
|
|
__p += __k;
|
|
}
|
|
}
|
|
|
|
else {
|
|
for (_Distance __j = 0; __j < __k/__d - 1; __j ++) {
|
|
if (__p < __last - __k) {
|
|
*__p = *(__p + __k);
|
|
__p += __k;
|
|
}
|
|
|
|
*__p = * (__p - __l);
|
|
__p -= __l;
|
|
}
|
|
}
|
|
|
|
*__p = __tmp;
|
|
++__first;
|
|
}
|
|
}
|
|
|
|
template<typename _ForwardIter>
|
|
inline void
|
|
rotate(_ForwardIter __first, _ForwardIter __middle, _ForwardIter __last)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>);
|
|
|
|
typedef typename iterator_traits<_ForwardIter>::iterator_category _IterType;
|
|
__rotate(__first, __middle, __last, _IterType());
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _OutputIter>
|
|
_OutputIter
|
|
rotate_copy(_ForwardIter __first, _ForwardIter __middle,
|
|
_ForwardIter __last, _OutputIter __result)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
|
|
return copy(__first, __middle, copy(__middle, __last, __result));
|
|
}
|
|
|
|
// Return a random number in the range [0, __n). This function encapsulates
|
|
// whether we're using rand (part of the standard C library) or lrand48
|
|
// (not standard, but a much better choice whenever it's available).
|
|
template<typename _Distance>
|
|
inline _Distance
|
|
__random_number(_Distance __n)
|
|
{
|
|
#ifdef _GLIBCPP_HAVE_DRAND48
|
|
return lrand48() % __n;
|
|
#else
|
|
return rand() % __n;
|
|
#endif
|
|
}
|
|
|
|
/// 25.2.11 random_shuffle().
|
|
|
|
template<typename _RandomAccessIter>
|
|
inline void
|
|
random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
|
|
_RandomAccessIter>);
|
|
|
|
if (__first == __last) return;
|
|
for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
|
|
iter_swap(__i, __first + __random_number((__i - __first) + 1));
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _RandomNumberGenerator>
|
|
void
|
|
random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last,
|
|
_RandomNumberGenerator& __rand)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
|
|
_RandomAccessIter>);
|
|
|
|
if (__first == __last) return;
|
|
for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
|
|
iter_swap(__i, __first + __rand((__i - __first) + 1));
|
|
}
|
|
|
|
// random_sample and random_sample_n (extensions, not part of the standard).
|
|
|
|
template<typename _ForwardIter, typename _OutputIter, typename _Distance>
|
|
_OutputIter
|
|
random_sample_n(_ForwardIter __first, _ForwardIter __last,
|
|
_OutputIter __out, const _Distance __n)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
|
|
_Distance __remaining = distance(__first, __last);
|
|
_Distance __m = min(__n, __remaining);
|
|
|
|
while (__m > 0) {
|
|
if (__random_number(__remaining) < __m) {
|
|
*__out = *__first;
|
|
++__out;
|
|
--__m;
|
|
}
|
|
|
|
--__remaining;
|
|
++__first;
|
|
}
|
|
return __out;
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _OutputIter, typename _Distance,
|
|
typename _RandomNumberGenerator>
|
|
_OutputIter
|
|
random_sample_n(_ForwardIter __first, _ForwardIter __last,
|
|
_OutputIter __out, const _Distance __n,
|
|
_RandomNumberGenerator& __rand)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
__glibcpp_function_requires(_UnaryFunctionConcept<
|
|
_RandomNumberGenerator, _Distance, _Distance>);
|
|
|
|
_Distance __remaining = distance(__first, __last);
|
|
_Distance __m = min(__n, __remaining);
|
|
|
|
while (__m > 0) {
|
|
if (__rand(__remaining) < __m) {
|
|
*__out = *__first;
|
|
++__out;
|
|
--__m;
|
|
}
|
|
|
|
--__remaining;
|
|
++__first;
|
|
}
|
|
return __out;
|
|
}
|
|
|
|
template<typename _InputIter, typename _RandomAccessIter, typename _Distance>
|
|
_RandomAccessIter
|
|
__random_sample(_InputIter __first, _InputIter __last,
|
|
_RandomAccessIter __out,
|
|
const _Distance __n)
|
|
{
|
|
_Distance __m = 0;
|
|
_Distance __t = __n;
|
|
for ( ; __first != __last && __m < __n; ++__m, ++__first)
|
|
__out[__m] = *__first;
|
|
|
|
while (__first != __last) {
|
|
++__t;
|
|
_Distance __M = __random_number(__t);
|
|
if (__M < __n)
|
|
__out[__M] = *__first;
|
|
++__first;
|
|
}
|
|
|
|
return __out + __m;
|
|
}
|
|
|
|
template<typename _InputIter, typename _RandomAccessIter,
|
|
typename _RandomNumberGenerator, typename _Distance>
|
|
_RandomAccessIter
|
|
__random_sample(_InputIter __first, _InputIter __last,
|
|
_RandomAccessIter __out,
|
|
_RandomNumberGenerator& __rand,
|
|
const _Distance __n)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_UnaryFunctionConcept<
|
|
_RandomNumberGenerator, _Distance, _Distance>);
|
|
|
|
_Distance __m = 0;
|
|
_Distance __t = __n;
|
|
for ( ; __first != __last && __m < __n; ++__m, ++__first)
|
|
__out[__m] = *__first;
|
|
|
|
while (__first != __last) {
|
|
++__t;
|
|
_Distance __M = __rand(__t);
|
|
if (__M < __n)
|
|
__out[__M] = *__first;
|
|
++__first;
|
|
}
|
|
|
|
return __out + __m;
|
|
}
|
|
|
|
template<typename _InputIter, typename _RandomAccessIter>
|
|
inline _RandomAccessIter
|
|
random_sample(_InputIter __first, _InputIter __last,
|
|
_RandomAccessIter __out_first, _RandomAccessIter __out_last)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
__glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
|
|
_RandomAccessIter>);
|
|
|
|
return __random_sample(__first, __last,
|
|
__out_first, __out_last - __out_first);
|
|
}
|
|
|
|
|
|
template<typename _InputIter, typename _RandomAccessIter,
|
|
typename _RandomNumberGenerator>
|
|
inline _RandomAccessIter
|
|
random_sample(_InputIter __first, _InputIter __last,
|
|
_RandomAccessIter __out_first, _RandomAccessIter __out_last,
|
|
_RandomNumberGenerator& __rand)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
__glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
|
|
_RandomAccessIter>);
|
|
|
|
return __random_sample(__first, __last,
|
|
__out_first, __rand,
|
|
__out_last - __out_first);
|
|
}
|
|
|
|
// partition, stable_partition, and their auxiliary functions
|
|
|
|
template<typename _ForwardIter, typename _Predicate>
|
|
_ForwardIter
|
|
__partition(_ForwardIter __first, _ForwardIter __last,
|
|
_Predicate __pred,
|
|
forward_iterator_tag)
|
|
{
|
|
if (__first == __last) return __first;
|
|
|
|
while (__pred(*__first))
|
|
if (++__first == __last) return __first;
|
|
|
|
_ForwardIter __next = __first;
|
|
|
|
while (++__next != __last)
|
|
if (__pred(*__next)) {
|
|
swap(*__first, *__next);
|
|
++__first;
|
|
}
|
|
|
|
return __first;
|
|
}
|
|
|
|
template<typename _BidirectionalIter, typename _Predicate>
|
|
_BidirectionalIter
|
|
__partition(_BidirectionalIter __first, _BidirectionalIter __last,
|
|
_Predicate __pred,
|
|
bidirectional_iterator_tag)
|
|
{
|
|
while (true) {
|
|
while (true)
|
|
if (__first == __last)
|
|
return __first;
|
|
else if (__pred(*__first))
|
|
++__first;
|
|
else
|
|
break;
|
|
--__last;
|
|
while (true)
|
|
if (__first == __last)
|
|
return __first;
|
|
else if (!__pred(*__last))
|
|
--__last;
|
|
else
|
|
break;
|
|
iter_swap(__first, __last);
|
|
++__first;
|
|
}
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _Predicate>
|
|
inline _ForwardIter
|
|
partition(_ForwardIter __first, _ForwardIter __last,
|
|
_Predicate __pred)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_UnaryPredicateConcept<_Predicate,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
|
|
return __partition(__first, __last, __pred, __iterator_category(__first));
|
|
}
|
|
|
|
|
|
template<typename _ForwardIter, typename _Predicate, typename _Distance>
|
|
_ForwardIter
|
|
__inplace_stable_partition(_ForwardIter __first, _ForwardIter __last,
|
|
_Predicate __pred, _Distance __len)
|
|
{
|
|
if (__len == 1)
|
|
return __pred(*__first) ? __last : __first;
|
|
_ForwardIter __middle = __first;
|
|
advance(__middle, __len / 2);
|
|
_ForwardIter __begin = __inplace_stable_partition(__first, __middle,
|
|
__pred,
|
|
__len / 2);
|
|
_ForwardIter __end = __inplace_stable_partition(__middle, __last,
|
|
__pred,
|
|
__len - __len / 2);
|
|
rotate(__begin, __middle, __end);
|
|
advance(__begin, distance(__middle, __end));
|
|
return __begin;
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _Pointer, typename _Predicate,
|
|
typename _Distance>
|
|
_ForwardIter
|
|
__stable_partition_adaptive(_ForwardIter __first, _ForwardIter __last,
|
|
_Predicate __pred, _Distance __len,
|
|
_Pointer __buffer,
|
|
_Distance __buffer_size)
|
|
{
|
|
if (__len <= __buffer_size) {
|
|
_ForwardIter __result1 = __first;
|
|
_Pointer __result2 = __buffer;
|
|
for ( ; __first != __last ; ++__first)
|
|
if (__pred(*__first)) {
|
|
*__result1 = *__first;
|
|
++__result1;
|
|
}
|
|
else {
|
|
*__result2 = *__first;
|
|
++__result2;
|
|
}
|
|
copy(__buffer, __result2, __result1);
|
|
return __result1;
|
|
}
|
|
else {
|
|
_ForwardIter __middle = __first;
|
|
advance(__middle, __len / 2);
|
|
_ForwardIter __begin = __stable_partition_adaptive(__first, __middle,
|
|
__pred,
|
|
__len / 2,
|
|
__buffer, __buffer_size);
|
|
_ForwardIter __end = __stable_partition_adaptive( __middle, __last,
|
|
__pred,
|
|
__len - __len / 2,
|
|
__buffer, __buffer_size);
|
|
rotate(__begin, __middle, __end);
|
|
advance(__begin, distance(__middle, __end));
|
|
return __begin;
|
|
}
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _Predicate>
|
|
_ForwardIter
|
|
stable_partition(_ForwardIter __first, _ForwardIter __last,
|
|
_Predicate __pred)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_UnaryPredicateConcept<_Predicate,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
|
|
if (__first == __last)
|
|
return __first;
|
|
else
|
|
{
|
|
typedef typename iterator_traits<_ForwardIter>::value_type _ValueType;
|
|
typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType;
|
|
|
|
_Temporary_buffer<_ForwardIter, _ValueType> __buf(__first, __last);
|
|
if (__buf.size() > 0)
|
|
return __stable_partition_adaptive(__first, __last, __pred,
|
|
_DistanceType(__buf.requested_size()),
|
|
__buf.begin(), __buf.size());
|
|
else
|
|
return __inplace_stable_partition(__first, __last, __pred,
|
|
_DistanceType(__buf.requested_size()));
|
|
}
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Tp>
|
|
_RandomAccessIter
|
|
__unguarded_partition(_RandomAccessIter __first, _RandomAccessIter __last,
|
|
_Tp __pivot)
|
|
{
|
|
while (true) {
|
|
while (*__first < __pivot)
|
|
++__first;
|
|
--__last;
|
|
while (__pivot < *__last)
|
|
--__last;
|
|
if (!(__first < __last))
|
|
return __first;
|
|
iter_swap(__first, __last);
|
|
++__first;
|
|
}
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Tp, typename _Compare>
|
|
_RandomAccessIter
|
|
__unguarded_partition(_RandomAccessIter __first, _RandomAccessIter __last,
|
|
_Tp __pivot, _Compare __comp)
|
|
{
|
|
while (true) {
|
|
while (__comp(*__first, __pivot))
|
|
++__first;
|
|
--__last;
|
|
while (__comp(__pivot, *__last))
|
|
--__last;
|
|
if (!(__first < __last))
|
|
return __first;
|
|
iter_swap(__first, __last);
|
|
++__first;
|
|
}
|
|
}
|
|
|
|
const int __stl_threshold = 16;
|
|
|
|
// sort() and its auxiliary functions.
|
|
|
|
template<typename _RandomAccessIter, typename _Tp>
|
|
void
|
|
__unguarded_linear_insert(_RandomAccessIter __last, _Tp __val)
|
|
{
|
|
_RandomAccessIter __next = __last;
|
|
--__next;
|
|
while (__val < *__next) {
|
|
*__last = *__next;
|
|
__last = __next;
|
|
--__next;
|
|
}
|
|
*__last = __val;
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Tp, typename _Compare>
|
|
void
|
|
__unguarded_linear_insert(_RandomAccessIter __last, _Tp __val, _Compare __comp)
|
|
{
|
|
_RandomAccessIter __next = __last;
|
|
--__next;
|
|
while (__comp(__val, *__next)) {
|
|
*__last = *__next;
|
|
__last = __next;
|
|
--__next;
|
|
}
|
|
*__last = __val;
|
|
}
|
|
|
|
template<typename _RandomAccessIter>
|
|
void
|
|
__insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last)
|
|
{
|
|
if (__first == __last) return;
|
|
|
|
for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
|
|
{
|
|
typename iterator_traits<_RandomAccessIter>::value_type __val = *__i;
|
|
if (__val < *__first) {
|
|
copy_backward(__first, __i, __i + 1);
|
|
*__first = __val;
|
|
}
|
|
else
|
|
__unguarded_linear_insert(__i, __val);
|
|
}
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Compare>
|
|
void
|
|
__insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last,
|
|
_Compare __comp)
|
|
{
|
|
if (__first == __last) return;
|
|
|
|
for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
|
|
{
|
|
typename iterator_traits<_RandomAccessIter>::value_type __val = *__i;
|
|
if (__comp(__val, *__first)) {
|
|
copy_backward(__first, __i, __i + 1);
|
|
*__first = __val;
|
|
}
|
|
else
|
|
__unguarded_linear_insert(__i, __val, __comp);
|
|
}
|
|
}
|
|
|
|
template<typename _RandomAccessIter>
|
|
inline void
|
|
__unguarded_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last)
|
|
{
|
|
typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
|
|
|
|
for (_RandomAccessIter __i = __first; __i != __last; ++__i)
|
|
__unguarded_linear_insert(__i, _ValueType(*__i));
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Compare>
|
|
inline void
|
|
__unguarded_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last,
|
|
_Compare __comp)
|
|
{
|
|
typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
|
|
|
|
for (_RandomAccessIter __i = __first; __i != __last; ++__i)
|
|
__unguarded_linear_insert(__i, _ValueType(*__i), __comp);
|
|
}
|
|
|
|
template<typename _RandomAccessIter>
|
|
void
|
|
__final_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last)
|
|
{
|
|
if (__last - __first > __stl_threshold) {
|
|
__insertion_sort(__first, __first + __stl_threshold);
|
|
__unguarded_insertion_sort(__first + __stl_threshold, __last);
|
|
}
|
|
else
|
|
__insertion_sort(__first, __last);
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Compare>
|
|
void
|
|
__final_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last,
|
|
_Compare __comp)
|
|
{
|
|
if (__last - __first > __stl_threshold) {
|
|
__insertion_sort(__first, __first + __stl_threshold, __comp);
|
|
__unguarded_insertion_sort(__first + __stl_threshold, __last, __comp);
|
|
}
|
|
else
|
|
__insertion_sort(__first, __last, __comp);
|
|
}
|
|
|
|
template<typename _Size>
|
|
inline _Size
|
|
__lg(_Size __n)
|
|
{
|
|
_Size __k;
|
|
for (__k = 0; __n != 1; __n >>= 1) ++__k;
|
|
return __k;
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Size>
|
|
void
|
|
__introsort_loop(_RandomAccessIter __first, _RandomAccessIter __last,
|
|
_Size __depth_limit)
|
|
{
|
|
typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
|
|
|
|
while (__last - __first > __stl_threshold) {
|
|
if (__depth_limit == 0) {
|
|
partial_sort(__first, __last, __last);
|
|
return;
|
|
}
|
|
--__depth_limit;
|
|
_RandomAccessIter __cut =
|
|
__unguarded_partition(__first, __last,
|
|
_ValueType(__median(*__first,
|
|
*(__first + (__last - __first)/2),
|
|
*(__last - 1))));
|
|
__introsort_loop(__cut, __last, __depth_limit);
|
|
__last = __cut;
|
|
}
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Size, typename _Compare>
|
|
void
|
|
__introsort_loop(_RandomAccessIter __first, _RandomAccessIter __last,
|
|
_Size __depth_limit, _Compare __comp)
|
|
{
|
|
typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
|
|
|
|
while (__last - __first > __stl_threshold) {
|
|
if (__depth_limit == 0) {
|
|
partial_sort(__first, __last, __last, __comp);
|
|
return;
|
|
}
|
|
--__depth_limit;
|
|
_RandomAccessIter __cut =
|
|
__unguarded_partition(__first, __last,
|
|
_ValueType(__median(*__first,
|
|
*(__first + (__last - __first)/2),
|
|
*(__last - 1), __comp)),
|
|
__comp);
|
|
__introsort_loop(__cut, __last, __depth_limit, __comp);
|
|
__last = __cut;
|
|
}
|
|
}
|
|
|
|
template<typename _RandomAccessIter>
|
|
inline void
|
|
sort(_RandomAccessIter __first, _RandomAccessIter __last)
|
|
{
|
|
typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
|
|
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
|
|
_RandomAccessIter>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<_ValueType>);
|
|
|
|
if (__first != __last) {
|
|
__introsort_loop(__first, __last, __lg(__last - __first) * 2);
|
|
__final_insertion_sort(__first, __last);
|
|
}
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Compare>
|
|
inline void
|
|
sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp)
|
|
{
|
|
typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
|
|
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
|
|
_RandomAccessIter>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, _ValueType>);
|
|
|
|
if (__first != __last) {
|
|
__introsort_loop(__first, __last, __lg(__last - __first) * 2, __comp);
|
|
__final_insertion_sort(__first, __last, __comp);
|
|
}
|
|
}
|
|
|
|
// stable_sort() and its auxiliary functions.
|
|
|
|
template<typename _RandomAccessIter>
|
|
void
|
|
__inplace_stable_sort(_RandomAccessIter __first, _RandomAccessIter __last)
|
|
{
|
|
if (__last - __first < 15) {
|
|
__insertion_sort(__first, __last);
|
|
return;
|
|
}
|
|
_RandomAccessIter __middle = __first + (__last - __first) / 2;
|
|
__inplace_stable_sort(__first, __middle);
|
|
__inplace_stable_sort(__middle, __last);
|
|
__merge_without_buffer(__first, __middle, __last,
|
|
__middle - __first,
|
|
__last - __middle);
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Compare>
|
|
void
|
|
__inplace_stable_sort(_RandomAccessIter __first, _RandomAccessIter __last,
|
|
_Compare __comp)
|
|
{
|
|
if (__last - __first < 15) {
|
|
__insertion_sort(__first, __last, __comp);
|
|
return;
|
|
}
|
|
_RandomAccessIter __middle = __first + (__last - __first) / 2;
|
|
__inplace_stable_sort(__first, __middle, __comp);
|
|
__inplace_stable_sort(__middle, __last, __comp);
|
|
__merge_without_buffer(__first, __middle, __last,
|
|
__middle - __first,
|
|
__last - __middle,
|
|
__comp);
|
|
}
|
|
|
|
template<typename _RandomAccessIter1, typename _RandomAccessIter2,
|
|
typename _Distance>
|
|
void
|
|
__merge_sort_loop(_RandomAccessIter1 __first, _RandomAccessIter1 __last,
|
|
_RandomAccessIter2 __result, _Distance __step_size)
|
|
{
|
|
_Distance __two_step = 2 * __step_size;
|
|
|
|
while (__last - __first >= __two_step) {
|
|
__result = merge(__first, __first + __step_size,
|
|
__first + __step_size, __first + __two_step,
|
|
__result);
|
|
__first += __two_step;
|
|
}
|
|
|
|
__step_size = min(_Distance(__last - __first), __step_size);
|
|
merge(__first, __first + __step_size, __first + __step_size, __last,
|
|
__result);
|
|
}
|
|
|
|
template<typename _RandomAccessIter1, typename _RandomAccessIter2,
|
|
typename _Distance, typename _Compare>
|
|
void
|
|
__merge_sort_loop(_RandomAccessIter1 __first, _RandomAccessIter1 __last,
|
|
_RandomAccessIter2 __result, _Distance __step_size,
|
|
_Compare __comp)
|
|
{
|
|
_Distance __two_step = 2 * __step_size;
|
|
|
|
while (__last - __first >= __two_step) {
|
|
__result = merge(__first, __first + __step_size,
|
|
__first + __step_size, __first + __two_step,
|
|
__result,
|
|
__comp);
|
|
__first += __two_step;
|
|
}
|
|
__step_size = min(_Distance(__last - __first), __step_size);
|
|
|
|
merge(__first, __first + __step_size,
|
|
__first + __step_size, __last,
|
|
__result,
|
|
__comp);
|
|
}
|
|
|
|
const int __stl_chunk_size = 7;
|
|
|
|
template<typename _RandomAccessIter, typename _Distance>
|
|
void
|
|
__chunk_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last,
|
|
_Distance __chunk_size)
|
|
{
|
|
while (__last - __first >= __chunk_size) {
|
|
__insertion_sort(__first, __first + __chunk_size);
|
|
__first += __chunk_size;
|
|
}
|
|
__insertion_sort(__first, __last);
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Distance, typename _Compare>
|
|
void
|
|
__chunk_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last,
|
|
_Distance __chunk_size, _Compare __comp)
|
|
{
|
|
while (__last - __first >= __chunk_size) {
|
|
__insertion_sort(__first, __first + __chunk_size, __comp);
|
|
__first += __chunk_size;
|
|
}
|
|
__insertion_sort(__first, __last, __comp);
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Pointer>
|
|
void
|
|
__merge_sort_with_buffer(_RandomAccessIter __first, _RandomAccessIter __last,
|
|
_Pointer __buffer)
|
|
{
|
|
typedef typename iterator_traits<_RandomAccessIter>::difference_type _Distance;
|
|
|
|
_Distance __len = __last - __first;
|
|
_Pointer __buffer_last = __buffer + __len;
|
|
|
|
_Distance __step_size = __stl_chunk_size;
|
|
__chunk_insertion_sort(__first, __last, __step_size);
|
|
|
|
while (__step_size < __len) {
|
|
__merge_sort_loop(__first, __last, __buffer, __step_size);
|
|
__step_size *= 2;
|
|
__merge_sort_loop(__buffer, __buffer_last, __first, __step_size);
|
|
__step_size *= 2;
|
|
}
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Pointer, typename _Compare>
|
|
void
|
|
__merge_sort_with_buffer(_RandomAccessIter __first, _RandomAccessIter __last,
|
|
_Pointer __buffer, _Compare __comp)
|
|
{
|
|
typedef typename iterator_traits<_RandomAccessIter>::difference_type _Distance;
|
|
|
|
_Distance __len = __last - __first;
|
|
_Pointer __buffer_last = __buffer + __len;
|
|
|
|
_Distance __step_size = __stl_chunk_size;
|
|
__chunk_insertion_sort(__first, __last, __step_size, __comp);
|
|
|
|
while (__step_size < __len) {
|
|
__merge_sort_loop(__first, __last, __buffer, __step_size, __comp);
|
|
__step_size *= 2;
|
|
__merge_sort_loop(__buffer, __buffer_last, __first, __step_size, __comp);
|
|
__step_size *= 2;
|
|
}
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Pointer, typename _Distance>
|
|
void
|
|
__stable_sort_adaptive(_RandomAccessIter __first, _RandomAccessIter __last,
|
|
_Pointer __buffer, _Distance __buffer_size)
|
|
{
|
|
_Distance __len = (__last - __first + 1) / 2;
|
|
_RandomAccessIter __middle = __first + __len;
|
|
if (__len > __buffer_size) {
|
|
__stable_sort_adaptive(__first, __middle, __buffer, __buffer_size);
|
|
__stable_sort_adaptive(__middle, __last, __buffer, __buffer_size);
|
|
}
|
|
else {
|
|
__merge_sort_with_buffer(__first, __middle, __buffer);
|
|
__merge_sort_with_buffer(__middle, __last, __buffer);
|
|
}
|
|
__merge_adaptive(__first, __middle, __last, _Distance(__middle - __first),
|
|
_Distance(__last - __middle), __buffer, __buffer_size);
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Pointer, typename _Distance,
|
|
typename _Compare>
|
|
void
|
|
__stable_sort_adaptive(_RandomAccessIter __first, _RandomAccessIter __last,
|
|
_Pointer __buffer, _Distance __buffer_size,
|
|
_Compare __comp)
|
|
{
|
|
_Distance __len = (__last - __first + 1) / 2;
|
|
_RandomAccessIter __middle = __first + __len;
|
|
if (__len > __buffer_size) {
|
|
__stable_sort_adaptive(__first, __middle, __buffer, __buffer_size,
|
|
__comp);
|
|
__stable_sort_adaptive(__middle, __last, __buffer, __buffer_size,
|
|
__comp);
|
|
}
|
|
else {
|
|
__merge_sort_with_buffer(__first, __middle, __buffer, __comp);
|
|
__merge_sort_with_buffer(__middle, __last, __buffer, __comp);
|
|
}
|
|
__merge_adaptive(__first, __middle, __last, _Distance(__middle - __first),
|
|
_Distance(__last - __middle), __buffer, __buffer_size,
|
|
__comp);
|
|
}
|
|
|
|
template<typename _RandomAccessIter>
|
|
inline void
|
|
stable_sort(_RandomAccessIter __first, _RandomAccessIter __last)
|
|
{
|
|
typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
|
|
typedef typename iterator_traits<_RandomAccessIter>::difference_type _DistanceType;
|
|
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
|
|
_RandomAccessIter>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<_ValueType>);
|
|
|
|
_Temporary_buffer<_RandomAccessIter, _ValueType> buf(__first, __last);
|
|
if (buf.begin() == 0)
|
|
__inplace_stable_sort(__first, __last);
|
|
else
|
|
__stable_sort_adaptive(__first, __last, buf.begin(), _DistanceType(buf.size()));
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Compare>
|
|
inline void
|
|
stable_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp)
|
|
{
|
|
typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
|
|
typedef typename iterator_traits<_RandomAccessIter>::difference_type _DistanceType;
|
|
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
|
|
_RandomAccessIter>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
|
|
_ValueType, _ValueType>);
|
|
|
|
_Temporary_buffer<_RandomAccessIter, _ValueType> buf(__first, __last);
|
|
if (buf.begin() == 0)
|
|
__inplace_stable_sort(__first, __last, __comp);
|
|
else
|
|
__stable_sort_adaptive(__first, __last, buf.begin(), _DistanceType(buf.size()),
|
|
__comp);
|
|
}
|
|
|
|
template<typename _RandomAccessIter>
|
|
void
|
|
partial_sort(_RandomAccessIter __first,
|
|
_RandomAccessIter __middle,
|
|
_RandomAccessIter __last)
|
|
{
|
|
typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
|
|
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
|
|
_RandomAccessIter>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<_ValueType);
|
|
|
|
make_heap(__first, __middle);
|
|
for (_RandomAccessIter __i = __middle; __i < __last; ++__i)
|
|
if (*__i < *__first)
|
|
__pop_heap(__first, __middle, __i, _ValueType(*__i));
|
|
sort_heap(__first, __middle);
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Compare>
|
|
void
|
|
partial_sort(_RandomAccessIter __first,
|
|
_RandomAccessIter __middle,
|
|
_RandomAccessIter __last,
|
|
_Compare __comp)
|
|
{
|
|
typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
|
|
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
|
|
_RandomAccessIter>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
|
|
_ValueType, _ValueType>);
|
|
|
|
make_heap(__first, __middle, __comp);
|
|
for (_RandomAccessIter __i = __middle; __i < __last; ++__i)
|
|
if (__comp(*__i, *__first))
|
|
__pop_heap(__first, __middle, __i, _ValueType(*__i), __comp);
|
|
sort_heap(__first, __middle, __comp);
|
|
}
|
|
|
|
template<typename _InputIter, typename _RandomAccessIter>
|
|
_RandomAccessIter
|
|
partial_sort_copy(_InputIter __first, _InputIter __last,
|
|
_RandomAccessIter __result_first,
|
|
_RandomAccessIter __result_last)
|
|
{
|
|
typedef typename iterator_traits<_InputIter>::value_type _InputValueType;
|
|
typedef typename iterator_traits<_RandomAccessIter>::value_type _OutputValueType;
|
|
typedef typename iterator_traits<_RandomAccessIter>::difference_type _DistanceType;
|
|
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
__glibcpp_function_requires(_ConvertibleConcept<_InputValueType, _OutputValueType>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<_OutputValueType>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<_InputValueType>);
|
|
|
|
if (__result_first == __result_last) return __result_last;
|
|
_RandomAccessIter __result_real_last = __result_first;
|
|
while(__first != __last && __result_real_last != __result_last) {
|
|
*__result_real_last = *__first;
|
|
++__result_real_last;
|
|
++__first;
|
|
}
|
|
make_heap(__result_first, __result_real_last);
|
|
while (__first != __last) {
|
|
if (*__first < *__result_first)
|
|
__adjust_heap(__result_first, _DistanceType(0),
|
|
_DistanceType(__result_real_last - __result_first),
|
|
_InputValueType(*__first));
|
|
++__first;
|
|
}
|
|
sort_heap(__result_first, __result_real_last);
|
|
return __result_real_last;
|
|
}
|
|
|
|
template<typename _InputIter, typename _RandomAccessIter, typename _Compare>
|
|
_RandomAccessIter
|
|
partial_sort_copy(_InputIter __first, _InputIter __last,
|
|
_RandomAccessIter __result_first,
|
|
_RandomAccessIter __result_last,
|
|
_Compare __comp)
|
|
{
|
|
typedef typename iterator_traits<_InputIter>::value_type _InputValueType;
|
|
typedef typename iterator_traits<_RandomAccessIter>::value_type _OutputValueType;
|
|
typedef typename iterator_traits<_RandomAccessIter>::difference_type _DistanceType;
|
|
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
__glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<_RandomAccessIter>);
|
|
__glibcpp_function_requires(_ConvertibleConcept<_InputValueType, _OutputValueType>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
|
|
_OutputValueType, _OutputValueType>);
|
|
|
|
if (__result_first == __result_last) return __result_last;
|
|
_RandomAccessIter __result_real_last = __result_first;
|
|
while(__first != __last && __result_real_last != __result_last) {
|
|
*__result_real_last = *__first;
|
|
++__result_real_last;
|
|
++__first;
|
|
}
|
|
make_heap(__result_first, __result_real_last, __comp);
|
|
while (__first != __last) {
|
|
if (__comp(*__first, *__result_first))
|
|
__adjust_heap(__result_first, _DistanceType(0),
|
|
_DistanceType(__result_real_last - __result_first),
|
|
_InputValueType(*__first),
|
|
__comp);
|
|
++__first;
|
|
}
|
|
sort_heap(__result_first, __result_real_last, __comp);
|
|
return __result_real_last;
|
|
}
|
|
|
|
template<typename _RandomAccessIter>
|
|
void
|
|
nth_element(_RandomAccessIter __first,
|
|
_RandomAccessIter __nth,
|
|
_RandomAccessIter __last)
|
|
{
|
|
typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
|
|
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<_RandomAccessIter>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<_ValueType>);
|
|
|
|
while (__last - __first > 3) {
|
|
_RandomAccessIter __cut =
|
|
__unguarded_partition(__first, __last,
|
|
_ValueType(__median(*__first,
|
|
*(__first + (__last - __first)/2),
|
|
*(__last - 1))));
|
|
if (__cut <= __nth)
|
|
__first = __cut;
|
|
else
|
|
__last = __cut;
|
|
}
|
|
__insertion_sort(__first, __last);
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Compare>
|
|
void
|
|
nth_element(_RandomAccessIter __first,
|
|
_RandomAccessIter __nth,
|
|
_RandomAccessIter __last,
|
|
_Compare __comp)
|
|
{
|
|
typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType;
|
|
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<_RandomAccessIter>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
|
|
_ValueType, _ValueType>);
|
|
|
|
while (__last - __first > 3) {
|
|
_RandomAccessIter __cut =
|
|
__unguarded_partition(__first, __last,
|
|
_ValueType(__median(*__first,
|
|
*(__first + (__last - __first)/2),
|
|
*(__last - 1),
|
|
__comp)),
|
|
__comp);
|
|
if (__cut <= __nth)
|
|
__first = __cut;
|
|
else
|
|
__last = __cut;
|
|
}
|
|
__insertion_sort(__first, __last, __comp);
|
|
}
|
|
|
|
|
|
// Binary search (lower_bound, upper_bound, equal_range, binary_search).
|
|
|
|
template<typename _ForwardIter, typename _Tp>
|
|
_ForwardIter
|
|
lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val)
|
|
{
|
|
typedef typename iterator_traits<_ForwardIter>::value_type _ValueType;
|
|
typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType;
|
|
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_SameTypeConcept<_Tp, _ValueType>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<_Tp>);
|
|
|
|
_DistanceType __len = distance(__first, __last);
|
|
_DistanceType __half;
|
|
_ForwardIter __middle;
|
|
|
|
while (__len > 0) {
|
|
__half = __len >> 1;
|
|
__middle = __first;
|
|
advance(__middle, __half);
|
|
if (*__middle < __val) {
|
|
__first = __middle;
|
|
++__first;
|
|
__len = __len - __half - 1;
|
|
}
|
|
else
|
|
__len = __half;
|
|
}
|
|
return __first;
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _Tp, typename _Compare>
|
|
_ForwardIter
|
|
lower_bound(_ForwardIter __first, _ForwardIter __last,
|
|
const _Tp& __val, _Compare __comp)
|
|
{
|
|
typedef typename iterator_traits<_ForwardIter>::value_type _ValueType;
|
|
typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType;
|
|
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_SameTypeConcept<_Tp, _ValueType>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare, _Tp, _Tp>);
|
|
|
|
_DistanceType __len = distance(__first, __last);
|
|
_DistanceType __half;
|
|
_ForwardIter __middle;
|
|
|
|
while (__len > 0) {
|
|
__half = __len >> 1;
|
|
__middle = __first;
|
|
advance(__middle, __half);
|
|
if (__comp(*__middle, __val)) {
|
|
__first = __middle;
|
|
++__first;
|
|
__len = __len - __half - 1;
|
|
}
|
|
else
|
|
__len = __half;
|
|
}
|
|
return __first;
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _Tp>
|
|
_ForwardIter
|
|
upper_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val)
|
|
{
|
|
typedef typename iterator_traits<_ForwardIter>::value_type _ValueType;
|
|
typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType;
|
|
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_SameTypeConcept<_Tp, _ValueType>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<_Tp>);
|
|
|
|
_DistanceType __len = distance(__first, __last);
|
|
_DistanceType __half;
|
|
_ForwardIter __middle;
|
|
|
|
while (__len > 0) {
|
|
__half = __len >> 1;
|
|
__middle = __first;
|
|
advance(__middle, __half);
|
|
if (__val < *__middle)
|
|
__len = __half;
|
|
else {
|
|
__first = __middle;
|
|
++__first;
|
|
__len = __len - __half - 1;
|
|
}
|
|
}
|
|
return __first;
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _Tp, typename _Compare>
|
|
_ForwardIter
|
|
upper_bound(_ForwardIter __first, _ForwardIter __last,
|
|
const _Tp& __val, _Compare __comp)
|
|
{
|
|
typedef typename iterator_traits<_ForwardIter>::value_type _ValueType;
|
|
typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType;
|
|
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_SameTypeConcept<_Tp, _ValueType>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare, _Tp, _Tp>);
|
|
|
|
_DistanceType __len = distance(__first, __last);
|
|
_DistanceType __half;
|
|
_ForwardIter __middle;
|
|
|
|
while (__len > 0) {
|
|
__half = __len >> 1;
|
|
__middle = __first;
|
|
advance(__middle, __half);
|
|
if (__comp(__val, *__middle))
|
|
__len = __half;
|
|
else {
|
|
__first = __middle;
|
|
++__first;
|
|
__len = __len - __half - 1;
|
|
}
|
|
}
|
|
return __first;
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _Tp>
|
|
pair<_ForwardIter, _ForwardIter>
|
|
equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val)
|
|
{
|
|
typedef typename iterator_traits<_ForwardIter>::value_type _ValueType;
|
|
typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType;
|
|
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_SameTypeConcept<_Tp, _ValueType>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<_Tp>);
|
|
|
|
_DistanceType __len = distance(__first, __last);
|
|
_DistanceType __half;
|
|
_ForwardIter __middle, __left, __right;
|
|
|
|
while (__len > 0) {
|
|
__half = __len >> 1;
|
|
__middle = __first;
|
|
advance(__middle, __half);
|
|
if (*__middle < __val) {
|
|
__first = __middle;
|
|
++__first;
|
|
__len = __len - __half - 1;
|
|
}
|
|
else if (__val < *__middle)
|
|
__len = __half;
|
|
else {
|
|
__left = lower_bound(__first, __middle, __val);
|
|
advance(__first, __len);
|
|
__right = upper_bound(++__middle, __first, __val);
|
|
return pair<_ForwardIter, _ForwardIter>(__left, __right);
|
|
}
|
|
}
|
|
return pair<_ForwardIter, _ForwardIter>(__first, __first);
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _Tp, typename _Compare>
|
|
pair<_ForwardIter, _ForwardIter>
|
|
equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val,
|
|
_Compare __comp)
|
|
{
|
|
typedef typename iterator_traits<_ForwardIter>::value_type _ValueType;
|
|
typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType;
|
|
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_SameTypeConcept<_Tp, _ValueType>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare, _Tp, _Tp>);
|
|
|
|
_DistanceType __len = distance(__first, __last);
|
|
_DistanceType __half;
|
|
_ForwardIter __middle, __left, __right;
|
|
|
|
while (__len > 0) {
|
|
__half = __len >> 1;
|
|
__middle = __first;
|
|
advance(__middle, __half);
|
|
if (__comp(*__middle, __val)) {
|
|
__first = __middle;
|
|
++__first;
|
|
__len = __len - __half - 1;
|
|
}
|
|
else if (__comp(__val, *__middle))
|
|
__len = __half;
|
|
else {
|
|
__left = lower_bound(__first, __middle, __val, __comp);
|
|
advance(__first, __len);
|
|
__right = upper_bound(++__middle, __first, __val, __comp);
|
|
return pair<_ForwardIter, _ForwardIter>(__left, __right);
|
|
}
|
|
}
|
|
return pair<_ForwardIter, _ForwardIter>(__first, __first);
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _Tp>
|
|
bool
|
|
binary_search(_ForwardIter __first, _ForwardIter __last,
|
|
const _Tp& __val)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_SameTypeConcept<_Tp,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<_Tp>);
|
|
|
|
_ForwardIter __i = lower_bound(__first, __last, __val);
|
|
return __i != __last && !(__val < *__i);
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _Tp, typename _Compare>
|
|
bool
|
|
binary_search(_ForwardIter __first, _ForwardIter __last,
|
|
const _Tp& __val, _Compare __comp)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_SameTypeConcept<_Tp,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare, _Tp, _Tp>);
|
|
|
|
_ForwardIter __i = lower_bound(__first, __last, __val, __comp);
|
|
return __i != __last && !__comp(__val, *__i);
|
|
}
|
|
|
|
// merge, with and without an explicitly supplied comparison function.
|
|
|
|
template<typename _InputIter1, typename _InputIter2, typename _OutputIter>
|
|
_OutputIter
|
|
merge(_InputIter1 __first1, _InputIter1 __last1,
|
|
_InputIter2 __first2, _InputIter2 __last2,
|
|
_OutputIter __result)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter1>);
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter2>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_InputIter1>::value_type>);
|
|
__glibcpp_function_requires(_SameTypeConcept<
|
|
typename iterator_traits<_InputIter1>::value_type,
|
|
typename iterator_traits<_InputIter2>::value_type>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<
|
|
typename iterator_traits<_InputIter1>::value_type>);
|
|
|
|
while (__first1 != __last1 && __first2 != __last2) {
|
|
if (*__first2 < *__first1) {
|
|
*__result = *__first2;
|
|
++__first2;
|
|
}
|
|
else {
|
|
*__result = *__first1;
|
|
++__first1;
|
|
}
|
|
++__result;
|
|
}
|
|
return copy(__first2, __last2, copy(__first1, __last1, __result));
|
|
}
|
|
|
|
template<typename _InputIter1, typename _InputIter2, typename _OutputIter,
|
|
typename _Compare>
|
|
_OutputIter
|
|
merge(_InputIter1 __first1, _InputIter1 __last1,
|
|
_InputIter2 __first2, _InputIter2 __last2,
|
|
_OutputIter __result, _Compare __comp)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter1>);
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter2>);
|
|
__glibcpp_function_requires(_SameTypeConcept<
|
|
typename iterator_traits<_InputIter1>::value_type,
|
|
typename iterator_traits<_InputIter2>::value_type>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_InputIter1>::value_type>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
|
|
typename iterator_traits<_InputIter1>::value_type,
|
|
typename iterator_traits<_InputIter2>::value_type>);
|
|
|
|
while (__first1 != __last1 && __first2 != __last2) {
|
|
if (__comp(*__first2, *__first1)) {
|
|
*__result = *__first2;
|
|
++__first2;
|
|
}
|
|
else {
|
|
*__result = *__first1;
|
|
++__first1;
|
|
}
|
|
++__result;
|
|
}
|
|
return copy(__first2, __last2, copy(__first1, __last1, __result));
|
|
}
|
|
|
|
// inplace_merge and its auxiliary functions.
|
|
|
|
template<typename _BidirectionalIter, typename _Distance>
|
|
void
|
|
__merge_without_buffer(_BidirectionalIter __first,
|
|
_BidirectionalIter __middle,
|
|
_BidirectionalIter __last,
|
|
_Distance __len1, _Distance __len2)
|
|
{
|
|
if (__len1 == 0 || __len2 == 0)
|
|
return;
|
|
if (__len1 + __len2 == 2) {
|
|
if (*__middle < *__first)
|
|
iter_swap(__first, __middle);
|
|
return;
|
|
}
|
|
_BidirectionalIter __first_cut = __first;
|
|
_BidirectionalIter __second_cut = __middle;
|
|
_Distance __len11 = 0;
|
|
_Distance __len22 = 0;
|
|
if (__len1 > __len2) {
|
|
__len11 = __len1 / 2;
|
|
advance(__first_cut, __len11);
|
|
__second_cut = lower_bound(__middle, __last, *__first_cut);
|
|
__len22 = distance(__middle, __second_cut);
|
|
}
|
|
else {
|
|
__len22 = __len2 / 2;
|
|
advance(__second_cut, __len22);
|
|
__first_cut = upper_bound(__first, __middle, *__second_cut);
|
|
__len11 = distance(__first, __first_cut);
|
|
}
|
|
rotate(__first_cut, __middle, __second_cut);
|
|
_BidirectionalIter __new_middle = __first_cut;
|
|
advance(__new_middle, distance(__middle, __second_cut));
|
|
__merge_without_buffer(__first, __first_cut, __new_middle,
|
|
__len11, __len22);
|
|
__merge_without_buffer(__new_middle, __second_cut, __last,
|
|
__len1 - __len11, __len2 - __len22);
|
|
}
|
|
|
|
template<typename _BidirectionalIter, typename _Distance, typename _Compare>
|
|
void
|
|
__merge_without_buffer(_BidirectionalIter __first,
|
|
_BidirectionalIter __middle,
|
|
_BidirectionalIter __last,
|
|
_Distance __len1, _Distance __len2,
|
|
_Compare __comp)
|
|
{
|
|
if (__len1 == 0 || __len2 == 0)
|
|
return;
|
|
if (__len1 + __len2 == 2) {
|
|
if (__comp(*__middle, *__first))
|
|
iter_swap(__first, __middle);
|
|
return;
|
|
}
|
|
_BidirectionalIter __first_cut = __first;
|
|
_BidirectionalIter __second_cut = __middle;
|
|
_Distance __len11 = 0;
|
|
_Distance __len22 = 0;
|
|
if (__len1 > __len2) {
|
|
__len11 = __len1 / 2;
|
|
advance(__first_cut, __len11);
|
|
__second_cut = lower_bound(__middle, __last, *__first_cut, __comp);
|
|
__len22 = distance(__middle, __second_cut);
|
|
}
|
|
else {
|
|
__len22 = __len2 / 2;
|
|
advance(__second_cut, __len22);
|
|
__first_cut = upper_bound(__first, __middle, *__second_cut, __comp);
|
|
__len11 = distance(__first, __first_cut);
|
|
}
|
|
rotate(__first_cut, __middle, __second_cut);
|
|
_BidirectionalIter __new_middle = __first_cut;
|
|
advance(__new_middle, distance(__middle, __second_cut));
|
|
__merge_without_buffer(__first, __first_cut, __new_middle,
|
|
__len11, __len22, __comp);
|
|
__merge_without_buffer(__new_middle, __second_cut, __last,
|
|
__len1 - __len11, __len2 - __len22, __comp);
|
|
}
|
|
|
|
template<typename _BidirectionalIter1, typename _BidirectionalIter2,
|
|
typename _Distance>
|
|
_BidirectionalIter1
|
|
__rotate_adaptive(_BidirectionalIter1 __first,
|
|
_BidirectionalIter1 __middle,
|
|
_BidirectionalIter1 __last,
|
|
_Distance __len1, _Distance __len2,
|
|
_BidirectionalIter2 __buffer,
|
|
_Distance __buffer_size)
|
|
{
|
|
_BidirectionalIter2 __buffer_end;
|
|
if (__len1 > __len2 && __len2 <= __buffer_size) {
|
|
__buffer_end = copy(__middle, __last, __buffer);
|
|
copy_backward(__first, __middle, __last);
|
|
return copy(__buffer, __buffer_end, __first);
|
|
}
|
|
else if (__len1 <= __buffer_size) {
|
|
__buffer_end = copy(__first, __middle, __buffer);
|
|
copy(__middle, __last, __first);
|
|
return copy_backward(__buffer, __buffer_end, __last);
|
|
}
|
|
else {
|
|
rotate(__first, __middle, __last);
|
|
advance(__first, distance(__middle, __last));
|
|
return __first;
|
|
}
|
|
}
|
|
|
|
template<typename _BidirectionalIter1, typename _BidirectionalIter2,
|
|
typename _BidirectionalIter3>
|
|
_BidirectionalIter3
|
|
__merge_backward(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1,
|
|
_BidirectionalIter2 __first2, _BidirectionalIter2 __last2,
|
|
_BidirectionalIter3 __result)
|
|
{
|
|
if (__first1 == __last1)
|
|
return copy_backward(__first2, __last2, __result);
|
|
if (__first2 == __last2)
|
|
return copy_backward(__first1, __last1, __result);
|
|
--__last1;
|
|
--__last2;
|
|
while (true) {
|
|
if (*__last2 < *__last1) {
|
|
*--__result = *__last1;
|
|
if (__first1 == __last1)
|
|
return copy_backward(__first2, ++__last2, __result);
|
|
--__last1;
|
|
}
|
|
else {
|
|
*--__result = *__last2;
|
|
if (__first2 == __last2)
|
|
return copy_backward(__first1, ++__last1, __result);
|
|
--__last2;
|
|
}
|
|
}
|
|
}
|
|
|
|
template<typename _BidirectionalIter1, typename _BidirectionalIter2,
|
|
typename _BidirectionalIter3, typename _Compare>
|
|
_BidirectionalIter3
|
|
__merge_backward(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1,
|
|
_BidirectionalIter2 __first2, _BidirectionalIter2 __last2,
|
|
_BidirectionalIter3 __result,
|
|
_Compare __comp)
|
|
{
|
|
if (__first1 == __last1)
|
|
return copy_backward(__first2, __last2, __result);
|
|
if (__first2 == __last2)
|
|
return copy_backward(__first1, __last1, __result);
|
|
--__last1;
|
|
--__last2;
|
|
while (true) {
|
|
if (__comp(*__last2, *__last1)) {
|
|
*--__result = *__last1;
|
|
if (__first1 == __last1)
|
|
return copy_backward(__first2, ++__last2, __result);
|
|
--__last1;
|
|
}
|
|
else {
|
|
*--__result = *__last2;
|
|
if (__first2 == __last2)
|
|
return copy_backward(__first1, ++__last1, __result);
|
|
--__last2;
|
|
}
|
|
}
|
|
}
|
|
|
|
template<typename _BidirectionalIter, typename _Distance, typename _Pointer>
|
|
void
|
|
__merge_adaptive(_BidirectionalIter __first,
|
|
_BidirectionalIter __middle,
|
|
_BidirectionalIter __last,
|
|
_Distance __len1, _Distance __len2,
|
|
_Pointer __buffer, _Distance __buffer_size)
|
|
{
|
|
if (__len1 <= __len2 && __len1 <= __buffer_size) {
|
|
_Pointer __buffer_end = copy(__first, __middle, __buffer);
|
|
merge(__buffer, __buffer_end, __middle, __last, __first);
|
|
}
|
|
else if (__len2 <= __buffer_size) {
|
|
_Pointer __buffer_end = copy(__middle, __last, __buffer);
|
|
__merge_backward(__first, __middle, __buffer, __buffer_end, __last);
|
|
}
|
|
else {
|
|
_BidirectionalIter __first_cut = __first;
|
|
_BidirectionalIter __second_cut = __middle;
|
|
_Distance __len11 = 0;
|
|
_Distance __len22 = 0;
|
|
if (__len1 > __len2) {
|
|
__len11 = __len1 / 2;
|
|
advance(__first_cut, __len11);
|
|
__second_cut = lower_bound(__middle, __last, *__first_cut);
|
|
__len22 = distance(__middle, __second_cut);
|
|
}
|
|
else {
|
|
__len22 = __len2 / 2;
|
|
advance(__second_cut, __len22);
|
|
__first_cut = upper_bound(__first, __middle, *__second_cut);
|
|
__len11 = distance(__first, __first_cut);
|
|
}
|
|
_BidirectionalIter __new_middle =
|
|
__rotate_adaptive(__first_cut, __middle, __second_cut,
|
|
__len1 - __len11, __len22, __buffer,
|
|
__buffer_size);
|
|
__merge_adaptive(__first, __first_cut, __new_middle, __len11,
|
|
__len22, __buffer, __buffer_size);
|
|
__merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11,
|
|
__len2 - __len22, __buffer, __buffer_size);
|
|
}
|
|
}
|
|
|
|
template<typename _BidirectionalIter, typename _Distance, typename _Pointer,
|
|
typename _Compare>
|
|
void
|
|
__merge_adaptive(_BidirectionalIter __first,
|
|
_BidirectionalIter __middle,
|
|
_BidirectionalIter __last,
|
|
_Distance __len1, _Distance __len2,
|
|
_Pointer __buffer, _Distance __buffer_size,
|
|
_Compare __comp)
|
|
{
|
|
if (__len1 <= __len2 && __len1 <= __buffer_size) {
|
|
_Pointer __buffer_end = copy(__first, __middle, __buffer);
|
|
merge(__buffer, __buffer_end, __middle, __last, __first, __comp);
|
|
}
|
|
else if (__len2 <= __buffer_size) {
|
|
_Pointer __buffer_end = copy(__middle, __last, __buffer);
|
|
__merge_backward(__first, __middle, __buffer, __buffer_end, __last,
|
|
__comp);
|
|
}
|
|
else {
|
|
_BidirectionalIter __first_cut = __first;
|
|
_BidirectionalIter __second_cut = __middle;
|
|
_Distance __len11 = 0;
|
|
_Distance __len22 = 0;
|
|
if (__len1 > __len2) {
|
|
__len11 = __len1 / 2;
|
|
advance(__first_cut, __len11);
|
|
__second_cut = lower_bound(__middle, __last, *__first_cut, __comp);
|
|
__len22 = distance(__middle, __second_cut);
|
|
}
|
|
else {
|
|
__len22 = __len2 / 2;
|
|
advance(__second_cut, __len22);
|
|
__first_cut = upper_bound(__first, __middle, *__second_cut, __comp);
|
|
__len11 = distance(__first, __first_cut);
|
|
}
|
|
_BidirectionalIter __new_middle =
|
|
__rotate_adaptive(__first_cut, __middle, __second_cut,
|
|
__len1 - __len11, __len22, __buffer,
|
|
__buffer_size);
|
|
__merge_adaptive(__first, __first_cut, __new_middle, __len11,
|
|
__len22, __buffer, __buffer_size, __comp);
|
|
__merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11,
|
|
__len2 - __len22, __buffer, __buffer_size, __comp);
|
|
}
|
|
}
|
|
|
|
template<typename _BidirectionalIter>
|
|
void
|
|
inplace_merge(_BidirectionalIter __first,
|
|
_BidirectionalIter __middle,
|
|
_BidirectionalIter __last)
|
|
{
|
|
typedef typename iterator_traits<_BidirectionalIter>::value_type
|
|
_ValueType;
|
|
typedef typename iterator_traits<_BidirectionalIter>::difference_type
|
|
_DistanceType;
|
|
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_BidirectionalIteratorConcept<
|
|
_BidirectionalIter>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<_ValueType>);
|
|
|
|
if (__first == __middle || __middle == __last)
|
|
return;
|
|
|
|
_DistanceType __len1 = distance(__first, __middle);
|
|
_DistanceType __len2 = distance(__middle, __last);
|
|
|
|
_Temporary_buffer<_BidirectionalIter, _ValueType> __buf(__first, __last);
|
|
if (__buf.begin() == 0)
|
|
__merge_without_buffer(__first, __middle, __last, __len1, __len2);
|
|
else
|
|
__merge_adaptive(__first, __middle, __last, __len1, __len2,
|
|
__buf.begin(), _DistanceType(__buf.size()));
|
|
}
|
|
|
|
template<typename _BidirectionalIter, typename _Compare>
|
|
void
|
|
inplace_merge(_BidirectionalIter __first,
|
|
_BidirectionalIter __middle,
|
|
_BidirectionalIter __last,
|
|
_Compare __comp)
|
|
{
|
|
typedef typename iterator_traits<_BidirectionalIter>::value_type
|
|
_ValueType;
|
|
typedef typename iterator_traits<_BidirectionalIter>::difference_type
|
|
_DistanceType;
|
|
|
|
// concept requirements
|
|
__glibcpp_function_requires(_Mutable_BidirectionalIteratorConcept<
|
|
_BidirectionalIter>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
|
|
_ValueType, _ValueType>);
|
|
|
|
if (__first == __middle || __middle == __last)
|
|
return;
|
|
|
|
_DistanceType __len1 = distance(__first, __middle);
|
|
_DistanceType __len2 = distance(__middle, __last);
|
|
|
|
_Temporary_buffer<_BidirectionalIter, _ValueType> __buf(__first, __last);
|
|
if (__buf.begin() == 0)
|
|
__merge_without_buffer(__first, __middle, __last, __len1, __len2, __comp);
|
|
else
|
|
__merge_adaptive(__first, __middle, __last, __len1, __len2,
|
|
__buf.begin(), _DistanceType(__buf.size()),
|
|
__comp);
|
|
}
|
|
|
|
// Set algorithms: includes, set_union, set_intersection, set_difference,
|
|
// set_symmetric_difference. All of these algorithms have the precondition
|
|
// that their input ranges are sorted and the postcondition that their output
|
|
// ranges are sorted.
|
|
|
|
template<typename _InputIter1, typename _InputIter2>
|
|
bool
|
|
includes(_InputIter1 __first1, _InputIter1 __last1,
|
|
_InputIter2 __first2, _InputIter2 __last2)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter1>);
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter2>);
|
|
__glibcpp_function_requires(_SameTypeConcept<
|
|
typename iterator_traits<_InputIter1>::value_type,
|
|
typename iterator_traits<_InputIter2>::value_type>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<
|
|
typename iterator_traits<_InputIter1>::value_type>);
|
|
|
|
while (__first1 != __last1 && __first2 != __last2)
|
|
if (*__first2 < *__first1)
|
|
return false;
|
|
else if(*__first1 < *__first2)
|
|
++__first1;
|
|
else
|
|
++__first1, ++__first2;
|
|
|
|
return __first2 == __last2;
|
|
}
|
|
|
|
template<typename _InputIter1, typename _InputIter2, typename _Compare>
|
|
bool
|
|
includes(_InputIter1 __first1, _InputIter1 __last1,
|
|
_InputIter2 __first2, _InputIter2 __last2, _Compare __comp)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter1>);
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter2>);
|
|
__glibcpp_function_requires(_SameTypeConcept<
|
|
typename iterator_traits<_InputIter1>::value_type,
|
|
typename iterator_traits<_InputIter2>::value_type>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
|
|
typename iterator_traits<_InputIter1>::value_type,
|
|
typename iterator_traits<_InputIter2>::value_type>);
|
|
|
|
while (__first1 != __last1 && __first2 != __last2)
|
|
if (__comp(*__first2, *__first1))
|
|
return false;
|
|
else if(__comp(*__first1, *__first2))
|
|
++__first1;
|
|
else
|
|
++__first1, ++__first2;
|
|
|
|
return __first2 == __last2;
|
|
}
|
|
|
|
template<typename _InputIter1, typename _InputIter2, typename _OutputIter>
|
|
_OutputIter
|
|
set_union(_InputIter1 __first1, _InputIter1 __last1,
|
|
_InputIter2 __first2, _InputIter2 __last2,
|
|
_OutputIter __result)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter1>);
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter2>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_InputIter1>::value_type>);
|
|
__glibcpp_function_requires(_SameTypeConcept<
|
|
typename iterator_traits<_InputIter1>::value_type,
|
|
typename iterator_traits<_InputIter2>::value_type>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<
|
|
typename iterator_traits<_InputIter1>::value_type>);
|
|
|
|
while (__first1 != __last1 && __first2 != __last2) {
|
|
if (*__first1 < *__first2) {
|
|
*__result = *__first1;
|
|
++__first1;
|
|
}
|
|
else if (*__first2 < *__first1) {
|
|
*__result = *__first2;
|
|
++__first2;
|
|
}
|
|
else {
|
|
*__result = *__first1;
|
|
++__first1;
|
|
++__first2;
|
|
}
|
|
++__result;
|
|
}
|
|
return copy(__first2, __last2, copy(__first1, __last1, __result));
|
|
}
|
|
|
|
template<typename _InputIter1, typename _InputIter2, typename _OutputIter,
|
|
typename _Compare>
|
|
_OutputIter
|
|
set_union(_InputIter1 __first1, _InputIter1 __last1,
|
|
_InputIter2 __first2, _InputIter2 __last2,
|
|
_OutputIter __result, _Compare __comp)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter1>);
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter2>);
|
|
__glibcpp_function_requires(_SameTypeConcept<
|
|
typename iterator_traits<_InputIter1>::value_type,
|
|
typename iterator_traits<_InputIter2>::value_type>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_InputIter1>::value_type>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
|
|
typename iterator_traits<_InputIter1>::value_type,
|
|
typename iterator_traits<_InputIter2>::value_type>);
|
|
|
|
while (__first1 != __last1 && __first2 != __last2) {
|
|
if (__comp(*__first1, *__first2)) {
|
|
*__result = *__first1;
|
|
++__first1;
|
|
}
|
|
else if (__comp(*__first2, *__first1)) {
|
|
*__result = *__first2;
|
|
++__first2;
|
|
}
|
|
else {
|
|
*__result = *__first1;
|
|
++__first1;
|
|
++__first2;
|
|
}
|
|
++__result;
|
|
}
|
|
return copy(__first2, __last2, copy(__first1, __last1, __result));
|
|
}
|
|
|
|
template<typename _InputIter1, typename _InputIter2, typename _OutputIter>
|
|
_OutputIter
|
|
set_intersection(_InputIter1 __first1, _InputIter1 __last1,
|
|
_InputIter2 __first2, _InputIter2 __last2,
|
|
_OutputIter __result)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter1>);
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter2>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_InputIter1>::value_type>);
|
|
__glibcpp_function_requires(_SameTypeConcept<
|
|
typename iterator_traits<_InputIter1>::value_type,
|
|
typename iterator_traits<_InputIter2>::value_type>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<
|
|
typename iterator_traits<_InputIter1>::value_type>);
|
|
|
|
while (__first1 != __last1 && __first2 != __last2)
|
|
if (*__first1 < *__first2)
|
|
++__first1;
|
|
else if (*__first2 < *__first1)
|
|
++__first2;
|
|
else {
|
|
*__result = *__first1;
|
|
++__first1;
|
|
++__first2;
|
|
++__result;
|
|
}
|
|
return __result;
|
|
}
|
|
|
|
template<typename _InputIter1, typename _InputIter2, typename _OutputIter,
|
|
typename _Compare>
|
|
_OutputIter
|
|
set_intersection(_InputIter1 __first1, _InputIter1 __last1,
|
|
_InputIter2 __first2, _InputIter2 __last2,
|
|
_OutputIter __result, _Compare __comp)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter1>);
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter2>);
|
|
__glibcpp_function_requires(_SameTypeConcept<
|
|
typename iterator_traits<_InputIter1>::value_type,
|
|
typename iterator_traits<_InputIter2>::value_type>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_InputIter1>::value_type>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
|
|
typename iterator_traits<_InputIter1>::value_type,
|
|
typename iterator_traits<_InputIter2>::value_type>);
|
|
|
|
while (__first1 != __last1 && __first2 != __last2)
|
|
if (__comp(*__first1, *__first2))
|
|
++__first1;
|
|
else if (__comp(*__first2, *__first1))
|
|
++__first2;
|
|
else {
|
|
*__result = *__first1;
|
|
++__first1;
|
|
++__first2;
|
|
++__result;
|
|
}
|
|
return __result;
|
|
}
|
|
|
|
template<typename _InputIter1, typename _InputIter2, typename _OutputIter>
|
|
_OutputIter
|
|
set_difference(_InputIter1 __first1, _InputIter1 __last1,
|
|
_InputIter2 __first2, _InputIter2 __last2,
|
|
_OutputIter __result)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter1>);
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter2>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_InputIter1>::value_type>);
|
|
__glibcpp_function_requires(_SameTypeConcept<
|
|
typename iterator_traits<_InputIter1>::value_type,
|
|
typename iterator_traits<_InputIter2>::value_type>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<
|
|
typename iterator_traits<_InputIter1>::value_type>);
|
|
|
|
while (__first1 != __last1 && __first2 != __last2)
|
|
if (*__first1 < *__first2) {
|
|
*__result = *__first1;
|
|
++__first1;
|
|
++__result;
|
|
}
|
|
else if (*__first2 < *__first1)
|
|
++__first2;
|
|
else {
|
|
++__first1;
|
|
++__first2;
|
|
}
|
|
return copy(__first1, __last1, __result);
|
|
}
|
|
|
|
template<typename _InputIter1, typename _InputIter2, typename _OutputIter,
|
|
typename _Compare>
|
|
_OutputIter
|
|
set_difference(_InputIter1 __first1, _InputIter1 __last1,
|
|
_InputIter2 __first2, _InputIter2 __last2,
|
|
_OutputIter __result, _Compare __comp)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter1>);
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter2>);
|
|
__glibcpp_function_requires(_SameTypeConcept<
|
|
typename iterator_traits<_InputIter1>::value_type,
|
|
typename iterator_traits<_InputIter2>::value_type>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_InputIter1>::value_type>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
|
|
typename iterator_traits<_InputIter1>::value_type,
|
|
typename iterator_traits<_InputIter2>::value_type>);
|
|
|
|
while (__first1 != __last1 && __first2 != __last2)
|
|
if (__comp(*__first1, *__first2)) {
|
|
*__result = *__first1;
|
|
++__first1;
|
|
++__result;
|
|
}
|
|
else if (__comp(*__first2, *__first1))
|
|
++__first2;
|
|
else {
|
|
++__first1;
|
|
++__first2;
|
|
}
|
|
return copy(__first1, __last1, __result);
|
|
}
|
|
|
|
template<typename _InputIter1, typename _InputIter2, typename _OutputIter>
|
|
_OutputIter
|
|
set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1,
|
|
_InputIter2 __first2, _InputIter2 __last2,
|
|
_OutputIter __result)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter1>);
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter2>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_InputIter1>::value_type>);
|
|
__glibcpp_function_requires(_SameTypeConcept<
|
|
typename iterator_traits<_InputIter1>::value_type,
|
|
typename iterator_traits<_InputIter2>::value_type>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<
|
|
typename iterator_traits<_InputIter1>::value_type>);
|
|
|
|
while (__first1 != __last1 && __first2 != __last2)
|
|
if (*__first1 < *__first2) {
|
|
*__result = *__first1;
|
|
++__first1;
|
|
++__result;
|
|
}
|
|
else if (*__first2 < *__first1) {
|
|
*__result = *__first2;
|
|
++__first2;
|
|
++__result;
|
|
}
|
|
else {
|
|
++__first1;
|
|
++__first2;
|
|
}
|
|
return copy(__first2, __last2, copy(__first1, __last1, __result));
|
|
}
|
|
|
|
template<typename _InputIter1, typename _InputIter2, typename _OutputIter,
|
|
typename _Compare>
|
|
_OutputIter
|
|
set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1,
|
|
_InputIter2 __first2, _InputIter2 __last2,
|
|
_OutputIter __result,
|
|
_Compare __comp)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter1>);
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter2>);
|
|
__glibcpp_function_requires(_SameTypeConcept<
|
|
typename iterator_traits<_InputIter1>::value_type,
|
|
typename iterator_traits<_InputIter2>::value_type>);
|
|
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
|
|
typename iterator_traits<_InputIter1>::value_type>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
|
|
typename iterator_traits<_InputIter1>::value_type,
|
|
typename iterator_traits<_InputIter2>::value_type>);
|
|
|
|
while (__first1 != __last1 && __first2 != __last2)
|
|
if (__comp(*__first1, *__first2)) {
|
|
*__result = *__first1;
|
|
++__first1;
|
|
++__result;
|
|
}
|
|
else if (__comp(*__first2, *__first1)) {
|
|
*__result = *__first2;
|
|
++__first2;
|
|
++__result;
|
|
}
|
|
else {
|
|
++__first1;
|
|
++__first2;
|
|
}
|
|
return copy(__first2, __last2, copy(__first1, __last1, __result));
|
|
}
|
|
|
|
// min_element and max_element, with and without an explicitly supplied
|
|
// comparison function.
|
|
|
|
template<typename _ForwardIter>
|
|
_ForwardIter
|
|
max_element(_ForwardIter __first, _ForwardIter __last)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
|
|
if (__first == __last) return __first;
|
|
_ForwardIter __result = __first;
|
|
while (++__first != __last)
|
|
if (*__result < *__first)
|
|
__result = __first;
|
|
return __result;
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _Compare>
|
|
_ForwardIter
|
|
max_element(_ForwardIter __first, _ForwardIter __last,
|
|
_Compare __comp)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
|
|
typename iterator_traits<_ForwardIter>::value_type,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
|
|
if (__first == __last) return __first;
|
|
_ForwardIter __result = __first;
|
|
while (++__first != __last)
|
|
if (__comp(*__result, *__first)) __result = __first;
|
|
return __result;
|
|
}
|
|
|
|
template<typename _ForwardIter>
|
|
_ForwardIter
|
|
min_element(_ForwardIter __first, _ForwardIter __last)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
|
|
if (__first == __last) return __first;
|
|
_ForwardIter __result = __first;
|
|
while (++__first != __last)
|
|
if (*__first < *__result)
|
|
__result = __first;
|
|
return __result;
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _Compare>
|
|
_ForwardIter
|
|
min_element(_ForwardIter __first, _ForwardIter __last,
|
|
_Compare __comp)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
|
|
typename iterator_traits<_ForwardIter>::value_type,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
|
|
if (__first == __last) return __first;
|
|
_ForwardIter __result = __first;
|
|
while (++__first != __last)
|
|
if (__comp(*__first, *__result))
|
|
__result = __first;
|
|
return __result;
|
|
}
|
|
|
|
// next_permutation and prev_permutation, with and without an explicitly
|
|
// supplied comparison function.
|
|
|
|
template<typename _BidirectionalIter>
|
|
bool
|
|
next_permutation(_BidirectionalIter __first, _BidirectionalIter __last)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<
|
|
typename iterator_traits<_BidirectionalIter>::value_type>);
|
|
|
|
if (__first == __last)
|
|
return false;
|
|
_BidirectionalIter __i = __first;
|
|
++__i;
|
|
if (__i == __last)
|
|
return false;
|
|
__i = __last;
|
|
--__i;
|
|
|
|
for(;;) {
|
|
_BidirectionalIter __ii = __i;
|
|
--__i;
|
|
if (*__i < *__ii) {
|
|
_BidirectionalIter __j = __last;
|
|
while (!(*__i < *--__j))
|
|
{}
|
|
iter_swap(__i, __j);
|
|
reverse(__ii, __last);
|
|
return true;
|
|
}
|
|
if (__i == __first) {
|
|
reverse(__first, __last);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
template<typename _BidirectionalIter, typename _Compare>
|
|
bool
|
|
next_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
|
|
_Compare __comp)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
|
|
typename iterator_traits<_BidirectionalIter>::value_type,
|
|
typename iterator_traits<_BidirectionalIter>::value_type>);
|
|
|
|
if (__first == __last)
|
|
return false;
|
|
_BidirectionalIter __i = __first;
|
|
++__i;
|
|
if (__i == __last)
|
|
return false;
|
|
__i = __last;
|
|
--__i;
|
|
|
|
for(;;) {
|
|
_BidirectionalIter __ii = __i;
|
|
--__i;
|
|
if (__comp(*__i, *__ii)) {
|
|
_BidirectionalIter __j = __last;
|
|
while (!__comp(*__i, *--__j))
|
|
{}
|
|
iter_swap(__i, __j);
|
|
reverse(__ii, __last);
|
|
return true;
|
|
}
|
|
if (__i == __first) {
|
|
reverse(__first, __last);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
template<typename _BidirectionalIter>
|
|
bool
|
|
prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<
|
|
typename iterator_traits<_BidirectionalIter>::value_type>);
|
|
|
|
if (__first == __last)
|
|
return false;
|
|
_BidirectionalIter __i = __first;
|
|
++__i;
|
|
if (__i == __last)
|
|
return false;
|
|
__i = __last;
|
|
--__i;
|
|
|
|
for(;;) {
|
|
_BidirectionalIter __ii = __i;
|
|
--__i;
|
|
if (*__ii < *__i) {
|
|
_BidirectionalIter __j = __last;
|
|
while (!(*--__j < *__i))
|
|
{}
|
|
iter_swap(__i, __j);
|
|
reverse(__ii, __last);
|
|
return true;
|
|
}
|
|
if (__i == __first) {
|
|
reverse(__first, __last);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
template<typename _BidirectionalIter, typename _Compare>
|
|
bool
|
|
prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
|
|
_Compare __comp)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
|
|
typename iterator_traits<_BidirectionalIter>::value_type,
|
|
typename iterator_traits<_BidirectionalIter>::value_type>);
|
|
|
|
if (__first == __last)
|
|
return false;
|
|
_BidirectionalIter __i = __first;
|
|
++__i;
|
|
if (__i == __last)
|
|
return false;
|
|
__i = __last;
|
|
--__i;
|
|
|
|
for(;;) {
|
|
_BidirectionalIter __ii = __i;
|
|
--__i;
|
|
if (__comp(*__ii, *__i)) {
|
|
_BidirectionalIter __j = __last;
|
|
while (!__comp(*--__j, *__i))
|
|
{}
|
|
iter_swap(__i, __j);
|
|
reverse(__ii, __last);
|
|
return true;
|
|
}
|
|
if (__i == __first) {
|
|
reverse(__first, __last);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// find_first_of, with and without an explicitly supplied comparison function.
|
|
|
|
template<typename _InputIter, typename _ForwardIter>
|
|
_InputIter
|
|
find_first_of(_InputIter __first1, _InputIter __last1,
|
|
_ForwardIter __first2, _ForwardIter __last2)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_EqualOpConcept<
|
|
typename iterator_traits<_InputIter>::value_type,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
|
|
for ( ; __first1 != __last1; ++__first1)
|
|
for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter)
|
|
if (*__first1 == *__iter)
|
|
return __first1;
|
|
return __last1;
|
|
}
|
|
|
|
template<typename _InputIter, typename _ForwardIter, typename _BinaryPredicate>
|
|
_InputIter
|
|
find_first_of(_InputIter __first1, _InputIter __last1,
|
|
_ForwardIter __first2, _ForwardIter __last2,
|
|
_BinaryPredicate __comp)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>);
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_EqualOpConcept<
|
|
typename iterator_traits<_InputIter>::value_type,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
|
|
typename iterator_traits<_InputIter>::value_type,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
|
|
for ( ; __first1 != __last1; ++__first1)
|
|
for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter)
|
|
if (__comp(*__first1, *__iter))
|
|
return __first1;
|
|
return __last1;
|
|
}
|
|
|
|
|
|
// find_end, with and without an explicitly supplied comparison function.
|
|
// Search [first2, last2) as a subsequence in [first1, last1), and return
|
|
// the *last* possible match. Note that find_end for bidirectional iterators
|
|
// is much faster than for forward iterators.
|
|
|
|
// find_end for forward iterators.
|
|
template<typename _ForwardIter1, typename _ForwardIter2>
|
|
_ForwardIter1
|
|
__find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
|
|
_ForwardIter2 __first2, _ForwardIter2 __last2,
|
|
forward_iterator_tag, forward_iterator_tag)
|
|
{
|
|
if (__first2 == __last2)
|
|
return __last1;
|
|
else {
|
|
_ForwardIter1 __result = __last1;
|
|
while (1) {
|
|
_ForwardIter1 __new_result
|
|
= search(__first1, __last1, __first2, __last2);
|
|
if (__new_result == __last1)
|
|
return __result;
|
|
else {
|
|
__result = __new_result;
|
|
__first1 = __new_result;
|
|
++__first1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
template<typename _ForwardIter1, typename _ForwardIter2,
|
|
typename _BinaryPredicate>
|
|
_ForwardIter1
|
|
__find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
|
|
_ForwardIter2 __first2, _ForwardIter2 __last2,
|
|
forward_iterator_tag, forward_iterator_tag,
|
|
_BinaryPredicate __comp)
|
|
{
|
|
if (__first2 == __last2)
|
|
return __last1;
|
|
else {
|
|
_ForwardIter1 __result = __last1;
|
|
while (1) {
|
|
_ForwardIter1 __new_result
|
|
= search(__first1, __last1, __first2, __last2, __comp);
|
|
if (__new_result == __last1)
|
|
return __result;
|
|
else {
|
|
__result = __new_result;
|
|
__first1 = __new_result;
|
|
++__first1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// find_end for bidirectional iterators. Requires partial specialization.
|
|
template<typename _BidirectionalIter1, typename _BidirectionalIter2>
|
|
_BidirectionalIter1
|
|
__find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1,
|
|
_BidirectionalIter2 __first2, _BidirectionalIter2 __last2,
|
|
bidirectional_iterator_tag, bidirectional_iterator_tag)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter1>);
|
|
__glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter2>);
|
|
|
|
typedef reverse_iterator<_BidirectionalIter1> _RevIter1;
|
|
typedef reverse_iterator<_BidirectionalIter2> _RevIter2;
|
|
|
|
_RevIter1 __rlast1(__first1);
|
|
_RevIter2 __rlast2(__first2);
|
|
_RevIter1 __rresult = search(_RevIter1(__last1), __rlast1,
|
|
_RevIter2(__last2), __rlast2);
|
|
|
|
if (__rresult == __rlast1)
|
|
return __last1;
|
|
else {
|
|
_BidirectionalIter1 __result = __rresult.base();
|
|
advance(__result, -distance(__first2, __last2));
|
|
return __result;
|
|
}
|
|
}
|
|
|
|
template<typename _BidirectionalIter1, typename _BidirectionalIter2,
|
|
typename _BinaryPredicate>
|
|
_BidirectionalIter1
|
|
__find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1,
|
|
_BidirectionalIter2 __first2, _BidirectionalIter2 __last2,
|
|
bidirectional_iterator_tag, bidirectional_iterator_tag,
|
|
_BinaryPredicate __comp)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter1>);
|
|
__glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter2>);
|
|
|
|
typedef reverse_iterator<_BidirectionalIter1> _RevIter1;
|
|
typedef reverse_iterator<_BidirectionalIter2> _RevIter2;
|
|
|
|
_RevIter1 __rlast1(__first1);
|
|
_RevIter2 __rlast2(__first2);
|
|
_RevIter1 __rresult = search(_RevIter1(__last1), __rlast1,
|
|
_RevIter2(__last2), __rlast2,
|
|
__comp);
|
|
|
|
if (__rresult == __rlast1)
|
|
return __last1;
|
|
else {
|
|
_BidirectionalIter1 __result = __rresult.base();
|
|
advance(__result, -distance(__first2, __last2));
|
|
return __result;
|
|
}
|
|
}
|
|
|
|
// Dispatching functions for find_end.
|
|
|
|
template<typename _ForwardIter1, typename _ForwardIter2>
|
|
inline _ForwardIter1
|
|
find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
|
|
_ForwardIter2 __first2, _ForwardIter2 __last2)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter1>);
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter2>);
|
|
__glibcpp_function_requires(_EqualOpConcept<
|
|
typename iterator_traits<_ForwardIter1>::value_type,
|
|
typename iterator_traits<_ForwardIter2>::value_type>);
|
|
|
|
return __find_end(__first1, __last1, __first2, __last2,
|
|
__iterator_category(__first1),
|
|
__iterator_category(__first2));
|
|
}
|
|
|
|
template<typename _ForwardIter1, typename _ForwardIter2,
|
|
typename _BinaryPredicate>
|
|
inline _ForwardIter1
|
|
find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
|
|
_ForwardIter2 __first2, _ForwardIter2 __last2,
|
|
_BinaryPredicate __comp)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter1>);
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter2>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
|
|
typename iterator_traits<_ForwardIter1>::value_type,
|
|
typename iterator_traits<_ForwardIter2>::value_type>);
|
|
|
|
return __find_end(__first1, __last1, __first2, __last2,
|
|
__iterator_category(__first1),
|
|
__iterator_category(__first2),
|
|
__comp);
|
|
}
|
|
|
|
// is_heap, a predicate testing whether or not a range is
|
|
// a heap. This function is an extension, not part of the C++
|
|
// standard.
|
|
|
|
template<typename _RandomAccessIter, typename _Distance>
|
|
bool
|
|
__is_heap(_RandomAccessIter __first, _Distance __n)
|
|
{
|
|
_Distance __parent = 0;
|
|
for (_Distance __child = 1; __child < __n; ++__child) {
|
|
if (__first[__parent] < __first[__child])
|
|
return false;
|
|
if ((__child & 1) == 0)
|
|
++__parent;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
template<typename _RandomAccessIter, typename _Distance,
|
|
typename _StrictWeakOrdering>
|
|
bool
|
|
__is_heap(_RandomAccessIter __first, _StrictWeakOrdering __comp,
|
|
_Distance __n)
|
|
{
|
|
_Distance __parent = 0;
|
|
for (_Distance __child = 1; __child < __n; ++__child) {
|
|
if (__comp(__first[__parent], __first[__child]))
|
|
return false;
|
|
if ((__child & 1) == 0)
|
|
++__parent;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
template<typename _RandomAccessIter>
|
|
inline bool
|
|
is_heap(_RandomAccessIter __first, _RandomAccessIter __last)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIter>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<
|
|
typename iterator_traits<_RandomAccessIter>::value_type>);
|
|
|
|
return __is_heap(__first, __last - __first);
|
|
}
|
|
|
|
|
|
template<typename _RandomAccessIter, typename _StrictWeakOrdering>
|
|
inline bool
|
|
is_heap(_RandomAccessIter __first, _RandomAccessIter __last,
|
|
_StrictWeakOrdering __comp)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIter>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering,
|
|
typename iterator_traits<_RandomAccessIter>::value_type,
|
|
typename iterator_traits<_RandomAccessIter>::value_type>);
|
|
|
|
return __is_heap(__first, __comp, __last - __first);
|
|
}
|
|
|
|
// is_sorted, a predicated testing whether a range is sorted in
|
|
// nondescending order. This is an extension, not part of the C++
|
|
// standard.
|
|
|
|
template<typename _ForwardIter>
|
|
bool
|
|
is_sorted(_ForwardIter __first, _ForwardIter __last)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_LessThanComparableConcept<
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
|
|
if (__first == __last)
|
|
return true;
|
|
|
|
_ForwardIter __next = __first;
|
|
for (++__next; __next != __last; __first = __next, ++__next) {
|
|
if (*__next < *__first)
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
template<typename _ForwardIter, typename _StrictWeakOrdering>
|
|
bool
|
|
is_sorted(_ForwardIter __first, _ForwardIter __last, _StrictWeakOrdering __comp)
|
|
{
|
|
// concept requirements
|
|
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>);
|
|
__glibcpp_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering,
|
|
typename iterator_traits<_ForwardIter>::value_type,
|
|
typename iterator_traits<_ForwardIter>::value_type>);
|
|
|
|
if (__first == __last)
|
|
return true;
|
|
|
|
_ForwardIter __next = __first;
|
|
for (++__next; __next != __last; __first = __next, ++__next) {
|
|
if (__comp(*__next, *__first))
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
} // namespace std
|
|
|
|
#endif /* __SGI_STL_INTERNAL_ALGO_H */
|
|
|
|
// Local Variables:
|
|
// mode:C++
|
|
// End:
|