您的位置:首页 > 编程语言 > C语言/C++

C++ STL源码学习(迭代器篇)

2014-09-21 23:34 381 查看
stl_iterator_base.h

<span style="font-size:24px;">
/// This file contains all of the general iterator-related utilities.
/// The internal file stl_iterator.h contains predefined iterators,
/// such as front_insert_iterator and istream_iterator.

#include <concept_checks.h>

struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};

///这些迭代器类型并非C++ Standard,客户端系自己的迭代器时
///可以根据属性继承这些类,以便拥有迭代器需具备的基本属性
///方可使得自定义迭代器与STL算法融合
template <class _Tp, class _Distance> struct input_iterator {
typedef input_iterator_tag iterator_category;
typedef _Tp                value_type;
typedef _Distance          difference_type;
typedef _Tp*               pointer;
typedef _Tp&               reference;
};

struct output_iterator {
typedef output_iterator_tag iterator_category;
typedef void                value_type;
typedef void                difference_type;
typedef void                pointer;
typedef void                reference;
};

template <class _Tp, class _Distance> struct forward_iterator {
typedef forward_iterator_tag iterator_category;
typedef _Tp                  value_type;
typedef _Distance            difference_type;
typedef _Tp*                 pointer;
typedef _Tp&                 reference;
};

template <class _Tp, class _Distance> struct bidirectional_iterator {
typedef bidirectional_iterator_tag iterator_category;
typedef _Tp                        value_type;
typedef _Distance                  difference_type;
typedef _Tp*                       pointer;
typedef _Tp&                       reference;
};

template <class _Tp, class _Distance> struct random_access_iterator {
typedef random_access_iterator_tag iterator_category;
typedef _Tp                        value_type;
typedef _Distance                  difference_type;
typedef _Tp*                       pointer;
typedef _Tp&                       reference;
};

///对这些迭代器重要属性的型别推导函数
template <class _Tp, class _Distance>
inline input_iterator_tag
iterator_category(const input_iterator<_Tp, _Distance>&)
{ return input_iterator_tag(); }

inline output_iterator_tag iterator_category(const output_iterator&)
{ return output_iterator_tag(); }

template <class _Tp, class _Distance>
inline forward_iterator_tag
iterator_category(const forward_iterator<_Tp, _Distance>&)
{ return forward_iterator_tag(); }

template <class _Tp, class _Distance>
inline bidirectional_iterator_tag
iterator_category(const bidirectional_iterator<_Tp, _Distance>&)
{ return bidirectional_iterator_tag(); }

template <class _Tp, class _Distance>
inline random_access_iterator_tag
iterator_category(const random_access_iterator<_Tp, _Distance>&)
{ return random_access_iterator_tag(); }

template <class _Tp>
inline random_access_iterator_tag iterator_category(const _Tp*)
{ return random_access_iterator_tag(); }

template <class _Tp, class _Distance>
inline _Tp* value_type(const input_iterator<_Tp, _Distance>&)
{ return (_Tp*)(0); }

template <class _Tp, class _Distance>
inline _Tp* value_type(const forward_iterator<_Tp, _Distance>&)
{ return (_Tp*)(0); }

template <class _Tp, class _Distance>
inline _Tp* value_type(const bidirectional_iterator<_Tp, _Distance>&)
{ return (_Tp*)(0); }

template <class _Tp, class _Distance>
inline _Tp* value_type(const random_access_iterator<_Tp, _Distance>&)
{ return (_Tp*)(0); }

template <class _Tp>
inline _Tp* value_type(const _Tp*) { return (_Tp*)(0); }

template <class _Tp, class _Distance>
inline _Distance* distance_type(const input_iterator<_Tp, _Distance>&)
{
return (_Distance*)(0);
}

template <class _Tp, class _Distance>
inline _Distance* distance_type(const forward_iterator<_Tp, _Distance>&)
{
return (_Distance*)(0);
}

template <class _Tp, class _Distance>
inline _Distance*
distance_type(const bidirectional_iterator<_Tp, _Distance>&)
{
return (_Distance*)(0);
}

template <class _Tp, class _Distance>
inline _Distance*
distance_type(const random_access_iterator<_Tp, _Distance>&)
{
return (_Distance*)(0);
}

template <class _Tp>
inline ptrdiff_t* distance_type(const _Tp*) { return (ptrdiff_t*)(0); }

///iterator_traits使得Tp*和const Tp*可以再STL中用到任何需要迭代器的地方
template <class _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;
};

template <class _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;
};

template <class _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;
};

///对通用迭代器求距离,采用了型别推导,这是STL非常常见的一种
///泛型编程技法
template <class _InputIterator, class _Distance>
inline void __distance(_InputIterator __first, _InputIterator __last,
_Distance& __n, input_iterator_tag)
{
while (__first != __last) { ++__first; ++__n; }
}

template <class _RandomAccessIterator, class _Distance>
inline void __distance(_RandomAccessIterator __first,
_RandomAccessIterator __last,
_Distance& __n, random_access_iterator_tag)
{
///对型别的检验,使得在编译器发现问题,而非在运行期导致程序崩溃
///检验型别是否确实为随机迭代器
__STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator);

__n += __last - __first;
}

template <class _InputIterator, class _Distance>
inline void distance(_InputIterator __first,
_InputIterator __last, _Distance& __n)
{
__STL_REQUIRES(_InputIterator, _InputIterator);

///调用型别推导函数iterator_category得到迭代器的属性,从而调用合适的求距离函数
///为了或得效率(具有random_access_iterator_tag的迭代器求距离可以采用更具效率的做法)
__distance(__first, __last, __n, iterator_category(__first));
}

template <class _InputIter, class _Distance>
inline void __advance(_InputIter& __i, _Distance __n, input_iterator_tag) {
while (__n--) ++__i;
}

template <class _BidirectionalIterator, class _Distance>
inline void __advance(_BidirectionalIterator& __i, _Distance __n,
bidirectional_iterator_tag) {
__STL_REQUIRES(_BidirectionalIterator, _BidirectionalIterator);
if (__n >= 0)
while (__n--) ++__i;
else
while (__n++) --__i;
}

template <class _RandomAccessIterator, class _Distance>
inline void __advance(_RandomAccessIterator& __i, _Distance __n,
random_access_iterator_tag) {
__STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator);
__i += __n;
}

template <class _InputIterator, class _Distance>
inline void advance(_InputIterator& __i, _Distance __n) {
__STL_REQUIRES(_InputIterator, _InputIterator);
__advance(__i, __n, iterator_category(__i));
}
</span>


stl_iterator.h

///back_insert_iterator通过保存需要插入元素的容器指针
///每次容器元素的插入实际是调用其push_back成员函数实现的
///因此该容器必须具备push_back成员函数.

#include <stl_iterator_base.h>
template <class _Container>
class back_insert_iterator {
protected:
_Container* container;
public:
typedef _Container          container_type;
typedef output_iterator_tag iterator_category;
typedef void                value_type;
typedef void                difference_type;
typedef void                pointer;
typedef void                reference;

explicit back_insert_iterator(_Container& __x) : container(&__x) {}

back_insert_iterator<_Container>&
operator=(const typename _Container::value_type& __value) {
container->push_back(__value);    ///每次为其赋值都调用绑定容器的push_back函数
return *this;
}

back_insert_iterator<_Container>& operator*() { return *this; }
back_insert_iterator<_Container>& operator++() { return *this; }
back_insert_iterator<_Container>& operator++(int) { return *this; }
};

template <class _Container>
inline output_iterator_tag
iterator_category(const back_insert_iterator<_Container>&)
{
return output_iterator_tag();
}

///实际更经常使用这个函数
template <class _Container>
inline back_insert_iterator<_Container> back_inserter(_Container& __x) {
return back_insert_iterator<_Container>(__x);
}

///除了调用push_front函数外,与back_insert_iterator如出一辙
template <class _Container>
class front_insert_iterator {
protected:
_Container* container;
public:
typedef _Container          container_type;
typedef output_iterator_tag iterator_category;
typedef void                value_type;
typedef void                difference_type;
typedef void                pointer;
typedef void                reference;

explicit front_insert_iterator(_Container& __x) : container(&__x) {}
front_insert_iterator<_Container>&
operator=(const typename _Container::value_type& __value) {
container->push_front(__value);
return *this;
}

front_insert_iterator<_Container>& operator*() { return *this; }
front_insert_iterator<_Container>& operator++() { return *this; }
front_insert_iterator<_Container>& operator++(int) { return *this; }
};

template <class _Container>
inline output_iterator_tag
iterator_category(const front_insert_iterator<_Container>&)
{
return output_iterator_tag();
}

template <class _Container>
inline front_insert_iterator<_Container> front_inserter(_Container& __x) {
return front_insert_iterator<_Container>(__x);
}

///提供插入位置的插入迭代器,调用绑定容器的insert函数
template <class _Container>
class insert_iterator {
protected:
_Container* container;
typename _Container::iterator iter;
public:
typedef _Container          container_type;
typedef output_iterator_tag iterator_category;
typedef void                value_type;
typedef void                difference_type;
typedef void                pointer;
typedef void                reference;

insert_iterator(_Container& __x, typename _Container::iterator __i)
: container(&__x), iter(__i) {}
insert_iterator<_Container>&
operator=(const typename _Container::value_type& __value) {
iter = container->insert(iter, __value);
++iter;    ///插入后要将所提供迭代器的位置前移一位
return *this;
}
insert_iterator<_Container>& operator*() { return *this; }
insert_iterator<_Container>& operator++() { return *this; }
insert_iterator<_Container>& operator++(int) { return *this; }
};

template <class _Container>
inline output_iterator_tag
iterator_category(const insert_iterator<_Container>&)
{
return output_iterator_tag();
}

template <class _Container, class _Iterator>
inline
insert_iterator<_Container> inserter(_Container& __x, _Iterator __i)
{
typedef typename _Container::iterator __iter;
return insert_iterator<_Container>(__x, __iter(__i));
}

/// This is the new version of reverse_iterator, as defined in the
///  draft C++ standard.  It relies on the iterator_traits template,
///  which in turn relies on partial specialization.  The class
///  reverse_bidirectional_iterator is no longer part of the draft
///  standard, but it is retained for backward compatibility.

template <class _Iterator>
class reverse_iterator
{
protected:
_Iterator current;
public:
///反向迭代器的各项性质型别与基迭代器保持一致
typedef typename iterator_traits<_Iterator>::iterator_category
iterator_category;
typedef typename iterator_traits<_Iterator>::value_type
value_type;
typedef typename iterator_traits<_Iterator>::difference_type
difference_type;
typedef typename iterator_traits<_Iterator>::pointer
pointer;
typedef typename iterator_traits<_Iterator>::reference
reference;

typedef _Iterator iterator_type;
typedef reverse_iterator<_Iterator> _Self;

public:
reverse_iterator() {}
explicit reverse_iterator(iterator_type __x) : current(__x) {}

reverse_iterator(const _Self& __x) : current(__x.current) {}

iterator_type base() const { return current; }

reference operator*() const {
///由于STL中所有区间都是左闭右开区间,因此对反向迭代器的提领需要在
///基迭代器的基础上后退一步再提领,才不至于提领到非法指针
_Iterator __tmp = current;
return *--__tmp;
}

pointer operator->() const { return &(operator*()); }

_Self& operator++() {
--current;          ///反向迭代器前进即使基迭代器的后退
return *this;
}
_Self operator++(int) {
_Self __tmp = *this;
--current;
return __tmp;
}
_Self& operator--() {
++current;
return *this;
}
_Self operator--(int) {
_Self __tmp = *this;
++current;
return __tmp;
}

_Self operator+(difference_type __n) const {
return _Self(current - __n);
}
_Self& operator+=(difference_type __n) {
current -= __n;
return *this;
}
_Self operator-(difference_type __n) const {
return _Self(current + __n);
}
_Self& operator-=(difference_type __n) {
current += __n;
return *this;
}
reference operator[](difference_type __n) const { return *(*this + __n); }
};

template <class _Iterator>
inline bool operator==(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y) {
return __x.base() == __y.base();
}

template <class _Iterator>
inline bool operator<(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y) {
return __y.base() < __x.base();
}

template <class _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 <class _Iterator>
inline reverse_iterator<_Iterator>
operator+(typename reverse_iterator<_Iterator>::difference_type __n,
const reverse_iterator<_Iterator>& __x) {
return reverse_iterator<_Iterator>(__x.base() - __n);
}

///istream_iterator类的声明,后面operator==要用到
template <class _Tp, class _Dist = ptrdiff_t>
class istream_iterator;

///operator==函数必须提前声明,否则不能作为istream_iterator类的友元函数出现
template <class _Tp, class _Dist>
inline bool operator==(const istream_iterator<_Tp, _Dist>&,
const istream_iterator<_Tp, _Dist>&);

///istream_iterator类通过封装一个istream类型的指针来实现对istream流的操作
template <class _Tp, class _Dist>
class istream_iterator {

friend bool operator==<>(const istream_iterator&,
const istream_iterator&);
protected:
istream* _M_stream;
_Tp _M_value;         ///写入的数据类型
bool _M_end_marker;      ///流结束标志

void _M_read() {
///先判断流是否结束,并重置结束标志
_M_end_marker = (*_M_stream) ? true : false;
///若尚未结束,读取一个对象
if (_M_end_marker) *_M_stream >> _M_value;
///再次重置流结束标志
_M_end_marker = (*_M_stream) ? true : false;
}

public:
typedef input_iterator_tag  iterator_category;
typedef _Tp                 value_type;
typedef _Dist               difference_type;
typedef const _Tp*          pointer;
typedef const _Tp&          reference;
///默认关联cin,并且处于流结束处
istream_iterator() : _M_stream(&cin), _M_end_marker(false) {}

///创建流对象时,调用read,试图读入一个对象
istream_iterator(istream& __s) : _M_stream(&__s) { _M_read(); }
reference operator*() const { return _M_value; }

pointer operator->() const { return &(operator*()); }

istream_iterator<_Tp, _Dist>& operator++() {
///迭代器每前进一步,调用一次read函数,试图读取一个对象
_M_read();
return *this;
}
istream_iterator<_Tp, _Dist> operator++(int)  {
istream_iterator<_Tp, _Dist> __tmp = *this;
_M_read();
return __tmp;
}
};

template <class _Tp, class _Dist>
inline input_iterator_tag
iterator_category(const istream_iterator<_Tp, _Dist>&)
{
return input_iterator_tag();
}

template <class _Tp, class _Dist>
inline _Tp*
value_type(const istream_iterator<_Tp, _Dist>&) { return (_Tp*) 0; }

template <class _Tp, class _Dist>
inline _Dist*
distance_type(const istream_iterator<_Tp, _Dist>&) { return (_Dist*)0; }

template <class _Tp, class _Distance>
inline bool operator==(const istream_iterator<_Tp, _Distance>& __x,
const istream_iterator<_Tp, _Distance>& __y) {
return (__x._M_stream == __y._M_stream &&
__x._M_end_marker == __y._M_end_marker) ||
__x._M_end_marker == false && __y._M_end_marker == false;
}

///基本和istream实现相同,无结束标示符
template <class _Tp>
class ostream_iterator {
protected:
ostream* _M_stream;
const char* _M_string;    ///输出时用于分隔不同对象,有客户端提供
public:
typedef output_iterator_tag iterator_category;
typedef void                value_type;
typedef void                difference_type;
typedef void                pointer;
typedef void                reference;

ostream_iterator(ostream& __s) : _M_stream(&__s), _M_string(0) {}
ostream_iterator(ostream& __s, const char* __c)
: _M_stream(&__s), _M_string(__c)  {}
ostream_iterator<_Tp>& operator=(const _Tp& __value) {
*_M_stream << __value;
if (_M_string) *_M_stream << _M_string;
return *this;
}
ostream_iterator<_Tp>& operator*() { return *this; }
ostream_iterator<_Tp>& operator++() { return *this; }
ostream_iterator<_Tp>& operator++(int) { return *this; }
};

template <class _Tp>
inline output_iterator_tag
iterator_category(const ostream_iterator<_Tp>&) {
return output_iterator_tag();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息