?? stl_list.h
字號:
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Copyright (c) 1997
* Moscow Center for SPARC Technology
*
* Copyright (c) 1999
* Boris Fomitchev
*
* 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 __SGI_STL_INTERNAL_LIST_H
#define __SGI_STL_INTERNAL_LIST_H
# ifndef __SGI_STL_INTERNAL_ALGOBASE_H
# include <stl_algobase.h>
# endif
# ifndef __SGI_STL_INTERNAL_ALLOC_H
# include <stl_alloc.h>
# endif
# ifndef __SGI_STL_INTERNAL_ITERATOR_H
# include <stl_iterator.h>
# endif
# ifndef __SGI_STL_INTERNAL_CONSTRUCT_H
# include <stl_construct.h>
# endif
__STL_BEGIN_NAMESPACE
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma set woff 1174
#pragma set woff 1375
#endif
# define list __WORKAROUND_RENAME(list)
# if defined ( __STL_USE_ABBREVS )
# define __list_iterator _L__It
# endif
struct _List_node_base {
void* _M_next;
void* _M_prev;
};
template <class _Dummy>
struct _List_global {
typedef _List_node_base _Node;
static void _Transfer(_List_node_base* __position,
_List_node_base* __first, _List_node_base* __last);
};
typedef _List_global<bool> _List_global_inst;
template <class _Tp>
struct _List_node : public _List_node_base {
_Tp _M_data;
__TRIVIAL_STUFF(_List_node)
};
template<class _Tp, class _Traits>
# if defined ( __STL_DEBUG )
struct _List_iterator : public __owned_link {
# else
struct _List_iterator {
# endif
typedef _Tp value_type;
typedef typename _Traits::pointer pointer;
typedef typename _Traits::reference reference;
typedef _List_iterator<_Tp, _Nonconst_traits<_Tp> > iterator;
typedef _List_iterator<_Tp, _Const_traits<_Tp> > const_iterator;
typedef _List_iterator<_Tp, _Traits> _Self;
typedef bidirectional_iterator_tag iterator_category;
typedef _List_node<_Tp> _Node;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
_Node* _M_node;
// operator const const_iterator& () const { return *(const const_iterator*)this; }
# if defined ( __STL_DEBUG )
_Node* _Owner_node() const {
const __owned_list* __ptr = _Owner();
return __ptr ? (_Node*)__ptr->_Owner() : (_Node*)0;
}
_List_iterator(const __owned_list* __root, _Node* __x) :
__owned_link(__root), _M_node(__x) {}
_List_iterator() : __owned_link(0) {}
_List_iterator(const iterator& __x) : __owned_link(__x), _M_node(__x._M_node) {}
# else
_List_iterator(_Node* __x) : _M_node(__x) {}
_List_iterator() {}
_List_iterator(const iterator& __x) : _M_node(__x._M_node) {}
# endif
reference operator*() const {
__stl_verbose_assert(_Valid() && _M_node!=_Owner_node(),
_StlMsg_NOT_DEREFERENCEABLE);
return (*_M_node)._M_data;
}
__STL_DEFINE_ARROW_OPERATOR
_Self& operator++() {
__stl_verbose_assert(_M_node!=_Owner_node(), _StlMsg_INVALID_ADVANCE);
_M_node = (_Node*)(_M_node->_M_next);
return *this;
}
_Self operator++(int) {
_Self __tmp = *this;
++*this;
return __tmp;
}
_Self& operator--() {
_M_node = (_Node*)(_M_node->_M_prev);
__stl_verbose_assert(_M_node!=_Owner_node(), _StlMsg_INVALID_ADVANCE);
return *this;
}
_Self operator--(int) {
_Self __tmp = *this;
--*this;
return __tmp;
}
};
template<class _Tp, class _Traits, class _Traits1>
inline bool operator==(const _List_iterator<_Tp, _Traits>& __x,
const _List_iterator<_Tp, _Traits1>& __y ) {
__stl_debug_check(__check_same_owner_or_null(__x,__y));
return __x._M_node == __y._M_node;
}
#ifdef __STL_USE_SEPARATE_RELOPS_NAMESPACE
template<class _Tp, class _Traits, class _Traits1>
inline bool operator!=(const _List_iterator<_Tp, _Traits>& __x,
const _List_iterator<_Tp, _Traits1>& __y ) {
__stl_debug_check(__check_same_owner_or_null(__x, __y));
return __x._M_node != __y._M_node;
}
#else
template<class _Tp>
inline bool operator!=(const _List_iterator<_Tp, _Nonconst_traits<_Tp> >& __x,
const _List_iterator<_Tp, _Const_traits<_Tp> >& __y ) {
__stl_debug_check(__check_same_owner_or_null(__x, __y));
return __x._M_node != __y._M_node;
}
# ifdef __SUNPRO_CC
template<class _Tp>
inline bool operator!=(const _List_iterator<_Tp, _Const_traits<_Tp> >& __x,
const _List_iterator<_Tp, _Nonconst_traits<_Tp> >& __y ) {
__stl_debug_check(__check_same_owner_or_null(__x, __y));
return __x._M_node != __y._M_node;
}
# endif
#endif
#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
template <class _Tp, class _Traits>
inline _Tp*
value_type(const _List_iterator<_Tp, _Traits>&) { return 0; }
template <class _Tp, class _Traits>
inline bidirectional_iterator_tag
iterator_category(const _List_iterator<_Tp, _Traits>&) { return bidirectional_iterator_tag();}
template <class _Tp, class _Traits>
inline ptrdiff_t* distance_type(const _List_iterator<_Tp, _Traits>&) { return 0; }
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
// Base class that encapsulates details of allocators and helps
// to simplify EH
template <class _Tp, class _Alloc>
class _List_base
{
protected:
typedef _List_node<_Tp> _Node;
typedef typename _Alloc_traits<_Node, _Alloc>::allocator_type
_Node_allocator_type;
public:
typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type
allocator_type;
allocator_type get_allocator() const {
return __STL_CONVERT_ALLOCATOR((const _Node_allocator_type&)_M_node, _Tp);
}
_List_base(const allocator_type& __a) : _M_node(__STL_CONVERT_ALLOCATOR(__a, _Node), (_Node*)0) {
_M_node._M_data = _M_node.allocate(1);
_M_node._M_data->_M_next = _M_node._M_data;
_M_node._M_data->_M_prev = _M_node._M_data;
__stl_debug_do(_M_iter_list._Safe_init(_M_node._M_data));
}
~_List_base() {
clear();
_M_node.deallocate(_M_node._M_data, 1);
}
void clear();
public:
_STL_alloc_proxy<_Node*, _Node, _Node_allocator_type> _M_node;
# if defined (__STL_DEBUG)
protected:
mutable __owned_list _M_iter_list;
void _Invalidate_all() { _M_iter_list._Invalidate_all();}
# endif
};
template <class _Tp, __STL_DEFAULT_ALLOCATOR_SELECT(_Tp) >
class list : protected _List_base<_Tp, _Alloc> {
typedef _List_base<_Tp, _Alloc> _Base;
typedef list<_Tp, _Alloc> _Self;
protected:
typedef void* _Void_pointer;
public:
typedef _Tp value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef _List_node<_Tp> _Node;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef typename _Base::allocator_type allocator_type;
public:
typedef _List_iterator<_Tp, _Nonconst_traits<_Tp> > iterator;
typedef _List_iterator<_Tp, _Const_traits<_Tp> > const_iterator;
#if defined ( __STL_CLASS_PARTIAL_SPECIALIZATION ) && \
! defined (__STL_PARTIAL_SPECIALIZATION_BUG)
typedef __STLPORT_STD::reverse_iterator<const_iterator> const_reverse_iterator;
typedef __STLPORT_STD::reverse_iterator<iterator> reverse_iterator;
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
# if defined (__STL_MSVC50_COMPATIBILITY)
typedef reverse_bidirectional_iterator<const_iterator, value_type,
const_reference, const value_type*, difference_type>
const_reverse_iterator;
typedef reverse_bidirectional_iterator<iterator, value_type, reference,
pointer, difference_type>
reverse_iterator;
# else
typedef reverse_bidirectional_iterator<const_iterator,value_type,
const_reference,difference_type>
const_reverse_iterator;
typedef reverse_bidirectional_iterator<iterator,value_type,reference,
difference_type>
reverse_iterator;
# endif /* __STL_MSVC50_COMPATIBILITY */
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
// protected:
#if defined( __STL_HAS_NAMESPACES )
__STL_USING_BASE_MEMBER _List_base<_Tp, _Alloc>::_M_node;
#endif /* __STL_HAS_NAMESPACES */
public:
__STL_USING_BASE_MEMBER _List_base<_Tp, _Alloc>::get_allocator;
__STL_USING_BASE_MEMBER _List_base<_Tp, _Alloc>::clear;
protected:
_Node* _M_create_node(const _Tp& __x)
{
_Node* __p = _M_node.allocate(1);
__STL_TRY {
construct(&__p->_M_data, __x);
}
__STL_UNWIND(_M_node.deallocate(__p, 1));
return __p;
}
_Node* _M_create_node()
{
_Node* __p = _M_node.allocate(1);
__STL_TRY {
construct(&__p->_M_data);
}
__STL_UNWIND(_M_node.deallocate(__p, 1));
return __p;
}
public:
explicit list(const allocator_type& __a = __STL_ALLOC_INSTANCE(allocator_type)) :
_List_base<_Tp, _Alloc>(__a) {}
# if defined (__STL_DEBUG)
iterator begin() { return iterator(&_M_iter_list, (_Node*)(_M_node._M_data->_M_next)); }
const_iterator begin() const { return const_iterator(&_M_iter_list, (_Node*)(_M_node._M_data->_M_next)); }
iterator end() { return iterator(&_M_iter_list, _M_node._M_data); }
const_iterator end() const { return const_iterator(&_M_iter_list, _M_node._M_data); }
# else
iterator begin() { return iterator((_Node*)(_M_node._M_data->_M_next)); }
const_iterator begin() const { return const_iterator((_Node*)(_M_node._M_data->_M_next)); }
iterator end() { return _M_node._M_data; }
const_iterator end() const { return _M_node._M_data; }
# endif
reverse_iterator rbegin()
{ return reverse_iterator(end()); }
const_reverse_iterator rbegin() const
{ return const_reverse_iterator(end()); }
reverse_iterator rend()
{ return reverse_iterator(begin()); }
const_reverse_iterator rend() const
{ return const_reverse_iterator(begin()); }
bool empty() const { return _M_node._M_data->_M_next == _M_node._M_data; }
size_type size() const {
size_type __result = 0;
distance(begin(), end(), __result);
return __result;
}
size_type max_size() const { return size_type(-1); }
reference front() { return *begin(); }
const_reference front() const { return *begin(); }
reference back() { return *(--end()); }
const_reference back() const { return *(--end()); }
void swap(list<_Tp, _Alloc>& __x) {
__stl_debug_do(_M_iter_list._Swap_owners(__x._M_iter_list, true));
__STLPORT_STD::swap(_M_node, __x._M_node);
}
iterator insert(iterator __position, const _Tp& __x) {
__stl_debug_check(__check_if_owner(&_M_iter_list,__position));
_Node* __tmp = _M_create_node(__x);
__tmp->_M_next = __position._M_node;
__tmp->_M_prev = __position._M_node->_M_prev;
((_Node*) (__position._M_node->_M_prev))->_M_next = __tmp;
__position._M_node->_M_prev = __tmp;
# if defined ( __STL_DEBUG )
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -