C++标准库——advance() & distance() & iter_swap()

本文详细介绍了C++标准库中的三个重要函数:advance()用于迭代器的步进或步退,distance()计算两个迭代器间的距离,iter_swap()实现两个元素的交换。文章通过实例展示了这些函数的具体应用。

C++标准库——advance() & distance() & iter_swap()

本博客转载自:https://blog.youkuaiyun.com/lanzhihui_10086/article/details/41805503

1.advance()

void advance(pos, n);

1.使名为pos的input迭代器步进(或步退)n个元素;
2.对Bidirectional迭代器和Random Access迭代器而言,n可为负值,表示向后退;
3.advance()并不检查迭代器是否超过序列的end()(因为迭代器通常不知道其所操作的容器,因此无从检查)。所以,调用advance()有可能导致未定义行为—-因为对“序列尾端调用operator++”是一种未定义的操作行为;
4.此函数总能根据迭代器类型采用最佳方案,这归功于迭代器特征的运用。面对Random Access迭代器,此函数只是简单的调用pos+=n,因此,具有常量复杂度;对于其他任何类型的迭代器则调用++pos(或–pos,如果n为负)n次,因此对于其他任何类型迭代器,本函数具有线性复杂度。
5.如果需要更换容器或迭代器种类,应该使用advance()而不是operator+=。但是存在“在不提供Random Access迭代器”的容器中,性能变差;
6.advance()没有返回值;
代码示例:

#include<iostream>  
#include<list>  
#include<algorithm>  
using namespace std;  
int main() {  
    list<int> coll;  
    for(int i=1;i<=9;i++) {  
        coll.push_back(i);  
    }  
    list<int>::iterator pos=coll.begin();  
    cout<<*pos<<endl;  
    advance(pos,3);  
    cout<<*pos<<endl;  
    advance(pos,-1);  
    cout<<*pos<<endl;  
    system("pause");  
    return 0;  
}  
运行结果:
1
4
3

2.distance()

函数distance()用来处理两个迭代器之间的距离

int distance(pos1, pos2); //具体返回值的类型可以认为是int

1.传回两个input迭代器pos1和pos2之间的距离;
2.两个迭代器都必须指向同一个容器;
3.对于random access迭代器,此函数仅仅只是传回pos2-pos1,因此具备常数复杂度;
4.对于其他迭代器类型,distance()会不断递增pos1,直到抵达pos2为止,然后传回递增次数,也就是说其他类型的迭代器,distance()具备线性复杂度,所以对于non-random access迭代器,尽力避免使用此函数;
5.如果需要更换容器型别和迭代器的型别,就应该使用distance()而不是operator-,但是存在对“non-random access迭代器”性能变差的问题,并且第一个迭代器绝对不能位于第二个迭代器之后,否则未定义行为;
代码示例:

#include<iostream>  
#include<vector>  
#include<algorithm>  
#include<iterator>  
using namespace std;  
int main() {  
    vector<int> coll;
    for(int i=-3;i<=9;i++) {  
        coll.push_back(i);  
    }  
    vector<int>::iterator pos;  
    pos=find(coll.begin(),coll.end(),5);  
    if(pos!=coll.end()) {  
        cout<<"distance between begining and 5:"<<distance(coll.begin(),pos)<<endl;  
    }  
    else {  
        cout<<"5 not found"<<endl;  
    }  
    system("pause");  
    return 0;  
}  
运行结果:
distance between begining and 5:8

3.iter_swap()

void iter_swap(pos1, pos2);

1.交换迭代器pos1和迭代器pos2所指的值
2.迭代器的类型不必相同,但其所指的两个值必须可以相互赋值
代码示例:

#include<iostream>  
#include<list>  
#include<iterator>  
#include<algorithm>  
using namespace std;  
int main() {  
    list<int> coll;  
    for(int i=1;i<=9;i++) {  
        coll.push_back(i);  
    }   
    copy(coll.begin(),coll.end(),ostream_iterator<int>(cout," "));  
    cout<<endl;  
    iter_swap(coll.begin(),++coll.begin());//交换迭代器所指元素的内容  
    copy(coll.begin(),coll.end(),ostream_iterator<int>(cout," "));  
    cout<<endl;  
    iter_swap(coll.begin(),--coll.end());  
    copy(coll.begin(),coll.end(),ostream_iterator<int>(cout," "));  
    cout<<endl;  
    system("pause");  
    return 0;  
}  
运行结果:
1 2 3 4 5 6 7 8 9

2 1 3 4 5 6 7 8 9

9 1 3 4 5 6 7 8 2
// Core algorithmic facilities -*- C++ -*- // Copyright (C) 2001-2014 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 3, 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. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // &lt;http://www.gnu.org/licenses/&gt;. /* * * 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 &quot;as is&quot; without express or implied warranty. * * * Copyright (c) 1996-1998 * 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 &quot;as is&quot; without express or implied warranty. */ /** @file bits/stl_algobase.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{algorithm} */ #ifndef _STL_ALGOBASE_H #define _STL_ALGOBASE_H 1 #include &lt;bits/c++config.h&gt; #include &lt;bits/functexcept.h&gt; #include &lt;bits/cpp_type_traits.h&gt; #include &lt;ext/type_traits.h&gt; #include &lt;ext/numeric_traits.h&gt; #include &lt;bits/stl_pair.h&gt; #include &lt;bits/stl_iterator_base_types.h&gt; #include &lt;bits/stl_iterator_base_funcs.h&gt; #include &lt;bits/stl_iterator.h&gt; #include &lt;bits/concept_check.h&gt; #include &lt;debug/debug.h&gt; #include &lt;bits/move.h&gt; // For std::swap and _GLIBCXX_MOVE #include &lt;bits/predefined_ops.h&gt; namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus &lt; 201103L // See http://gcc.gnu.org/ml/libstdc++/2004-08/msg00167.html: in a // nutshell, we are partially implementing the resolution of DR 187, // when it&#39;s safe, i.e., the value_types are equal. template&lt;bool _BoolType&gt; struct __iter_swap { template&lt;typename _ForwardIterator1, typename _ForwardIterator2&gt; static void iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) { typedef typename iterator_traits&lt;_ForwardIterator1&gt;::value_type _ValueType1; _ValueType1 __tmp = _GLIBCXX_MOVE(*__a); *__a = _GLIBCXX_MOVE(*__b); *__b = _GLIBCXX_MOVE(__tmp); } }; template&lt;&gt; struct __iter_swap&lt;true&gt; { template&lt;typename _ForwardIterator1, typename _ForwardIterator2&gt; static void iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) { swap(*__a, *__b); } }; #endif /** * @brief Swaps the contents of two iterators. * @ingroup mutating_algorithms * @param __a An iterator. * @param __b Another iterator. * @return Nothing. * * This function swaps the values pointed to by two iterators, not the * iterators themselves. */ template&lt;typename _ForwardIterator1, typename _ForwardIterator2&gt; inline void iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept&lt; _ForwardIterator1&gt;) __glibcxx_function_requires(_Mutable_ForwardIteratorConcept&lt; _ForwardIterator2&gt;) #if __cplusplus &lt; 201103L typedef typename iterator_traits&lt;_ForwardIterator1&gt;::value_type _ValueType1; typedef typename iterator_traits&lt;_ForwardIterator2&gt;::value_type _ValueType2; __glibcxx_function_requires(_ConvertibleConcept&lt;_ValueType1, _ValueType2&gt;) __glibcxx_function_requires(_ConvertibleConcept&lt;_ValueType2, _ValueType1&gt;) typedef typename iterator_traits&lt;_ForwardIterator1&gt;::reference _ReferenceType1; typedef typename iterator_traits&lt;_ForwardIterator2&gt;::reference _ReferenceType2; std::__iter_swap&lt;__are_same&lt;_ValueType1, _ValueType2&gt;::__value &amp;&amp; __are_same&lt;_ValueType1&amp;, _ReferenceType1&gt;::__value &amp;&amp; __are_same&lt;_ValueType2&amp;, _ReferenceType2&gt;::__value&gt;:: iter_swap(__a, __b); #else swap(*__a, *__b); #endif } /** * @brief Swap the elements of two sequences. * @ingroup mutating_algorithms * @param __first1 A forward iterator. * @param __last1 A forward iterator. * @param __first2 A forward iterator. * @return An iterator equal to @p first2+(last1-first1). * * Swaps each element in the range @p [first1,last1) with the * corresponding element in the range @p [first2,(last1-first1)). * The ranges must not overlap. */ template&lt;typename _ForwardIterator1, typename _ForwardIterator2&gt; _ForwardIterator2 swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept&lt; _ForwardIterator1&gt;) __glibcxx_function_requires(_Mutable_ForwardIteratorConcept&lt; _ForwardIterator2&gt;) __glibcxx_requires_valid_range(__first1, __last1); for (; __first1 != __last1; ++__first1, ++__first2) std::iter_swap(__first1, __first2); return __first2; } /** * @brief This does what you think it does. * @ingroup sorting_algorithms * @param __a A thing of arbitrary type. * @param __b Another thing of arbitrary type. * @return The lesser of the parameters. * * This is the simple classic generic implementation. It will work on * temporary expressions, since they are only evaluated once, unlike a * preprocessor macro. */ template&lt;typename _Tp&gt; inline const _Tp&amp; min(const _Tp&amp; __a, const _Tp&amp; __b) { // concept requirements __glibcxx_function_requires(_LessThanComparableConcept&lt;_Tp&gt;) //return __b &lt; __a ? __b : __a; if (__b &lt; __a) return __b; return __a; } /** * @brief This does what you think it does. * @ingroup sorting_algorithms * @param __a A thing of arbitrary type. * @param __b Another thing of arbitrary type. * @return The greater of the parameters. * * This is the simple classic generic implementation. It will work on * temporary expressions, since they are only evaluated once, unlike a * preprocessor macro. */ template&lt;typename _Tp&gt; inline const _Tp&amp; max(const _Tp&amp; __a, const _Tp&amp; __b) { // concept requirements __glibcxx_function_requires(_LessThanComparableConcept&lt;_Tp&gt;) //return __a &lt; __b ? __b : __a; if (__a &lt; __b) return __b; return __a; } /** * @brief This does what you think it does. * @ingroup sorting_algorithms * @param __a A thing of arbitrary type. * @param __b Another thing of arbitrary type. * @param __comp A @link comparison_functors comparison functor@endlink. * @return The lesser of the parameters. * * This will work on temporary expressions, since they are only evaluated * once, unlike a preprocessor macro. */ template&lt;typename _Tp, typename _Compare&gt; inline const _Tp&amp; min(const _Tp&amp; __a, const _Tp&amp; __b, _Compare __comp) { //return __comp(__b, __a) ? __b : __a; if (__comp(__b, __a)) return __b; return __a; } /** * @brief This does what you think it does. * @ingroup sorting_algorithms * @param __a A thing of arbitrary type. * @param __b Another thing of arbitrary type. * @param __comp A @link comparison_functors comparison functor@endlink. * @return The greater of the parameters. * * This will work on temporary expressions, since they are only evaluated * once, unlike a preprocessor macro. */ template&lt;typename _Tp, typename _Compare&gt; inline const _Tp&amp; max(const _Tp&amp; __a, const _Tp&amp; __b, _Compare __comp) { //return __comp(__a, __b) ? __b : __a; if (__comp(__a, __b)) return __b; return __a; } // If _Iterator is a __normal_iterator return its base (a plain pointer, // normally) otherwise return it untouched. See copy, fill, ... template&lt;typename _Iterator&gt; struct _Niter_base : _Iter_base&lt;_Iterator, __is_normal_iterator&lt;_Iterator&gt;::__value&gt; { }; template&lt;typename _Iterator&gt; inline typename _Niter_base&lt;_Iterator&gt;::iterator_type __niter_base(_Iterator __it) { return std::_Niter_base&lt;_Iterator&gt;::_S_base(__it); } // Likewise, for move_iterator. template&lt;typename _Iterator&gt; struct _Miter_base : _Iter_base&lt;_Iterator, __is_move_iterator&lt;_Iterator&gt;::__value&gt; { }; template&lt;typename _Iterator&gt; inline typename _Miter_base&lt;_Iterator&gt;::iterator_type __miter_base(_Iterator __it) { return std::_Miter_base&lt;_Iterator&gt;::_S_base(__it); } // All of these auxiliary structs serve two purposes. (1) Replace // calls to copy with memmove whenever possible. (Memmove, not memcpy, // because the input and output ranges are permitted to overlap.) // (2) If we&#39;re using random access iterators, then write the loop as // a for loop with an explicit count. template&lt;bool, bool, typename&gt; struct __copy_move { template&lt;typename _II, typename _OI&gt; static _OI __copy_m(_II __first, _II __last, _OI __result) { for (; __first != __last; ++__result, ++__first) *__result = *__first; return __result; } }; #if __cplusplus &gt;= 201103L template&lt;typename _Category&gt; struct __copy_move&lt;true, false, _Category&gt; { template&lt;typename _II, typename _OI&gt; static _OI __copy_m(_II __first, _II __last, _OI __result) { for (; __first != __last; ++__result, ++__first) *__result = std::move(*__first); return __result; } }; #endif template&lt;&gt; struct __copy_move&lt;false, false, random_access_iterator_tag&gt; { template&lt;typename _II, typename _OI&gt; static _OI __copy_m(_II __first, _II __last, _OI __result) { typedef typename iterator_traits&lt;_II&gt;::difference_type _Distance; for(_Distance __n = __last - __first; __n &gt; 0; --__n) { *__result = *__first; ++__first; ++__result; } return __result; } }; #if __cplusplus &gt;= 201103L template&lt;&gt; struct __copy_move&lt;true, false, random_access_iterator_tag&gt; { template&lt;typename _II, typename _OI&gt; static _OI __copy_m(_II __first, _II __last, _OI __result) { typedef typename iterator_traits&lt;_II&gt;::difference_type _Distance; for(_Distance __n = __last - __first; __n &gt; 0; --__n) { *__result = std::move(*__first); ++__first; ++__result; } return __result; } }; #endif template&lt;bool _IsMove&gt; struct __copy_move&lt;_IsMove, true, random_access_iterator_tag&gt; { template&lt;typename _Tp&gt; static _Tp* __copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result) { #if __cplusplus &gt;= 201103L // trivial types can have deleted assignment static_assert( is_copy_assignable&lt;_Tp&gt;::value, &quot;type is not assignable&quot; ); #endif const ptrdiff_t _Num = __last - __first; if (_Num) __builtin_memmove(__result, __first, sizeof(_Tp) * _Num); return __result + _Num; } }; template&lt;bool _IsMove, typename _II, typename _OI&gt; inline _OI __copy_move_a(_II __first, _II __last, _OI __result) { typedef typename iterator_traits&lt;_II&gt;::value_type _ValueTypeI; typedef typename iterator_traits&lt;_OI&gt;::value_type _ValueTypeO; typedef typename iterator_traits&lt;_II&gt;::iterator_category _Category; const bool __simple = (__is_trivial(_ValueTypeI) &amp;&amp; __is_pointer&lt;_II&gt;::__value &amp;&amp; __is_pointer&lt;_OI&gt;::__value &amp;&amp; __are_same&lt;_ValueTypeI, _ValueTypeO&gt;::__value); return std::__copy_move&lt;_IsMove, __simple, _Category&gt;::__copy_m(__first, __last, __result); } // Helpers for streambuf iterators (either istream or ostream). // NB: avoid including &lt;iosfwd&gt;, relatively large. template&lt;typename _CharT&gt; struct char_traits; template&lt;typename _CharT, typename _Traits&gt; class istreambuf_iterator; template&lt;typename _CharT, typename _Traits&gt; class ostreambuf_iterator; template&lt;bool _IsMove, typename _CharT&gt; typename __gnu_cxx::__enable_if&lt;__is_char&lt;_CharT&gt;::__value, ostreambuf_iterator&lt;_CharT, char_traits&lt;_CharT&gt; &gt; &gt;::__type __copy_move_a2(_CharT*, _CharT*, ostreambuf_iterator&lt;_CharT, char_traits&lt;_CharT&gt; &gt;); template&lt;bool _IsMove, typename _CharT&gt; typename __gnu_cxx::__enable_if&lt;__is_char&lt;_CharT&gt;::__value, ostreambuf_iterator&lt;_CharT, char_traits&lt;_CharT&gt; &gt; &gt;::__type __copy_move_a2(const _CharT*, const _CharT*, ostreambuf_iterator&lt;_CharT, char_traits&lt;_CharT&gt; &gt;); template&lt;bool _IsMove, typename _CharT&gt; typename __gnu_cxx::__enable_if&lt;__is_char&lt;_CharT&gt;::__value, _CharT*&gt;::__type __copy_move_a2(istreambuf_iterator&lt;_CharT, char_traits&lt;_CharT&gt; &gt;, istreambuf_iterator&lt;_CharT, char_traits&lt;_CharT&gt; &gt;, _CharT*); template&lt;bool _IsMove, typename _II, typename _OI&gt; inline _OI __copy_move_a2(_II __first, _II __last, _OI __result) { return _OI(std::__copy_move_a&lt;_IsMove&gt;(std::__niter_base(__first), std::__niter_base(__last), std::__niter_base(__result))); } /** * @brief Copies the range [first,last) into result. * @ingroup mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __result An output iterator. * @return result + (first - last) * * This inline function will boil down to a call to @c memmove whenever * possible. Failing that, if random access iterators are passed, then the * loop count will be known (and therefore a candidate for compiler * optimizations such as unrolling). Result may not be contained within * [first,last); the copy_backward function should be used instead. * * Note that the end of the output range is permitted to be contained * within [first,last). */ template&lt;typename _II, typename _OI&gt; inline _OI copy(_II __first, _II __last, _OI __result) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept&lt;_II&gt;) __glibcxx_function_requires(_OutputIteratorConcept&lt;_OI, typename iterator_traits&lt;_II&gt;::value_type&gt;) __glibcxx_requires_valid_range(__first, __last); return (std::__copy_move_a2&lt;__is_move_iterator&lt;_II&gt;::__value&gt; (std::__miter_base(__first), std::__miter_base(__last), __result)); } #if __cplusplus &gt;= 201103L /** * @brief Moves the range [first,last) into result. * @ingroup mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __result An output iterator. * @return result + (first - last) * * This inline function will boil down to a call to @c memmove whenever * possible. Failing that, if random access iterators are passed, then the * loop count will be known (and therefore a candidate for compiler * optimizations such as unrolling). Result may not be contained within * [first,last); the move_backward function should be used instead. * * Note that the end of the output range is permitted to be contained * within [first,last). */ template&lt;typename _II, typename _OI&gt; inline _OI move(_II __first, _II __last, _OI __result) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept&lt;_II&gt;) __glibcxx_function_requires(_OutputIteratorConcept&lt;_OI, typename iterator_traits&lt;_II&gt;::value_type&gt;) __glibcxx_requires_valid_range(__first, __last); return std::__copy_move_a2&lt;true&gt;(std::__miter_base(__first), std::__miter_base(__last), __result); } #define _GLIBCXX_MOVE3(_Tp, _Up, _Vp) std::move(_Tp, _Up, _Vp) #else #define _GLIBCXX_MOVE3(_Tp, _Up, _Vp) std::copy(_Tp, _Up, _Vp) #endif template&lt;bool, bool, typename&gt; struct __copy_move_backward { template&lt;typename _BI1, typename _BI2&gt; static _BI2 __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result) { while (__first != __last) *--__result = *--__last; return __result; } }; #if __cplusplus &gt;= 201103L template&lt;typename _Category&gt; struct __copy_move_backward&lt;true, false, _Category&gt; { template&lt;typename _BI1, typename _BI2&gt; static _BI2 __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result) { while (__first != __last) *--__result = std::move(*--__last); return __result; } }; #endif template&lt;&gt; struct __copy_move_backward&lt;false, false, random_access_iterator_tag&gt; { template&lt;typename _BI1, typename _BI2&gt; static _BI2 __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result) { typename iterator_traits&lt;_BI1&gt;::difference_type __n; for (__n = __last - __first; __n &gt; 0; --__n) *--__result = *--__last; return __result; } }; #if __cplusplus &gt;= 201103L template&lt;&gt; struct __copy_move_backward&lt;true, false, random_access_iterator_tag&gt; { template&lt;typename _BI1, typename _BI2&gt; static _BI2 __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result) { typename iterator_traits&lt;_BI1&gt;::difference_type __n; for (__n = __last - __first; __n &gt; 0; --__n) *--__result = std::move(*--__last); return __result; } }; #endif template&lt;bool _IsMove&gt; struct __copy_move_backward&lt;_IsMove, true, random_access_iterator_tag&gt; { template&lt;typename _Tp&gt; static _Tp* __copy_move_b(const _Tp* __first, const _Tp* __last, _Tp* __result) { #if __cplusplus &gt;= 201103L // trivial types can have deleted assignment static_assert( is_copy_assignable&lt;_Tp&gt;::value, &quot;type is not assignable&quot; ); #endif const ptrdiff_t _Num = __last - __first; if (_Num) __builtin_memmove(__result - _Num, __first, sizeof(_Tp) * _Num); return __result - _Num; } }; template&lt;bool _IsMove, typename _BI1, typename _BI2&gt; inline _BI2 __copy_move_backward_a(_BI1 __first, _BI1 __last, _BI2 __result) { typedef typename iterator_traits&lt;_BI1&gt;::value_type _ValueType1; typedef typename iterator_traits&lt;_BI2&gt;::value_type _ValueType2; typedef typename iterator_traits&lt;_BI1&gt;::iterator_category _Category; const bool __simple = (__is_trivial(_ValueType1) &amp;&amp; __is_pointer&lt;_BI1&gt;::__value &amp;&amp; __is_pointer&lt;_BI2&gt;::__value &amp;&amp; __are_same&lt;_ValueType1, _ValueType2&gt;::__value); return std::__copy_move_backward&lt;_IsMove, __simple, _Category&gt;::__copy_move_b(__first, __last, __result); } template&lt;bool _IsMove, typename _BI1, typename _BI2&gt; inline _BI2 __copy_move_backward_a2(_BI1 __first, _BI1 __last, _BI2 __result) { return _BI2(std::__copy_move_backward_a&lt;_IsMove&gt; (std::__niter_base(__first), std::__niter_base(__last), std::__niter_base(__result))); } /** * @brief Copies the range [first,last) into result. * @ingroup mutating_algorithms * @param __first A bidirectional iterator. * @param __last A bidirectional iterator. * @param __result A bidirectional iterator. * @return result - (first - last) * * The function has the same effect as copy, but starts at the end of the * range and works its way to the start, returning the start of the result. * This inline function will boil down to a call to @c memmove whenever * possible. Failing that, if random access iterators are passed, then the * loop count will be known (and therefore a candidate for compiler * optimizations such as unrolling). * * Result may not be in the range (first,last]. Use copy instead. Note * that the start of the output range may overlap [first,last). */ template&lt;typename _BI1, typename _BI2&gt; inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) { // concept requirements __glibcxx_function_requires(_BidirectionalIteratorConcept&lt;_BI1&gt;) __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept&lt;_BI2&gt;) __glibcxx_function_requires(_ConvertibleConcept&lt; typename iterator_traits&lt;_BI1&gt;::value_type, typename iterator_traits&lt;_BI2&gt;::value_type&gt;) __glibcxx_requires_valid_range(__first, __last); return (std::__copy_move_backward_a2&lt;__is_move_iterator&lt;_BI1&gt;::__value&gt; (std::__miter_base(__first), std::__miter_base(__last), __result)); } #if __cplusplus &gt;= 201103L /** * @brief Moves the range [first,last) into result. * @ingroup mutating_algorithms * @param __first A bidirectional iterator. * @param __last A bidirectional iterator. * @param __result A bidirectional iterator. * @return result - (first - last) * * The function has the same effect as move, but starts at the end of the * range and works its way to the start, returning the start of the result. * This inline function will boil down to a call to @c memmove whenever * possible. Failing that, if random access iterators are passed, then the * loop count will be known (and therefore a candidate for compiler * optimizations such as unrolling). * * Result may not be in the range (first,last]. Use move instead. Note * that the start of the output range may overlap [first,last). */ template&lt;typename _BI1, typename _BI2&gt; inline _BI2 move_backward(_BI1 __first, _BI1 __last, _BI2 __result) { // concept requirements __glibcxx_function_requires(_BidirectionalIteratorConcept&lt;_BI1&gt;) __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept&lt;_BI2&gt;) __glibcxx_function_requires(_ConvertibleConcept&lt; typename iterator_traits&lt;_BI1&gt;::value_type, typename iterator_traits&lt;_BI2&gt;::value_type&gt;) __glibcxx_requires_valid_range(__first, __last); return std::__copy_move_backward_a2&lt;true&gt;(std::__miter_base(__first), std::__miter_base(__last), __result); } #define _GLIBCXX_MOVE_BACKWARD3(_Tp, _Up, _Vp) std::move_backward(_Tp, _Up, _Vp) #else #define _GLIBCXX_MOVE_BACKWARD3(_Tp, _Up, _Vp) std::copy_backward(_Tp, _Up, _Vp) #endif template&lt;typename _ForwardIterator, typename _Tp&gt; inline typename __gnu_cxx::__enable_if&lt;!__is_scalar&lt;_Tp&gt;::__value, void&gt;::__type __fill_a(_ForwardIterator __first, _ForwardIterator __last, const _Tp&amp; __value) { for (; __first != __last; ++__first) *__first = __value; } template&lt;typename _ForwardIterator, typename _Tp&gt; inline typename __gnu_cxx::__enable_if&lt;__is_scalar&lt;_Tp&gt;::__value, void&gt;::__type __fill_a(_ForwardIterator __first, _ForwardIterator __last, const _Tp&amp; __value) { const _Tp __tmp = __value; for (; __first != __last; ++__first) *__first = __tmp; } // Specialization: for char types we can use memset. template&lt;typename _Tp&gt; inline typename __gnu_cxx::__enable_if&lt;__is_byte&lt;_Tp&gt;::__value, void&gt;::__type __fill_a(_Tp* __first, _Tp* __last, const _Tp&amp; __c) { const _Tp __tmp = __c; __builtin_memset(__first, static_cast&lt;unsigned char&gt;(__tmp), __last - __first); } /** * @brief Fills the range [first,last) with copies of value. * @ingroup mutating_algorithms * @param __first A forward iterator. * @param __last A forward iterator. * @param __value A reference-to-const of arbitrary type. * @return Nothing. * * This function fills a range with copies of the same value. For char * types filling contiguous areas of memory, this becomes an inline call * to @c memset or @c wmemset. */ template&lt;typename _ForwardIterator, typename _Tp&gt; inline void fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp&amp; __value) { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept&lt; _ForwardIterator&gt;) __glibcxx_requires_valid_range(__first, __last); std::__fill_a(std::__niter_base(__first), std::__niter_base(__last), __value); } template&lt;typename _OutputIterator, typename _Size, typename _Tp&gt; inline typename __gnu_cxx::__enable_if&lt;!__is_scalar&lt;_Tp&gt;::__value, _OutputIterator&gt;::__type __fill_n_a(_OutputIterator __first, _Size __n, const _Tp&amp; __value) { for (__decltype(__n + 0) __niter = __n; __niter &gt; 0; --__niter, ++__first) *__first = __value; return __first; } template&lt;typename _OutputIterator, typename _Size, typename _Tp&gt; inline typename __gnu_cxx::__enable_if&lt;__is_scalar&lt;_Tp&gt;::__value, _OutputIterator&gt;::__type __fill_n_a(_OutputIterator __first, _Size __n, const _Tp&amp; __value) { const _Tp __tmp = __value; for (__decltype(__n + 0) __niter = __n; __niter &gt; 0; --__niter, ++__first) *__first = __tmp; return __first; } template&lt;typename _Size, typename _Tp&gt; inline typename __gnu_cxx::__enable_if&lt;__is_byte&lt;_Tp&gt;::__value, _Tp*&gt;::__type __fill_n_a(_Tp* __first, _Size __n, const _Tp&amp; __c) { std::__fill_a(__first, __first + __n, __c); return __first + __n; } /** * @brief Fills the range [first,first+n) with copies of value. * @ingroup mutating_algorithms * @param __first An output iterator. * @param __n The count of copies to perform. * @param __value A reference-to-const of arbitrary type. * @return The iterator at first+n. * * This function fills a range with copies of the same value. For char * types filling contiguous areas of memory, this becomes an inline call * to @c memset or @ wmemset. * * _GLIBCXX_RESOLVE_LIB_DEFECTS * DR 865. More algorithms that throw away information */ template&lt;typename _OI, typename _Size, typename _Tp&gt; inline _OI fill_n(_OI __first, _Size __n, const _Tp&amp; __value) { // concept requirements __glibcxx_function_requires(_OutputIteratorConcept&lt;_OI, _Tp&gt;) return _OI(std::__fill_n_a(std::__niter_base(__first), __n, __value)); } template&lt;bool _BoolType&gt; struct __equal { template&lt;typename _II1, typename _II2&gt; static bool equal(_II1 __first1, _II1 __last1, _II2 __first2) { for (; __first1 != __last1; ++__first1, ++__first2) if (!(*__first1 == *__first2)) return false; return true; } }; template&lt;&gt; struct __equal&lt;true&gt; { template&lt;typename _Tp&gt; static bool equal(const _Tp* __first1, const _Tp* __last1, const _Tp* __first2) { return !__builtin_memcmp(__first1, __first2, sizeof(_Tp) * (__last1 - __first1)); } }; template&lt;typename _II1, typename _II2&gt; inline bool __equal_aux(_II1 __first1, _II1 __last1, _II2 __first2) { typedef typename iterator_traits&lt;_II1&gt;::value_type _ValueType1; typedef typename iterator_traits&lt;_II2&gt;::value_type _ValueType2; const bool __simple = ((__is_integer&lt;_ValueType1&gt;::__value || __is_pointer&lt;_ValueType1&gt;::__value) &amp;&amp; __is_pointer&lt;_II1&gt;::__value &amp;&amp; __is_pointer&lt;_II2&gt;::__value &amp;&amp; __are_same&lt;_ValueType1, _ValueType2&gt;::__value); return std::__equal&lt;__simple&gt;::equal(__first1, __last1, __first2); } template&lt;typename, typename&gt; struct __lc_rai { template&lt;typename _II1, typename _II2&gt; static _II1 __newlast1(_II1, _II1 __last1, _II2, _II2) { return __last1; } template&lt;typename _II&gt; static bool __cnd2(_II __first, _II __last) { return __first != __last; } }; template&lt;&gt; struct __lc_rai&lt;random_access_iterator_tag, random_access_iterator_tag&gt; { template&lt;typename _RAI1, typename _RAI2&gt; static _RAI1 __newlast1(_RAI1 __first1, _RAI1 __last1, _RAI2 __first2, _RAI2 __last2) { const typename iterator_traits&lt;_RAI1&gt;::difference_type __diff1 = __last1 - __first1; const typename iterator_traits&lt;_RAI2&gt;::difference_type __diff2 = __last2 - __first2; return __diff2 &lt; __diff1 ? __first1 + __diff2 : __last1; } template&lt;typename _RAI&gt; static bool __cnd2(_RAI, _RAI) { return true; } }; template&lt;typename _II1, typename _II2, typename _Compare&gt; bool __lexicographical_compare_impl(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2, _Compare __comp) { typedef typename iterator_traits&lt;_II1&gt;::iterator_category _Category1; typedef typename iterator_traits&lt;_II2&gt;::iterator_category _Category2; typedef std::__lc_rai&lt;_Category1, _Category2&gt; __rai_type; __last1 = __rai_type::__newlast1(__first1, __last1, __first2, __last2); for (; __first1 != __last1 &amp;&amp; __rai_type::__cnd2(__first2, __last2); ++__first1, ++__first2) { if (__comp(__first1, __first2)) return true; if (__comp(__first2, __first1)) return false; } return __first1 == __last1 &amp;&amp; __first2 != __last2; } template&lt;bool _BoolType&gt; struct __lexicographical_compare { template&lt;typename _II1, typename _II2&gt; static bool __lc(_II1, _II1, _II2, _II2); }; template&lt;bool _BoolType&gt; template&lt;typename _II1, typename _II2&gt; bool __lexicographical_compare&lt;_BoolType&gt;:: __lc(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2) { return std::__lexicographical_compare_impl(__first1, __last1, __first2, __last2, __gnu_cxx::__ops::__iter_less_iter()); } template&lt;&gt; struct __lexicographical_compare&lt;true&gt; { template&lt;typename _Tp, typename _Up&gt; static bool __lc(const _Tp* __first1, const _Tp* __last1, const _Up* __first2, const _Up* __last2) { const size_t __len1 = __last1 - __first1; const size_t __len2 = __last2 - __first2; const int __result = __builtin_memcmp(__first1, __first2, std::min(__len1, __len2)); return __result != 0 ? __result &lt; 0 : __len1 &lt; __len2; } }; template&lt;typename _II1, typename _II2&gt; inline bool __lexicographical_compare_aux(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2) { typedef typename iterator_traits&lt;_II1&gt;::value_type _ValueType1; typedef typename iterator_traits&lt;_II2&gt;::value_type _ValueType2; const bool __simple = (__is_byte&lt;_ValueType1&gt;::__value &amp;&amp; __is_byte&lt;_ValueType2&gt;::__value &amp;&amp; !__gnu_cxx::__numeric_traits&lt;_ValueType1&gt;::__is_signed &amp;&amp; !__gnu_cxx::__numeric_traits&lt;_ValueType2&gt;::__is_signed &amp;&amp; __is_pointer&lt;_II1&gt;::__value &amp;&amp; __is_pointer&lt;_II2&gt;::__value); return std::__lexicographical_compare&lt;__simple&gt;::__lc(__first1, __last1, __first2, __last2); } template&lt;typename _ForwardIterator, typename _Tp, typename _Compare&gt; _ForwardIterator __lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp&amp; __val, _Compare __comp) { typedef typename iterator_traits&lt;_ForwardIterator&gt;::difference_type _DistanceType; _DistanceType __len = std::distance(__first, __last); while (__len &gt; 0) { _DistanceType __half = __len &gt;&gt; 1; _ForwardIterator __middle = __first; std::advance(__middle, __half); if (__comp(__middle, __val)) { __first = __middle; ++__first; __len = __len - __half - 1; } else __len = __half; } return __first; } /** * @brief Finds the first position in which @a val could be inserted * without changing the ordering. * @param __first An iterator. * @param __last Another iterator. * @param __val The search term. * @return An iterator pointing to the first element &lt;em&gt;not less * than&lt;/em&gt; @a val, or end() if every element is less than * @a val. * @ingroup binary_search_algorithms */ template&lt;typename _ForwardIterator, typename _Tp&gt; inline _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp&amp; __val) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept&lt;_ForwardIterator&gt;) __glibcxx_function_requires(_LessThanOpConcept&lt; typename iterator_traits&lt;_ForwardIterator&gt;::value_type, _Tp&gt;) __glibcxx_requires_partitioned_lower(__first, __last, __val); return std::__lower_bound(__first, __last, __val, __gnu_cxx::__ops::__iter_less_val()); } /// This is a helper function for the sort routines and for random.tcc. // Precondition: __n &gt; 0. inline _GLIBCXX_CONSTEXPR int __lg(int __n) { return sizeof(int) * __CHAR_BIT__ - 1 - __builtin_clz(__n); } inline _GLIBCXX_CONSTEXPR unsigned __lg(unsigned __n) { return sizeof(int) * __CHAR_BIT__ - 1 - __builtin_clz(__n); } inline _GLIBCXX_CONSTEXPR long __lg(long __n) { return sizeof(long) * __CHAR_BIT__ - 1 - __builtin_clzl(__n); } inline _GLIBCXX_CONSTEXPR unsigned long __lg(unsigned long __n) { return sizeof(long) * __CHAR_BIT__ - 1 - __builtin_clzl(__n); } inline _GLIBCXX_CONSTEXPR long long __lg(long long __n) { return sizeof(long long) * __CHAR_BIT__ - 1 - __builtin_clzll(__n); } inline _GLIBCXX_CONSTEXPR unsigned long long __lg(unsigned long long __n) { return sizeof(long long) * __CHAR_BIT__ - 1 - __builtin_clzll(__n); } _GLIBCXX_END_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_ALGO /** * @brief Tests a range for element-wise equality. * @ingroup non_mutating_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @return A boolean true or false. * * This compares the elements of two ranges using @c == and returns true or * false depending on whether all of the corresponding elements of the * ranges are equal. */ template&lt;typename _II1, typename _II2&gt; inline bool equal(_II1 __first1, _II1 __last1, _II2 __first2) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept&lt;_II1&gt;) __glibcxx_function_requires(_InputIteratorConcept&lt;_II2&gt;) __glibcxx_function_requires(_EqualOpConcept&lt; typename iterator_traits&lt;_II1&gt;::value_type, typename iterator_traits&lt;_II2&gt;::value_type&gt;) __glibcxx_requires_valid_range(__first1, __last1); return std::__equal_aux(std::__niter_base(__first1), std::__niter_base(__last1), std::__niter_base(__first2)); } /** * @brief Tests a range for element-wise equality. * @ingroup non_mutating_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __binary_pred A binary predicate @link functors * functor@endlink. * @return A boolean true or false. * * This compares the elements of two ranges using the binary_pred * parameter, and returns true or * false depending on whether all of the corresponding elements of the * ranges are equal. */ template&lt;typename _IIter1, typename _IIter2, typename _BinaryPredicate&gt; inline bool equal(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _BinaryPredicate __binary_pred) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept&lt;_IIter1&gt;) __glibcxx_function_requires(_InputIteratorConcept&lt;_IIter2&gt;) __glibcxx_requires_valid_range(__first1, __last1); for (; __first1 != __last1; ++__first1, ++__first2) if (!bool(__binary_pred(*__first1, *__first2))) return false; return true; } #if __cplusplus &gt; 201103L #define __cpp_lib_robust_nonmodifying_seq_ops 201304 /** * @brief Tests a range for element-wise equality. * @ingroup non_mutating_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __last2 An input iterator. * @return A boolean true or false. * * This compares the elements of two ranges using @c == and returns true or * false depending on whether all of the corresponding elements of the * ranges are equal. */ template&lt;typename _II1, typename _II2&gt; inline bool equal(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept&lt;_II1&gt;) __glibcxx_function_requires(_InputIteratorConcept&lt;_II2&gt;) __glibcxx_function_requires(_EqualOpConcept&lt; typename iterator_traits&lt;_II1&gt;::value_type, typename iterator_traits&lt;_II2&gt;::value_type&gt;) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); using _RATag = random_access_iterator_tag; using _Cat1 = typename iterator_traits&lt;_II1&gt;::iterator_category; using _Cat2 = typename iterator_traits&lt;_II2&gt;::iterator_category; using _RAIters = __and_&lt;is_same&lt;_Cat1, _RATag&gt;, is_same&lt;_Cat2, _RATag&gt;&gt;; if (_RAIters()) { auto __d1 = std::distance(__first1, __last1); auto __d2 = std::distance(__first2, __last2); if (__d1 != __d2) return false; return _GLIBCXX_STD_A::equal(__first1, __last1, __first2); } for (; __first1 != __last1 &amp;&amp; __first2 != __last2; ++__first1, ++__first2) if (!(*__first1 == *__first2)) return false; return __first1 == __last1 &amp;&amp; __first2 == __last2; } /** * @brief Tests a range for element-wise equality. * @ingroup non_mutating_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __last2 An input iterator. * @param __binary_pred A binary predicate @link functors * functor@endlink. * @return A boolean true or false. * * This compares the elements of two ranges using the binary_pred * parameter, and returns true or * false depending on whether all of the corresponding elements of the * ranges are equal. */ template&lt;typename _IIter1, typename _IIter2, typename _BinaryPredicate&gt; inline bool equal(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _IIter2 __last2, _BinaryPredicate __binary_pred) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept&lt;_IIter1&gt;) __glibcxx_function_requires(_InputIteratorConcept&lt;_IIter2&gt;) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); using _RATag = random_access_iterator_tag; using _Cat1 = typename iterator_traits&lt;_IIter1&gt;::iterator_category; using _Cat2 = typename iterator_traits&lt;_IIter2&gt;::iterator_category; using _RAIters = __and_&lt;is_same&lt;_Cat1, _RATag&gt;, is_same&lt;_Cat2, _RATag&gt;&gt;; if (_RAIters()) { auto __d1 = std::distance(__first1, __last1); auto __d2 = std::distance(__first2, __last2); if (__d1 != __d2) return false; return _GLIBCXX_STD_A::equal(__first1, __last1, __first2, __binary_pred); } for (; __first1 != __last1 &amp;&amp; __first2 != __last2; ++__first1, ++__first2) if (!bool(__binary_pred(*__first1, *__first2))) return false; return __first1 == __last1 &amp;&amp; __first2 == __last2; } #endif /** * @brief Performs @b dictionary comparison on ranges. * @ingroup sorting_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __last2 An input iterator. * @return A boolean true or false. * * &lt;em&gt;Returns true if the sequence of elements defined by the range * [first1,last1) is lexicographically less than the sequence of elements * defined by the range [first2,last2). Returns false otherwise.&lt;/em&gt; * (Quoted from [25.3.8]/1.) If the iterators are all character pointers, * then this is an inline call to @c memcmp. */ template&lt;typename _II1, typename _II2&gt; inline bool lexicographical_compare(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2) { #ifdef _GLIBCXX_CONCEPT_CHECKS // concept requirements typedef typename iterator_traits&lt;_II1&gt;::value_type _ValueType1; typedef typename iterator_traits&lt;_II2&gt;::value_type _ValueType2; #endif __glibcxx_function_requires(_InputIteratorConcept&lt;_II1&gt;) __glibcxx_function_requires(_InputIteratorConcept&lt;_II2&gt;) __glibcxx_function_requires(_LessThanOpConcept&lt;_ValueType1, _ValueType2&gt;) __glibcxx_function_requires(_LessThanOpConcept&lt;_ValueType2, _ValueType1&gt;) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); return std::__lexicographical_compare_aux(std::__niter_base(__first1), std::__niter_base(__last1), std::__niter_base(__first2), std::__niter_base(__last2)); } /** * @brief Performs @b dictionary comparison on ranges. * @ingroup sorting_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __last2 An input iterator. * @param __comp A @link comparison_functors comparison functor@endlink. * @return A boolean true or false. * * The same as the four-parameter @c lexicographical_compare, but uses the * comp parameter instead of @c &lt;. */ template&lt;typename _II1, typename _II2, typename _Compare&gt; inline bool lexicographical_compare(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2, _Compare __comp) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept&lt;_II1&gt;) __glibcxx_function_requires(_InputIteratorConcept&lt;_II2&gt;) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); return std::__lexicographical_compare_impl (__first1, __last1, __first2, __last2, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } template&lt;typename _InputIterator1, typename _InputIterator2, typename _BinaryPredicate&gt; pair&lt;_InputIterator1, _InputIterator2&gt; __mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __binary_pred) { while (__first1 != __last1 &amp;&amp; __binary_pred(__first1, __first2)) { ++__first1; ++__first2; } return pair&lt;_InputIterator1, _InputIterator2&gt;(__first1, __first2); } /** * @brief Finds the places in ranges which don&#39;t match. * @ingroup non_mutating_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @return A pair of iterators pointing to the first mismatch. * * This compares the elements of two ranges using @c == and returns a pair * of iterators. The first iterator points into the first range, the * second iterator points into the second range, and the elements pointed * to by the iterators are not equal. */ template&lt;typename _InputIterator1, typename _InputIterator2&gt; inline pair&lt;_InputIterator1, _InputIterator2&gt; mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept&lt;_InputIterator1&gt;) __glibcxx_function_requires(_InputIteratorConcept&lt;_InputIterator2&gt;) __glibcxx_function_requires(_EqualOpConcept&lt; typename iterator_traits&lt;_InputIterator1&gt;::value_type, typename iterator_traits&lt;_InputIterator2&gt;::value_type&gt;) __glibcxx_requires_valid_range(__first1, __last1); return _GLIBCXX_STD_A::__mismatch(__first1, __last1, __first2, __gnu_cxx::__ops::__iter_equal_to_iter()); } /** * @brief Finds the places in ranges which don&#39;t match. * @ingroup non_mutating_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __binary_pred A binary predicate @link functors * functor@endlink. * @return A pair of iterators pointing to the first mismatch. * * This compares the elements of two ranges using the binary_pred * parameter, and returns a pair * of iterators. The first iterator points into the first range, the * second iterator points into the second range, and the elements pointed * to by the iterators are not equal. */ template&lt;typename _InputIterator1, typename _InputIterator2, typename _BinaryPredicate&gt; inline pair&lt;_InputIterator1, _InputIterator2&gt; mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __binary_pred) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept&lt;_InputIterator1&gt;) __glibcxx_function_requires(_InputIteratorConcept&lt;_InputIterator2&gt;) __glibcxx_requires_valid_range(__first1, __last1); return _GLIBCXX_STD_A::__mismatch(__first1, __last1, __first2, __gnu_cxx::__ops::__iter_comp_iter(__binary_pred)); } #if __cplusplus &gt; 201103L template&lt;typename _InputIterator1, typename _InputIterator2, typename _BinaryPredicate&gt; pair&lt;_InputIterator1, _InputIterator2&gt; __mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __binary_pred) { while (__first1 != __last1 &amp;&amp; __first2 != __last2 &amp;&amp; __binary_pred(__first1, __first2)) { ++__first1; ++__first2; } return pair&lt;_InputIterator1, _InputIterator2&gt;(__first1, __first2); } /** * @brief Finds the places in ranges which don&#39;t match. * @ingroup non_mutating_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __last2 An input iterator. * @return A pair of iterators pointing to the first mismatch. * * This compares the elements of two ranges using @c == and returns a pair * of iterators. The first iterator points into the first range, the * second iterator points into the second range, and the elements pointed * to by the iterators are not equal. */ template&lt;typename _InputIterator1, typename _InputIterator2&gt; inline pair&lt;_InputIterator1, _InputIterator2&gt; mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept&lt;_InputIterator1&gt;) __glibcxx_function_requires(_InputIteratorConcept&lt;_InputIterator2&gt;) __glibcxx_function_requires(_EqualOpConcept&lt; typename iterator_traits&lt;_InputIterator1&gt;::value_type, typename iterator_traits&lt;_InputIterator2&gt;::value_type&gt;) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); return _GLIBCXX_STD_A::__mismatch(__first1, __last1, __first2, __last2, __gnu_cxx::__ops::__iter_equal_to_iter()); } /** * @brief Finds the places in ranges which don&#39;t match. * @ingroup non_mutating_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __last2 An input iterator. * @param __binary_pred A binary predicate @link functors * functor@endlink. * @return A pair of iterators pointing to the first mismatch. * * This compares the elements of two ranges using the binary_pred * parameter, and returns a pair * of iterators. The first iterator points into the first range, the * second iterator points into the second range, and the elements pointed * to by the iterators are not equal. */ template&lt;typename _InputIterator1, typename _InputIterator2, typename _BinaryPredicate&gt; inline pair&lt;_InputIterator1, _InputIterator2&gt; mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __binary_pred) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept&lt;_InputIterator1&gt;) __glibcxx_function_requires(_InputIteratorConcept&lt;_InputIterator2&gt;) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); return _GLIBCXX_STD_A::__mismatch(__first1, __last1, __first2, __last2, __gnu_cxx::__ops::__iter_comp_iter(__binary_pred)); } #endif _GLIBCXX_END_NAMESPACE_ALGO } // namespace std // NB: This file is included within many other C++ includes, as a way // of getting the base algorithms. So, make sure that parallel bits // come in too if requested. #ifdef _GLIBCXX_PARALLEL # include &lt;parallel/algobase.h&gt; #endif #endif
最新发布
12-20
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值