1)equal算法:用来比较两个序列在[first,last)区间内是否相等。如果第二个序列的元素多于第一个序列元素,则多出的元素不予考虑。
// equal算法用来判断两个序列在[frist,last)区间内是否相等。当第二个序列的元素较多时,多出来的元素不予考虑。
// 版本1
template <class _InputIter1, class _InputIter2>
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 <class _InputIter1, class _InputIter2, class _BinaryPredicate>
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 <class _ForwardIter, class _Tp>
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<unsigned char>(__tmp), __last - __first);
}
inline void fill(char* __first, char* __last, const char& __c) {
char __tmp = __c;
memset(__first, static_cast<unsigned char>(__tmp), __last - __first);
}
3)fill_n算法:将[first,last)内的前n个元素改填新值,返回的迭代器指向被填入的最后一个元素的下一个位置。
// fill_n算法用来将[first,last)内的前n个元素改填新值,返回的迭代器指向被填入的最后一个元素的下一位置
template <class _OutputIter, class _Size, class _Tp>
_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 <class _Size>
inline unsigned char* fill_n(unsigned char* __first, _Size __n,
const unsigned char& __c) {
fill(__first, __first + __n, __c);
return __first + __n;
}
template <class _Size>
inline signed char* fill_n(char* __first, _Size __n,
const signed char& __c) {
fill(__first, __first + __n, __c);
return __first + __n;
}
template <class _Size>
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 <class _ForwardIter1, class _ForwardIter2, class _Tp>
inline void __iter_swap(_ForwardIter1 __a, _ForwardIter2 __b, _Tp*) {
_Tp __tmp = *__a; // 执行交换过程
*__a = *__b;
*__b = __tmp;
}
// iter_swap算法用来将两个ForwardIterator所指对象对调。它是迭代器值value type派上用场的一个好例子。
template <class _ForwardIter1, class _ForwardIter2>
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 <class _InputIter1, class _InputIter2>
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 <class _InputIter1, class _InputIter2, class _Compare>
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 <class _Tp>
inline const _Tp& max(const _Tp& __a, const _Tp& __b) {
__STL_REQUIRES(_Tp, _LessThanComparable);
return __a < __b ? __b : __a;
}
// 版本2
template <class _Tp, class _Compare>
inline const _Tp& max(const _Tp& __a, const _Tp& __b, _Compare __comp) {
return __comp(__a, __b) ? __b : __a; // 有comp决定“大小比较”标准
}
7)min算法:取两个对象中的较小值。
// min算法用来取两个对象中的较小值
// 版本1
template <class _Tp>
inline const _Tp& min(const _Tp& __a, const _Tp& __b) {
__STL_REQUIRES(_Tp, _LessThanComparable);
return __b < __a ? __b : __a;
}
// 版本2
template <class _Tp, class _Compare>
inline const _Tp& min(const _Tp& __a, const _Tp& __b, _Compare __comp) {
return __comp(__b, __a) ? __b : __a;
}
8)mismatch算法:用来平行比较两个序列,指出两者之间的第一个不匹配点。返回一对迭代器,分别指向两序列中的不匹配点。如果两序列的所有对应元素都匹配,返回的便是两序列各自的last迭代器。如果第二序列的元素个数比第一序列多,多出来的元素忽略不计。如果第二序列的元素个数比第一序列少,会发生未可预测的行为。
// mismath算法用来平行比较两个序列,指出两者之间的第一个不匹配点。返回一对迭代器,分别指向两序列中的不匹配点。
// 版本1
template <class _InputIter1, class _InputIter2>
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 <class _InputIter1, class _InputIter2, class _BinaryPredicate>
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 <class _Tp>
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 <class _InputIter, class _OutputIter, class _Distance>
inline _OutputIter __copy(_InputIter __first, _InputIter __last,
_OutputIter __result,
input_iterator_tag, _Distance*)
{
for ( ; __first != __last; ++__result, ++__first) // 以迭代器等同与否,决定循环是否继续。速度慢
*__result = *__first;
return __result;
}
// RandomAccessIterator版本
template <class _RandomAccessIter, class _OutputIter, class _Distance>
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 <class _Tp>
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 <class _InputIter, class _OutputIter>
inline _OutputIter __copy_aux2(_InputIter __first, _InputIter __last,
_OutputIter __result, __false_type) {
return __copy(__first, __last, __result,
__ITERATOR_CATEGORY(__first),
__DISTANCE_TYPE(__first));
}
template <class _InputIter, class _OutputIter>
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 <class _Tp>
inline _Tp* __copy_aux2(_Tp* __first, _Tp* __last, _Tp* __result,
__true_type) {
return __copy_trivial(__first, __last, __result);
}
#endif /* __USLC__ */
template <class _Tp>
inline _Tp* __copy_aux2(const _Tp* __first, const _Tp* __last, _Tp* __result,
__true_type) {
return __copy_trivial(__first, __last, __result);
}
template <class _InputIter, class _OutputIter, class _Tp>
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 <class _InputIter, class _OutputIter>
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 <class _InputIter, class _OutputIter, class _BoolType>
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 <class _Tp>
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 <class _Tp>
struct __copy_dispatch<const _Tp*, _Tp*, __true_type>
{
static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) {
return __copy_trivial(__first, __last, __result);
}
};
// 完全泛化版本
template <class _InputIter, class _OutputIter>
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 <class _InputIter, class _OutputIter>
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 <class _BidirectionalIter1, class _BidirectionalIter2,
class _Distance>
inline _BidirectionalIter2 __copy_backward(_BidirectionalIter1 __first,
_BidirectionalIter1 __last,
_BidirectionalIter2 __result,
bidirectional_iterator_tag,
_Distance*)
{
while (__first != __last)
*--__result = *--__last;
return __result;
}
// RandomAccessIter班本
template <class _RandomAccessIter, class _BidirectionalIter, class _Distance>
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 <class _BidirectionalIter1, class _BidirectionalIter2,
class _BoolType>
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 <class _Tp>
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 <class _Tp>
struct __copy_backward_dispatch<const _Tp*, _Tp*, __true_type>
{
static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) {
return __copy_backward_dispatch<_Tp*, _Tp*, __true_type>
::copy(__first, __last, __result);
}
};
template <class _BI1, class _BI2>
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<typename iterator_traits<_BI2>::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 <class _BI1, class _BI2>
inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) {
return __copy_backward(__first, __last, __result,
__ITERATOR_CATEGORY(__first),
__DISTANCE_TYPE(__first));
}
#endif
参考:
STL源码剖析——侯捷
STL源码