forked from OSchip/llvm-project
[libcxx] Fix for ALL undefined behavior in <list>.
Summary: This patch fixes std::list for builtin pointer types in the current ABI version and fixes std::list for all fancy pointer types in the next ABI version. The patch was designed to minimize the amount of code needed to support both ABI configurations. Currently only ~5 lines of code differ. Reviewers: danalbert, jroelofs, mclow.lists Subscribers: dexonsmith, awi, cfe-commits Differential Revision: http://reviews.llvm.org/D12299 llvm-svn: 256652
This commit is contained in:
parent
50d5b97449
commit
b88ea354fe
|
@ -39,6 +39,8 @@
|
|||
#define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
|
||||
// Fix deque iterator type in order to support incomplete types.
|
||||
#define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
|
||||
// Fix undefined behavior in how std::list stores it's linked nodes.
|
||||
#define _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB
|
||||
#endif
|
||||
|
||||
#define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y
|
||||
|
|
|
@ -175,6 +175,7 @@ template <class T, class Alloc>
|
|||
#include <initializer_list>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <type_traits>
|
||||
|
||||
#include <__undef_min_max>
|
||||
|
||||
|
@ -187,25 +188,55 @@ template <class T, class Alloc>
|
|||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Tp, class _VoidPtr> struct __list_node;
|
||||
template <class _Tp, class _VoidPtr> struct __list_node_base;
|
||||
|
||||
template <class _Tp, class _VoidPtr>
|
||||
struct __list_node_pointer_traits {
|
||||
typedef typename __rebind_pointer<_VoidPtr, __list_node<_Tp, _VoidPtr> >::type
|
||||
__node_pointer;
|
||||
typedef typename __rebind_pointer<_VoidPtr, __list_node_base<_Tp, _VoidPtr> >::type
|
||||
__base_pointer;
|
||||
|
||||
#if defined(_LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB)
|
||||
typedef __base_pointer __link_pointer;
|
||||
#else
|
||||
typedef typename conditional<
|
||||
is_pointer<_VoidPtr>::value,
|
||||
__base_pointer,
|
||||
__node_pointer
|
||||
>::type __link_pointer;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
template <class _Tp, class _VoidPtr>
|
||||
struct __list_node_base
|
||||
{
|
||||
typedef typename __rebind_pointer<_VoidPtr, __list_node<_Tp, _VoidPtr> >::type
|
||||
pointer;
|
||||
typedef typename __rebind_pointer<_VoidPtr, __list_node_base>::type
|
||||
__base_pointer;
|
||||
typedef __list_node_pointer_traits<_Tp, _VoidPtr> _NodeTraits;
|
||||
typedef typename _NodeTraits::__node_pointer __node_pointer;
|
||||
typedef typename _NodeTraits::__base_pointer __base_pointer;
|
||||
typedef typename _NodeTraits::__link_pointer __link_pointer;
|
||||
|
||||
pointer __prev_;
|
||||
pointer __next_;
|
||||
__link_pointer __prev_;
|
||||
__link_pointer __next_;
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__list_node_base() : __prev_(__self()), __next_(__self()) {}
|
||||
__list_node_base() : __prev_(__as_link()), __next_(__as_link()) {}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
pointer __self()
|
||||
{
|
||||
return static_cast<pointer>(pointer_traits<__base_pointer>::pointer_to(*this));
|
||||
__base_pointer __as_base() {
|
||||
return pointer_traits<__base_pointer>::pointer_to(*this);
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__link_pointer __as_link() {
|
||||
return static_cast<__link_pointer>(static_cast<_VoidPtr>(
|
||||
__as_base()));
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__node_pointer __as_node() {
|
||||
return static_cast<__node_pointer>(__as_base());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -223,21 +254,21 @@ template <class _Tp, class _VoidPtr> class _LIBCPP_TYPE_VIS_ONLY __list_const_it
|
|||
template <class _Tp, class _VoidPtr>
|
||||
class _LIBCPP_TYPE_VIS_ONLY __list_iterator
|
||||
{
|
||||
typedef typename __rebind_pointer<_VoidPtr, __list_node<_Tp, _VoidPtr> >::type
|
||||
__node_pointer;
|
||||
typedef __list_node_pointer_traits<_Tp, _VoidPtr> _NodeTraits;
|
||||
typedef typename _NodeTraits::__link_pointer __link_pointer;
|
||||
|
||||
__node_pointer __ptr_;
|
||||
__link_pointer __ptr_;
|
||||
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
explicit __list_iterator(__node_pointer __p, const void* __c) _NOEXCEPT
|
||||
explicit __list_iterator(__link_pointer __p, const void* __c) _NOEXCEPT
|
||||
: __ptr_(__p)
|
||||
{
|
||||
__get_db()->__insert_ic(this, __c);
|
||||
}
|
||||
#else
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
explicit __list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
|
||||
explicit __list_iterator(__link_pointer __p) _NOEXCEPT : __ptr_(__p) {}
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -295,7 +326,7 @@ public:
|
|||
_LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
|
||||
"Attempted to dereference a non-dereferenceable list::iterator");
|
||||
#endif
|
||||
return __ptr_->__value_;
|
||||
return __ptr_->__as_node()->__value_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
pointer operator->() const
|
||||
|
@ -304,7 +335,7 @@ public:
|
|||
_LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
|
||||
"Attempted to dereference a non-dereferenceable list::iterator");
|
||||
#endif
|
||||
return pointer_traits<pointer>::pointer_to(__ptr_->__value_);
|
||||
return pointer_traits<pointer>::pointer_to(__ptr_->__as_node()->__value_);
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
|
@ -346,21 +377,21 @@ public:
|
|||
template <class _Tp, class _VoidPtr>
|
||||
class _LIBCPP_TYPE_VIS_ONLY __list_const_iterator
|
||||
{
|
||||
typedef typename __rebind_pointer<_VoidPtr, __list_node<_Tp, _VoidPtr> >::type
|
||||
__node_pointer;
|
||||
typedef __list_node_pointer_traits<_Tp, _VoidPtr> _NodeTraits;
|
||||
typedef typename _NodeTraits::__link_pointer __link_pointer;
|
||||
|
||||
__node_pointer __ptr_;
|
||||
__link_pointer __ptr_;
|
||||
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
explicit __list_const_iterator(__node_pointer __p, const void* __c) _NOEXCEPT
|
||||
explicit __list_const_iterator(__link_pointer __p, const void* __c) _NOEXCEPT
|
||||
: __ptr_(__p)
|
||||
{
|
||||
__get_db()->__insert_ic(this, __c);
|
||||
}
|
||||
#else
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
explicit __list_const_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
|
||||
explicit __list_const_iterator(__link_pointer __p) _NOEXCEPT : __ptr_(__p) {}
|
||||
#endif
|
||||
|
||||
template<class, class> friend class list;
|
||||
|
@ -422,7 +453,7 @@ public:
|
|||
_LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
|
||||
"Attempted to dereference a non-dereferenceable list::const_iterator");
|
||||
#endif
|
||||
return __ptr_->__value_;
|
||||
return __ptr_->__as_node()->__value_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
pointer operator->() const
|
||||
|
@ -431,7 +462,7 @@ public:
|
|||
_LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
|
||||
"Attempted to dereference a non-dereferenceable list::iterator");
|
||||
#endif
|
||||
return pointer_traits<pointer>::pointer_to(__ptr_->__value_);
|
||||
return pointer_traits<pointer>::pointer_to(__ptr_->__as_node()->__value_);
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
|
@ -489,6 +520,8 @@ protected:
|
|||
typedef allocator_traits<__node_allocator> __node_alloc_traits;
|
||||
typedef typename __node_alloc_traits::pointer __node_pointer;
|
||||
typedef typename __node_alloc_traits::pointer __node_const_pointer;
|
||||
typedef typename __list_node_pointer_traits<value_type, __void_pointer>::__link_pointer __link_pointer;
|
||||
typedef __link_pointer __link_const_pointer;
|
||||
typedef typename __alloc_traits::pointer pointer;
|
||||
typedef typename __alloc_traits::const_pointer const_pointer;
|
||||
typedef typename __alloc_traits::difference_type difference_type;
|
||||
|
@ -511,7 +544,7 @@ protected:
|
|||
const __node_allocator& __node_alloc() const _NOEXCEPT
|
||||
{return __size_alloc_.second();}
|
||||
|
||||
static void __unlink_nodes(__node_pointer __f, __node_pointer __l) _NOEXCEPT;
|
||||
static void __unlink_nodes(__link_pointer __f, __link_pointer __l) _NOEXCEPT;
|
||||
|
||||
__list_imp()
|
||||
_NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value);
|
||||
|
@ -543,22 +576,18 @@ protected:
|
|||
iterator end() _NOEXCEPT
|
||||
{
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
return iterator(static_cast<__node_pointer>(
|
||||
pointer_traits<__node_base_pointer>::pointer_to(__end_)), this);
|
||||
return iterator(__end_.__as_link(), this);
|
||||
#else
|
||||
return iterator(static_cast<__node_pointer>(
|
||||
pointer_traits<__node_base_pointer>::pointer_to(__end_)));
|
||||
return iterator(__end_.__as_link());
|
||||
#endif
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
const_iterator end() const _NOEXCEPT
|
||||
{
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
return const_iterator(static_cast<__node_const_pointer>(
|
||||
pointer_traits<__node_base_pointer>::pointer_to(const_cast<__node_base&>(__end_))), this);
|
||||
return const_iterator(const_cast<__node_base&>(__end_).__as_link(), this);
|
||||
#else
|
||||
return const_iterator(static_cast<__node_const_pointer>(
|
||||
pointer_traits<__node_base_pointer>::pointer_to(const_cast<__node_base&>(__end_))));
|
||||
return const_iterator(const_cast<__node_base&>(__end_).__as_link());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -613,7 +642,7 @@ private:
|
|||
template <class _Tp, class _Alloc>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void
|
||||
__list_imp<_Tp, _Alloc>::__unlink_nodes(__node_pointer __f, __node_pointer __l)
|
||||
__list_imp<_Tp, _Alloc>::__unlink_nodes(__link_pointer __f, __link_pointer __l)
|
||||
_NOEXCEPT
|
||||
{
|
||||
__f->__prev_->__next_ = __l->__next_;
|
||||
|
@ -651,17 +680,16 @@ __list_imp<_Tp, _Alloc>::clear() _NOEXCEPT
|
|||
if (!empty())
|
||||
{
|
||||
__node_allocator& __na = __node_alloc();
|
||||
__node_pointer __f = __end_.__next_;
|
||||
__node_pointer __l = static_cast<__node_pointer>(
|
||||
pointer_traits<__node_base_pointer>::pointer_to(__end_));
|
||||
__link_pointer __f = __end_.__next_;
|
||||
__link_pointer __l = __end_.__as_link();
|
||||
__unlink_nodes(__f, __l->__prev_);
|
||||
__sz() = 0;
|
||||
while (__f != __l)
|
||||
{
|
||||
__node_pointer __n = __f;
|
||||
__node_pointer __np = __f->__as_node();
|
||||
__f = __f->__next_;
|
||||
__node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
|
||||
__node_alloc_traits::deallocate(__na, __n, 1);
|
||||
__node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
|
||||
__node_alloc_traits::deallocate(__na, __np, 1);
|
||||
}
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
__c_node* __c = __get_db()->__find_c_and_lock(this);
|
||||
|
@ -700,13 +728,13 @@ __list_imp<_Tp, _Alloc>::swap(__list_imp& __c)
|
|||
swap(__sz(), __c.__sz());
|
||||
swap(__end_, __c.__end_);
|
||||
if (__sz() == 0)
|
||||
__end_.__next_ = __end_.__prev_ = __end_.__self();
|
||||
__end_.__next_ = __end_.__prev_ = __end_.__as_link();
|
||||
else
|
||||
__end_.__prev_->__next_ = __end_.__next_->__prev_ = __end_.__self();
|
||||
__end_.__prev_->__next_ = __end_.__next_->__prev_ = __end_.__as_link();
|
||||
if (__c.__sz() == 0)
|
||||
__c.__end_.__next_ = __c.__end_.__prev_ = __c.__end_.__self();
|
||||
__c.__end_.__next_ = __c.__end_.__prev_ = __c.__end_.__as_link();
|
||||
else
|
||||
__c.__end_.__prev_->__next_ = __c.__end_.__next_->__prev_ = __c.__end_.__self();
|
||||
__c.__end_.__prev_->__next_ = __c.__end_.__next_->__prev_ = __c.__end_.__as_link();
|
||||
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
__libcpp_db* __db = __get_db();
|
||||
|
@ -719,8 +747,7 @@ __list_imp<_Tp, _Alloc>::swap(__list_imp& __c)
|
|||
{
|
||||
--__p;
|
||||
const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
|
||||
if (__i->__ptr_ == static_cast<__node_pointer>(
|
||||
pointer_traits<__node_base_pointer>::pointer_to(__c.__end_)))
|
||||
if (__i->__ptr_ == __c.__end_.__as_link())
|
||||
{
|
||||
__cn2->__add(*__p);
|
||||
if (--__cn1->end_ != __p)
|
||||
|
@ -733,8 +760,7 @@ __list_imp<_Tp, _Alloc>::swap(__list_imp& __c)
|
|||
{
|
||||
--__p;
|
||||
const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
|
||||
if (__i->__ptr_ == static_cast<__node_pointer>(
|
||||
pointer_traits<__node_base_pointer>::pointer_to(__end_)))
|
||||
if (__i->__ptr_ == __end_.__as_link())
|
||||
{
|
||||
__cn1->__add(*__p);
|
||||
if (--__cn2->end_ != __p)
|
||||
|
@ -758,6 +784,7 @@ class _LIBCPP_TYPE_VIS_ONLY list
|
|||
typedef typename base::__node_alloc_traits __node_alloc_traits;
|
||||
typedef typename base::__node_base __node_base;
|
||||
typedef typename base::__node_base_pointer __node_base_pointer;
|
||||
typedef typename base::__link_pointer __link_pointer;
|
||||
|
||||
public:
|
||||
typedef _Tp value_type;
|
||||
|
@ -881,25 +908,25 @@ public:
|
|||
reference front()
|
||||
{
|
||||
_LIBCPP_ASSERT(!empty(), "list::front called on empty list");
|
||||
return base::__end_.__next_->__value_;
|
||||
return base::__end_.__next_->__as_node()->__value_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
const_reference front() const
|
||||
{
|
||||
_LIBCPP_ASSERT(!empty(), "list::front called on empty list");
|
||||
return base::__end_.__next_->__value_;
|
||||
return base::__end_.__next_->__as_node()->__value_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
reference back()
|
||||
{
|
||||
_LIBCPP_ASSERT(!empty(), "list::back called on empty list");
|
||||
return base::__end_.__prev_->__value_;
|
||||
return base::__end_.__prev_->__as_node()->__value_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
const_reference back() const
|
||||
{
|
||||
_LIBCPP_ASSERT(!empty(), "list::back called on empty list");
|
||||
return base::__end_.__prev_->__value_;
|
||||
return base::__end_.__prev_->__as_node()->__value_;
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
@ -1004,9 +1031,9 @@ public:
|
|||
#endif // _LIBCPP_DEBUG_LEVEL >= 2
|
||||
|
||||
private:
|
||||
static void __link_nodes (__node_pointer __p, __node_pointer __f, __node_pointer __l);
|
||||
void __link_nodes_at_front(__node_pointer __f, __node_pointer __l);
|
||||
void __link_nodes_at_back (__node_pointer __f, __node_pointer __l);
|
||||
static void __link_nodes (__link_pointer __p, __link_pointer __f, __link_pointer __l);
|
||||
void __link_nodes_at_front(__link_pointer __f, __link_pointer __l);
|
||||
void __link_nodes_at_back (__link_pointer __f, __link_pointer __l);
|
||||
iterator __iterator(size_type __n);
|
||||
template <class _Comp>
|
||||
static iterator __sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp);
|
||||
|
@ -1020,7 +1047,7 @@ private:
|
|||
template <class _Tp, class _Alloc>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void
|
||||
list<_Tp, _Alloc>::__link_nodes(__node_pointer __p, __node_pointer __f, __node_pointer __l)
|
||||
list<_Tp, _Alloc>::__link_nodes(__link_pointer __p, __link_pointer __f, __link_pointer __l)
|
||||
{
|
||||
__p->__prev_->__next_ = __f;
|
||||
__f->__prev_ = __p->__prev_;
|
||||
|
@ -1032,9 +1059,9 @@ list<_Tp, _Alloc>::__link_nodes(__node_pointer __p, __node_pointer __f, __node_p
|
|||
template <class _Tp, class _Alloc>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void
|
||||
list<_Tp, _Alloc>::__link_nodes_at_front(__node_pointer __f, __node_pointer __l)
|
||||
list<_Tp, _Alloc>::__link_nodes_at_front(__link_pointer __f, __link_pointer __l)
|
||||
{
|
||||
__f->__prev_ = base::__end_.__self();
|
||||
__f->__prev_ = base::__end_.__as_link();
|
||||
__l->__next_ = base::__end_.__next_;
|
||||
__l->__next_->__prev_ = __l;
|
||||
base::__end_.__next_ = __f;
|
||||
|
@ -1044,9 +1071,9 @@ list<_Tp, _Alloc>::__link_nodes_at_front(__node_pointer __f, __node_pointer __l)
|
|||
template <class _Tp, class _Alloc>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void
|
||||
list<_Tp, _Alloc>::__link_nodes_at_back(__node_pointer __f, __node_pointer __l)
|
||||
list<_Tp, _Alloc>::__link_nodes_at_back(__link_pointer __f, __link_pointer __l)
|
||||
{
|
||||
__l->__next_ = base::__end_.__self();
|
||||
__l->__next_ = base::__end_.__as_link();
|
||||
__f->__prev_ = base::__end_.__prev_;
|
||||
__f->__prev_->__next_ = __f;
|
||||
base::__end_.__prev_ = __l;
|
||||
|
@ -1323,12 +1350,12 @@ list<_Tp, _Alloc>::insert(const_iterator __p, const value_type& __x)
|
|||
unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
|
||||
__hold->__prev_ = 0;
|
||||
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
|
||||
__link_nodes(__p.__ptr_, __hold.get(), __hold.get());
|
||||
__link_nodes(__p.__ptr_, __hold->__as_link(), __hold->__as_link());
|
||||
++base::__sz();
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
return iterator(__hold.release(), this);
|
||||
return iterator(__hold.release()->__as_link(), this);
|
||||
#else
|
||||
return iterator(__hold.release());
|
||||
return iterator(__hold.release()->__as_link());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1354,9 +1381,9 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
|
|||
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
|
||||
++__ds;
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
__r = iterator(__hold.get(), this);
|
||||
__r = iterator(__hold->__as_link(), this);
|
||||
#else
|
||||
__r = iterator(__hold.get());
|
||||
__r = iterator(__hold->__as_link());
|
||||
#endif
|
||||
__hold.release();
|
||||
iterator __e = __r;
|
||||
|
@ -1368,7 +1395,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
|
|||
{
|
||||
__hold.reset(__node_alloc_traits::allocate(__na, 1));
|
||||
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
|
||||
__e.__ptr_->__next_ = __hold.get();
|
||||
__e.__ptr_->__next_ = __hold->__as_link();
|
||||
__hold->__prev_ = __e.__ptr_;
|
||||
__hold.release();
|
||||
}
|
||||
|
@ -1379,8 +1406,8 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
|
|||
while (true)
|
||||
{
|
||||
__node_alloc_traits::destroy(__na, _VSTD::addressof(*__e));
|
||||
__node_pointer __prev = __e.__ptr_->__prev_;
|
||||
__node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
|
||||
__link_pointer __prev = __e.__ptr_->__prev_;
|
||||
__node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
|
||||
if (__prev == 0)
|
||||
break;
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
|
@ -1422,9 +1449,9 @@ list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
|
|||
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f);
|
||||
++__ds;
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
__r = iterator(__hold.get(), this);
|
||||
__r = iterator(__hold.get()->__as_link(), this);
|
||||
#else
|
||||
__r = iterator(__hold.get());
|
||||
__r = iterator(__hold.get()->__as_link());
|
||||
#endif
|
||||
__hold.release();
|
||||
iterator __e = __r;
|
||||
|
@ -1436,7 +1463,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
|
|||
{
|
||||
__hold.reset(__node_alloc_traits::allocate(__na, 1));
|
||||
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f);
|
||||
__e.__ptr_->__next_ = __hold.get();
|
||||
__e.__ptr_->__next_ = __hold.get()->__as_link();
|
||||
__hold->__prev_ = __e.__ptr_;
|
||||
__hold.release();
|
||||
}
|
||||
|
@ -1447,8 +1474,8 @@ list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
|
|||
while (true)
|
||||
{
|
||||
__node_alloc_traits::destroy(__na, _VSTD::addressof(*__e));
|
||||
__node_pointer __prev = __e.__ptr_->__prev_;
|
||||
__node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
|
||||
__link_pointer __prev = __e.__ptr_->__prev_;
|
||||
__node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
|
||||
if (__prev == 0)
|
||||
break;
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
|
@ -1474,7 +1501,8 @@ list<_Tp, _Alloc>::push_front(const value_type& __x)
|
|||
typedef __allocator_destructor<__node_allocator> _Dp;
|
||||
unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
|
||||
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
|
||||
__link_nodes_at_front(__hold.get(), __hold.get());
|
||||
__link_pointer __nl = __hold->__as_link();
|
||||
__link_nodes_at_front(__nl, __nl);
|
||||
++base::__sz();
|
||||
__hold.release();
|
||||
}
|
||||
|
@ -1487,7 +1515,7 @@ list<_Tp, _Alloc>::push_back(const value_type& __x)
|
|||
typedef __allocator_destructor<__node_allocator> _Dp;
|
||||
unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
|
||||
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
|
||||
__link_nodes_at_back(__hold.get(), __hold.get());
|
||||
__link_nodes_at_back(__hold.get()->__as_link(), __hold.get()->__as_link());
|
||||
++base::__sz();
|
||||
__hold.release();
|
||||
}
|
||||
|
@ -1502,7 +1530,7 @@ list<_Tp, _Alloc>::push_front(value_type&& __x)
|
|||
typedef __allocator_destructor<__node_allocator> _Dp;
|
||||
unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
|
||||
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x));
|
||||
__link_nodes_at_front(__hold.get(), __hold.get());
|
||||
__link_nodes_at_front(__hold.get()->__as_link(), __hold.get()->__as_link());
|
||||
++base::__sz();
|
||||
__hold.release();
|
||||
}
|
||||
|
@ -1515,7 +1543,7 @@ list<_Tp, _Alloc>::push_back(value_type&& __x)
|
|||
typedef __allocator_destructor<__node_allocator> _Dp;
|
||||
unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
|
||||
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x));
|
||||
__link_nodes_at_back(__hold.get(), __hold.get());
|
||||
__link_nodes_at_back(__hold.get()->__as_link(), __hold.get()->__as_link());
|
||||
++base::__sz();
|
||||
__hold.release();
|
||||
}
|
||||
|
@ -1531,7 +1559,7 @@ list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
|
|||
typedef __allocator_destructor<__node_allocator> _Dp;
|
||||
unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
|
||||
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...);
|
||||
__link_nodes_at_front(__hold.get(), __hold.get());
|
||||
__link_nodes_at_front(__hold.get()->__as_link(), __hold.get()->__as_link());
|
||||
++base::__sz();
|
||||
__hold.release();
|
||||
}
|
||||
|
@ -1545,7 +1573,8 @@ list<_Tp, _Alloc>::emplace_back(_Args&&... __args)
|
|||
typedef __allocator_destructor<__node_allocator> _Dp;
|
||||
unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
|
||||
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...);
|
||||
__link_nodes_at_back(__hold.get(), __hold.get());
|
||||
__link_pointer __nl = __hold->__as_link();
|
||||
__link_nodes_at_back(__nl, __nl);
|
||||
++base::__sz();
|
||||
__hold.release();
|
||||
}
|
||||
|
@ -1565,12 +1594,14 @@ list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args)
|
|||
unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
|
||||
__hold->__prev_ = 0;
|
||||
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...);
|
||||
__link_nodes(__p.__ptr_, __hold.get(), __hold.get());
|
||||
__link_pointer __nl = __hold.get()->__as_link();
|
||||
__link_nodes(__p.__ptr_, __nl, __nl);
|
||||
++base::__sz();
|
||||
__hold.release();
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
return iterator(__hold.release(), this);
|
||||
return iterator(__nl, this);
|
||||
#else
|
||||
return iterator(__hold.release());
|
||||
return iterator(__nl);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1590,12 +1621,14 @@ list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x)
|
|||
unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
|
||||
__hold->__prev_ = 0;
|
||||
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x));
|
||||
__link_nodes(__p.__ptr_, __hold.get(), __hold.get());
|
||||
__link_pointer __nl = __hold->__as_link();
|
||||
__link_nodes(__p.__ptr_, __nl, __nl);
|
||||
++base::__sz();
|
||||
__hold.release();
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
return iterator(__hold.release(), this);
|
||||
return iterator(__nl, this);
|
||||
#else
|
||||
return iterator(__hold.release());
|
||||
return iterator(__nl);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1607,7 +1640,7 @@ list<_Tp, _Alloc>::pop_front()
|
|||
{
|
||||
_LIBCPP_ASSERT(!empty(), "list::pop_front() called with empty list");
|
||||
__node_allocator& __na = base::__node_alloc();
|
||||
__node_pointer __n = base::__end_.__next_;
|
||||
__link_pointer __n = base::__end_.__next_;
|
||||
base::__unlink_nodes(__n, __n);
|
||||
--base::__sz();
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
|
@ -1625,8 +1658,9 @@ list<_Tp, _Alloc>::pop_front()
|
|||
}
|
||||
__get_db()->unlock();
|
||||
#endif
|
||||
__node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
|
||||
__node_alloc_traits::deallocate(__na, __n, 1);
|
||||
__node_pointer __np = __n->__as_node();
|
||||
__node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
|
||||
__node_alloc_traits::deallocate(__na, __np, 1);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Alloc>
|
||||
|
@ -1635,7 +1669,7 @@ list<_Tp, _Alloc>::pop_back()
|
|||
{
|
||||
_LIBCPP_ASSERT(!empty(), "list::pop_back() called with empty list");
|
||||
__node_allocator& __na = base::__node_alloc();
|
||||
__node_pointer __n = base::__end_.__prev_;
|
||||
__link_pointer __n = base::__end_.__prev_;
|
||||
base::__unlink_nodes(__n, __n);
|
||||
--base::__sz();
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
|
@ -1653,8 +1687,9 @@ list<_Tp, _Alloc>::pop_back()
|
|||
}
|
||||
__get_db()->unlock();
|
||||
#endif
|
||||
__node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
|
||||
__node_alloc_traits::deallocate(__na, __n, 1);
|
||||
__node_pointer __np = __n->__as_node();
|
||||
__node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
|
||||
__node_alloc_traits::deallocate(__na, __np, 1);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Alloc>
|
||||
|
@ -1669,8 +1704,8 @@ list<_Tp, _Alloc>::erase(const_iterator __p)
|
|||
_LIBCPP_ASSERT(__p != end(),
|
||||
"list::erase(iterator) called with a non-dereferenceable iterator");
|
||||
__node_allocator& __na = base::__node_alloc();
|
||||
__node_pointer __n = __p.__ptr_;
|
||||
__node_pointer __r = __n->__next_;
|
||||
__link_pointer __n = __p.__ptr_;
|
||||
__link_pointer __r = __n->__next_;
|
||||
base::__unlink_nodes(__n, __n);
|
||||
--base::__sz();
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
|
@ -1688,8 +1723,9 @@ list<_Tp, _Alloc>::erase(const_iterator __p)
|
|||
}
|
||||
__get_db()->unlock();
|
||||
#endif
|
||||
__node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
|
||||
__node_alloc_traits::deallocate(__na, __n, 1);
|
||||
__node_pointer __np = __n->__as_node();
|
||||
__node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
|
||||
__node_alloc_traits::deallocate(__na, __np, 1);
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
return iterator(__r, this);
|
||||
#else
|
||||
|
@ -1712,7 +1748,7 @@ list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l)
|
|||
base::__unlink_nodes(__f.__ptr_, __l.__ptr_->__prev_);
|
||||
while (__f != __l)
|
||||
{
|
||||
__node_pointer __n = __f.__ptr_;
|
||||
__link_pointer __n = __f.__ptr_;
|
||||
++__f;
|
||||
--base::__sz();
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
|
@ -1730,8 +1766,9 @@ list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l)
|
|||
}
|
||||
__get_db()->unlock();
|
||||
#endif
|
||||
__node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
|
||||
__node_alloc_traits::deallocate(__na, __n, 1);
|
||||
__node_pointer __np = __n->__as_node();
|
||||
__node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
|
||||
__node_alloc_traits::deallocate(__na, __np, 1);
|
||||
}
|
||||
}
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
|
@ -1758,9 +1795,9 @@ list<_Tp, _Alloc>::resize(size_type __n)
|
|||
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_));
|
||||
++__ds;
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
iterator __r = iterator(__hold.release(), this);
|
||||
iterator __r = iterator(__hold.release()->__as_link(), this);
|
||||
#else
|
||||
iterator __r = iterator(__hold.release());
|
||||
iterator __r = iterator(__hold.release()->__as_link());
|
||||
#endif
|
||||
iterator __e = __r;
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
|
@ -1771,7 +1808,7 @@ list<_Tp, _Alloc>::resize(size_type __n)
|
|||
{
|
||||
__hold.reset(__node_alloc_traits::allocate(__na, 1));
|
||||
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_));
|
||||
__e.__ptr_->__next_ = __hold.get();
|
||||
__e.__ptr_->__next_ = __hold.get()->__as_link();
|
||||
__hold->__prev_ = __e.__ptr_;
|
||||
__hold.release();
|
||||
}
|
||||
|
@ -1782,8 +1819,8 @@ list<_Tp, _Alloc>::resize(size_type __n)
|
|||
while (true)
|
||||
{
|
||||
__node_alloc_traits::destroy(__na, _VSTD::addressof(*__e));
|
||||
__node_pointer __prev = __e.__ptr_->__prev_;
|
||||
__node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
|
||||
__link_pointer __prev = __e.__ptr_->__prev_;
|
||||
__node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
|
||||
if (__prev == 0)
|
||||
break;
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
|
@ -1816,10 +1853,11 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
|
|||
__hold->__prev_ = 0;
|
||||
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
|
||||
++__ds;
|
||||
__link_pointer __nl = __hold.release()->__as_link();
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
iterator __r = iterator(__hold.release(), this);
|
||||
iterator __r = iterator(__nl, this);
|
||||
#else
|
||||
iterator __r = iterator(__hold.release());
|
||||
iterator __r = iterator(__nl);
|
||||
#endif
|
||||
iterator __e = __r;
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
|
@ -1830,7 +1868,7 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
|
|||
{
|
||||
__hold.reset(__node_alloc_traits::allocate(__na, 1));
|
||||
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
|
||||
__e.__ptr_->__next_ = __hold.get();
|
||||
__e.__ptr_->__next_ = __hold.get()->__as_link();
|
||||
__hold->__prev_ = __e.__ptr_;
|
||||
__hold.release();
|
||||
}
|
||||
|
@ -1841,8 +1879,8 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
|
|||
while (true)
|
||||
{
|
||||
__node_alloc_traits::destroy(__na, _VSTD::addressof(*__e));
|
||||
__node_pointer __prev = __e.__ptr_->__prev_;
|
||||
__node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
|
||||
__link_pointer __prev = __e.__ptr_->__prev_;
|
||||
__node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1);
|
||||
if (__prev == 0)
|
||||
break;
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
|
@ -1854,8 +1892,7 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
|
|||
throw;
|
||||
}
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
__link_nodes(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::
|
||||
pointer_to(base::__end_)), __r.__ptr_, __e.__ptr_);
|
||||
__link_nodes(base::__end_.__as_link(), __r.__ptr_, __e.__ptr_);
|
||||
base::__sz() += __ds;
|
||||
}
|
||||
}
|
||||
|
@ -1873,8 +1910,8 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c)
|
|||
#endif
|
||||
if (!__c.empty())
|
||||
{
|
||||
__node_pointer __f = __c.__end_.__next_;
|
||||
__node_pointer __l = __c.__end_.__prev_;
|
||||
__link_pointer __f = __c.__end_.__next_;
|
||||
__link_pointer __l = __c.__end_.__prev_;
|
||||
base::__unlink_nodes(__f, __l);
|
||||
__link_nodes(__p.__ptr_, __f, __l);
|
||||
base::__sz() += __c.__sz();
|
||||
|
@ -1887,8 +1924,7 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c)
|
|||
{
|
||||
--__p;
|
||||
iterator* __i = static_cast<iterator*>((*__p)->__i_);
|
||||
if (__i->__ptr_ != static_cast<__node_pointer>(
|
||||
pointer_traits<__node_base_pointer>::pointer_to(__c.__end_)))
|
||||
if (__i->__ptr_ != __c.__end_.__as_link())
|
||||
{
|
||||
__cn1->__add(*__p);
|
||||
(*__p)->__c_ = __cn1;
|
||||
|
@ -1918,7 +1954,7 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i)
|
|||
#endif
|
||||
if (__p.__ptr_ != __i.__ptr_ && __p.__ptr_ != __i.__ptr_->__next_)
|
||||
{
|
||||
__node_pointer __f = __i.__ptr_;
|
||||
__link_pointer __f = __i.__ptr_;
|
||||
base::__unlink_nodes(__f, __f);
|
||||
__link_nodes(__p.__ptr_, __f, __f);
|
||||
--__c.__sz();
|
||||
|
@ -1972,9 +2008,9 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, con
|
|||
__c.__sz() -= __s;
|
||||
base::__sz() += __s;
|
||||
}
|
||||
__node_pointer __first = __f.__ptr_;
|
||||
__link_pointer __first = __f.__ptr_;
|
||||
--__l;
|
||||
__node_pointer __last = __l.__ptr_;
|
||||
__link_pointer __last = __l.__ptr_;
|
||||
base::__unlink_nodes(__first, __last);
|
||||
__link_nodes(__p.__ptr_, __first, __last);
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
|
@ -1985,7 +2021,7 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, con
|
|||
{
|
||||
--__p;
|
||||
iterator* __j = static_cast<iterator*>((*__p)->__i_);
|
||||
for (__node_pointer __k = __f.__ptr_;
|
||||
for (__link_pointer __k = __f.__ptr_;
|
||||
__k != __l.__ptr_; __k = __k->__next_)
|
||||
{
|
||||
if (__j->__ptr_ == __k)
|
||||
|
@ -2097,8 +2133,8 @@ list<_Tp, _Alloc>::merge(list& __c, _Comp __comp)
|
|||
;
|
||||
base::__sz() += __ds;
|
||||
__c.__sz() -= __ds;
|
||||
__node_pointer __f = __f2.__ptr_;
|
||||
__node_pointer __l = __m2.__ptr_->__prev_;
|
||||
__link_pointer __f = __f2.__ptr_;
|
||||
__link_pointer __l = __m2.__ptr_->__prev_;
|
||||
__f2 = __m2;
|
||||
base::__unlink_nodes(__f, __l);
|
||||
__m2 = _VSTD::next(__f1);
|
||||
|
@ -2117,8 +2153,7 @@ list<_Tp, _Alloc>::merge(list& __c, _Comp __comp)
|
|||
{
|
||||
--__p;
|
||||
iterator* __i = static_cast<iterator*>((*__p)->__i_);
|
||||
if (__i->__ptr_ != static_cast<__node_pointer>(
|
||||
pointer_traits<__node_base_pointer>::pointer_to(__c.__end_)))
|
||||
if (__i->__ptr_ != __c.__end_.__as_link())
|
||||
{
|
||||
__cn1->__add(*__p);
|
||||
(*__p)->__c_ = __cn1;
|
||||
|
@ -2161,7 +2196,7 @@ list<_Tp, _Alloc>::__sort(iterator __f1, iterator __e2, size_type __n, _Comp& __
|
|||
case 2:
|
||||
if (__comp(*--__e2, *__f1))
|
||||
{
|
||||
__node_pointer __f = __e2.__ptr_;
|
||||
__link_pointer __f = __e2.__ptr_;
|
||||
base::__unlink_nodes(__f, __f);
|
||||
__link_nodes(__f1.__ptr_, __f, __f);
|
||||
return __e2;
|
||||
|
@ -2177,8 +2212,8 @@ list<_Tp, _Alloc>::__sort(iterator __f1, iterator __e2, size_type __n, _Comp& __
|
|||
iterator __m2 = _VSTD::next(__f2);
|
||||
for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2)
|
||||
;
|
||||
__node_pointer __f = __f2.__ptr_;
|
||||
__node_pointer __l = __m2.__ptr_->__prev_;
|
||||
__link_pointer __f = __f2.__ptr_;
|
||||
__link_pointer __l = __m2.__ptr_->__prev_;
|
||||
__r = __f2;
|
||||
__e1 = __f2 = __m2;
|
||||
base::__unlink_nodes(__f, __l);
|
||||
|
@ -2195,8 +2230,8 @@ list<_Tp, _Alloc>::__sort(iterator __f1, iterator __e2, size_type __n, _Comp& __
|
|||
iterator __m2 = _VSTD::next(__f2);
|
||||
for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2)
|
||||
;
|
||||
__node_pointer __f = __f2.__ptr_;
|
||||
__node_pointer __l = __m2.__ptr_->__prev_;
|
||||
__link_pointer __f = __f2.__ptr_;
|
||||
__link_pointer __l = __m2.__ptr_->__prev_;
|
||||
if (__e1 == __f2)
|
||||
__e1 = __m2;
|
||||
__f2 = __m2;
|
||||
|
@ -2240,8 +2275,7 @@ template <class _Tp, class _Alloc>
|
|||
bool
|
||||
list<_Tp, _Alloc>::__dereferenceable(const const_iterator* __i) const
|
||||
{
|
||||
return __i->__ptr_ != static_cast<__node_pointer>(
|
||||
pointer_traits<__node_base_pointer>::pointer_to(const_cast<__node_base&>(this->__end_)));
|
||||
return __i->__ptr_ != const_cast<__node_base&>(this->__end_).__as_link();
|
||||
}
|
||||
|
||||
template <class _Tp, class _Alloc>
|
||||
|
|
Loading…
Reference in New Issue