_slist.h

来自「C++类模版库实现」· C头文件 代码 · 共 872 行 · 第 1/3 页

H
872
字号
/* * * Copyright (c) 2003 * Francois Dumont * * This material is provided "as is", with absolutely no warranty expressed * or implied. Any use is at your own risk. * * Permission to use or copy this software for any purpose is hereby granted  * without fee, provided the above notices are retained on all copies. * Permission to modify the code and to distribute modified code is granted, * provided the above notices are retained, and a notice that the code was * modified is included with the above copyright notice. * *//* NOTE: This is an internal header file, included by other STL headers. *   You should not attempt to use it directly. */#ifndef _STLP_SPECIALIZED_SLIST_H#define _STLP_SPECIALIZED_SLIST_H#include <stl/pointers/_void_ptr_traits.h>template <class _Alloc>class slist<void*, _Alloc> : protected _Slist_base<void*, _Alloc> _STLP_STLPORT_CLASS_N{private:  typedef _Slist_base<void*,_Alloc> _Base;  typedef slist<void*, _Alloc> _Self;public:  typedef void*             value_type;  typedef value_type*       pointer;  typedef const value_type* const_pointer;  typedef value_type&       reference;  typedef value_type        const_reference;  typedef size_t            size_type;  typedef ptrdiff_t         difference_type;  typedef forward_iterator_tag _Iterator_category;  typedef _Slist_iterator<void*, _Nonconst_traits<void*> >  iterator;  typedef _Slist_iterator<void*, _Const_traits<void*> >     const_iterator;  _STLP_FORCE_ALLOCATORS(void*, _Alloc)  typedef typename _Base::allocator_type allocator_type;private:  typedef _Slist_node<void*>    _Node;  typedef _Slist_node_base      _Node_base;#if !defined(_STLP_DONT_SUP_DFLT_PARAM)  _Node* _M_create_node(const_reference __x = static_cast<void*>(0)) {#else  _Node* _M_create_node(const_reference __x) {#endif /*_STLP_DONT_SUP_DFLT_PARAM*/    _Node* __node = this->_M_head.allocate(1);    __node->_M_data = __x;    __node->_M_next = 0;    return __node;  }  #if defined(_STLP_DONT_SUP_DFLT_PARAM)  _Node* _M_create_node() {    _Node* __node = this->_M_head.allocate(1);    __node->_M_data = 0;    __node->_M_next = 0;    return __node;  }#endif /*_STLP_DONT_SUP_DFLT_PARAM*/public:  allocator_type get_allocator() const { return _Base::get_allocator(); }  explicit slist(const allocator_type& __a = allocator_type()) : _Slist_base<void*,_Alloc>(__a) {}#if !defined(_STLP_DONT_SUP_DFLT_PARAM)  explicit slist(size_type __n, const_reference __x = 0,#else  slist(size_type __n, const_reference __x,#endif /*_STLP_DONT_SUP_DFLT_PARAM*/        const allocator_type& __a =  allocator_type()) : _Slist_base<void*,_Alloc>(__a)    { _M_insert_after_fill(&this->_M_head._M_data, __n, __x); }#if defined(_STLP_DONT_SUP_DFLT_PARAM)  explicit slist(size_type __n) : _Slist_base<void*,_Alloc>(allocator_type())    { _M_insert_after_fill(&this->_M_head._M_data, __n, static_cast<void*>(0)); }#endif /*_STLP_DONT_SUP_DFLT_PARAM*/#ifdef _STLP_MEMBER_TEMPLATES  // We don't need any dispatching tricks here, because _M_insert_after_range  // already does them.  template <class _InputIterator>  slist(_InputIterator __first, _InputIterator __last,        const allocator_type& __a _STLP_ALLOCATOR_TYPE_DFL) :     _Slist_base<void*,_Alloc>(__a)  { _M_insert_after_range(&this->_M_head._M_data, __first, __last); }# ifdef _STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS  // VC++ needs this crazyness  template <class _InputIterator>  slist(_InputIterator __first, _InputIterator __last) :    _Slist_base<void*,_Alloc>(allocator_type())  { _M_insert_after_range(&this->_M_head._M_data, __first, __last); }# endif  #else /* _STLP_MEMBER_TEMPLATES */  slist(const_iterator __first, const_iterator __last,        const allocator_type& __a =  allocator_type() ) :    _Slist_base<void*,_Alloc>(__a)    { _M_insert_after_range(&this->_M_head._M_data, __first, __last); }  slist(const value_type* __first, const value_type* __last,        const allocator_type& __a =  allocator_type()) :     _Slist_base<void*,_Alloc>(__a)    { _M_insert_after_range(&this->_M_head._M_data, __first, __last); }#endif /* _STLP_MEMBER_TEMPLATES */  slist(const _Self& __x) : _Slist_base<void*,_Alloc>(__x.get_allocator())    { _M_insert_after_range(&this->_M_head._M_data, __x.begin(), __x.end()); }  /*explicit slist(__full_move_source<_Self> src)    : _Slist_base<void*, _Alloc>(_FullMoveSource<_Slist_base<void*, _Alloc> >(src.get())) {  }*/  explicit slist(__partial_move_source<_Self> src)    : _Slist_base<void*, _Alloc>(src.get()) {    src.get()._M_head._M_data._M_next = 0;  }  _Self& operator= (const _Self& __x);  ~slist() {}public:  // assign(), a generalized assignment member function.  Two  // versions: one that takes a count, and one that takes a range.  // The range version is a member template, so we dispatch on whether  // or not the type is an integer.  void assign(size_type __n, const_reference __val)    { _M_fill_assign(__n, __val); }  void _M_fill_assign(size_type __n, const_reference __val);#ifdef _STLP_MEMBER_TEMPLATES  template <class _InputIterator>  void assign(_InputIterator __first, _InputIterator __last) {    typedef typename _Is_integer<_InputIterator>::_Integral _Integral;    _M_assign_dispatch(__first, __last, _Integral());  }  template <class _Integer>  void _M_assign_dispatch(_Integer __n, _Integer __val, const __true_type& /*_IsIntegral*/) {    _M_fill_assign((size_type) __n, static_cast<void*>(__val));  }  template <class _InputIter>  void _M_assign_dispatch(_InputIter __first, _InputIter __last,                          const __false_type& /*_IsIntegral*/) {    _Node_base* __prev = &this->_M_head._M_data;    _Node_base* __node = this->_M_head._M_data._M_next;    while (__node != 0 && __first != __last) {      static_cast<_Node*>(__node)->_M_data = *__first;      __prev = __node;      __node = __node->_M_next;      ++__first;    }    if (__first != __last)      _M_insert_after_range(__prev, __first, __last);    else      this->_M_erase_after(__prev, 0);  }#endif /* _STLP_MEMBER_TEMPLATES */public:  // Experimental new feature: before_begin() returns a  // non-dereferenceable iterator that, when incremented, yields  // begin().  This iterator may be used as the argument to  // insert_after, erase_after, etc.  Note that even for an empty   // slist, before_begin() is not the same iterator as end().  It   // is always necessary to increment before_begin() at least once to  // obtain end().  iterator before_begin() { return iterator(&this->_M_head._M_data); }  const_iterator before_begin() const    { return const_iterator(const_cast<_Slist_node_base*>(&this->_M_head._M_data)); }  iterator begin() { return iterator(this->_M_head._M_data._M_next); }  const_iterator begin() const     { return const_iterator(const_cast<_Slist_node_base*>(this->_M_head._M_data._M_next));}  iterator end() { return iterator(0); }  const_iterator end() const { return const_iterator(0); }  size_type size() const { return _Sl_global_inst::size(this->_M_head._M_data._M_next); }    size_type max_size() const { return size_type(-1); }  bool empty() const { return this->_M_head._M_data._M_next == 0; }  void swap(_Self& __x) {     _STLP_STD::swap(this->_M_head, __x._M_head);   }public:  reference front()             { return *begin(); }  const_reference front() const { return *begin(); }#if !defined(_STLP_DONT_SUP_DFLT_PARAM) && !defined(_STLP_NO_ANACHRONISMS)  void push_front(const_reference __x = 0)   {#else  void push_front(const_reference __x)   {#endif /*!_STLP_DONT_SUP_DFLT_PARAM && !_STLP_NO_ANACHRONISMS*/    __slist_make_link(&this->_M_head._M_data, _M_create_node(__x));  }# if defined(_STLP_DONT_SUP_DFLT_PARAM) && !defined(_STLP_NO_ANACHRONISMS)  void push_front() { __slist_make_link(&this->_M_head._M_data, _M_create_node());}# endif /*_STLP_DONT_SUP_DFLT_PARAM && !_STLP_NO_ANACHRONISMS*/  void pop_front() {    _Node* __node = static_cast<_Node*>(this->_M_head._M_data._M_next);    this->_M_head._M_data._M_next = __node->_M_next;    this->_M_head.deallocate(__node, 1);  }  iterator previous(const_iterator __pos) {    return iterator(_Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node));  }  const_iterator previous(const_iterator __pos) const {    return const_iterator(const_cast<_Slist_node_base*>(_Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node)));  }private:#if !defined(_STLP_DONT_SUP_DFLT_PARAM)  _Node* _M_insert_after(_Node_base* __pos, const_reference __x = 0) {#else  _Node* _M_insert_after(_Node_base* __pos, const_reference __x) {#endif /*_STLP_DONT_SUP_DFLT_PARAM*/    return static_cast<_Node*>(__slist_make_link(__pos, _M_create_node(__x)));  }#if defined(_STLP_DONT_SUP_DFLT_PARAM)  _Node* _M_insert_after(_Node_base* __pos) {    return static_cast<_Node*>(__slist_make_link(__pos, _M_create_node()));  }#endif /*_STLP_DONT_SUP_DFLT_PARAM*/  void _M_insert_after_fill(_Node_base* __pos,                            size_type __n, const_reference __x) {    for (size_type __i = 0; __i < __n; ++__i)      __pos = __slist_make_link(__pos, _M_create_node(__x));  }#ifdef _STLP_MEMBER_TEMPLATES  // Check whether it's an integral type.  If so, it's not an iterator.  template <class _InIter>  void _M_insert_after_range(_Node_base* __pos,                              _InIter __first, _InIter __last) {    typedef typename _Is_integer<_InIter>::_Integral _Integral;    _M_insert_after_range(__pos, __first, __last, _Integral());  }  template <class _Integer>  void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x,                             const __true_type& /*_IsIntegral*/) {    _M_insert_after_fill(__pos, __n, __x);  }  template <class _InIter>  void _M_insert_after_range(_Node_base* __pos, _InIter __first, _InIter __last,                             const __false_type& /*_IsIntegral*/) {    while (__first != __last) {      __pos = __slist_make_link(__pos, _M_create_node(*__first));      ++__first;    }  }#else /* _STLP_MEMBER_TEMPLATES */  void _M_insert_after_range(_Node_base* __pos,                             const_iterator __first, const_iterator __last) {    while (__first != __last) {      __pos = __slist_make_link(__pos, _M_create_node(*__first));      ++__first;    }  }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?