2424#include < __memory/pointer_traits.h>
2525#include < __memory/swap_allocator.h>
2626#include < __memory/unique_ptr.h>
27+ #include < __new/launder.h>
2728#include < __type_traits/copy_cvref.h>
2829#include < __type_traits/enable_if.h>
2930#include < __type_traits/invoke.h>
@@ -566,8 +567,7 @@ public:
566567};
567568
568569template <class _VoidPtr >
569- class _LIBCPP_STANDALONE_DEBUG
570- __tree_node_base : public __tree_end_node<__rebind_pointer_t <_VoidPtr, __tree_node_base<_VoidPtr> > > {
570+ class __tree_node_base : public __tree_end_node <__rebind_pointer_t <_VoidPtr, __tree_node_base<_VoidPtr> > > {
571571public:
572572 using pointer = __rebind_pointer_t <_VoidPtr, __tree_node_base>;
573573 using __end_node_pointer _LIBCPP_NODEBUG = __rebind_pointer_t <_VoidPtr, __tree_end_node<pointer> >;
@@ -609,21 +609,35 @@ error> is not a constant expression
609609};
610610
611611template <class _Tp , class _VoidPtr >
612- class _LIBCPP_STANDALONE_DEBUG __tree_node : public __tree_node_base<_VoidPtr> {
612+ class __tree_node : public __tree_node_base <_VoidPtr> {
613613public:
614614 using __node_value_type _LIBCPP_NODEBUG = __get_node_value_type_t <_Tp>;
615615
616+ // We use a union to avoid initialization during member initialization, which allows us
617+ // to use the allocator from the container to allocate the node itself
618+ #ifndef _LIBCPP_CXX03_LANG
619+
620+ private:
616621 union {
617622 __node_value_type __value_;
618623 };
619624
620625public:
621626 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_value_type& __get_value () { return __value_; }
627+ #else
628+
629+ private:
630+ _ALIGNAS_TYPE (__node_value_type) unsigned char __buffer_[sizeof(__node_value_type)];
631+
632+ public:
633+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_value_type& __get_value () { return *reinterpret_cast <__node_value_type*>(__buffer_); }
634+ #endif
622635
623636 template <class _Alloc , class ... _Args>
624637 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit __tree_node (_Alloc& __na, _Args&&... __args) {
625- allocator_traits<_Alloc>::construct (__na, std::addressof (__value_ ), std::forward<_Args>(__args)...);
638+ allocator_traits<_Alloc>::construct (__na, std::addressof (__get_value () ), std::forward<_Args>(__args)...);
626639 }
640+
627641// TODO: workaround for arm CI which uses clang-19.1.4
628642/*
629643note: non-literal type 'std::__tree_node<std::__value_type<int, int>, void *>' cannot be used in a constant expression
@@ -1958,7 +1972,7 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator _LIBCPP_CONSTEXPR_SINCE_CXX
19581972__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p, _Args&&... __args) {
19591973 __node_holder __h = __construct_node (std::forward<_Args>(__args)...);
19601974 __end_node_pointer __parent;
1961- __node_base_pointer& __child = __find_leaf (__p, __parent, __h->__value_ );
1975+ __node_base_pointer& __child = __find_leaf (__p, __parent, __h->__get_value () );
19621976 __insert_node_at (__parent, __child, std::__static_fancy_pointer_cast<__node_base_pointer>(__h.get ()));
19631977 return iterator (static_cast <__node_pointer>(__h.release ()));
19641978}
@@ -1971,7 +1985,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_assign_unique(const value_type& __v, _
19711985 __node_pointer __r = static_cast <__node_pointer>(__child);
19721986 bool __inserted = false ;
19731987 if (__child == nullptr ) {
1974- __assign_value (__nd->__value_ , __v);
1988+ __assign_value (__nd->__get_value () , __v);
19751989 __insert_node_at (__parent, __child, std::__static_fancy_pointer_cast<__node_base_pointer>(__nd));
19761990 __r = __nd;
19771991 __inserted = true ;
@@ -1983,7 +1997,7 @@ template <class _Tp, class _Compare, class _Allocator>
19831997_LIBCPP_CONSTEXPR_SINCE_CXX26 typename __tree<_Tp, _Compare, _Allocator>::iterator
19841998__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd) {
19851999 __end_node_pointer __parent;
1986- __node_base_pointer& __child = __find_leaf_high (__parent, __nd->__value_ );
2000+ __node_base_pointer& __child = __find_leaf_high (__parent, __nd->__get_value () );
19872001 __insert_node_at (__parent, __child, std::__static_fancy_pointer_cast<__node_base_pointer>(__nd));
19882002 return iterator (__nd);
19892003}
0 commit comments