aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Dionne <ldionne.2@gmail.com>2023-09-15 10:10:26 -0400
committerGitHub <noreply@github.com>2023-09-15 10:10:26 -0400
commit69875d59bc08f358abcb4b4d3a6ed25c059d3441 (patch)
treec3966e6c6dbef49bacf17f5305ae8e0b46cd9a7d
parent4d08eccd63669a6ff39b6aa01f46b4d467e6d489 (diff)
downloadllvm-69875d59bc08f358abcb4b4d3a6ed25c059d3441.zip
llvm-69875d59bc08f358abcb4b4d3a6ed25c059d3441.tar.gz
llvm-69875d59bc08f358abcb4b4d3a6ed25c059d3441.tar.bz2
[libc++] Refactor node creation and destruction in list and forward_list (#65614)
This removes a lot of code duplication, makes the code simpler and prepares the terrain for https://reviews.llvm.org/D101206, which will fix some UB in the node-based containers. This also allows removing the dependency of list and forward_list on unique_ptr by using __allocation_guard instead.
-rw-r--r--libcxx/include/chrono2
-rw-r--r--libcxx/include/forward_list171
-rw-r--r--libcxx/include/list201
-rw-r--r--libcxx/test/libcxx/transitive_includes/cxx23.csv2
-rw-r--r--libcxx/test/libcxx/transitive_includes/cxx26.csv2
5 files changed, 122 insertions, 256 deletions
diff --git a/libcxx/include/chrono b/libcxx/include/chrono
index 2ef7d7d..becf95c 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -846,6 +846,8 @@ constexpr chrono::year operator ""y(unsigned lo
# include <bit>
# include <concepts>
# include <cstring>
+# include <forward_list>
+# include <string>
#endif
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER == 20
diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index 1dbf1a3..75ac685 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -209,12 +209,10 @@ template <class T, class Allocator, class Predicate>
#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>
@@ -272,13 +270,12 @@ struct __forward_list_node_value_type<__forward_list_node<_Tp, _VoidPtr> > {
template <class _NodePtr>
struct __forward_node_traits {
- typedef __remove_cv_t<
- typename pointer_traits<_NodePtr>::element_type> __node;
- typedef typename __forward_list_node_value_type<__node>::type __node_value_type;
- typedef _NodePtr __node_pointer;
- typedef __forward_begin_node<_NodePtr> __begin_node;
- typedef __rebind_pointer_t<_NodePtr, __begin_node> __begin_node_pointer;
- typedef __rebind_pointer_t<_NodePtr, void> __void_pointer;
+ typedef __remove_cv_t<typename pointer_traits<_NodePtr>::element_type> __node_type;
+ typedef typename __forward_list_node_value_type<__node_type>::type __node_value_type;
+ typedef _NodePtr __node_pointer;
+ typedef __forward_begin_node<_NodePtr> __begin_node;
+ typedef __rebind_pointer_t<_NodePtr, __begin_node> __begin_node_pointer;
+ typedef __rebind_pointer_t<_NodePtr, void> __void_pointer;
#if defined(_LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB)
typedef __begin_node_pointer __iter_node_pointer;
@@ -423,7 +420,7 @@ class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator
typedef _NodeConstPtr _NodePtr;
typedef __forward_node_traits<_NodePtr> __traits;
- typedef typename __traits::__node __node;
+ typedef typename __traits::__node_type __node_type;
typedef typename __traits::__node_pointer __node_pointer;
typedef typename __traits::__begin_node_pointer __begin_node_pointer;
typedef typename __traits::__iter_node_pointer __iter_node_pointer;
@@ -508,9 +505,9 @@ protected:
typedef _Alloc allocator_type;
typedef typename allocator_traits<allocator_type>::void_pointer void_pointer;
- typedef __forward_list_node<value_type, void_pointer> __node;
+ typedef __forward_list_node<value_type, void_pointer> __node_type;
typedef __begin_node_of<value_type, void_pointer> __begin_node;
- typedef __rebind_alloc<allocator_traits<allocator_type>, __node> __node_allocator;
+ typedef __rebind_alloc<allocator_traits<allocator_type>, __node_type> __node_allocator;
typedef allocator_traits<__node_allocator> __node_traits;
typedef typename __node_traits::pointer __node_pointer;
@@ -576,6 +573,22 @@ protected:
{__move_assign_alloc(__x, integral_constant<bool,
__node_traits::propagate_on_container_move_assignment::value>());}
+ template <class ..._Args>
+ _LIBCPP_HIDE_FROM_ABI __node_pointer __create_node(__node_pointer __next, _Args&& ...__args) {
+ __node_allocator& __a = __alloc();
+ __allocation_guard<__node_allocator> __guard(__a, 1);
+ __guard.__get()->__next_ = __next;
+ __node_traits::construct(__a, std::addressof(__guard.__get()->__value_), std::forward<_Args>(__args)...);
+ return __guard.__release_ptr();
+ }
+
+ template <class ..._Args>
+ _LIBCPP_HIDE_FROM_ABI void __delete_node(__node_pointer __node) {
+ __node_allocator& __a = __alloc();
+ __node_traits::destroy(__a, std::addressof(__node->__value_));
+ __node_traits::deallocate(__a, __node, 1);
+ }
+
public:
_LIBCPP_INLINE_VISIBILITY
void swap(__forward_list_base& __x)
@@ -661,12 +674,10 @@ template <class _Tp, class _Alloc>
void
__forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT
{
- __node_allocator& __a = __alloc();
for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;)
{
__node_pointer __next = __p->__next_;
- __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
- __node_traits::deallocate(__a, __p, 1);
+ __delete_node(__p);
__p = __next;
}
__before_begin()->__next_ = nullptr;
@@ -678,7 +689,7 @@ class _LIBCPP_TEMPLATE_VIS forward_list
{
typedef __forward_list_base<_Tp, _Alloc> base;
typedef typename base::__node_allocator __node_allocator;
- typedef typename base::__node __node;
+ typedef typename base::__node_type __node_type;
typedef typename base::__node_traits __node_traits;
typedef typename base::__node_pointer __node_pointer;
typedef typename base::__begin_node_pointer __begin_node_pointer;
@@ -1006,16 +1017,10 @@ forward_list<_Tp, _Alloc>::forward_list(size_type __n)
{
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_ = this->__create_node(/* next = */nullptr);
}
}
}
@@ -1028,16 +1033,10 @@ forward_list<_Tp, _Alloc>::forward_list(size_type __n,
{
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_ = this->__create_node(/* next = */nullptr);
}
}
}
@@ -1226,13 +1225,7 @@ void
#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_ = this->__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 +1235,7 @@ template <class _Tp, class _Alloc>
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_ = this->__create_node(/* next = */base::__before_begin()->__next_, std::move(__v));
}
#endif // _LIBCPP_CXX03_LANG
@@ -1256,23 +1244,16 @@ template <class _Tp, class _Alloc>
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_ = this->__create_node(/* next = */base::__before_begin()->__next_, __v);
}
template <class _Tp, class _Alloc>
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);
+ this->__delete_node(__p);
}
#ifndef _LIBCPP_CXX03_LANG
@@ -1283,13 +1264,7 @@ typename forward_list<_Tp, _Alloc>::iterator
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_ = this->__create_node(/* next = */__r->__next_, std::forward<_Args>(__args)...);
return iterator(__r->__next_);
}
@@ -1298,12 +1273,7 @@ typename forward_list<_Tp, _Alloc>::iterator
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_ = this->__create_node(/* next = */__r->__next_, std::move(__v));
return iterator(__r->__next_);
}
@@ -1314,12 +1284,7 @@ typename forward_list<_Tp, _Alloc>::iterator
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_ = this->__create_node(/* next = */__r->__next_, __v);
return iterator(__r->__next_);
}
@@ -1328,20 +1293,10 @@ typename forward_list<_Tp, _Alloc>::iterator
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 = this->__create_node(/* next = */nullptr, __v);
__node_pointer __last = __first;
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try
@@ -1349,10 +1304,7 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
#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_ = this->__create_node(/* next = */nullptr, __v);
}
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
}
@@ -1361,8 +1313,7 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
while (__first != nullptr)
{
__node_pointer __next = __first->__next_;
- __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
- __node_traits::deallocate(__a, __first, 1);
+ this->__delete_node(__first);
__first = __next;
}
throw;
@@ -1389,19 +1340,11 @@ template <class _InputIterator, class _Sentinel>
_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 = this->__create_node(/* next = */nullptr, *__f);
__node_pointer __last = __first;
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
@@ -1410,10 +1353,7 @@ forward_list<_Tp, _Alloc>::__insert_after_with_sentinel(const_iterator __p, _Inp
#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_ = this->__create_node(/* next = */nullptr, *__f);
}
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
}
@@ -1422,8 +1362,7 @@ forward_list<_Tp, _Alloc>::__insert_after_with_sentinel(const_iterator __p, _Inp
while (__first != nullptr)
{
__node_pointer __next = __first->__next_;
- __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
- __node_traits::deallocate(__a, __first, 1);
+ this->__delete_node(__first);
__first = __next;
}
throw;
@@ -1445,9 +1384,7 @@ forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
__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);
+ this->__delete_node(__n);
return iterator(__p->__next_);
}
@@ -1464,12 +1401,10 @@ forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
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);
+ this->__delete_node(__n);
__n = __tmp;
} while (__n != __e);
}
@@ -1494,16 +1429,10 @@ forward_list<_Tp, _Alloc>::resize(size_type __n)
__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_ = this->__create_node(/* next = */nullptr);
}
}
}
@@ -1526,16 +1455,10 @@ forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
__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_ = this->__create_node(/* next = */nullptr, __v);
}
}
}
@@ -1931,7 +1854,9 @@ _LIBCPP_POP_MACROS
# include <algorithm>
# include <atomic>
# include <concepts>
+# include <cstdint>
# include <cstdlib>
+# include <cstring>
# include <functional>
# include <iosfwd>
# include <iterator>
diff --git a/libcxx/include/list b/libcxx/include/list
index 77b988c..b02599b 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -213,13 +213,12 @@ template <class T, class Allocator, class Predicate>
#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>
@@ -494,8 +493,8 @@ protected:
typedef __list_iterator<value_type, __void_pointer> iterator;
typedef __list_const_iterator<value_type, __void_pointer> const_iterator;
typedef __list_node_base<value_type, __void_pointer> __node_base;
- typedef __list_node<value_type, __void_pointer> __node;
- typedef __rebind_alloc<__alloc_traits, __node> __node_allocator;
+ typedef __list_node<value_type, __void_pointer> __node_type;
+ typedef __rebind_alloc<__alloc_traits, __node_type> __node_allocator;
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;
@@ -597,6 +596,23 @@ protected:
{__move_assign_alloc(__c, integral_constant<bool,
__node_alloc_traits::propagate_on_container_move_assignment::value>());}
+ template <class ..._Args>
+ _LIBCPP_HIDE_FROM_ABI __node_pointer __create_node(__link_pointer __prev, __link_pointer __next, _Args&& ...__args) {
+ __node_allocator& __alloc = __node_alloc();
+ __allocation_guard<__node_allocator> __guard(__alloc, 1);
+ __guard.__get()->__prev_ = __prev;
+ __guard.__get()->__next_ = __next;
+ __node_alloc_traits::construct(__alloc, std::addressof(__guard.__get()->__value_), std::forward<_Args>(__args)...);
+ return __guard.__release_ptr();
+ }
+
+ template <class ..._Args>
+ _LIBCPP_HIDE_FROM_ABI void __delete_node(__node_pointer __node) {
+ __node_allocator& __alloc = __node_alloc();
+ __node_alloc_traits::destroy(__alloc, std::addressof(__node->__value_));
+ __node_alloc_traits::deallocate(__alloc, __node, 1);
+ }
+
private:
_LIBCPP_INLINE_VISIBILITY
void __copy_assign_alloc(const __list_imp& __c, true_type)
@@ -670,7 +686,6 @@ __list_imp<_Tp, _Alloc>::clear() _NOEXCEPT
{
if (!empty())
{
- __node_allocator& __na = __node_alloc();
__link_pointer __f = __end_.__next_;
__link_pointer __l = __end_as_link();
__unlink_nodes(__f, __l->__prev_);
@@ -679,8 +694,7 @@ __list_imp<_Tp, _Alloc>::clear() _NOEXCEPT
{
__node_pointer __np = __f->__as_node();
__f = __f->__next_;
- __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
- __node_alloc_traits::deallocate(__na, __np, 1);
+ __delete_node(__np);
}
}
}
@@ -718,7 +732,7 @@ class _LIBCPP_TEMPLATE_VIS list
: private __list_imp<_Tp, _Alloc>
{
typedef __list_imp<_Tp, _Alloc> base;
- typedef typename base::__node __node;
+ typedef typename base::__node_type __node_type;
typedef typename base::__node_allocator __node_allocator;
typedef typename base::__node_pointer __node_pointer;
typedef typename base::__node_alloc_traits __node_alloc_traits;
@@ -1032,16 +1046,6 @@ public:
_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 <class _Iterator, class _Sentinel>
_LIBCPP_HIDE_FROM_ABI
@@ -1342,12 +1346,10 @@ template <class _Tp, class _Alloc>
typename list<_Tp, _Alloc>::iterator
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());
+ __node_pointer __node = this->__create_node(/* prev = */nullptr, /* next = */nullptr, __x);
+ __link_nodes(__p.__ptr_, __node->__as_link(), __node->__as_link());
++base::__sz();
- return iterator(__hold.release()->__as_link());
+ return iterator(__node->__as_link());
}
template <class _Tp, class _Alloc>
@@ -1358,12 +1360,9 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
if (__n > 0)
{
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);
+ __node_pointer __node = this->__create_node(/* prev = */nullptr, /* next = */nullptr, __x);
++__ds;
- __r = iterator(__hold->__as_link());
- __hold.release();
+ __r = iterator(__node->__as_link());
iterator __e = __r;
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try
@@ -1371,11 +1370,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
#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();
+ __e.__ptr_->__next_ = this->__create_node(/* prev = */__e.__ptr_, /* next = */nullptr, __x)->__as_link();
}
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
}
@@ -1383,9 +1378,9 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
{
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();
+ this->__delete_node(__current);
if (__prev == 0)
break;
__e = iterator(__prev);
@@ -1417,12 +1412,9 @@ list<_Tp, _Alloc>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Se
if (__f != __l)
{
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);
+ __node_pointer __node = this->__create_node(/* prev = */nullptr, /* next = */nullptr, *__f);
++__ds;
- __r = iterator(__hold.get()->__as_link());
- __hold.release();
+ __r = iterator(__node->__as_link());
iterator __e = __r;
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try
@@ -1430,11 +1422,7 @@ list<_Tp, _Alloc>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Se
#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();
+ __e.__ptr_->__next_ = this->__create_node(/* prev = */__e.__ptr_, /* next = */nullptr, *__f)->__as_link();
}
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
}
@@ -1442,9 +1430,9 @@ list<_Tp, _Alloc>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Se
{
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();
+ this->__delete_node(__current);
if (__prev == 0)
break;
__e = iterator(__prev);
@@ -1462,25 +1450,20 @@ template <class _Tp, class _Alloc>
void
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();
+ __node_pointer __node = this->__create_node(/* prev = */nullptr, /* next = */nullptr, __x);
+ __link_pointer __nl = __node->__as_link();
__link_nodes_at_front(__nl, __nl);
++base::__sz();
- __hold.release();
}
template <class _Tp, class _Alloc>
void
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());
+ __node_pointer __node = this->__create_node(/* prev = */nullptr, /* next = */nullptr, __x);
+ __link_pointer __nl = __node->__as_link();
+ __link_nodes_at_back(__nl, __nl);
++base::__sz();
- __hold.release();
}
#ifndef _LIBCPP_CXX03_LANG
@@ -1489,24 +1472,20 @@ template <class _Tp, class _Alloc>
void
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());
+ __node_pointer __node = this->__create_node(/* prev = */nullptr, /* next = */nullptr, std::move(__x));
+ __link_pointer __nl = __node->__as_link();
+ __link_nodes_at_front(__nl, __nl);
++base::__sz();
- __hold.release();
}
template <class _Tp, class _Alloc>
void
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());
+ __node_pointer __node = this->__create_node(/* prev = */nullptr, /* next = */nullptr, std::move(__x));
+ __link_pointer __nl = __node->__as_link();
+ __link_nodes_at_back(__nl, __nl);
++base::__sz();
- __hold.release();
}
template <class _Tp, class _Alloc>
@@ -1518,15 +1497,12 @@ void
#endif
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());
+ __node_pointer __node = this->__create_node(/* prev = */nullptr, /* next = */nullptr, std::forward<_Args>(__args)...);
+ __link_pointer __nl = __node->__as_link();
+ __link_nodes_at_front(__nl, __nl);
++base::__sz();
#if _LIBCPP_STD_VER >= 17
- return __hold.release()->__value_;
-#else
- __hold.release();
+ return __node->__value_;
#endif
}
@@ -1539,16 +1515,12 @@ void
#endif
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();
+ __node_pointer __node = this->__create_node(/* prev = */nullptr, /* next = */nullptr, std::forward<_Args>(__args)...);
+ __link_pointer __nl = __node->__as_link();
__link_nodes_at_back(__nl, __nl);
++base::__sz();
#if _LIBCPP_STD_VER >= 17
- return __hold.release()->__value_;
-#else
- __hold.release();
+ return __node->__value_;
#endif
}
@@ -1557,13 +1529,10 @@ template <class... _Args>
typename list<_Tp, _Alloc>::iterator
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();
+ __node_pointer __node = this->__create_node(/* prev = */nullptr, /* next = */nullptr, std::forward<_Args>(__args)...);
+ __link_pointer __nl = __node->__as_link();
__link_nodes(__p.__ptr_, __nl, __nl);
++base::__sz();
- __hold.release();
return iterator(__nl);
}
@@ -1571,13 +1540,10 @@ template <class _Tp, class _Alloc>
typename list<_Tp, _Alloc>::iterator
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();
+ __node_pointer __node = this->__create_node(/* prev = */nullptr, /* next = */nullptr, std::move(__x));
+ __link_pointer __nl = __node->__as_link();
__link_nodes(__p.__ptr_, __nl, __nl);
++base::__sz();
- __hold.release();
return iterator(__nl);
}
@@ -1588,13 +1554,10 @@ void
list<_Tp, _Alloc>::pop_front()
{
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::pop_front() called with empty list");
- __node_allocator& __na = base::__node_alloc();
__link_pointer __n = base::__end_.__next_;
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::deallocate(__na, __np, 1);
+ this->__delete_node(__n->__as_node());
}
template <class _Tp, class _Alloc>
@@ -1602,13 +1565,10 @@ void
list<_Tp, _Alloc>::pop_back()
{
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::pop_back() called on an empty list");
- __node_allocator& __na = base::__node_alloc();
__link_pointer __n = base::__end_.__prev_;
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::deallocate(__na, __np, 1);
+ this->__delete_node(__n->__as_node());
}
template <class _Tp, class _Alloc>
@@ -1617,14 +1577,11 @@ list<_Tp, _Alloc>::erase(const_iterator __p)
{
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p != end(),
"list::erase(iterator) called with a non-dereferenceable iterator");
- __node_allocator& __na = base::__node_alloc();
__link_pointer __n = __p.__ptr_;
__link_pointer __r = __n->__next_;
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::deallocate(__na, __np, 1);
+ this->__delete_node(__n->__as_node());
return iterator(__r);
}
@@ -1634,16 +1591,13 @@ list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l)
{
if (__f != __l)
{
- __node_allocator& __na = base::__node_alloc();
base::__unlink_nodes(__f.__ptr_, __l.__ptr_->__prev_);
while (__f != __l)
{
__link_pointer __n = __f.__ptr_;
++__f;
--base::__sz();
- __node_pointer __np = __n->__as_node();
- __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
- __node_alloc_traits::deallocate(__na, __np, 1);
+ this->__delete_node(__n->__as_node());
}
}
return iterator(__l.__ptr_);
@@ -1659,11 +1613,9 @@ list<_Tp, _Alloc>::resize(size_type __n)
{
__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_));
+ __node_pointer __node = this->__create_node(/* prev = */nullptr, /* next = */nullptr);
++__ds;
- iterator __r = iterator(__hold.release()->__as_link());
+ iterator __r = iterator(__node->__as_link());
iterator __e = __r;
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try
@@ -1671,11 +1623,7 @@ list<_Tp, _Alloc>::resize(size_type __n)
#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();
+ __e.__ptr_->__next_ = this->__create_node(/* prev = */__e.__ptr_, /* next = */nullptr)->__as_link();
}
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
}
@@ -1683,9 +1631,9 @@ list<_Tp, _Alloc>::resize(size_type __n)
{
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();
+ this->__delete_node(__current);
if (__prev == 0)
break;
__e = iterator(__prev);
@@ -1708,11 +1656,9 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
{
__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);
+ __node_pointer __node = this->__create_node(/* prev = */nullptr, /* next = */nullptr, __x);
++__ds;
- __link_pointer __nl = __hold.release()->__as_link();
+ __link_pointer __nl = __node->__as_link();
iterator __r = iterator(__nl);
iterator __e = __r;
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
@@ -1721,11 +1667,7 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
#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();
+ __e.__ptr_->__next_ = this->__create_node(/* prev = */__e.__ptr_, /* next = */nullptr, __x)->__as_link();
}
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
}
@@ -1733,9 +1675,9 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
{
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();
+ this->__delete_node(__current);
if (__prev == 0)
break;
__e = iterator(__prev);
@@ -2124,6 +2066,7 @@ _LIBCPP_POP_MACROS
# include <algorithm>
# include <atomic>
# include <concepts>
+# include <cstdint>
# include <cstdlib>
# include <functional>
# include <iosfwd>
diff --git a/libcxx/test/libcxx/transitive_includes/cxx23.csv b/libcxx/test/libcxx/transitive_includes/cxx23.csv
index b77ffa4..3709566 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx23.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx23.csv
@@ -230,8 +230,6 @@ format tuple
format version
forward_list compare
forward_list cstddef
-forward_list cstdint
-forward_list cstring
forward_list initializer_list
forward_list limits
forward_list new
diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv
index b77ffa4..3709566 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx26.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv
@@ -230,8 +230,6 @@ format tuple
format version
forward_list compare
forward_list cstddef
-forward_list cstdint
-forward_list cstring
forward_list initializer_list
forward_list limits
forward_list new