diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table --- a/libcxx/include/__hash_table +++ b/libcxx/include/__hash_table @@ -119,7 +119,17 @@ typedef _Tp __node_value_type; size_t __hash_; + +#ifndef _LIBCPP_CXX03_LANG + union { + __node_value_type __value_; + }; + + _LIBCPP_HIDE_FROM_ABI + explicit __hash_node() {} +#else __node_value_type __value_; +#endif }; inline _LIBCPP_INLINE_VISIBILITY @@ -2193,6 +2203,9 @@ "Construct cannot be called with a hash value type"); __node_allocator& __na = __node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); +#ifndef _LIBCPP_CXX03_LANG + ::new ((void*)std::addressof(*__h)) __node(); +#endif __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...); __h.get_deleter().__value_constructed = true; __h->__hash_ = hash_function()(__h->__value_); @@ -2210,6 +2223,9 @@ "Construct cannot be called with a hash value type"); __node_allocator& __na = __node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); +#ifndef _LIBCPP_CXX03_LANG + ::new ((void*)std::addressof(*__h)) __node(); +#endif __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_First>(__f), _VSTD::forward<_Rest>(__rest)...); diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list --- a/libcxx/include/forward_list +++ b/libcxx/include/forward_list @@ -209,12 +209,11 @@ #include <__memory/addressof.h> #include <__memory/allocation_guard.h> #include <__memory/allocator.h> -#include <__memory/allocator_destructor.h> #include <__memory/allocator_traits.h> #include <__memory/compressed_pair.h> +#include <__memory/construct_at.h> #include <__memory/pointer_traits.h> #include <__memory/swap_allocator.h> -#include <__memory/unique_ptr.h> #include <__memory_resource/polymorphic_allocator.h> #include <__ranges/access.h> #include <__ranges/concepts.h> @@ -328,13 +327,16 @@ typedef __begin_node_of<_Tp, _VoidPtr> _Base; typedef typename _Base::pointer _NodePtr; - value_type __value_; + // Allow starting the lifetime of nodes without initializing the value held by the node. + union { + value_type __value_; + }; - _LIBCPP_HIDE_FROM_ABI __forward_list_node() = default; - _LIBCPP_HIDE_FROM_ABI __forward_list_node(const value_type& __v, _NodePtr __next) : _Base(__next), __value_(__v) {} + // Don't construct or destroy the value_type -- this is handled by the list itself to be allocator-aware + _LIBCPP_HIDE_FROM_ABI explicit __forward_list_node(_NodePtr __next) : _Base(__next) { } + _LIBCPP_HIDE_FROM_ABI ~__forward_list_node() { } }; - template > class _LIBCPP_TEMPLATE_VIS forward_list; template class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator; @@ -943,6 +945,34 @@ _LIBCPP_HIDE_FROM_ABI void reverse() _NOEXCEPT; private: + template + _LIBCPP_HIDE_FROM_ABI __node_pointer __create_node(__node_pointer __next, _Args&& ...__args) { + __node_allocator& __alloc = base::__alloc(); + __allocation_guard<__node_allocator> __guard(__alloc, 1); + // Begin the lifetime of the node itself. Note that this doesn't begin the lifetime of the value + // held inside the node, since we need to use the allocator's construct() method for that. + // + // We don't use the allocator's construct() method to construct the node itself since the + // Cpp17FooInsertable named requirements don't require the allocator's construct() method + // to work on anything other than the value_type. + std::__construct_at(std::addressof(*__guard.__get()), __next); + + // Now construct the value_type using the allocator's construct() method. + __node_traits::construct(__alloc, std::addressof(__guard.__get()->__value_), std::forward<_Args>(__args)...); + return __guard.__release_ptr(); + } + + template + _LIBCPP_HIDE_FROM_ABI void __delete_node(__node_pointer __node) { + // For the same reason as above, we use the allocator's destroy() method for the value_type, + // but not for the node itself. + __node_allocator& __alloc = base::__alloc(); + __node_traits::destroy(__alloc, std::addressof(__node->__value_)); + + std::__destroy_at(std::addressof(*__node)); + + __node_traits::deallocate(__alloc, __node, 1); + } #ifndef _LIBCPP_CXX03_LANG _LIBCPP_HIDE_FROM_ABI void __move_assign(forward_list& __x, true_type) @@ -1006,16 +1036,10 @@ { if (__n > 0) { - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n, __p = __p->__next_as_begin()) { - __h.reset(__node_traits::allocate(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); - __h->__next_ = nullptr; - __p->__next_ = __h.release(); + __p->__next_ = __create_node(/* next = */nullptr); } } } @@ -1028,16 +1052,10 @@ { if (__n > 0) { - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n, __p = __p->__next_as_begin()) { - __h.reset(__node_traits::allocate(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); - __h->__next_ = nullptr; - __p->__next_ = __h.release(); + __p->__next_ = __create_node(/* next = */nullptr); } } } @@ -1226,13 +1244,7 @@ #endif forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args) { - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_), - _VSTD::forward<_Args>(__args)...); - __h->__next_ = base::__before_begin()->__next_; - base::__before_begin()->__next_ = __h.release(); + base::__before_begin()->__next_ = __create_node(/* next = */base::__before_begin()->__next_, std::forward<_Args>(__args)...); #if _LIBCPP_STD_VER >= 17 return base::__before_begin()->__next_->__value_; #endif @@ -1242,12 +1254,7 @@ void forward_list<_Tp, _Alloc>::push_front(value_type&& __v) { - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v)); - __h->__next_ = base::__before_begin()->__next_; - base::__before_begin()->__next_ = __h.release(); + base::__before_begin()->__next_ = __create_node(/* next = */base::__before_begin()->__next_, std::move(__v)); } #endif // _LIBCPP_CXX03_LANG @@ -1256,23 +1263,16 @@ void forward_list<_Tp, _Alloc>::push_front(const value_type& __v) { - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); - __h->__next_ = base::__before_begin()->__next_; - base::__before_begin()->__next_ = __h.release(); + base::__before_begin()->__next_ = __create_node(/* next = */base::__before_begin()->__next_, __v); } template void forward_list<_Tp, _Alloc>::pop_front() { - __node_allocator& __a = base::__alloc(); __node_pointer __p = base::__before_begin()->__next_; base::__before_begin()->__next_ = __p->__next_; - __node_traits::destroy(__a, _VSTD::addressof(__p->__value_)); - __node_traits::deallocate(__a, __p, 1); + __delete_node(__p); } #ifndef _LIBCPP_CXX03_LANG @@ -1283,13 +1283,7 @@ forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args) { __begin_node_pointer const __r = __p.__get_begin(); - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_), - _VSTD::forward<_Args>(__args)...); - __h->__next_ = __r->__next_; - __r->__next_ = __h.release(); + __r->__next_ = __create_node(/* next = */__r->__next_, std::forward<_Args>(__args)...); return iterator(__r->__next_); } @@ -1298,12 +1292,7 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v) { __begin_node_pointer const __r = __p.__get_begin(); - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v)); - __h->__next_ = __r->__next_; - __r->__next_ = __h.release(); + __r->__next_ = __create_node(/* next = */__r->__next_, std::move(__v)); return iterator(__r->__next_); } @@ -1314,12 +1303,7 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v) { __begin_node_pointer const __r = __p.__get_begin(); - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); - __h->__next_ = __r->__next_; - __r->__next_ = __h.release(); + __r->__next_ = __create_node(/* next = */__r->__next_, __v); return iterator(__r->__next_); } @@ -1328,20 +1312,10 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n, const value_type& __v) { - using _Guard = __allocation_guard<__node_allocator>; - __begin_node_pointer __r = __p.__get_begin(); if (__n > 0) { - __node_allocator& __a = base::__alloc(); - - __node_pointer __first = nullptr; - { - _Guard __h(__a, 1); - __node_traits::construct(__a, std::addressof(__h.__get()->__value_), __v); - __h.__get()->__next_ = nullptr; - __first = __h.__release_ptr(); - } + __node_pointer __first = __create_node(/* next = */nullptr, __v); __node_pointer __last = __first; #ifndef _LIBCPP_HAS_NO_EXCEPTIONS try @@ -1349,10 +1323,7 @@ #endif // _LIBCPP_HAS_NO_EXCEPTIONS for (--__n; __n != 0; --__n, __last = __last->__next_) { - _Guard __h(__a, 1); - __node_traits::construct(__a, std::addressof(__h.__get()->__value_), __v); - __h.__get()->__next_ = nullptr; - __last->__next_ = __h.__release_ptr(); + __last->__next_ = __create_node(/* next = */nullptr, __v); } #ifndef _LIBCPP_HAS_NO_EXCEPTIONS } @@ -1361,8 +1332,7 @@ while (__first != nullptr) { __node_pointer __next = __first->__next_; - __node_traits::destroy(__a, _VSTD::addressof(__first->__value_)); - __node_traits::deallocate(__a, __first, 1); + __delete_node(__first); __first = __next; } throw; @@ -1389,19 +1359,11 @@ _LIBCPP_HIDE_FROM_ABI typename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>::__insert_after_with_sentinel(const_iterator __p, _InputIterator __f, _Sentinel __l) { - using _Guard = __allocation_guard<__node_allocator>; __begin_node_pointer __r = __p.__get_begin(); if (__f != __l) { - __node_allocator& __a = base::__alloc(); - __node_pointer __first = nullptr; - { - _Guard __h(__a, 1); - __node_traits::construct(__a, std::addressof(__h.__get()->__value_), *__f); - __h.__get()->__next_ = nullptr; - __first = __h.__release_ptr(); - } + __node_pointer __first = __create_node(/* next = */nullptr, *__f); __node_pointer __last = __first; #ifndef _LIBCPP_HAS_NO_EXCEPTIONS @@ -1410,10 +1372,7 @@ #endif // _LIBCPP_HAS_NO_EXCEPTIONS for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_))) { - _Guard __h(__a, 1); - __node_traits::construct(__a, std::addressof(__h.__get()->__value_), *__f); - __h.__get()->__next_ = nullptr; - __last->__next_ = __h.__release_ptr(); + __last->__next_ = __create_node(/* next = */nullptr, *__f); } #ifndef _LIBCPP_HAS_NO_EXCEPTIONS } @@ -1422,8 +1381,7 @@ while (__first != nullptr) { __node_pointer __next = __first->__next_; - __node_traits::destroy(__a, _VSTD::addressof(__first->__value_)); - __node_traits::deallocate(__a, __first, 1); + __delete_node(__first); __first = __next; } throw; @@ -1445,9 +1403,7 @@ __begin_node_pointer __p = __f.__get_begin(); __node_pointer __n = __p->__next_; __p->__next_ = __n->__next_; - __node_allocator& __a = base::__alloc(); - __node_traits::destroy(__a, _VSTD::addressof(__n->__value_)); - __node_traits::deallocate(__a, __n, 1); + __delete_node(__n); return iterator(__p->__next_); } @@ -1464,12 +1420,10 @@ if (__n != __e) { __bp->__next_ = __e; - __node_allocator& __a = base::__alloc(); do { __node_pointer __tmp = __n->__next_; - __node_traits::destroy(__a, _VSTD::addressof(__n->__value_)); - __node_traits::deallocate(__a, __n, 1); + __delete_node(__n); __n = __tmp; } while (__n != __e); } @@ -1494,16 +1448,10 @@ __n -= __sz; if (__n > 0) { - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n, __ptr = __ptr->__next_as_begin()) { - __h.reset(__node_traits::allocate(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); - __h->__next_ = nullptr; - __ptr->__next_ = __h.release(); + __ptr->__next_ = __create_node(/* next = */nullptr); } } } @@ -1526,16 +1474,10 @@ __n -= __sz; if (__n > 0) { - __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n, __ptr = __ptr->__next_as_begin()) { - __h.reset(__node_traits::allocate(__a, 1)); - __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); - __h->__next_ = nullptr; - __ptr->__next_ = __h.release(); + __ptr->__next_ = __create_node(/* next = */nullptr, __v); } } } diff --git a/libcxx/include/list b/libcxx/include/list --- a/libcxx/include/list +++ b/libcxx/include/list @@ -213,13 +213,12 @@ #include <__iterator/prev.h> #include <__iterator/reverse_iterator.h> #include <__memory/addressof.h> +#include <__memory/allocation_guard.h> #include <__memory/allocator.h> -#include <__memory/allocator_destructor.h> #include <__memory/allocator_traits.h> #include <__memory/compressed_pair.h> #include <__memory/pointer_traits.h> #include <__memory/swap_allocator.h> -#include <__memory/unique_ptr.h> #include <__memory_resource/polymorphic_allocator.h> #include <__ranges/access.h> #include <__ranges/concepts.h> @@ -305,6 +304,9 @@ __link_pointer __prev_; __link_pointer __next_; + _LIBCPP_HIDE_FROM_ABI explicit __list_node_base(__link_pointer __prev, __link_pointer __next) + : __prev_(__prev), __next_(__next) {} + _LIBCPP_INLINE_VISIBILITY __list_node_base() : __prev_(_NodeTraits::__unsafe_link_pointer_cast(__self())), __next_(_NodeTraits::__unsafe_link_pointer_cast(__self())) {} @@ -329,6 +331,10 @@ typedef __list_node_base<_Tp, _VoidPtr> __base; typedef typename __base::__link_pointer __link_pointer; + template + _LIBCPP_HIDE_FROM_ABI explicit __list_node(__link_pointer __prev, __link_pointer __next, _Args&&... __args) + : __base(__prev, __next), __value_(std::forward<_Args>(__args)...) {} + _LIBCPP_INLINE_VISIBILITY __link_pointer __as_link() { return static_cast<__link_pointer>(__base::__self()); @@ -679,7 +685,7 @@ { __node_pointer __np = __f->__as_node(); __f = __f->__next_; - __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); + __node_alloc_traits::destroy(__na, std::addressof(*__np)); __node_alloc_traits::deallocate(__na, __np, 1); } } @@ -726,6 +732,8 @@ typedef typename base::__node_base_pointer __node_base_pointer; typedef typename base::__link_pointer __link_pointer; + using _Guard = __allocation_guard<__node_allocator>; + public: typedef _Tp value_type; typedef _Alloc allocator_type; @@ -1032,16 +1040,6 @@ _LIBCPP_HIDE_FROM_ABI bool __invariants() const; - typedef __allocator_destructor<__node_allocator> __node_destructor; - typedef unique_ptr<__node, __node_destructor> __hold_pointer; - - _LIBCPP_INLINE_VISIBILITY - __hold_pointer __allocate_node(__node_allocator& __na) { - __node_pointer __p = __node_alloc_traits::allocate(__na, 1); - __p->__prev_ = nullptr; - return __hold_pointer(__p, __node_destructor(__na, 1)); - } - private: template _LIBCPP_HIDE_FROM_ABI @@ -1343,11 +1341,11 @@ list<_Tp, _Alloc>::insert(const_iterator __p, const value_type& __x) { __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); - __link_nodes(__p.__ptr_, __hold->__as_link(), __hold->__as_link()); + _Guard __hold(__na, 1); + __node_alloc_traits::construct(__na, std::addressof(*__hold.__get()), /* prev = */nullptr, /* next = */nullptr, __x); + __link_nodes(__p.__ptr_, __hold.__get()->__as_link(), __hold.__get()->__as_link()); ++base::__sz(); - return iterator(__hold.release()->__as_link()); + return iterator(__hold.__release_ptr()->__as_link()); } template @@ -1359,11 +1357,11 @@ { size_type __ds = 0; __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); + _Guard __hold(__na, 1); + __node_alloc_traits::construct(__na, std::addressof(*__hold.__get()), /* prev = */nullptr, /* next = */nullptr, __x); ++__ds; - __r = iterator(__hold->__as_link()); - __hold.release(); + __r = iterator(__hold.__get()->__as_link()); + __hold.__release_ptr(); iterator __e = __r; #ifndef _LIBCPP_HAS_NO_EXCEPTIONS try @@ -1371,11 +1369,10 @@ #endif // _LIBCPP_HAS_NO_EXCEPTIONS for (--__n; __n != 0; --__n, (void) ++__e, ++__ds) { - __hold.reset(__node_alloc_traits::allocate(__na, 1)); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); - __e.__ptr_->__next_ = __hold->__as_link(); - __hold->__prev_ = __e.__ptr_; - __hold.release(); + _Guard __h(__na, 1); + __node_alloc_traits::construct(__na, std::addressof(*__h.__get()), /* prev = */__e.__ptr_, /* next = */nullptr, __x); + __e.__ptr_->__next_ = __h.__get()->__as_link(); + __h.__release_ptr(); } #ifndef _LIBCPP_HAS_NO_EXCEPTIONS } @@ -1383,9 +1380,10 @@ { while (true) { - __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); __link_pointer __prev = __e.__ptr_->__prev_; - __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); + __node_pointer __current = __e.__ptr_->__as_node(); + __node_alloc_traits::destroy(__na, std::addressof(*__current)); + __node_alloc_traits::deallocate(__na, __current, 1); if (__prev == 0) break; __e = iterator(__prev); @@ -1418,11 +1416,11 @@ { size_type __ds = 0; __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f); + _Guard __hold(__na, 1); + __node_alloc_traits::construct(__na, std::addressof(*__hold.__get()), /* prev = */nullptr, /* next = */nullptr, *__f); ++__ds; - __r = iterator(__hold.get()->__as_link()); - __hold.release(); + __r = iterator(__hold.__get()->__as_link()); + __hold.__release_ptr(); iterator __e = __r; #ifndef _LIBCPP_HAS_NO_EXCEPTIONS try @@ -1430,11 +1428,10 @@ #endif // _LIBCPP_HAS_NO_EXCEPTIONS for (++__f; __f != __l; ++__f, (void) ++__e, ++__ds) { - __hold.reset(__node_alloc_traits::allocate(__na, 1)); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f); - __e.__ptr_->__next_ = __hold.get()->__as_link(); - __hold->__prev_ = __e.__ptr_; - __hold.release(); + _Guard __h(__na, 1); + __node_alloc_traits::construct(__na, std::addressof(*__h.__get()), /* prev = */__e.__ptr_, /* next = */nullptr, *__f); + __e.__ptr_->__next_ = __h.__get()->__as_link(); + __h.__release_ptr(); } #ifndef _LIBCPP_HAS_NO_EXCEPTIONS } @@ -1442,9 +1439,10 @@ { while (true) { - __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); __link_pointer __prev = __e.__ptr_->__prev_; - __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); + __node_pointer __current = __e.__ptr_->__as_node(); + __node_alloc_traits::destroy(__na, std::addressof(*__current)); + __node_alloc_traits::deallocate(__na, __current, 1); if (__prev == 0) break; __e = iterator(__prev); @@ -1463,12 +1461,12 @@ list<_Tp, _Alloc>::push_front(const value_type& __x) { __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); - __link_pointer __nl = __hold->__as_link(); + _Guard __hold(__na, 1); + __node_alloc_traits::construct(__na, std::addressof(*__hold.__get()), /* prev = */nullptr, /* next = */nullptr, __x); + __link_pointer __nl = __hold.__get()->__as_link(); __link_nodes_at_front(__nl, __nl); ++base::__sz(); - __hold.release(); + __hold.__release_ptr(); } template @@ -1476,11 +1474,11 @@ list<_Tp, _Alloc>::push_back(const value_type& __x) { __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); - __link_nodes_at_back(__hold.get()->__as_link(), __hold.get()->__as_link()); + _Guard __hold(__na, 1); + __node_alloc_traits::construct(__na, std::addressof(*__hold.__get()), /* prev = */nullptr, /* next = */nullptr, __x); + __link_nodes_at_back(__hold.__get()->__as_link(), __hold.__get()->__as_link()); ++base::__sz(); - __hold.release(); + __hold.__release_ptr(); } #ifndef _LIBCPP_CXX03_LANG @@ -1490,11 +1488,11 @@ list<_Tp, _Alloc>::push_front(value_type&& __x) { __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); - __link_nodes_at_front(__hold.get()->__as_link(), __hold.get()->__as_link()); + _Guard __hold(__na, 1); + __node_alloc_traits::construct(__na, std::addressof(*__hold.__get()), /* prev = */nullptr, /* next = */nullptr, std::move(__x)); + __link_nodes_at_front(__hold.__get()->__as_link(), __hold.__get()->__as_link()); ++base::__sz(); - __hold.release(); + __hold.__release_ptr(); } template @@ -1502,11 +1500,11 @@ list<_Tp, _Alloc>::push_back(value_type&& __x) { __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); - __link_nodes_at_back(__hold.get()->__as_link(), __hold.get()->__as_link()); + _Guard __hold(__na, 1); + __node_alloc_traits::construct(__na, std::addressof(*__hold.__get()), /* prev = */nullptr, /* next = */nullptr, std::move(__x)); + __link_nodes_at_back(__hold.__get()->__as_link(), __hold.__get()->__as_link()); ++base::__sz(); - __hold.release(); + __hold.__release_ptr(); } template @@ -1519,14 +1517,14 @@ list<_Tp, _Alloc>::emplace_front(_Args&&... __args) { __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); - __link_nodes_at_front(__hold.get()->__as_link(), __hold.get()->__as_link()); + _Guard __hold(__na, 1); + __node_alloc_traits::construct(__na, std::addressof(*__hold.__get()), /* prev = */nullptr, /* next = */nullptr, std::forward<_Args>(__args)...); + __link_nodes_at_front(__hold.__get()->__as_link(), __hold.__get()->__as_link()); ++base::__sz(); #if _LIBCPP_STD_VER >= 17 - return __hold.release()->__value_; + return __hold.__release_ptr()->__value_; #else - __hold.release(); + __hold.__release_ptr(); #endif } @@ -1540,15 +1538,15 @@ list<_Tp, _Alloc>::emplace_back(_Args&&... __args) { __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); - __link_pointer __nl = __hold->__as_link(); + _Guard __hold(__na, 1); + __node_alloc_traits::construct(__na, std::addressof(*__hold.__get()), /* prev = */nullptr, /* next = */nullptr, std::forward<_Args>(__args)...); + __link_pointer __nl = __hold.__get()->__as_link(); __link_nodes_at_back(__nl, __nl); ++base::__sz(); #if _LIBCPP_STD_VER >= 17 - return __hold.release()->__value_; + return __hold.__release_ptr()->__value_; #else - __hold.release(); + __hold.__release_ptr(); #endif } @@ -1558,12 +1556,12 @@ list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args) { __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); - __link_pointer __nl = __hold.get()->__as_link(); + _Guard __hold(__na, 1); + __node_alloc_traits::construct(__na, std::addressof(*__hold.__get()), /* prev = */nullptr, /* next = */nullptr, std::forward<_Args>(__args)...); + __link_pointer __nl = __hold.__get()->__as_link(); __link_nodes(__p.__ptr_, __nl, __nl); ++base::__sz(); - __hold.release(); + __hold.__release_ptr(); return iterator(__nl); } @@ -1572,12 +1570,12 @@ list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x) { __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); - __link_pointer __nl = __hold->__as_link(); + _Guard __hold(__na, 1); + __node_alloc_traits::construct(__na, std::addressof(*__hold.__get()), /* prev = */nullptr, /* next = */nullptr, std::move(__x)); + __link_pointer __nl = __hold.__get()->__as_link(); __link_nodes(__p.__ptr_, __nl, __nl); ++base::__sz(); - __hold.release(); + __hold.__release_ptr(); return iterator(__nl); } @@ -1593,7 +1591,7 @@ base::__unlink_nodes(__n, __n); --base::__sz(); __node_pointer __np = __n->__as_node(); - __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); + __node_alloc_traits::destroy(__na, std::addressof(*__np)); __node_alloc_traits::deallocate(__na, __np, 1); } @@ -1607,7 +1605,7 @@ base::__unlink_nodes(__n, __n); --base::__sz(); __node_pointer __np = __n->__as_node(); - __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); + __node_alloc_traits::destroy(__na, std::addressof(*__np)); __node_alloc_traits::deallocate(__na, __np, 1); } @@ -1623,7 +1621,7 @@ base::__unlink_nodes(__n, __n); --base::__sz(); __node_pointer __np = __n->__as_node(); - __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); + __node_alloc_traits::destroy(__na, std::addressof(*__np)); __node_alloc_traits::deallocate(__na, __np, 1); return iterator(__r); } @@ -1642,7 +1640,7 @@ ++__f; --base::__sz(); __node_pointer __np = __n->__as_node(); - __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); + __node_alloc_traits::destroy(__na, std::addressof(*__np)); __node_alloc_traits::deallocate(__na, __np, 1); } } @@ -1660,10 +1658,10 @@ __n -= base::__sz(); size_type __ds = 0; __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_)); + _Guard __hold(__na, 1); + __node_alloc_traits::construct(__na, std::addressof(*__hold.__get()), /* prev = */nullptr, /* next = */nullptr); ++__ds; - iterator __r = iterator(__hold.release()->__as_link()); + iterator __r = iterator(__hold.__release_ptr()->__as_link()); iterator __e = __r; #ifndef _LIBCPP_HAS_NO_EXCEPTIONS try @@ -1671,11 +1669,10 @@ #endif // _LIBCPP_HAS_NO_EXCEPTIONS for (--__n; __n != 0; --__n, (void) ++__e, ++__ds) { - __hold.reset(__node_alloc_traits::allocate(__na, 1)); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_)); - __e.__ptr_->__next_ = __hold.get()->__as_link(); - __hold->__prev_ = __e.__ptr_; - __hold.release(); + _Guard __h(__na, 1); + __node_alloc_traits::construct(__na, std::addressof(*__h.__get()), /* prev = */__e.__ptr_, /* next = */nullptr); + __e.__ptr_->__next_ = __h.__get()->__as_link(); + __h.__release_ptr(); } #ifndef _LIBCPP_HAS_NO_EXCEPTIONS } @@ -1683,9 +1680,10 @@ { while (true) { - __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); __link_pointer __prev = __e.__ptr_->__prev_; - __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); + __node_pointer __current = __e.__ptr_->__as_node(); + __node_alloc_traits::destroy(__na, std::addressof(*__current)); + __node_alloc_traits::deallocate(__na, __current, 1); if (__prev == 0) break; __e = iterator(__prev); @@ -1709,10 +1707,10 @@ __n -= base::__sz(); size_type __ds = 0; __node_allocator& __na = base::__node_alloc(); - __hold_pointer __hold = __allocate_node(__na); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); + _Guard __hold(__na, 1); + __node_alloc_traits::construct(__na, std::addressof(*__hold.__get()), /* prev = */nullptr, /* next = */nullptr, __x); ++__ds; - __link_pointer __nl = __hold.release()->__as_link(); + __link_pointer __nl = __hold.__release_ptr()->__as_link(); iterator __r = iterator(__nl); iterator __e = __r; #ifndef _LIBCPP_HAS_NO_EXCEPTIONS @@ -1721,11 +1719,10 @@ #endif // _LIBCPP_HAS_NO_EXCEPTIONS for (--__n; __n != 0; --__n, (void) ++__e, ++__ds) { - __hold.reset(__node_alloc_traits::allocate(__na, 1)); - __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); - __e.__ptr_->__next_ = __hold.get()->__as_link(); - __hold->__prev_ = __e.__ptr_; - __hold.release(); + _Guard __h(__na, 1); + __node_alloc_traits::construct(__na, std::addressof(*__h.__get()), /* prev = */__e.__ptr_, /* next = */nullptr, __x); + __e.__ptr_->__next_ = __h.__get()->__as_link(); + __h.__release_ptr(); } #ifndef _LIBCPP_HAS_NO_EXCEPTIONS } @@ -1733,9 +1730,10 @@ { while (true) { - __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); __link_pointer __prev = __e.__ptr_->__prev_; - __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); + __node_pointer __current = __e.__ptr_->__as_node(); + __node_alloc_traits::destroy(__na, std::addressof(*__current)); + __node_alloc_traits::deallocate(__na, __current, 1); if (__prev == 0) break; __e = iterator(__prev);