stl_list.h

来自「symbian上STL模板库的实现」· C头文件 代码 · 共 1,254 行 · 第 1/3 页

H
1,254
字号
// List implementation -*- C++ -*-// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.//// This file is part of the GNU ISO C++ Library.  This library is free// software; you can redistribute it and/or modify it under the// terms of the GNU General Public License as published by the// Free Software Foundation; either version 2, or (at your option)// any later version.// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.// You should have received a copy of the GNU General Public License along// with this library; see the file COPYING.  If not, write to the Free// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,// USA.// As a special exception, you may use this file as part of a free software// library without restriction.  Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License.  This exception does not however// invalidate any other reasons why the executable file might be covered by// the GNU General Public License./* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation.  Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose.  It is provided "as is" without express or implied warranty. * * * Copyright (c) 1996,1997 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation.  Silicon Graphics makes no * representations about the suitability of this software for any * purpose.  It is provided "as is" without express or implied warranty. *//** @file stl_list.h *  This is an internal header file, included by other library headers. *  You should not attempt to use it directly. */#ifndef _LIST_H#define _LIST_H 1#include <bits/concept_check.h>namespace _GLIBCXX_STD{    // Supporting structures are split into common and templated types; the    // latter publicly inherits from the former in an effort to reduce code    // duplication.  This results in some "needless" static_cast'ing later on,    // but it's all safe downcasting.    /// @if maint Common part of a node in the %list.  @endif    struct _List_node_base    {        _List_node_base* _M_next;   ///< Self-explanatory        _List_node_base* _M_prev;   ///< Self-explanatory        static void            swap(_List_node_base& __x, _List_node_base& __y);        void            transfer(_List_node_base * const __first,                    _List_node_base * const __last);        void            reverse();        void            hook(_List_node_base * const __position);        void            unhook();    };    /// @if maint An actual node in the %list.  @endif    template<typename _Tp>        struct _List_node : public _List_node_base    {        _Tp _M_data;                ///< User's data.    };    /**     *  @brief A list::iterator.     *     *  @if maint     *  All the functions are op overloads.     *  @endif     */    template<typename _Tp>        struct _List_iterator        {            typedef _List_iterator<_Tp>           _Self;            typedef _List_node<_Tp>               _Node;            typedef ptrdiff_t                     difference_type;            typedef bidirectional_iterator_tag    iterator_category;            typedef _Tp                           value_type;            typedef _Tp*                          pointer;            typedef _Tp&                          reference;            _List_iterator() { }            _List_iterator(_List_node_base* __x)                : _M_node(__x) { }            // Must downcast from List_node_base to _List_node to get to _M_data.            reference                operator*() const                { return static_cast<_Node*>(_M_node)->_M_data; }            pointer                operator->() const                { return &static_cast<_Node*>(_M_node)->_M_data; }            _Self&                operator++()                {                    _M_node = _M_node->_M_next;                    return *this;                }            _Self                operator++(int)                {                    _Self __tmp = *this;                    _M_node = _M_node->_M_next;                    return __tmp;                }            _Self&                operator--()                {                    _M_node = _M_node->_M_prev;                    return *this;                }            _Self                operator--(int)                {                    _Self __tmp = *this;                    _M_node = _M_node->_M_prev;                    return __tmp;                }            bool                operator==(const _Self& __x) const                { return _M_node == __x._M_node; }            bool                operator!=(const _Self& __x) const                { return _M_node != __x._M_node; }            // The only member points to the %list element.            _List_node_base* _M_node;        };    /**     *  @brief A list::const_iterator.     *     *  @if maint     *  All the functions are op overloads.     *  @endif     */    template<typename _Tp>        struct _List_const_iterator        {            typedef _List_const_iterator<_Tp>     _Self;            typedef const _List_node<_Tp>         _Node;            typedef _List_iterator<_Tp>           iterator;            typedef ptrdiff_t                     difference_type;            typedef bidirectional_iterator_tag    iterator_category;            typedef _Tp                           value_type;            typedef const _Tp*                    pointer;            typedef const _Tp&                    reference;            _List_const_iterator() { }            _List_const_iterator(const _List_node_base* __x)                : _M_node(__x) { }            _List_const_iterator(const iterator& __x)                : _M_node(__x._M_node) { }            // Must downcast from List_node_base to _List_node to get to            // _M_data.            reference                operator*() const                { return static_cast<_Node*>(_M_node)->_M_data; }            pointer                operator->() const                { return &static_cast<_Node*>(_M_node)->_M_data; }            _Self&                operator++()                {                    _M_node = _M_node->_M_next;                    return *this;                }            _Self                operator++(int)                {                    _Self __tmp = *this;                    _M_node = _M_node->_M_next;                    return __tmp;                }            _Self&                operator--()                {                    _M_node = _M_node->_M_prev;                    return *this;                }            _Self                operator--(int)                {                    _Self __tmp = *this;                    _M_node = _M_node->_M_prev;                    return __tmp;                }            bool                operator==(const _Self& __x) const                { return _M_node == __x._M_node; }            bool                operator!=(const _Self& __x) const                { return _M_node != __x._M_node; }            // The only member points to the %list element.            const _List_node_base* _M_node;        };    template<typename _Val>        inline bool        operator==(const _List_iterator<_Val>& __x,                const _List_const_iterator<_Val>& __y)        { return __x._M_node == __y._M_node; }    template<typename _Val>        inline bool        operator!=(const _List_iterator<_Val>& __x,                const _List_const_iterator<_Val>& __y)        { return __x._M_node != __y._M_node; }    /**     *  @if maint     *  See bits/stl_deque.h's _Deque_base for an explanation.     *  @endif     */    template<typename _Tp, typename _Alloc>        class _List_base        {            protected:                // NOTA BENE                // The stored instance is not actually of "allocator_type"'s                // type.  Instead we rebind the type to                // Allocator<List_node<Tp>>, which according to [20.1.5]/4                // should probably be the same.  List_node<Tp> is not the same                // size as Tp (it's two pointers larger), and specializations on                // Tp may go unused because List_node<Tp> is being bound                // instead.                //                // We put this to the test in the constructors and in                // get_allocator, where we use conversions between                // allocator_type and _Node_Alloc_type. The conversion is                // required by table 32 in [20.1.5].                typedef typename _Alloc::template rebind<_List_node<_Tp> >::other                    _Node_Alloc_type;                struct _List_impl                     : public _Node_Alloc_type {                        _List_node_base _M_node;                        _List_impl (const _Node_Alloc_type& __a)                            : _Node_Alloc_type(__a)                        { }                    };                _List_impl _M_impl;                _List_node<_Tp>*                    _M_get_node()                    { return _M_impl._Node_Alloc_type::allocate(1); }                void                    _M_put_node(_List_node<_Tp>* __p)                    { _M_impl._Node_Alloc_type::deallocate(__p, 1); }            public:                typedef _Alloc allocator_type;                allocator_type                    get_allocator() const                    { return allocator_type(*static_cast<const _Node_Alloc_type*>(&this->_M_impl)); }                _List_base(const allocator_type& __a)                    : _M_impl(__a)                { _M_init(); }                // This is what actually destroys the list.                ~_List_base()                { _M_clear(); }                void                    _M_clear();                void                    _M_init()                    {                        this->_M_impl._M_node._M_next = &this->_M_impl._M_node;                        this->_M_impl._M_node._M_prev = &this->_M_impl._M_node;                    }        };    /**     *  @brief A standard container with linear time access to elements,     *  and fixed time insertion/deletion at any point in the sequence.     *     *  @ingroup Containers     *  @ingroup Sequences     *     *  Meets the requirements of a <a href="tables.html#65">container</a>, a     *  <a href="tables.html#66">reversible container</a>, and a     *  <a href="tables.html#67">sequence</a>, including the     *  <a href="tables.html#68">optional sequence requirements</a> with the     *  %exception of @c at and @c operator[].     *     *  This is a @e doubly @e linked %list.  Traversal up and down the     *  %list requires linear time, but adding and removing elements (or     *  @e nodes) is done in constant time, regardless of where the     *  change takes place.  Unlike std::vector and std::deque,     *  random-access iterators are not provided, so subscripting ( @c     *  [] ) access is not allowed.  For algorithms which only need     *  sequential access, this lack makes no difference.     *     *  Also unlike the other standard containers, std::list provides     *  specialized algorithms %unique to linked lists, such as     *  splicing, sorting, and in-place reversal.     *     *  @if maint     *  A couple points on memory allocation for list<Tp>:     *     *  First, we never actually allocate a Tp, we allocate     *  List_node<Tp>'s and trust [20.1.5]/4 to DTRT.  This is to ensure     *  that after elements from %list<X,Alloc1> are spliced into     *  %list<X,Alloc2>, destroying the memory of the second %list is a     *  valid operation, i.e., Alloc1 giveth and Alloc2 taketh away.     *     *  Second, a %list conceptually represented as     *  @code     *    A <---> B <---> C <---> D     *  @endcode     *  is actually circular; a link exists between A and D.  The %list     *  class holds (as its only data member) a private list::iterator     *  pointing to @e D, not to @e A!  To get to the head of the %list,     *  we start at the tail and move forward by one.  When this member     *  iterator's next/previous pointers refer to itself, the %list is     *  %empty.  @endif     */    template<typename _Tp, typename _Alloc = allocator<_Tp> >        class list : protected _List_base<_Tp, _Alloc>    {        // concept requirements        __glibcxx_class_requires(_Tp, _SGIAssignableConcept)            typedef _List_base<_Tp, _Alloc>                   _Base;        public:        typedef _Tp                                        value_type;        typedef typename _Alloc::pointer                   pointer;        typedef typename _Alloc::const_pointer             const_pointer;        typedef typename _Alloc::reference                 reference;        typedef typename _Alloc::const_reference           const_reference;        typedef _List_iterator<_Tp>                        iterator;        typedef _List_const_iterator<_Tp>                  const_iterator;        typedef std::reverse_iterator<const_iterator>      const_reverse_iterator;        typedef std::reverse_iterator<iterator>            reverse_iterator;        typedef size_t                                     size_type;        typedef ptrdiff_t                                  difference_type;        typedef typename _Base::allocator_type             allocator_type;        protected:        // Note that pointers-to-_Node's can be ctor-converted to        // iterator types.        typedef _List_node<_Tp>				_Node;        /** @if maint         *  One data member plus two memory-handling functions.  If the         *  _Alloc type requires separate instances, then one of those         *  will also be included, accumulated from the topmost parent.         *  @endif         */

⌨️ 快捷键说明

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