21
21
#include < __memory/addressof.h>
22
22
#include < __memory/allocator_traits.h>
23
23
#include < __memory/compressed_pair.h>
24
- #include < __memory/construct_at.h>
25
24
#include < __memory/pointer_traits.h>
26
25
#include < __memory/swap_allocator.h>
27
26
#include < __memory/unique_ptr.h>
46
45
#include < cmath>
47
46
#include < cstring>
48
47
#include < initializer_list>
49
- #include < new> // __launder
50
48
51
49
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
52
50
# pragma GCC system_header
@@ -109,44 +107,19 @@ struct __hash_node_base
109
107
}
110
108
111
109
_LIBCPP_INLINE_VISIBILITY __hash_node_base () _NOEXCEPT : __next_(nullptr ) {}
112
- _LIBCPP_HIDE_FROM_ABI explicit __hash_node_base (__next_pointer __next) _NOEXCEPT : __next_(__next) {}
113
110
};
114
111
115
112
template <class _Tp , class _VoidPtr >
116
- struct __hash_node
113
+ struct _LIBCPP_STANDALONE_DEBUG __hash_node
117
114
: public __hash_node_base
118
115
<
119
116
__rebind_pointer_t <_VoidPtr, __hash_node<_Tp, _VoidPtr> >
120
117
>
121
118
{
122
119
typedef _Tp __node_value_type;
123
- using _Base = __hash_node_base<__rebind_pointer_t <_VoidPtr, __hash_node<_Tp, _VoidPtr> > >;
124
- using __next_pointer = typename _Base::__next_pointer;
125
120
126
121
size_t __hash_;
127
-
128
- // We allow starting the lifetime of nodes without initializing the value held by the node,
129
- // since that is handled by the hash table itself in order to be allocator-aware.
130
- #ifndef _LIBCPP_CXX03_LANG
131
- private:
132
- union {
133
- _Tp __value_;
134
- };
135
-
136
- public:
137
- _LIBCPP_HIDE_FROM_ABI _Tp& __get_value () { return __value_; }
138
- #else
139
- private:
140
- _ALIGNAS_TYPE (_Tp) char __buffer_[sizeof(_Tp)];
141
-
142
- public:
143
- _LIBCPP_HIDE_FROM_ABI _Tp& __get_value () {
144
- return *std::__launder (reinterpret_cast <_Tp*>(&__buffer_));
145
- }
146
- #endif
147
-
148
- _LIBCPP_HIDE_FROM_ABI explicit __hash_node (__next_pointer __next, size_t __hash) : _Base(__next), __hash_(__hash) {}
149
- _LIBCPP_HIDE_FROM_ABI ~__hash_node () {}
122
+ __node_value_type __value_;
150
123
};
151
124
152
125
inline _LIBCPP_INLINE_VISIBILITY
@@ -338,12 +311,12 @@ public:
338
311
339
312
_LIBCPP_INLINE_VISIBILITY
340
313
reference operator *() const {
341
- return __node_->__upcast ()->__get_value () ;
314
+ return __node_->__upcast ()->__value_ ;
342
315
}
343
316
344
317
_LIBCPP_INLINE_VISIBILITY
345
318
pointer operator ->() const {
346
- return pointer_traits<pointer>::pointer_to (__node_->__upcast ()->__get_value () );
319
+ return pointer_traits<pointer>::pointer_to (__node_->__upcast ()->__value_ );
347
320
}
348
321
349
322
_LIBCPP_INLINE_VISIBILITY
@@ -414,11 +387,11 @@ public:
414
387
415
388
_LIBCPP_INLINE_VISIBILITY
416
389
reference operator *() const {
417
- return __node_->__upcast ()->__get_value () ;
390
+ return __node_->__upcast ()->__value_ ;
418
391
}
419
392
_LIBCPP_INLINE_VISIBILITY
420
393
pointer operator ->() const {
421
- return pointer_traits<pointer>::pointer_to (__node_->__upcast ()->__get_value () );
394
+ return pointer_traits<pointer>::pointer_to (__node_->__upcast ()->__value_ );
422
395
}
423
396
424
397
_LIBCPP_INLINE_VISIBILITY
@@ -480,12 +453,12 @@ public:
480
453
481
454
_LIBCPP_INLINE_VISIBILITY
482
455
reference operator *() const {
483
- return __node_->__upcast ()->__get_value () ;
456
+ return __node_->__upcast ()->__value_ ;
484
457
}
485
458
486
459
_LIBCPP_INLINE_VISIBILITY
487
460
pointer operator ->() const {
488
- return pointer_traits<pointer>::pointer_to (__node_->__upcast ()->__get_value () );
461
+ return pointer_traits<pointer>::pointer_to (__node_->__upcast ()->__value_ );
489
462
}
490
463
491
464
_LIBCPP_INLINE_VISIBILITY
@@ -570,12 +543,12 @@ public:
570
543
571
544
_LIBCPP_INLINE_VISIBILITY
572
545
reference operator *() const {
573
- return __node_->__upcast ()->__get_value () ;
546
+ return __node_->__upcast ()->__value_ ;
574
547
}
575
548
576
549
_LIBCPP_INLINE_VISIBILITY
577
550
pointer operator ->() const {
578
- return pointer_traits<pointer>::pointer_to (__node_->__upcast ()->__get_value () );
551
+ return pointer_traits<pointer>::pointer_to (__node_->__upcast ()->__value_ );
579
552
}
580
553
581
554
_LIBCPP_INLINE_VISIBILITY
@@ -697,10 +670,8 @@ public:
697
670
_LIBCPP_INLINE_VISIBILITY
698
671
void operator ()(pointer __p) _NOEXCEPT
699
672
{
700
- if (__value_constructed) {
701
- __alloc_traits::destroy (__na_, _NodeTypes::__get_ptr (__p->__get_value ()));
702
- std::__destroy_at (std::addressof (*__p));
703
- }
673
+ if (__value_constructed)
674
+ __alloc_traits::destroy (__na_, _NodeTypes::__get_ptr (__p->__value_ ));
704
675
if (__p)
705
676
__alloc_traits::deallocate (__na_, __p, 1 );
706
677
}
@@ -1394,8 +1365,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np)
1394
1365
{
1395
1366
__next_pointer __next = __np->__next_ ;
1396
1367
__node_pointer __real_np = __np->__upcast ();
1397
- __node_traits::destroy (__na, _NodeTypes::__get_ptr (__real_np->__get_value ()));
1398
- std::__destroy_at (std::addressof (*__real_np));
1368
+ __node_traits::destroy (__na, _NodeTypes::__get_ptr (__real_np->__value_ ));
1399
1369
__node_traits::deallocate (__na, __real_np, 1 );
1400
1370
__np = __next;
1401
1371
}
@@ -1464,8 +1434,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
1464
1434
const_iterator __i = __u.begin ();
1465
1435
while (__cache != nullptr && __u.size () != 0 )
1466
1436
{
1467
- __cache->__upcast ()->__get_value () =
1468
- _VSTD::move (__u.remove (__i++)->__get_value () );
1437
+ __cache->__upcast ()->__value_ =
1438
+ _VSTD::move (__u.remove (__i++)->__value_ );
1469
1439
__next_pointer __next = __cache->__next_ ;
1470
1440
__node_insert_multi (__cache->__upcast ());
1471
1441
__cache = __next;
@@ -1483,7 +1453,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
1483
1453
const_iterator __i = __u.begin ();
1484
1454
while (__u.size () != 0 )
1485
1455
{
1486
- __node_holder __h = __construct_node (_NodeTypes::__move (__u.remove (__i++)->__get_value () ));
1456
+ __node_holder __h = __construct_node (_NodeTypes::__move (__u.remove (__i++)->__value_ ));
1487
1457
__node_insert_multi (__h.get ());
1488
1458
__h.release ();
1489
1459
}
@@ -1525,7 +1495,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first
1525
1495
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
1526
1496
for (; __cache != nullptr && __first != __last; ++__first)
1527
1497
{
1528
- __cache->__upcast ()->__get_value () = *__first;
1498
+ __cache->__upcast ()->__value_ = *__first;
1529
1499
__next_pointer __next = __cache->__next_ ;
1530
1500
__node_insert_unique (__cache->__upcast ());
1531
1501
__cache = __next;
@@ -1565,7 +1535,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first,
1565
1535
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
1566
1536
for (; __cache != nullptr && __first != __last; ++__first)
1567
1537
{
1568
- __cache->__upcast ()->__get_value () = *__first;
1538
+ __cache->__upcast ()->__value_ = *__first;
1569
1539
__next_pointer __next = __cache->__next_ ;
1570
1540
__node_insert_multi (__cache->__upcast ());
1571
1541
__cache = __next;
@@ -1659,7 +1629,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare(
1659
1629
__ndptr = __ndptr->__next_ )
1660
1630
{
1661
1631
if ((__ndptr->__hash () == __hash) &&
1662
- key_eq ()(__ndptr->__upcast ()->__get_value () , __value))
1632
+ key_eq ()(__ndptr->__upcast ()->__value_ , __value))
1663
1633
return __ndptr;
1664
1634
}
1665
1635
}
@@ -1708,9 +1678,9 @@ template <class _Tp, class _Hash, class _Equal, class _Alloc>
1708
1678
pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool >
1709
1679
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique (__node_pointer __nd)
1710
1680
{
1711
- __nd->__hash_ = hash_function ()(__nd->__get_value () );
1681
+ __nd->__hash_ = hash_function ()(__nd->__value_ );
1712
1682
__next_pointer __existing_node =
1713
- __node_insert_unique_prepare (__nd->__hash (), __nd->__get_value () );
1683
+ __node_insert_unique_prepare (__nd->__hash (), __nd->__value_ );
1714
1684
1715
1685
// Insert the node, unless it already exists in the container.
1716
1686
bool __inserted = false ;
@@ -1756,7 +1726,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare(
1756
1726
// false true set __found to true
1757
1727
// true false break
1758
1728
if (__found != (__pn->__next_ ->__hash () == __cp_hash &&
1759
- key_eq ()(__pn->__next_ ->__upcast ()->__get_value () , __cp_val)))
1729
+ key_eq ()(__pn->__next_ ->__upcast ()->__value_ , __cp_val)))
1760
1730
{
1761
1731
if (!__found)
1762
1732
__found = true ;
@@ -1810,8 +1780,8 @@ template <class _Tp, class _Hash, class _Equal, class _Alloc>
1810
1780
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1811
1781
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi (__node_pointer __cp)
1812
1782
{
1813
- __cp->__hash_ = hash_function ()(__cp->__get_value () );
1814
- __next_pointer __pn = __node_insert_multi_prepare (__cp->__hash (), __cp->__get_value () );
1783
+ __cp->__hash_ = hash_function ()(__cp->__value_ );
1784
+ __next_pointer __pn = __node_insert_multi_prepare (__cp->__hash (), __cp->__value_ );
1815
1785
__node_insert_multi_perform (__cp, __pn);
1816
1786
1817
1787
return iterator (__cp->__ptr ());
@@ -1822,7 +1792,7 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1822
1792
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi (
1823
1793
const_iterator __p, __node_pointer __cp)
1824
1794
{
1825
- if (__p != end () && key_eq ()(*__p, __cp->__get_value () ))
1795
+ if (__p != end () && key_eq ()(*__p, __cp->__value_ ))
1826
1796
{
1827
1797
__next_pointer __np = __p.__node_ ;
1828
1798
__cp->__hash_ = __np->__hash ();
@@ -1869,7 +1839,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const&
1869
1839
__nd = __nd->__next_ )
1870
1840
{
1871
1841
if ((__nd->__hash () == __hash) &&
1872
- key_eq ()(__nd->__upcast ()->__get_value () , __k))
1842
+ key_eq ()(__nd->__upcast ()->__value_ , __k))
1873
1843
goto __done;
1874
1844
}
1875
1845
}
@@ -2013,9 +1983,9 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_unique(
2013
1983
__it != __source.end ();)
2014
1984
{
2015
1985
__node_pointer __src_ptr = __it.__node_ ->__upcast ();
2016
- size_t __hash = hash_function ()(__src_ptr->__get_value () );
1986
+ size_t __hash = hash_function ()(__src_ptr->__value_ );
2017
1987
__next_pointer __existing_node =
2018
- __node_insert_unique_prepare (__hash, __src_ptr->__get_value () );
1988
+ __node_insert_unique_prepare (__hash, __src_ptr->__value_ );
2019
1989
auto __prev_iter = __it++;
2020
1990
if (__existing_node == nullptr )
2021
1991
{
@@ -2067,9 +2037,9 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi(
2067
2037
__it != __source.end ();)
2068
2038
{
2069
2039
__node_pointer __src_ptr = __it.__node_ ->__upcast ();
2070
- size_t __src_hash = hash_function ()(__src_ptr->__get_value () );
2040
+ size_t __src_hash = hash_function ()(__src_ptr->__value_ );
2071
2041
__next_pointer __pn =
2072
- __node_insert_multi_prepare (__src_hash, __src_ptr->__get_value () );
2042
+ __node_insert_multi_prepare (__src_hash, __src_ptr->__value_ );
2073
2043
(void )__source.remove (__it++).release ();
2074
2044
__src_ptr->__hash_ = __src_hash;
2075
2045
__node_insert_multi_perform (__src_ptr, __pn);
@@ -2143,8 +2113,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc)
2143
2113
if _LIBCPP_CONSTEXPR_SINCE_CXX17 (!_UniqueKeys)
2144
2114
{
2145
2115
for (; __np->__next_ != nullptr &&
2146
- key_eq ()(__cp->__upcast ()->__get_value () ,
2147
- __np->__next_ ->__upcast ()->__get_value () );
2116
+ key_eq ()(__cp->__upcast ()->__value_ ,
2117
+ __np->__next_ ->__upcast ()->__value_ );
2148
2118
__np = __np->__next_ )
2149
2119
;
2150
2120
}
@@ -2178,7 +2148,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k)
2178
2148
__nd = __nd->__next_ )
2179
2149
{
2180
2150
if ((__nd->__hash () == __hash)
2181
- && key_eq ()(__nd->__upcast ()->__get_value () , __k))
2151
+ && key_eq ()(__nd->__upcast ()->__value_ , __k))
2182
2152
return iterator (__nd);
2183
2153
}
2184
2154
}
@@ -2205,7 +2175,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const
2205
2175
__nd = __nd->__next_ )
2206
2176
{
2207
2177
if ((__nd->__hash () == __hash)
2208
- && key_eq ()(__nd->__upcast ()->__get_value () , __k))
2178
+ && key_eq ()(__nd->__upcast ()->__value_ , __k))
2209
2179
return const_iterator (__nd);
2210
2180
}
2211
2181
}
@@ -2223,20 +2193,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&& ...__args)
2223
2193
" Construct cannot be called with a hash value type" );
2224
2194
__node_allocator& __na = __node_alloc ();
2225
2195
__node_holder __h (__node_traits::allocate (__na, 1 ), _Dp (__na));
2226
-
2227
- // Begin the lifetime of the node itself. Note that this doesn't begin the lifetime of the value
2228
- // held inside the node, since we need to use the allocator's construct() method for that.
2229
- //
2230
- // We don't use the allocator's construct() method to construct the node itself since the
2231
- // Cpp17FooInsertable named requirements don't require the allocator's construct() method
2232
- // to work on anything other than the value_type.
2233
- std::__construct_at (std::addressof (*__h), /* next = */ nullptr , /* hash = */ 0 );
2234
-
2235
- // Now construct the value_type using the allocator's construct() method.
2236
- __node_traits::construct (__na, _NodeTypes::__get_ptr (__h->__get_value ()), _VSTD::forward<_Args>(__args)...);
2196
+ __node_traits::construct (__na, _NodeTypes::__get_ptr (__h->__value_ ), _VSTD::forward<_Args>(__args)...);
2237
2197
__h.get_deleter ().__value_constructed = true ;
2238
-
2239
- __h->__hash_ = hash_function ()(__h-> __get_value ()) ;
2198
+ __h-> __hash_ = hash_function ()(__h-> __value_ );
2199
+ __h->__next_ = nullptr ;
2240
2200
return __h;
2241
2201
}
2242
2202
@@ -2250,11 +2210,12 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash(
2250
2210
" Construct cannot be called with a hash value type" );
2251
2211
__node_allocator& __na = __node_alloc ();
2252
2212
__node_holder __h (__node_traits::allocate (__na, 1 ), _Dp (__na));
2253
- std::__construct_at (std::addressof (*__h), /* next = */ nullptr , /* hash = */ __hash);
2254
- __node_traits::construct (__na, _NodeTypes::__get_ptr (__h->__get_value ()),
2213
+ __node_traits::construct (__na, _NodeTypes::__get_ptr (__h->__value_ ),
2255
2214
_VSTD::forward<_First>(__f),
2256
2215
_VSTD::forward<_Rest>(__rest)...);
2257
2216
__h.get_deleter ().__value_constructed = true ;
2217
+ __h->__hash_ = __hash;
2218
+ __h->__next_ = nullptr ;
2258
2219
return __h;
2259
2220
}
2260
2221
0 commit comments