1)equal算法:用來比較兩個序列在[first,last)區間內是否相等。如果第二個序列的元素多於第一個序列元素,則多出的元素不予考慮。
// equal算法用來判斷兩個序列在[frist,last)區間內是否相等。當第二個序列的元素較多時,多出來的元素不予考慮。
// 版本1
template
inline bool equal(_InputIter1 __first1, _InputIter1 __last1,
_InputIter2 __first2) {
__STL_REQUIRES(_InputIter1, _InputIterator);
__STL_REQUIRES(_InputIter2, _InputIterator);
__STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type,
_EqualityComparable);
__STL_REQUIRES(typename iterator_traits<_InputIter2>::value_type,
_EqualityComparable);
// 以下,將序列一走過一遍。序列二亦步亦趨
// 如果序列一的元素個數多序列二的個數,就糟糕了
for ( ; __first1 != __last1; ++__first1, ++__first2)
if (*__first1 != *__first2) // 只要對應元素不相等
return false; // 就結束並返回false
return true; // 至此,全部相等,返回true
}
// 版本2
template
inline bool equal(_InputIter1 __first1, _InputIter1 __last1,
_InputIter2 __first2, _BinaryPredicate __binary_pred) {
__STL_REQUIRES(_InputIter1, _InputIterator);
__STL_REQUIRES(_InputIter2, _InputIterator);
for ( ; __first1 != __last1; ++__first1, ++__first2)
if (!__binary_pred(*__first1, *__first2))
return false;
return true;
}
2)fill算法:將[first,last)內的所有元素改填新值。
// fill算法用來將[first,last)內的所有元素改填新值
template
void fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __value) {
__STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator);
for ( ; __first != __last; ++__first) // 迭代走過整個區間
*__first = __value; // 設定新值
}
// 版本2
// 特例化,針對單字節類型使用memset函數實現
inline void fill(unsigned char* __first, unsigned char* __last,
const unsigned char& __c) {
unsigned char __tmp = __c;
memset(__first, __tmp, __last - __first);
}
inline void fill(signed char* __first, signed char* __last,
const signed char& __c) {
signed char __tmp = __c;
memset(__first, static_cast(__tmp), __last - __first);
}
inline void fill(char* __first, char* __last, const char& __c) {
char __tmp = __c;
memset(__first, static_cast(__tmp), __last - __first);
}
3)fill_n算法:將[first,last)內的前n個元素改填新值,返回的迭代器指向被填入的最後一個元素的下一個位置。
// fill_n算法用來將[first,last)內的前n個元素改填新值,返回的迭代器指向被填入的最後一個元素的下一位置
template
_OutputIter fill_n(_OutputIter __first, _Size __n, const _Tp& __value) {
__STL_REQUIRES(_OutputIter, _OutputIterator);
for ( ; __n > 0; --__n, ++__first) // 經過n個元素
*__first = __value; // 設定新值
return __first;
}
// 版本2
#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
template
inline unsigned char* fill_n(unsigned char* __first, _Size __n,
const unsigned char& __c) {
fill(__first, __first + __n, __c);
return __first + __n;
}
template
inline signed char* fill_n(char* __first, _Size __n,
const signed char& __c) {
fill(__first, __first + __n, __c);
return __first + __n;
}
template
inline char* fill_n(char* __first, _Size __n, const char& __c) {
fill(__first, __first + __n, __c);
return __first + __n;
}
4)iter_swap算法:將兩個ForwardIterator所指對象對調。它是迭代器value type派上用場的一個好例子。該函數必須知道迭代器的value type,才能夠據此聲明一個對象,用來暫時存放迭代器所指對象。
// iter_swap算法:將兩個ForwardIterator所指對象對調。它是迭代器value type派上用場的一個好例子。
// 該函數必須知道迭代器的value type,才能夠據此聲明一個對象,用來暫時存放迭代器所指對象。
template
inline void __iter_swap(_ForwardIter1 __a, _ForwardIter2 __b, _Tp*) {
_Tp __tmp = *__a; // 執行交換過程
*__a = *__b;
*__b = __tmp;
}
// iter_swap算法用來將兩個ForwardIterator所指對象對調。它是迭代器值value type派上用場的一個好例子。
template
inline void iter_swap(_ForwardIter1 __a, _ForwardIter2 __b) {
__STL_REQUIRES(_ForwardIter1, _Mutable_ForwardIterator);
__STL_REQUIRES(_ForwardIter2, _Mutable_ForwardIterator);
__STL_CONVERTIBLE(typename iterator_traits<_ForwardIter1>::value_type,
typename iterator_traits<_ForwardIter2>::value_type);
__STL_CONVERTIBLE(typename iterator_traits<_ForwardIter2>::value_type,
typename iterator_traits<_ForwardIter1>::value_type);
__iter_swap(__a, __b, __VALUE_TYPE(__a));
}
5)lexicographical_compare算法:以“字典排列方式”對兩個序列[first1,last1)和[firs2,last2)進行比較。比較操作針對兩序列中的對應位置上的元素進行,並持續直到1)某一組對應元素彼此不相等;2)同時到達last1和last2(當兩序列的大小相同);3)到達last1或last2(當兩序列的大小不同)。
這兩個函數在對應位置上發現第一組不相等的元素時,有以下幾種可能:1)如果第一序列的元素較小,返回true,否則返回false;2)如果到達last1而尚未到達last2,返回true;3)如果達到last2而尚未到達last1,返回false;4)如果同時到達last1和last2(即所有元素都匹配)返回false。
// lexicographical_compare算法用來以“字典排列方式”對兩個序列[first1,last1)和[firs2,last2)進行比較。
// 版本1
template
bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1,
_InputIter2 __first2, _InputIter2 __last2) {
__STL_REQUIRES(_InputIter1, _InputIterator);
__STL_REQUIRES(_InputIter2, _InputIterator);
__STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type,
_LessThanComparable);
__STL_REQUIRES(typename iterator_traits<_InputIter2>::value_type,
_LessThanComparable);
// 以下,任何一個序列到達尾端,就結束。否則兩序列就相應元素意義進行比較
for ( ; __first1 != __last1 && __first2 != __last2
; ++__first1, ++__first2) {
if (*__first1 < *__first2) // 第一序列元素值小於第二序列的相應元素值
return true;
if (*__first2 < *__first1) // 第二序列元素值小於第一序列的相應元素值
return false;
// 如果不符合以上兩條件,表示兩值相等,那就進行下一組相應元素值的比對
}
// 進行到這裡,如果第一序列到達尾端而第二序列尚有余額,那麼第一序列小於第二序列
return __first1 == __last1 && __first2 != __last2;
}
// 版本2
template
bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1,
_InputIter2 __first2, _InputIter2 __last2,
_Compare __comp) {
__STL_REQUIRES(_InputIter1, _InputIterator);
__STL_REQUIRES(_InputIter2, _InputIterator);
for ( ; __first1 != __last1 && __first2 != __last2
; ++__first1, ++__first2) {
if (__comp(*__first1, *__first2))
return true;
if (__comp(*__first2, *__first1))
return false;
}
return __first1 == __last1 && __first2 != __last2;
}
// lexicograhical_compare算法用來以“字典排列方式”對兩個序列[first1,last1)和[firs2,last2)進行比較。
// 下面利用原生指針const unsigned char *實現
// 版本3
inline bool
lexicographical_compare(const unsigned char* __first1,
const unsigned char* __last1,
const unsigned char* __first2,
const unsigned char* __last2)
{
const size_t __len1 = __last1 - __first1; // 第一序列長度
const size_t __len2 = __last2 - __first2; // 第二序列長度
const int __result = memcmp(__first1, __first2, min(__len1, __len2)); // 先比較相同長度的一段。memcmp()速度極快
return __result != 0 ? __result < 0 : __len1 < __len2; // 如果不相上下,則長度較長者被視為比較大
}
// 版本4
inline bool lexicographical_compare(const char* __first1, const char* __last1,
const char* __first2, const char* __last2)
{
#if CHAR_MAX == SCHAR_MAX
return lexicographical_compare((const signed char*) __first1,
(const signed char*) __last1,
(const signed char*) __first2,
(const signed char*) __last2);
#else /* CHAR_MAX == SCHAR_MAX */
return lexicographical_compare((const unsigned char*) __first1,
(const unsigned char*) __last1,
(const unsigned char*) __first2,
(const unsigned char*) __last2);
#endif /* CHAR_MAX == SCHAR_MAX */
}
6)max算法:取兩個對象中的較大值。
// max算法用來取兩個對象中的較大值
// 版本1
template
inline const _Tp& max(const _Tp& __a, const _Tp& __b) {
__STL_REQUIRES(_Tp, _LessThanComparable);
return __a < __b ? __b : __a;
}
// 版本2
template
inline const _Tp& max(const _Tp& __a, const _Tp& __b, _Compare __comp) {
return __comp(__a, __b) ? __b : __a; // 有comp決定“大小比較”標准
}
7)min算法:取兩個對象中的較小值。
// min算法用來取兩個對象中的較小值
// 版本1
template
inline const _Tp& min(const _Tp& __a, const _Tp& __b) {
__STL_REQUIRES(_Tp, _LessThanComparable);
return __b < __a ? __b : __a;
}
// 版本2
template
inline const _Tp& min(const _Tp& __a, const _Tp& __b, _Compare __comp) {
return __comp(__b, __a) ? __b : __a;
}
8)mismatch算法:用來平行比較兩個序列,指出兩者之間的第一個不匹配點。返回一對迭代器,分別指向兩序列中的不匹配點。如果兩序列的所有對應元素都匹配,返回的便是兩序列各自的last迭代器。如果第二序列的元素個數比第一序列多,多出來的元素忽略不計。如果第二序列的元素個數比第一序列少,會發生未可預測的行為。
// mismath算法用來平行比較兩個序列,指出兩者之間的第一個不匹配點。返回一對迭代器,分別指向兩序列中的不匹配點。
// 版本1
template
pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1,
_InputIter1 __last1,
_InputIter2 __first2) {
__STL_REQUIRES(_InputIter1, _InputIterator);
__STL_REQUIRES(_InputIter2, _InputIterator);
__STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type,
_EqualityComparable);
__STL_REQUIRES(typename iterator_traits<_InputIter2>::value_type,
_EqualityComparable);
// 以下,如果序列一走完,就結束
// 以下,如果序列一和序列二的對應元素相等,就結束
// 顯然,序列一的元素個數必須多過序列二的元素個數,否則結果無可預期
while (__first1 != __last1 && *__first1 == *__first2) {
++__first1;
++__first2;
}
return pair<_InputIter1, _InputIter2>(__first1, __first2);
}
// 版本2
template
pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1,
_InputIter1 __last1,
_InputIter2 __first2,
_BinaryPredicate __binary_pred) {
__STL_REQUIRES(_InputIter1, _InputIterator);
__STL_REQUIRES(_InputIter2, _InputIterator);
while (__first1 != __last1 && __binary_pred(*__first1, *__first2)) {
++__first1;
++__first2;
}
return pair<_InputIter1, _InputIter2>(__first1, __first2);
}
9)swap算法:用來交換(對調)兩個對象的內容。
// swap算法用來交換(對調)兩個對象的內容
template
inline void swap(_Tp& __a, _Tp& __b) {
__STL_REQUIRES(_Tp, _Assignable);
_Tp __tmp = __a; // 執行交換過程
__a = __b;
__b = __tmp;
}
10)copy算法:將輸入區間[first,last)內的元素賦值到輸出區間[result,result+(last-first))內。它返回一個迭代器:result+(last-first)。copy對其template參數所要求的條件非常寬松。其輸入區間只需有Input構成,輸出區間只需由OutputIterator構成即可。copy算法,將任何容器的任何一段區間的內容,復制到任何容器的任何一段區間上。copy算法為了提高效率,使用了各種方法,包括:函數重載、型別特性、偏特化等編程技巧。
// copy算法用來將[first,last)內的元素復制到輸出區間[result,result+(last-first))內
// InputIterator版本
template
inline _OutputIter __copy(_InputIter __first, _InputIter __last,
_OutputIter __result,
input_iterator_tag, _Distance*)
{
for ( ; __first != __last; ++__result, ++__first) // 以迭代器等同與否,決定循環是否繼續。速度慢
*__result = *__first;
return __result;
}
// RandomAccessIterator版本
template
inline _OutputIter
__copy(_RandomAccessIter __first, _RandomAccessIter __last,
_OutputIter __result, random_access_iterator_tag, _Distance*)
{
for (_Distance __n = __last - __first; __n > 0; --__n) { // 以n決定循環的次數。速度快
*__result = *__first;
++__first;
++__result;
}
return __result;
}
// 以下版本適用於“指針所指對象具備trival assignment operator”
template
inline _Tp*
__copy_trivial(const _Tp* __first, const _Tp* __last, _Tp* __result) {
memmove(__result, __first, sizeof(_Tp) * (__last - __first));
return __result + (__last - __first);
}
#if defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER)
template
inline _OutputIter __copy_aux2(_InputIter __first, _InputIter __last,
_OutputIter __result, __false_type) {
return __copy(__first, __last, __result,
__ITERATOR_CATEGORY(__first),
__DISTANCE_TYPE(__first));
}
template
inline _OutputIter __copy_aux2(_InputIter __first, _InputIter __last,
_OutputIter __result, __true_type) {
return __copy(__first, __last, __result,
__ITERATOR_CATEGORY(__first),
__DISTANCE_TYPE(__first));
}
#ifndef __USLC__
template
inline _Tp* __copy_aux2(_Tp* __first, _Tp* __last, _Tp* __result,
__true_type) {
return __copy_trivial(__first, __last, __result);
}
#endif /* __USLC__ */
template
inline _Tp* __copy_aux2(const _Tp* __first, const _Tp* __last, _Tp* __result,
__true_type) {
return __copy_trivial(__first, __last, __result);
}
template
inline _OutputIter __copy_aux(_InputIter __first, _InputIter __last,
_OutputIter __result, _Tp*) {
typedef typename __type_traits<_Tp>::has_trivial_assignment_operator
_Trivial;
return __copy_aux2(__first, __last, __result, _Trivial());
}
template
inline _OutputIter copy(_InputIter __first, _InputIter __last,
_OutputIter __result) {
__STL_REQUIRES(_InputIter, _InputIterator);
__STL_REQUIRES(_OutputIter, _OutputIterator);
return __copy_aux(__first, __last, __result, __VALUE_TYPE(__first));
}
// Hack for compilers that don't have partial ordering of function templates
// but do have partial specialization of class templates.
#elif defined(__STL_CLASS_PARTIAL_SPECIALIZATION)
// 完全泛化版本
template
struct __copy_dispatch {
static _OutputIter copy(_InputIter __first, _InputIter __last,
_OutputIter __result) {
typedef typename iterator_traits<_InputIter>::iterator_category _Category;
typedef typename iterator_traits<_InputIter>::difference_type _Distance;
return __copy(__first, __last, __result, _Category(), (_Distance*) 0);
}
};
// copy函數的泛化版本中調用一個__copy_dispatch()函數,此函數有一個完全泛化版本和兩個偏特化版本
// 偏特化版本(1),兩個參數都是T*指針形式
template
struct __copy_dispatch<_Tp*, _Tp*, __true_type>
{
static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) {
return __copy_trivial(__first, __last, __result);
}
};
// 偏特化版本(2),第一個參數為const T*指針形式,第二個參數為T*指針形式
template
struct __copy_dispatch
{
static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) {
return __copy_trivial(__first, __last, __result);
}
};
// 完全泛化版本
template
inline _OutputIter copy(_InputIter __first, _InputIter __last,
_OutputIter __result) {
__STL_REQUIRES(_InputIter, _InputIterator);
__STL_REQUIRES(_OutputIter, _OutputIterator);
typedef typename iterator_traits<_InputIter>::value_type _Tp;
typedef typename __type_traits<_Tp>::has_trivial_assignment_operator
_Trivial;
return __copy_dispatch<_InputIter, _OutputIter, _Trivial>
::copy(__first, __last, __result);
}
// Fallback for compilers with neither partial ordering nor partial
// specialization. Define the faster version for the basic builtin
// types.
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
template
inline _OutputIter copy(_InputIter __first, _InputIter __last,
_OutputIter __result)
{
return __copy(__first, __last, __result,
__ITERATOR_CATEGORY(__first),
__DISTANCE_TYPE(__first));
}
#define __SGI_STL_DECLARE_COPY_TRIVIAL(_Tp) \
inline _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { \
memmove(__result, __first, sizeof(_Tp) * (__last - __first)); \
return __result + (__last - __first); \
}
__SGI_STL_DECLARE_COPY_TRIVIAL(char)
__SGI_STL_DECLARE_COPY_TRIVIAL(signed char)
__SGI_STL_DECLARE_COPY_TRIVIAL(unsigned char)
__SGI_STL_DECLARE_COPY_TRIVIAL(short)
__SGI_STL_DECLARE_COPY_TRIVIAL(unsigned short)
__SGI_STL_DECLARE_COPY_TRIVIAL(int)
__SGI_STL_DECLARE_COPY_TRIVIAL(unsigned int)
__SGI_STL_DECLARE_COPY_TRIVIAL(long)
__SGI_STL_DECLARE_COPY_TRIVIAL(unsigned long)
#ifdef __STL_HAS_WCHAR_T
__SGI_STL_DECLARE_COPY_TRIVIAL(wchar_t)
#endif
#ifdef _STL_LONG_LONG
__SGI_STL_DECLARE_COPY_TRIVIAL(long long)
__SGI_STL_DECLARE_COPY_TRIVIAL(unsigned long long)
#endif
__SGI_STL_DECLARE_COPY_TRIVIAL(float)
__SGI_STL_DECLARE_COPY_TRIVIAL(double)
__SGI_STL_DECLARE_COPY_TRIVIAL(long double)
#undef __SGI_STL_DECLARE_COPY_TRIVIAL
#endif
11)copy_backward算法:將[first,last)區間內的每一個元素,以逆性的方向復制到以result-1為起點,方向亦為逆行的區間上。返回一個迭代器:result-(last-first)。copy_backward所接受的迭代器必須是BidirectionalIterators,才能夠“倒行逆施”。使用copy_backward算法,可將任何容器的任何一段區間的內容,復制到任何容器的任何一段區間上。如果輸入區間和輸出區間完全沒有重疊,則毫無問題,否則需特別注意。
// copy_backward算法用來將[first,last)區間內的每一個元素,以逆行的方向復制到以result-1為起點,方向亦為逆行的區間上。
// BidirectionalIter版本
template
inline _BidirectionalIter2 __copy_backward(_BidirectionalIter1 __first,
_BidirectionalIter1 __last,
_BidirectionalIter2 __result,
bidirectional_iterator_tag,
_Distance*)
{
while (__first != __last)
*--__result = *--__last;
return __result;
}
// RandomAccessIter班本
template
inline _BidirectionalIter __copy_backward(_RandomAccessIter __first,
_RandomAccessIter __last,
_BidirectionalIter __result,
random_access_iterator_tag,
_Distance*)
{
for (_Distance __n = __last - __first; __n > 0; --__n)
*--__result = *--__last;
return __result;
}
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
// This dispatch class is a workaround for compilers that do not
// have partial ordering of function templates. All we're doing is
// creating a specialization so that we can turn a call to copy_backward
// into a memmove whenever possible.
template
struct __copy_backward_dispatch
{
typedef typename iterator_traits<_BidirectionalIter1>::iterator_category
_Cat;
typedef typename iterator_traits<_BidirectionalIter1>::difference_type
_Distance;
static _BidirectionalIter2 copy(_BidirectionalIter1 __first,
_BidirectionalIter1 __last,
_BidirectionalIter2 __result) {
return __copy_backward(__first, __last, __result, _Cat(), (_Distance*) 0);
}
};
template
struct __copy_backward_dispatch<_Tp*, _Tp*, __true_type>
{
static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) {
const ptrdiff_t _Num = __last - __first;
memmove(__result - _Num, __first, sizeof(_Tp) * _Num);
return __result - _Num;
}
};
template
struct __copy_backward_dispatch
{
static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) {
return __copy_backward_dispatch<_Tp*, _Tp*, __true_type>
::copy(__first, __last, __result);
}
};
template
inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) {
__STL_REQUIRES(_BI1, _BidirectionalIterator);
__STL_REQUIRES(_BI2, _Mutable_BidirectionalIterator);
__STL_CONVERTIBLE(typename iterator_traits<_BI1>::value_type,
typename iterator_traits<_BI2>::value_type);
typedef typename __type_traits::value_type>
::has_trivial_assignment_operator
_Trivial;
return __copy_backward_dispatch<_BI1, _BI2, _Trivial>
::copy(__first, __last, __result);
}
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
// copy_backward算法:將[first,last)區間內的每一個元素,以逆性的方向復制到以result-1為起點,方向亦為逆行的區間上。
template
inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) {
return __copy_backward(__first, __last, __result,
__ITERATOR_CATEGORY(__first),
__DISTANCE_TYPE(__first));
}
#endif