20
20
#include < __memory/addressof.h>
21
21
#include < __memory/allocator_traits.h>
22
22
#include < __memory/compressed_pair.h>
23
+ #include < __memory/construct_at.h>
23
24
#include < __memory/pointer_traits.h>
24
25
#include < __memory/swap_allocator.h>
25
26
#include < __memory/unique_ptr.h>
27
+ #include < __new/launder.h>
26
28
#include < __type_traits/copy_cvref.h>
27
29
#include < __type_traits/enable_if.h>
28
30
#include < __type_traits/invoke.h>
@@ -559,8 +561,7 @@ public:
559
561
};
560
562
561
563
template <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> > > {
564
565
public:
565
566
using pointer = __rebind_pointer_t <_VoidPtr, __tree_node_base>;
566
567
using __end_node_pointer _LIBCPP_NODEBUG = __rebind_pointer_t <_VoidPtr, __tree_end_node<pointer> >;
@@ -573,22 +574,41 @@ public:
573
574
574
575
_LIBCPP_HIDE_FROM_ABI void __set_parent (pointer __p) { __parent_ = static_cast <__end_node_pointer>(__p); }
575
576
576
- ~ __tree_node_base () = delete ;
577
+ _LIBCPP_HIDE_FROM_ABI __tree_node_base () = default ;
577
578
__tree_node_base (__tree_node_base const &) = delete ;
578
579
__tree_node_base& operator =(__tree_node_base const &) = delete ;
579
580
};
580
581
581
582
template <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> {
583
584
public:
584
585
using __node_value_type _LIBCPP_NODEBUG = __get_node_value_type_t <_Tp>;
585
586
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
+
586
592
private:
587
- __node_value_type __value_;
593
+ union {
594
+ __node_value_type __value_;
595
+ };
588
596
589
597
public:
590
598
_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)];
591
603
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
+ }
592
612
~__tree_node () = delete ;
593
613
__tree_node (__tree_node const &) = delete ;
594
614
__tree_node& operator =(__tree_node const &) = delete ;
@@ -1816,7 +1836,7 @@ typename __tree<_Tp, _Compare, _Allocator>::__node_holder
1816
1836
__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&&... __args) {
1817
1837
__node_allocator& __na = __node_alloc ();
1818
1838
__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)...);
1820
1840
__h.get_deleter ().__value_constructed = true ;
1821
1841
return __h;
1822
1842
}
0 commit comments