STL源码分析--迭代器iterator
1. 简介
作为STL六大组件之一的迭代器(iterator),它提供一种方法,使之能够依次访问容器内所含的各个元素,而又不需暴露容器的内部表述方式。它扮演着容器与算法之间的胶合剂,也是所谓的“泛型指针”。从实现的角度看,迭代器是一种将operator*,operator->,operator++,operator--等指针相关操作予以重载的类模板。所有STL容器都有自己专属的迭代器。
2. 迭代器的几个特性
template<typename _Category, typename _Tp, typename _Distance = ptrdiff_t,
typename _Pointer = _Tp*, typename _Reference = _Tp&>
struct _GLIBCXX17_DEPRECATED iterator
{
typedef _Category iterator_category; // 迭代器类别
typedef _Tp value_type; // 迭代器指向的对象类型
typedef _Distance difference_type; // 迭代器间距离表示
typedef _Pointer pointer; // 迭代器指向对象的指针类型表示
typedef _Reference reference; // 迭代器指向对象的引用类型表示
};
迭代器的类别有以下几种:
-
Input Interator:迭代器所指对象不允许改变,即只读。迭代器只能单向遍历,支持operator++
-
Output Interator:迭代器所指对象只写。迭代器只能单向遍历,支持operator++
-
Forward Iterator:迭代器可在指定区间内单向遍历,并所指对象允许读写,支持operator++
-
Bidirectional Iterator:迭代器可在指定区间内双向遍历,并所指对象允许读写,支持operator++,operator--
-
Random Access Iterator:涵盖所有指针的算数能力,包括p++,p--,++p,--p,p+n,p-n,p[n],p1-p2,p1<p2。原生指针也作为一种 Random Access Iterator类型的迭代器。
五种迭代器类别关系如下图:
迭代器Iterator里的特性_Category ,即指如上的几种迭代器类别,在STL中以如下几个结构体体现
// Marking input iterators.
struct input_iterator_tag { };
// Marking output iterators.
struct output_iterator_tag { };
// Forward iterators support a superset of input iterator operations.
struct forward_iterator_tag : public input_iterator_tag { };
// Bidirectional iterators support a superset of forward iterator operations.
struct bidirectional_iterator_tag : public forward_iterator_tag { };
// Random-access iterators support a superset of bidirectional iterator operations.
struct random_access_iterator_tag : public bidirectional_iterator_tag { };
上述几个struct只做标签使用,不需要任何成员。之所以用struct来定义,是因为通过struct或class,可利用C++的重载机制和继承机制,来简化代码。<bits/stl_iterator_base_funcs.h>中的advance()和distance()函数可很好地体现。
// 以下为__advance的几个重载函数,该函数主要用于将迭代器移动n个单位。
// 不同的迭代器类别,迭代器移动的实现不一样
template<typename _InputIterator, typename _Distance>
inline _GLIBCXX14_CONSTEXPR void
__advance(_InputIterator& __i, _Distance __n, input_iterator_tag)
{
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_assert(__n >= 0);
while (__n--)
++__i;
}
template<typename _BidirectionalIterator, typename _Distance>
inline _GLIBCXX14_CONSTEXPR void
__advance(_BidirectionalIterator& __i, _Distance __n, bidirectional_iterator_tag)
{
__glibcxx_function_requires(_BidirectionalIteratorConcept<_BidirectionalIterator>)
if (__n > 0)
while (__n--)
++__i;
else
while (__n++)
--__i;
}
template<typename _RandomAccessIterator, typename _Distance>
inline _GLIBCXX14_CONSTEXPR void
__advance(_RandomAccessIterator& __i, _Distance __n, random_access_iterator_tag)
{
__glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>)
if (__builtin_constant_p(__n) && __n == 1)
++__i;
else if (__builtin_constant_p(__n) && __n == -1)
--__i;
else
__i += __n;
}
template<typename _InputIterator, typename _Distance>
inline _GLIBCXX17_CONSTEXPR void
advance(_InputIterator& __i, _Distance __n)
{
typename iterator_traits<_InputIterator>::difference_type __d = __n;
std::__advance(__i, __d, std::__iterator_category(__i));
}
通过struct或class来定义迭代器的类别,而不是通过enum、int等方式区分,使其可以利用C++的重载机制,以同一函数命名,将不同类别迭代器的特性操作实现。同时,如上__advance()函数实现,因为Forward Iterator的迭代器移动n个单位的操作与Input Iterator一致,通过C++的继承机制可以避免函数void __advance(_ForwardIterator& __i, _Distance __n, forward_iterator_tag);的定义,从而简化代码。
distance()函数的是实现如下:
// 以下为__distance的几个重载函数,该函数主要用于计算迭代器__first和__last间的距离。
template<typename _InputIterator>
inline _GLIBCXX14_CONSTEXPR
typename iterator_traits<_InputIterator>::difference_type
__distance(_InputIterator __first, _InputIterator __last, input_iterator_tag)
{
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
typename iterator_traits<_InputIterator>::difference_type __n = 0;
while (__first != __last)
{
++__first;
++__n;
}
return __n;
}
template<typename _RandomAccessIterator>
inline _GLIBCXX14_CONSTEXPR
typename iterator_traits<_RandomAccessIterator>::difference_type
__distance(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag)
{
__glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>)
return __last - __first;
}
template<typename _InputIterator>
_GLIBCXX_NODISCARD
inline _GLIBCXX17_CONSTEXPR
typename iterator_traits<_InputIterator>::difference_type
distance(_InputIterator __first, _InputIterator __last)
{
return std::__distance(__first, __last, std::__iterator_category(__first));
}
__glibcxx_function_requires宏的作用是“限制某类型的特定的操作是合法的”,如果不满足,则编译失败。STL整合了Boost里c++ concept checking的概念。
__builtin_constant_是GCC的内建函数,用于判断一个值是否为编译时常数,如果参数的值是常数,函数返回 1,否则返回 0。
__glibcxx_function_requires宏的实现如下,同时摘取宏 __glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) 做简单说明。
// 定义在 <bits/concept_check.h>
#if !defined(_GLIBCXX_CONCEPT_CHECKS) || !_GLIBCXX_HOSTED
#define __glibcxx_function_requires(...)
#else
#define __glibcxx_function_requires(...) \
__gnu_cxx::__function_requires< __gnu_cxx::__VA_ARGS__ >();
#endif
// 定义在 <bits/boost_concept_check.h>
template <class _Concept>
_GLIBCXX14_CONSTEXPR inline void __function_requires()
{
void (_Concept::*__x)() _IsUnused = &_Concept::__constraints;
}
template <class _Tp>
struct _RandomAccessIteratorConcept
{
void __constraints() {
// 判断 迭代器_Tp是否具有 Bidrectional Iterator的特性
__function_requires< _BidirectionalIteratorConcept<_Tp> >();
// 判断 迭代器_Tp是否具有 可比较(即支持 >, >=, <, <= 运算符)的特性
__function_requires< _ComparableConcept<_Tp> >();
// 判断 迭代器_Tp是否具有 可转换(即支持赋值运算符)的特性
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::random_access_iterator_tag> >();
typedef typename std::iterator_traits<_Tp>::reference _Ref;
// 判断 迭代器_Tp是否具有 Random Access Iterator的特性
_Tp& __j = __i += __n; // require assignment addition operator
__i = __i + __n; __i = __n + __i; // require addition with difference type
_Tp& __k = __i -= __n; // require assignment subtraction op
__i = __i - __n; // require subtraction with difference type
__n = __i - __j; // require difference operator
_Ref __r = __i[__n]; // require element access operator
}
_Tp __a, __b;
_Tp __i, __j;
typename std::iterator_traits<_Tp>::difference_type __n;
};
3. 迭代器特性的萃取
上面描述了迭代器定义的几大特性——类别、对象类型、距离、指针、引用。而需要使用这几大特性,则需借助STL的萃取机制。STL通过定义iterator_traits类,萃取出各个迭代器的特性。iterator_traits类的定义如下
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2408. SFINAE-friendly common_type/iterator_traits is missing in C++14
template<typename _Iterator, typename = __void_t<>>
struct __iterator_traits { };
#if ! __cpp_lib_concepts
template<typename _Iterator>
struct __iterator_traits<_Iterator,
__void_t<typename _Iterator::iterator_category,
typename _Iterator::value_type,
typename _Iterator::difference_type,
typename _Iterator::pointer,
typename _Iterator::reference>>
{
typedef typename _Iterator::iterator_category iterator_category;
typedef typename _Iterator::value_type value_type;
typedef typename _Iterator::difference_type difference_type;
typedef typename _Iterator::pointer pointer;
typedef typename _Iterator::reference reference;
};
#endif // ! concepts
template<typename _Iterator>
struct iterator_traits
: public __iterator_traits<_Iterator> { };
#else // ! C++11
template<typename _Iterator>
struct iterator_traits
{
typedef typename _Iterator::iterator_category iterator_category;
typedef typename _Iterator::value_type value_type;
typedef typename _Iterator::difference_type difference_type;
typedef typename _Iterator::pointer pointer;
typedef typename _Iterator::reference reference;
};
#endif // C++11
因为原生指针并非class,无法为其定义内嵌型别,所以还需要为原生指针定义偏特化版本的模板实现
#if __cplusplus > 201703L
/// Partial specialization for object pointer types.
template<typename _Tp>
#if __cpp_concepts >= 201907L
requires is_object_v<_Tp>
#endif
struct iterator_traits<_Tp*>
{
using iterator_concept = contiguous_iterator_tag;
using iterator_category = random_access_iterator_tag;
using value_type = remove_cv_t<_Tp>;
using difference_type = ptrdiff_t;
using pointer = _Tp*;
using reference = _Tp&;
};
#else
/// Partial specialization for pointer types.
template<typename _Tp>
struct iterator_traits<_Tp*>
{
typedef random_access_iterator_tag iterator_category;
typedef _Tp value_type;
typedef ptrdiff_t difference_type;
typedef _Tp* pointer;
typedef _Tp& reference;
};
/// Partial specialization for const pointer types.
template<typename _Tp>
struct iterator_traits<const _Tp*>
{
typedef random_access_iterator_tag iterator_category;
typedef _Tp value_type;
typedef ptrdiff_t difference_type;
typedef const _Tp* pointer;
typedef const _Tp& reference;
};
#endif
通过iterator_traits萃取出迭代器型别的方式如下:
template<typename _Iter>
inline _GLIBCXX_CONSTEXPR
typename iterator_traits<_Iter>::iterator_category
__iterator_category(const _Iter&)
{ return typename iterator_traits<_Iter>::iterator_category(); }
4. 几种特制的迭代器适配器
4.1 reverse_iterator
反向迭代器,该迭代器的遍历方向与正常迭代器的遍历方向相反,其++操作是向前遍历,--操作参数向后遍历。与正常迭代器 i 存在如下等式关系:&*(reverse_iterator(i)) == &*(i - 1)
// 反向迭代器实现(删除了部分代码)
template<typename _Iterator>
class reverse_iterator
: public iterator<typename iterator_traits<_Iterator>::iterator_category,
typename iterator_traits<_Iterator>::value_type,
typename iterator_traits<_Iterator>::difference_type,
typename iterator_traits<_Iterator>::pointer,
typename iterator_traits<_Iterator>::reference>
{
protected:
_Iterator current;
typedef iterator_traits<_Iterator> __traits_type;
public:
typedef _Iterator iterator_type;
typedef typename __traits_type::pointer pointer;
#if ! __cpp_lib_concepts
typedef typename __traits_type::difference_type difference_type;
typedef typename __traits_type::reference reference;
#else
using iterator_concept = __conditional_t<random_access_iterator<_Iterator>, random_access_iterator_tag, bidirectional_iterator_tag>;
using iterator_category = __detail::__clamp_iter_cat<typename __traits_type::iterator_category, random_access_iterator_tag>;
using value_type = iter_value_t<_Iterator>;
using difference_type = iter_difference_t<_Iterator>;
using reference = iter_reference_t<_Iterator>;
#endif
// 默认构造
_GLIBCXX17_CONSTEXPR
reverse_iterator()
_GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator())) : current(){ }
explicit _GLIBCXX17_CONSTEXPR
reverse_iterator(iterator_type __x)
_GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(__x))) : current(__x) { }
// 拷贝构造
_GLIBCXX17_CONSTEXPR
reverse_iterator(const reverse_iterator& __x)
_GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(__x.current)))
: current(__x.current)
{ }
#if __cplusplus >= 201103L
reverse_iterator& operator=(const reverse_iterator&) = default;
#endif
template<typename _Iter>
#if __cpp_lib_concepts
requires __convertible<_Iter>
#endif
_GLIBCXX17_CONSTEXPR
reverse_iterator(const reverse_iterator<_Iter>& __x)
_GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(__x.current))) : current(__x.current) { }
// 重载赋值运算符
#if __cplusplus >= 201103L
template<typename _Iter>
#if __cpp_lib_concepts
requires __convertible<_Iter> && assignable_from<_Iterator&, const _Iter&>
#endif
_GLIBCXX17_CONSTEXPR
reverse_iterator&
operator=(const reverse_iterator<_Iter>& __x)
_GLIBCXX_NOEXCEPT_IF(noexcept(current = __x.current))
{
current = __x.current;
return *this;
}
#endif
// base函数返回迭代器对象current
_GLIBCXX_NODISCARD
_GLIBCXX17_CONSTEXPR iterator_type
base() const
_GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(current)))
{ return current; }
// 重载*运算符,解引用当前迭代器的前一个指向
_GLIBCXX_NODISCARD
_GLIBCXX17_CONSTEXPR reference
operator*() const
{
_Iterator __tmp = current;
return *--__tmp;
}
// 重载->运算符,返回当前迭代器的前一个指向
_GLIBCXX_NODISCARD
_GLIBCXX17_CONSTEXPR pointer
operator->() const
#if __cplusplus > 201703L && __cpp_concepts >= 201907L
requires is_pointer_v<_Iterator> || requires(const _Iterator __i) { __i.operator->(); }
#endif
{
_Iterator __tmp = current;
--__tmp;
return _S_to_pointer(__tmp);
}
// 重载++运算符,迭代器向前遍历,返回遍历后的迭代器
_GLIBCXX17_CONSTEXPR reverse_iterator&
operator++()
{
--current;
return *this;
}
// 重载++(int)运算符,迭代器向前遍历,返回遍历前的迭代器
_GLIBCXX17_CONSTEXPR reverse_iterator
operator++(int)
{
reverse_iterator __tmp = *this;
--current;
return __tmp;
}
// 重载--运算符,迭代器向后遍历,返回遍历后的迭代器
_GLIBCXX17_CONSTEXPR reverse_iterator&
operator--()
{
++current;
return *this;
}
// 重载--(int)运算符,迭代器向后遍历,返回遍历前的迭代器
_GLIBCXX17_CONSTEXPR reverse_iterator
operator--(int)
{
reverse_iterator __tmp = *this;
++current;
return __tmp;
}
// 重载+运算符,迭代器向前遍历n个单位
_GLIBCXX_NODISCARD
_GLIBCXX17_CONSTEXPR reverse_iterator
operator+(difference_type __n) const
{ return reverse_iterator(current - __n); }
// 重载+=运算符,迭代器向前遍历n个单位
_GLIBCXX17_CONSTEXPR reverse_iterator&
operator+=(difference_type __n)
{
current -= __n;
return *this;
}
// 重载-运算符,迭代器向后遍历n个单位
_GLIBCXX_NODISCARD
_GLIBCXX17_CONSTEXPR reverse_iterator
operator-(difference_type __n) const
{ return reverse_iterator(current + __n); }
// 重载-=运算符,迭代器向后遍历n个单位
_GLIBCXX17_CONSTEXPR reverse_iterator&
operator-=(difference_type __n)
{
current += __n;
return *this;
}
// 重载[]运算符,随机存取
_GLIBCXX_NODISCARD
_GLIBCXX17_CONSTEXPR reference
operator[](difference_type __n) const
{ return *(*this + __n); }
private:
// 原生指针版本
template<typename _Tp>
static _GLIBCXX17_CONSTEXPR _Tp*
_S_to_pointer(_Tp* __p)
{ return __p; }
// 迭代器指针版本
template<typename _Tp>
static _GLIBCXX17_CONSTEXPR pointer
_S_to_pointer(_Tp __t)
{ return __t.operator->(); }
};
#if __cplusplus <= 201703L || ! defined __cpp_lib_concepts
template<typename _Iterator>
_GLIBCXX_NODISCARD
inline _GLIBCXX17_CONSTEXPR bool
operator==(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return __x.base() == __y.base(); }
template<typename _Iterator>
_GLIBCXX_NODISCARD
inline _GLIBCXX17_CONSTEXPR bool
operator<(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return __y.base() < __x.base(); }
template<typename _Iterator>
_GLIBCXX_NODISCARD
inline _GLIBCXX17_CONSTEXPR bool
operator!=(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return !(__x == __y); }
template<typename _Iterator>
_GLIBCXX_NODISCARD
inline _GLIBCXX17_CONSTEXPR bool
operator>(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return __y < __x; }
template<typename _Iterator>
_GLIBCXX_NODISCARD
inline _GLIBCXX17_CONSTEXPR bool
operator<=(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return !(__y < __x); }
template<typename _Iterator>
_GLIBCXX_NODISCARD
inline _GLIBCXX17_CONSTEXPR bool
operator>=(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return !(__x < __y); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 280. Comparison of reverse_iterator to const reverse_iterator.
template<typename _IteratorL, typename _IteratorR>
_GLIBCXX_NODISCARD
inline _GLIBCXX17_CONSTEXPR bool
operator==(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return __x.base() == __y.base(); }
template<typename _IteratorL, typename _IteratorR>
_GLIBCXX_NODISCARD
inline _GLIBCXX17_CONSTEXPR bool
operator<(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return __x.base() > __y.base(); }
template<typename _IteratorL, typename _IteratorR>
_GLIBCXX_NODISCARD
inline _GLIBCXX17_CONSTEXPR bool
operator!=(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return __x.base() != __y.base(); }
template<typename _IteratorL, typename _IteratorR>
_GLIBCXX_NODISCARD
inline _GLIBCXX17_CONSTEXPR bool
operator>(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return __x.base() < __y.base(); }
template<typename _IteratorL, typename _IteratorR>
inline _GLIBCXX17_CONSTEXPR bool
operator<=(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return __x.base() >= __y.base(); }
template<typename _IteratorL, typename _IteratorR>
_GLIBCXX_NODISCARD
inline _GLIBCXX17_CONSTEXPR bool
operator>=(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return __x.base() <= __y.base(); }
#endif
#if __cplusplus < 201103L
template<typename _Iterator>
inline typename reverse_iterator<_Iterator>::difference_type
operator-(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y)
{ return __y.base() - __x.base(); }
template<typename _IteratorL, typename _IteratorR>
inline typename reverse_iterator<_IteratorL>::difference_type
operator-(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return __y.base() - __x.base(); }
#endif
template<typename _Iterator>
_GLIBCXX_NODISCARD
inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator>
operator+(typename reverse_iterator<_Iterator>::difference_type __n,
const reverse_iterator<_Iterator>& __x)
{ return reverse_iterator<_Iterator>(__x.base() - __n); }
#if __cplusplus >= 201103L
// 将指定迭代器转换为反向迭代器
template<typename _Iterator>
inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator>
__make_reverse_iterator(_Iterator __i)
{ return reverse_iterator<_Iterator>(__i); }
#endif
4.2 back_insert_iterator
该迭代器用于向容器末尾插入元素,容器由迭代器构造的时候作为入参指定。其内部重载了operator=运算符,通过赋值运算可以将元素插入容器末端。
template<typename _Container>
class back_insert_iterator
: public iterator<output_iterator_tag, void, void, void, void>
{
protected:
// 指向迭代器所使用的容器
_Container* container;
public:
// 迭代器所使用的容器类型
typedef _Container container_type;
#if __cplusplus > 201703L
using difference_type = ptrdiff_t;
#endif
// 构造back_insert_iterator的唯一方式
explicit _GLIBCXX20_CONSTEXPR
back_insert_iterator(_Container& __x)
: container(std::__addressof(__x)) { }
// 重载赋值运算符,往容器末尾添加元素,形如
// std::vector<int> vec;
// back_insert_iterator<std::vector<int> > iter(vec);
// iter = 2;
#if __cplusplus < 201103L
back_insert_iterator&
operator=(typename _Container::const_reference __value)
{
container->push_back(__value);
return *this;
}
#else
_GLIBCXX20_CONSTEXPR
back_insert_iterator&
operator=(const typename _Container::value_type& __value)
{
container->push_back(__value);
return *this;
}
// 重载移动赋值运算
_GLIBCXX20_CONSTEXPR
back_insert_iterator&
operator=(typename _Container::value_type&& __value)
{
container->push_back(std::move(__value));
return *this;
}
#endif
// 重载*运算符,什么都不做
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
back_insert_iterator&
operator*()
{ return *this; }
// 重载++运算符,什么都不做
_GLIBCXX20_CONSTEXPR
back_insert_iterator&
operator++()
{ return *this; }
// 重载++(int)运算符,什么都不做
_GLIBCXX20_CONSTEXPR
back_insert_iterator
operator++(int)
{ return *this; }
};
// 全局模板函数,用于创建一个back_insert_iterator对象
template<typename _Container>
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline back_insert_iterator<_Container>
back_inserter(_Container& __x)
{ return back_insert_iterator<_Container>(__x); }
4.3 front_insert_iterator
该迭代器用于向容器首部插入元素,与back_insert_iterator相对,容器由迭代器构造的时候作为入参指定。其内部亦重载了operator=运算符,通过赋值运算可以将元素插入容器首部。
template<typename _Container>
class front_insert_iterator
: public iterator<output_iterator_tag, void, void, void, void>
{
protected:
// 指向迭代器所使用的容器
_Container* container;
public:
// 迭代器所使用容器的类型
typedef _Container container_type;
#if __cplusplus > 201703L
using difference_type = ptrdiff_t;
#endif
// 构造该迭代器的唯一方式
explicit _GLIBCXX20_CONSTEXPR
front_insert_iterator(_Container& __x)
: container(std::__addressof(__x)) { }
// 重载赋值运算符,将元素插入容器前端,形如
// std::vector<int> vec;
// front_insert_iterator<std::vector<int> > iter(vec);
// iter = 2;
#if __cplusplus < 201103L
front_insert_iterator&
operator=(typename _Container::const_reference __value)
{
container->push_front(__value);
return *this;
}
#else
_GLIBCXX20_CONSTEXPR
front_insert_iterator&
operator=(const typename _Container::value_type& __value)
{
container->push_front(__value);
return *this;
}
// 重载移动赋值运算
_GLIBCXX20_CONSTEXPR
front_insert_iterator&
operator=(typename _Container::value_type&& __value)
{
container->push_front(std::move(__value));
return *this;
}
#endif
// 重载*运算符,什么都不做
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
front_insert_iterator&
operator*()
{ return *this; }
// 重载++运算符,什么都不做
_GLIBCXX20_CONSTEXPR
front_insert_iterator&
operator++()
{ return *this; }
// 重载++(int)运算符,什么都不做
_GLIBCXX20_CONSTEXPR
front_insert_iterator
operator++(int)
{ return *this; }
};
// 创建一个front_insert_iterator对象
template<typename _Container>
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline front_insert_iterator<_Container>
front_inserter(_Container& __x)
{ return front_insert_iterator<_Container>(__x); }
4.4 insert_iterator
该迭代器用于向容器指定位置插入元素,其构造函数接受两个参数,一个为容器,一个为容器对应的迭代器。insert_iterator在构造时就已经指定了容器的插入位置了,其内部重载了operator=运算符,通过赋值运算将元素插入到迭代器指向的元素之前。
template<typename _Container>
class insert_iterator
: public iterator<output_iterator_tag, void, void, void, void>
{
#if __cplusplus > 201703L && defined __cpp_lib_concepts
using _Iter = std::__detail::__range_iter_t<_Container>;
#else
// 容器的迭代器类型
typedef typename _Container::iterator _Iter;
#endif
protected:
// 指向容器
_Container* container;
// 容器配套的迭代器
_Iter iter;
public:
// 容器类型
typedef _Container container_type;
#if __cplusplus > 201703L && defined __cpp_lib_concepts
using difference_type = ptrdiff_t;
#endif
// 构造迭代器的唯一方式
_GLIBCXX20_CONSTEXPR
insert_iterator(_Container& __x, _Iter __i)
: container(std::__addressof(__x)), iter(__i) {}
// 重载赋值运算符,在容器指定位置前插入元素,形如
// vector v contains A and Z
// insert_iterator i (v, ++v.begin());
// i = 1;
// i = 2;
// i = 3;
// vector v contains A, 1, 2, 3, and Z
#if __cplusplus < 201103L
insert_iterator&
operator=(typename _Container::const_reference __value)
{
// insert操作将__value插入到iter所指对象之前,其返回值指向新插入的元素
iter = container->insert(iter, __value);
// 将iter++,使其再次指向原先的位置
++iter;
return *this;
}
#else
_GLIBCXX20_CONSTEXPR
insert_iterator&
operator=(const typename _Container::value_type& __value)
{
iter = container->insert(iter, __value);
++iter;
return *this;
}
// 重载移动赋值运算
_GLIBCXX20_CONSTEXPR
insert_iterator&
operator=(typename _Container::value_type&& __value)
{
iter = container->insert(iter, std::move(__value));
++iter;
return *this;
}
#endif
// 重载*运算符,什么都不做
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
insert_iterator&
operator*()
{ return *this; }
// 重载++运算符,什么都不做
_GLIBCXX20_CONSTEXPR
insert_iterator&
operator++()
{ return *this; }
// 重载++(int)运算符,什么都不做
_GLIBCXX20_CONSTEXPR
insert_iterator&
operator++(int)
{ return *this; }
};
// 创建一个insert_iterator实例对象
#if __cplusplus > 201703L && defined __cpp_lib_concepts
template<typename _Container>
[[nodiscard]]
constexpr insert_iterator<_Container>
inserter(_Container& __x, std::__detail::__range_iter_t<_Container> __i)
{ return insert_iterator<_Container>(__x, __i); }
#else
template<typename _Container>
_GLIBCXX_NODISCARD
inline insert_iterator<_Container>
inserter(_Container& __x, typename _Container::iterator __i)
{ return insert_iterator<_Container>(__x, __i); }
#endif
4.5 __normal_iterator
该迭代器可用于将原生指针转化为class类型的迭代器,其内部重载了Random Access Iterator类型迭代器的所有指针算数运算。
template<typename _Iterator, typename _Container>
class __normal_iterator
{
protected:
_Iterator _M_current;
typedef std::iterator_traits<_Iterator> __traits_type;
#if __cplusplus >= 201103L
// std::is_convertible<A,B>模板用于检查是否可以将任何数据类型A隐式转换为任何数据类型B。它返回布尔值true或false。
// std::__enable_if_t<T>模板满足条件时类型有效,用于编译期检查,当T为true时编译成功,当T为false时编译失败
template<typename _Iter>
using __convertible_from = std::__enable_if_t<std::is_convertible<_Iter, _Iterator>::value>;
#endif
public:
typedef _Iterator iterator_type;
typedef typename __traits_type::iterator_category iterator_category;
typedef typename __traits_type::value_type value_type;
typedef typename __traits_type::difference_type difference_type;
typedef typename __traits_type::reference reference;
typedef typename __traits_type::pointer pointer;
#if __cplusplus > 201703L && __cpp_lib_concepts
using iterator_concept = std::__detail::__iter_concept<_Iterator>;
#endif
_GLIBCXX_CONSTEXPR __normal_iterator() _GLIBCXX_NOEXCEPT
: _M_current(_Iterator()) { }
explicit _GLIBCXX20_CONSTEXPR
__normal_iterator(const _Iterator& __i) _GLIBCXX_NOEXCEPT
: _M_current(__i) { }
// Allow iterator to const_iterator conversion
#if __cplusplus >= 201103L
template<typename _Iter, typename = __convertible_from<_Iter>>
_GLIBCXX20_CONSTEXPR
__normal_iterator(const __normal_iterator<_Iter, _Container>& __i)
noexcept
#else
// N.B. _Container::pointer is not actually in container requirements,
// but is present in std::vector and std::basic_string.
template<typename _Iter>
__normal_iterator(const __normal_iterator<_Iter,
typename __enable_if<(std::__are_same<_Iter, typename _Container::pointer>::__value), _Container>::__type>& __i)
#endif
: _M_current(__i.base()) { }
// 重载*运算符
_GLIBCXX20_CONSTEXPR
reference
operator*() const _GLIBCXX_NOEXCEPT
{ return *_M_current; }
// 重载->运算符
_GLIBCXX20_CONSTEXPR
pointer
operator->() const _GLIBCXX_NOEXCEPT
{ return _M_current; }
// 重载++运算符,迭代器自增,往后偏移一个单位,返回偏移后的迭代器
_GLIBCXX20_CONSTEXPR
__normal_iterator&
operator++() _GLIBCXX_NOEXCEPT
{
++_M_current;
return *this;
}
// 重载++(int)运算符,迭代器自增,往后偏移一个单位,返回偏移前的迭代器
_GLIBCXX20_CONSTEXPR
__normal_iterator
operator++(int) _GLIBCXX_NOEXCEPT
{ return __normal_iterator(_M_current++); }
// 重载--运算符,迭代器自减,往前偏移一个单位,返回偏移后的迭代器
_GLIBCXX20_CONSTEXPR
__normal_iterator&
operator--() _GLIBCXX_NOEXCEPT
{
--_M_current;
return *this;
}
// 重载--(int)运算符,迭代器自减,往前偏移一个单位,返回偏移前的迭代器
_GLIBCXX20_CONSTEXPR
__normal_iterator
operator--(int) _GLIBCXX_NOEXCEPT
{ return __normal_iterator(_M_current--); }
// 重载[]运算符,支持随机存取
_GLIBCXX20_CONSTEXPR
reference
operator[](difference_type __n) const _GLIBCXX_NOEXCEPT
{ return _M_current[__n]; }
// 重载+=运算符,迭代器往后偏移n个单位
_GLIBCXX20_CONSTEXPR
__normal_iterator&
operator+=(difference_type __n) _GLIBCXX_NOEXCEPT
{ _M_current += __n; return *this; }
// 重载+运算符,迭代器往后偏移n个单位
_GLIBCXX20_CONSTEXPR
__normal_iterator
operator+(difference_type __n) const _GLIBCXX_NOEXCEPT
{ return __normal_iterator(_M_current + __n); }
// 重载-=运算符,迭代器往前偏移n个单位
_GLIBCXX20_CONSTEXPR
__normal_iterator&
operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
{ _M_current -= __n; return *this; }
// 重载-运算符,迭代器往前偏移n个单位
_GLIBCXX20_CONSTEXPR
__normal_iterator
operator-(difference_type __n) const _GLIBCXX_NOEXCEPT
{ return __normal_iterator(_M_current - __n); }
_GLIBCXX20_CONSTEXPR
const _Iterator&
base() const _GLIBCXX_NOEXCEPT
{ return _M_current; }
};
// 重载==运算符
template<typename _IteratorL, typename _IteratorR, typename _Container>
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline bool
operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.base() == __rhs.base(); }
template<typename _Iterator, typename _Container>
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline bool
operator==(const __normal_iterator<_Iterator, _Container>& __lhs,
const __normal_iterator<_Iterator, _Container>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.base() == __rhs.base(); }
// 重载!=运算符
template<typename _IteratorL, typename _IteratorR, typename _Container>
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline bool
operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.base() != __rhs.base(); }
template<typename _Iterator, typename _Container>
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline bool
operator!=(const __normal_iterator<_Iterator, _Container>& __lhs,
const __normal_iterator<_Iterator, _Container>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.base() != __rhs.base(); }
// Random access iterator requirements
// 重载<运算符
template<typename _IteratorL, typename _IteratorR, typename _Container>
_GLIBCXX_NODISCARD
inline bool
operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.base() < __rhs.base(); }
template<typename _Iterator, typename _Container>
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline bool
operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
const __normal_iterator<_Iterator, _Container>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.base() < __rhs.base(); }
// 重载>运算符
template<typename _IteratorL, typename _IteratorR, typename _Container>
_GLIBCXX_NODISCARD
inline bool
operator>(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.base() > __rhs.base(); }
template<typename _Iterator, typename _Container>
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline bool
operator>(const __normal_iterator<_Iterator, _Container>& __lhs,
const __normal_iterator<_Iterator, _Container>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.base() > __rhs.base(); }
// 重载<=运算符
template<typename _IteratorL, typename _IteratorR, typename _Container>
_GLIBCXX_NODISCARD
inline bool
operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.base() <= __rhs.base(); }
template<typename _Iterator, typename _Container>
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline bool
operator<=(const __normal_iterator<_Iterator, _Container>& __lhs,
const __normal_iterator<_Iterator, _Container>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.base() <= __rhs.base(); }
// 重载>=运算符
template<typename _IteratorL, typename _IteratorR, typename _Container>
_GLIBCXX_NODISCARD
inline bool
operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.base() >= __rhs.base(); }
template<typename _Iterator, typename _Container>
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline bool
operator>=(const __normal_iterator<_Iterator, _Container>& __lhs,
const __normal_iterator<_Iterator, _Container>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.base() >= __rhs.base(); }
// 重载-运算符
template<typename _IteratorL, typename _IteratorR, typename _Container>
#if __cplusplus >= 201103L
[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
inline auto
operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs) noexcept
-> decltype(__lhs.base() - __rhs.base())
#else
inline typename __normal_iterator<_IteratorL, _Container>::difference_type
operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
#endif
{ return __lhs.base() - __rhs.base(); }
template<typename _Iterator, typename _Container>
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline typename __normal_iterator<_Iterator, _Container>::difference_type
operator-(const __normal_iterator<_Iterator, _Container>& __lhs,
const __normal_iterator<_Iterator, _Container>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.base() - __rhs.base(); }
// 重载+运算符
template<typename _Iterator, typename _Container>
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline __normal_iterator<_Iterator, _Container>
operator+(typename __normal_iterator<_Iterator, _Container>::difference_type
__n, const __normal_iterator<_Iterator, _Container>& __i)
_GLIBCXX_NOEXCEPT
{ return __normal_iterator<_Iterator, _Container>(__i.base() + __n); }
4.6 move_iterator
类模板move_iterator是一个迭代器适配器,其行为与基础迭代器相同,只是其解引用运算符将基础迭代器的解引用运算符返回的值隐式转换为右值引用。一些通用算法可以通过移动迭代器来调用,以移动代替复制。C++11及以上版本使用。
template<typename _Iterator>
class move_iterator
#if __cplusplus > 201703L && __cpp_lib_concepts
: public __detail::__move_iter_cat<_Iterator>
#endif
{
// move_iterator对此迭代器进行适配
_Iterator _M_current;
using __traits_type = iterator_traits<_Iterator>;
#if ! (__cplusplus > 201703L && __cpp_lib_concepts)
using __base_ref = typename __traits_type::reference;
#endif
template<typename _Iter2>
friend class move_iterator;
#if __cpp_lib_concepts
template<typename _Iter2>
static constexpr bool __convertible = !is_same_v<_Iter2, _Iterator> && convertible_to<const _Iter2&, _Iterator>;
#endif
public:
using iterator_type = _Iterator;
#if __cplusplus > 201703L && __cpp_lib_concepts
using iterator_concept = input_iterator_tag;
// iterator_category defined in __move_iter_cat
using value_type = iter_value_t<_Iterator>;
using difference_type = iter_difference_t<_Iterator>;
using pointer = _Iterator;
using reference = iter_rvalue_reference_t<_Iterator>;
#else
typedef typename __traits_type::iterator_category iterator_category;
typedef typename __traits_type::value_type value_type;
typedef typename __traits_type::difference_type difference_type;
typedef _Iterator pointer;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2106. move_iterator wrapping iterators returning prvalues
using reference = __conditional_t<is_reference<__base_ref>::value,
typename remove_reference<__base_ref>::type&&, __base_ref>;
#endif
_GLIBCXX17_CONSTEXPR
move_iterator()
: _M_current() { }
explicit _GLIBCXX17_CONSTEXPR
move_iterator(iterator_type __i)
: _M_current(std::move(__i)) { }
template<typename _Iter>
#if __cpp_lib_concepts
requires __convertible<_Iter>
#endif
_GLIBCXX17_CONSTEXPR
move_iterator(const move_iterator<_Iter>& __i)
: _M_current(__i._M_current) { }
// 重载赋值运算符
template<typename _Iter>
#if __cpp_lib_concepts
requires __convertible<_Iter> && assignable_from<_Iterator&, const _Iter&>
#endif
_GLIBCXX17_CONSTEXPR
move_iterator& operator=(const move_iterator<_Iter>& __i)
{
_M_current = __i._M_current;
return *this;
}
#if __cplusplus <= 201703L
[[__nodiscard__]]
_GLIBCXX17_CONSTEXPR iterator_type
base() const
{ return _M_current; }
#else
[[nodiscard]]
constexpr const iterator_type&
base() const & noexcept
{ return _M_current; }
[[nodiscard]]
constexpr iterator_type
base() &&
{ return std::move(_M_current); }
#endif
// 重载*运算符,返回值为右值引用
[[__nodiscard__]]
_GLIBCXX17_CONSTEXPR reference
operator*() const
#if __cplusplus > 201703L && __cpp_lib_concepts
{ return ranges::iter_move(_M_current); }
#else
{ return static_cast<reference>(*_M_current); }
#endif
// 重载->运算符
[[__nodiscard__]]
_GLIBCXX17_CONSTEXPR pointer
operator->() const
{ return _M_current; }
// 重载++运算符
_GLIBCXX17_CONSTEXPR move_iterator&
operator++()
{
++_M_current;
return *this;
}
// 重载++(int)运算符
_GLIBCXX17_CONSTEXPR move_iterator
operator++(int)
{
move_iterator __tmp = *this;
++_M_current;
return __tmp;
}
#if __cpp_lib_concepts
constexpr void
operator++(int) requires (!forward_iterator<_Iterator>)
{ ++_M_current; }
#endif
// 重载--运算符
_GLIBCXX17_CONSTEXPR move_iterator&
operator--()
{
--_M_current;
return *this;
}
// 重载--(int)运算符
_GLIBCXX17_CONSTEXPR move_iterator
operator--(int)
{
move_iterator __tmp = *this;
--_M_current;
return __tmp;
}
// 重载+运算符
[[__nodiscard__]]
_GLIBCXX17_CONSTEXPR move_iterator
operator+(difference_type __n) const
{ return move_iterator(_M_current + __n); }
// 重载+=运算符
_GLIBCXX17_CONSTEXPR move_iterator&
operator+=(difference_type __n)
{
_M_current += __n;
return *this;
}
// 重载-运算符
[[__nodiscard__]]
_GLIBCXX17_CONSTEXPR move_iterator
operator-(difference_type __n) const
{ return move_iterator(_M_current - __n); }
// 重载-=运算符
_GLIBCXX17_CONSTEXPR move_iterator&
operator-=(difference_type __n)
{
_M_current -= __n;
return *this;
}
// 重载[]运算符,支持随机存取,返回值为右值引用
[[__nodiscard__]]
_GLIBCXX17_CONSTEXPR reference
operator[](difference_type __n) const
#if __cplusplus > 201703L && __cpp_lib_concepts
{ return ranges::iter_move(_M_current + __n); }
#else
{ return std::move(_M_current[__n]); }
#endif
#if __cplusplus > 201703L && __cpp_lib_concepts
template<sentinel_for<_Iterator> _Sent>
[[nodiscard]]
friend constexpr bool
operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y)
{ return __x.base() == __y.base(); }
template<sized_sentinel_for<_Iterator> _Sent>
[[nodiscard]]
friend constexpr iter_difference_t<_Iterator>
operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y)
{ return __x.base() - __y.base(); }
template<sized_sentinel_for<_Iterator> _Sent>
[[nodiscard]]
friend constexpr iter_difference_t<_Iterator>
operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y)
{ return __x.base() - __y.base(); }
[[nodiscard]]
friend constexpr iter_rvalue_reference_t<_Iterator>
iter_move(const move_iterator& __i)
noexcept(noexcept(ranges::iter_move(__i._M_current)))
{ return ranges::iter_move(__i._M_current); }
template<indirectly_swappable<_Iterator> _Iter2>
friend constexpr void
iter_swap(const move_iterator& __x, const move_iterator<_Iter2>& __y)
noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
{ return ranges::iter_swap(__x._M_current, __y._M_current); }
#endif // C++20
};
template<typename _IteratorL, typename _IteratorR>
[[__nodiscard__]]
inline _GLIBCXX17_CONSTEXPR bool
operator==(const move_iterator<_IteratorL>& __x,
const move_iterator<_IteratorR>& __y)
#if __cplusplus > 201703L && __cpp_lib_concepts
requires requires { { __x.base() == __y.base() } -> convertible_to<bool>; }
#endif
{ return __x.base() == __y.base(); }
#if __cpp_lib_three_way_comparison
template<typename _IteratorL,
three_way_comparable_with<_IteratorL> _IteratorR>
[[__nodiscard__]]
constexpr compare_three_way_result_t<_IteratorL, _IteratorR>
operator<=>(const move_iterator<_IteratorL>& __x,
const move_iterator<_IteratorR>& __y)
{ return __x.base() <=> __y.base(); }
#else
template<typename _IteratorL, typename _IteratorR>
[[__nodiscard__]]
inline _GLIBCXX17_CONSTEXPR bool
operator!=(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y)
{ return !(__x == __y); }
#endif
template<typename _IteratorL, typename _IteratorR>
[[__nodiscard__]]
inline _GLIBCXX17_CONSTEXPR bool
operator<(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y)
#if __cplusplus > 201703L && __cpp_lib_concepts
requires requires { { __x.base() < __y.base() } -> convertible_to<bool>; }
#endif
{ return __x.base() < __y.base(); }
template<typename _IteratorL, typename _IteratorR>
[[__nodiscard__]]
inline _GLIBCXX17_CONSTEXPR bool
operator<=(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y)
#if __cplusplus > 201703L && __cpp_lib_concepts
requires requires { { __y.base() < __x.base() } -> convertible_to<bool>; }
#endif
{ return !(__y < __x); }
template<typename _IteratorL, typename _IteratorR>
[[__nodiscard__]]
inline _GLIBCXX17_CONSTEXPR bool
operator>(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y)
#if __cplusplus > 201703L && __cpp_lib_concepts
requires requires { { __y.base() < __x.base() } -> convertible_to<bool>; }
#endif
{ return __y < __x; }
template<typename _IteratorL, typename _IteratorR>
[[__nodiscard__]]
inline _GLIBCXX17_CONSTEXPR bool
operator>=(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y)
#if __cplusplus > 201703L && __cpp_lib_concepts
requires requires { { __x.base() < __y.base() } -> convertible_to<bool>; }
#endif
{ return !(__x < __y); }
// Note: See __normal_iterator operators note from Gaby to understand
// why we have these extra overloads for some move_iterator operators.
template<typename _Iterator>
[[__nodiscard__]]
inline _GLIBCXX17_CONSTEXPR bool
operator==(const move_iterator<_Iterator>& __x, const move_iterator<_Iterator>& __y)
{ return __x.base() == __y.base(); }
#if __cpp_lib_three_way_comparison
template<three_way_comparable _Iterator>
[[__nodiscard__]]
constexpr compare_three_way_result_t<_Iterator>
operator<=>(const move_iterator<_Iterator>& __x, const move_iterator<_Iterator>& __y)
{ return __x.base() <=> __y.base(); }
#else
template<typename _Iterator>
[[__nodiscard__]]
inline _GLIBCXX17_CONSTEXPR bool
operator!=(const move_iterator<_Iterator>& __x, const move_iterator<_Iterator>& __y)
{ return !(__x == __y); }
template<typename _Iterator>
[[__nodiscard__]]
inline _GLIBCXX17_CONSTEXPR bool
operator<(const move_iterator<_Iterator>& __x, const move_iterator<_Iterator>& __y)
{ return __x.base() < __y.base(); }
template<typename _Iterator>
[[__nodiscard__]]
inline _GLIBCXX17_CONSTEXPR bool
operator<=(const move_iterator<_Iterator>& __x, const move_iterator<_Iterator>& __y)
{ return !(__y < __x); }
template<typename _Iterator>
[[__nodiscard__]]
inline _GLIBCXX17_CONSTEXPR bool
operator>(const move_iterator<_Iterator>& __x, const move_iterator<_Iterator>& __y)
{ return __y < __x; }
template<typename _Iterator>
[[__nodiscard__]]
inline _GLIBCXX17_CONSTEXPR bool
operator>=(const move_iterator<_Iterator>& __x, const move_iterator<_Iterator>& __y)
{ return !(__x < __y); }
#endif // ! C++20
template<typename _IteratorL, typename _IteratorR>
[[__nodiscard__]]
inline _GLIBCXX17_CONSTEXPR auto
operator-(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y)
-> decltype(__x.base() - __y.base())
{ return __x.base() - __y.base(); }
template<typename _Iterator>
[[__nodiscard__]]
inline _GLIBCXX17_CONSTEXPR move_iterator<_Iterator>
operator+(typename move_iterator<_Iterator>::difference_type __n, const move_iterator<_Iterator>& __x)
{ return __x + __n; }
template<typename _Iterator>
[[__nodiscard__]]
inline _GLIBCXX17_CONSTEXPR move_iterator<_Iterator>
make_move_iterator(_Iterator __i)
{ return move_iterator<_Iterator>(std::move(__i)); }
template<typename _Iterator, typename _ReturnType = __conditional_t<__move_if_noexcept_cond
<typename iterator_traits<_Iterator>::value_type>::value, _Iterator, move_iterator<_Iterator>>>
inline _GLIBCXX17_CONSTEXPR _ReturnType
__make_move_if_noexcept_iterator(_Iterator __i)
{ return _ReturnType(__i); }
// Overload for pointers that matches std::move_if_noexcept more closely,
// returning a constant iterator when we don't want to move.
template<typename _Tp, typename _ReturnType = __conditional_t<__move_if_noexcept_cond<_Tp>::value,
const _Tp*, move_iterator<_Tp*>>>
inline _GLIBCXX17_CONSTEXPR _ReturnType
__make_move_if_noexcept_iterator(_Tp* __i)
{ return _ReturnType(__i); }
4.7 common_iterator
一种用于将非通用范围的迭代器转换为通用范围迭代器的适配器,C++20定义,此处不做探讨。
4.8 counted_iterator
一种用于跟踪到end()的距离的迭代器适配器,C++20定义,此处不做探讨。
本文来自博客园,作者:流翎,转载请注明原文链接:https://www.cnblogs.com/hjx168/p/16157626.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)