2020#include < __memory/addressof.h>
2121#include < __memory/allocator_traits.h>
2222#include < __memory/compressed_pair.h>
23+ #include < __memory/construct_at.h>
2324#include < __memory/pointer_traits.h>
2425#include < __memory/swap_allocator.h>
2526#include < __memory/unique_ptr.h>
27+ #include < __new/launder.h>
2628#include < __type_traits/copy_cvref.h>
2729#include < __type_traits/enable_if.h>
2830#include < __type_traits/invoke.h>
@@ -559,8 +561,7 @@ public:
559561};
560562
561563template <class _VoidPtr >
562- class _LIBCPP_STANDALONE_DEBUG
563- __tree_node_base : public __tree_end_node<__rebind_pointer_t <_VoidPtr, __tree_node_base<_VoidPtr> > > {
564+ class __tree_node_base : public __tree_end_node <__rebind_pointer_t <_VoidPtr, __tree_node_base<_VoidPtr> > > {
564565public:
565566 using pointer = __rebind_pointer_t <_VoidPtr, __tree_node_base>;
566567 using __end_node_pointer _LIBCPP_NODEBUG = __rebind_pointer_t <_VoidPtr, __tree_end_node<pointer> >;
@@ -573,22 +574,41 @@ public:
573574
574575 _LIBCPP_HIDE_FROM_ABI void __set_parent (pointer __p) { __parent_ = static_cast <__end_node_pointer>(__p); }
575576
576- ~ __tree_node_base () = delete ;
577+ _LIBCPP_HIDE_FROM_ABI __tree_node_base () = default ;
577578 __tree_node_base (__tree_node_base const &) = delete ;
578579 __tree_node_base& operator =(__tree_node_base const &) = delete ;
579580};
580581
581582template <class _Tp , class _VoidPtr >
582- class _LIBCPP_STANDALONE_DEBUG __tree_node : public __tree_node_base<_VoidPtr> {
583+ class __tree_node : public __tree_node_base <_VoidPtr> {
583584public:
584585 using __node_value_type _LIBCPP_NODEBUG = __get_node_value_type_t <_Tp>;
585586
587+ // We use a union to avoid initialization during member initialization, which allows us
588+ // to use the allocator from the container to construct the `__node_value_type` in the
589+ // memory provided by the union member
590+ #ifndef _LIBCPP_CXX03_LANG
591+
586592private:
587- __node_value_type __value_;
593+ union {
594+ __node_value_type __value_;
595+ };
588596
589597public:
590598 _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value () { return __value_; }
599+ #else
600+
601+ private:
602+ _ALIGNAS_TYPE (__node_value_type) unsigned char __buffer_[sizeof(__node_value_type)];
591603
604+ public:
605+ _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value () { return *reinterpret_cast <__node_value_type*>(__buffer_); }
606+ #endif
607+
608+ template <class _Alloc , class ... _Args>
609+ _LIBCPP_HIDE_FROM_ABI explicit __tree_node (_Alloc& __na, _Args&&... __args) {
610+ allocator_traits<_Alloc>::construct (__na, std::addressof (__get_value ()), std::forward<_Args>(__args)...);
611+ }
592612 ~__tree_node () = delete ;
593613 __tree_node (__tree_node const &) = delete ;
594614 __tree_node& operator =(__tree_node const &) = delete ;
@@ -1816,7 +1836,7 @@ typename __tree<_Tp, _Compare, _Allocator>::__node_holder
18161836__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&&... __args) {
18171837 __node_allocator& __na = __node_alloc ();
18181838 __node_holder __h (__node_traits::allocate (__na, 1 ), _Dp (__na));
1819- __node_traits::construct (__na, std::addressof (__h-> __get_value ()) , std::forward<_Args>(__args)...);
1839+ std::__construct_at ( std::addressof (* __h), __na , std::forward<_Args>(__args)...);
18201840 __h.get_deleter ().__value_constructed = true ;
18211841 return __h;
18221842}
0 commit comments