@@ -237,11 +237,15 @@ struct TableLayout {
237
237
238
238
impl TableLayout {
239
239
#[ inline]
240
- fn new < T > ( ) -> Self {
240
+ const fn new < T > ( ) -> Self {
241
241
let layout = Layout :: new :: < T > ( ) ;
242
242
Self {
243
243
size : layout. size ( ) ,
244
- ctrl_align : usize:: max ( layout. align ( ) , Group :: WIDTH ) ,
244
+ ctrl_align : if layout. align ( ) > Group :: WIDTH {
245
+ layout. align ( )
246
+ } else {
247
+ Group :: WIDTH
248
+ } ,
245
249
}
246
250
}
247
251
@@ -268,16 +272,6 @@ impl TableLayout {
268
272
}
269
273
}
270
274
271
- /// Returns a Layout which describes the allocation required for a hash table,
272
- /// and the offset of the control bytes in the allocation.
273
- /// (the offset is also one past last element of buckets)
274
- ///
275
- /// Returns `None` if an overflow occurs.
276
- #[ cfg_attr( feature = "inline-more" , inline) ]
277
- fn calculate_layout < T > ( buckets : usize ) -> Option < ( Layout , usize ) > {
278
- TableLayout :: new :: < T > ( ) . calculate_layout_for ( buckets)
279
- }
280
-
281
275
/// A reference to a hash table bucket containing a `T`.
282
276
///
283
277
/// This is usually just a pointer to the element itself. However if the element
@@ -428,6 +422,9 @@ impl<T> RawTable<T, Global> {
428
422
}
429
423
430
424
impl < T , A : Allocator + Clone > RawTable < T , A > {
425
+ const TABLE_LAYOUT : TableLayout = TableLayout :: new :: < T > ( ) ;
426
+ const DATA_NEEDS_DROP : bool = mem:: needs_drop :: < T > ( ) ;
427
+
431
428
/// Creates a new empty hash table without allocating any memory, using the
432
429
/// given allocator.
433
430
///
@@ -456,7 +453,7 @@ impl<T, A: Allocator + Clone> RawTable<T, A> {
456
453
Ok ( Self {
457
454
table : RawTableInner :: new_uninitialized (
458
455
alloc,
459
- TableLayout :: new :: < T > ( ) ,
456
+ Self :: TABLE_LAYOUT ,
460
457
buckets,
461
458
fallibility,
462
459
) ?,
@@ -474,7 +471,7 @@ impl<T, A: Allocator + Clone> RawTable<T, A> {
474
471
Ok ( Self {
475
472
table : RawTableInner :: fallible_with_capacity (
476
473
alloc,
477
- TableLayout :: new :: < T > ( ) ,
474
+ Self :: TABLE_LAYOUT ,
478
475
capacity,
479
476
fallibility,
480
477
) ?,
@@ -508,7 +505,7 @@ impl<T, A: Allocator + Clone> RawTable<T, A> {
508
505
/// Deallocates the table without dropping any entries.
509
506
#[ cfg_attr( feature = "inline-more" , inline) ]
510
507
unsafe fn free_buckets ( & mut self ) {
511
- self . table . free_buckets ( TableLayout :: new :: < T > ( ) ) ;
508
+ self . table . free_buckets ( Self :: TABLE_LAYOUT ) ;
512
509
}
513
510
514
511
/// Returns pointer to one past last element of data table.
@@ -608,7 +605,7 @@ impl<T, A: Allocator + Clone> RawTable<T, A> {
608
605
}
609
606
610
607
unsafe fn drop_elements ( & mut self ) {
611
- if mem :: needs_drop :: < T > ( ) && !self . is_empty ( ) {
608
+ if Self :: DATA_NEEDS_DROP && !self . is_empty ( ) {
612
609
for item in self . iter ( ) {
613
610
item. drop ( ) ;
614
611
}
@@ -696,8 +693,8 @@ impl<T, A: Allocator + Clone> RawTable<T, A> {
696
693
additional,
697
694
& |table, index| hasher ( table. bucket :: < T > ( index) . as_ref ( ) ) ,
698
695
fallibility,
699
- TableLayout :: new :: < T > ( ) ,
700
- if mem :: needs_drop :: < T > ( ) {
696
+ Self :: TABLE_LAYOUT ,
697
+ if Self :: DATA_NEEDS_DROP {
701
698
Some ( mem:: transmute ( ptr:: drop_in_place :: < T > as unsafe fn ( * mut T ) ) )
702
699
} else {
703
700
None
@@ -719,7 +716,7 @@ impl<T, A: Allocator + Clone> RawTable<T, A> {
719
716
capacity,
720
717
& |table, index| hasher ( table. bucket :: < T > ( index) . as_ref ( ) ) ,
721
718
fallibility,
722
- TableLayout :: new :: < T > ( ) ,
719
+ Self :: TABLE_LAYOUT ,
723
720
)
724
721
}
725
722
}
@@ -1036,10 +1033,11 @@ impl<T, A: Allocator + Clone> RawTable<T, A> {
1036
1033
None
1037
1034
} else {
1038
1035
// Avoid `Option::unwrap_or_else` because it bloats LLVM IR.
1039
- let ( layout, ctrl_offset) = match calculate_layout :: < T > ( self . table . buckets ( ) ) {
1040
- Some ( lco) => lco,
1041
- None => unsafe { hint:: unreachable_unchecked ( ) } ,
1042
- } ;
1036
+ let ( layout, ctrl_offset) =
1037
+ match Self :: TABLE_LAYOUT . calculate_layout_for ( self . table . buckets ( ) ) {
1038
+ Some ( lco) => lco,
1039
+ None => unsafe { hint:: unreachable_unchecked ( ) } ,
1040
+ } ;
1043
1041
Some ( (
1044
1042
unsafe { NonNull :: new_unchecked ( self . table . ctrl . as_ptr ( ) . sub ( ctrl_offset) ) } ,
1045
1043
layout,
@@ -1748,7 +1746,7 @@ impl<T: Clone, A: Allocator + Clone> RawTable<T, A> {
1748
1746
// to make sure we drop only the elements that have been
1749
1747
// cloned so far.
1750
1748
let mut guard = guard ( ( 0 , & mut * self ) , |( index, self_) | {
1751
- if mem :: needs_drop :: < T > ( ) && !self_. is_empty ( ) {
1749
+ if Self :: DATA_NEEDS_DROP && !self_. is_empty ( ) {
1752
1750
for i in 0 ..=* index {
1753
1751
if self_. is_bucket_full ( i) {
1754
1752
self_. bucket ( i) . drop ( ) ;
@@ -2036,6 +2034,8 @@ pub struct RawIter<T> {
2036
2034
}
2037
2035
2038
2036
impl < T > RawIter < T > {
2037
+ const DATA_NEEDS_DROP : bool = mem:: needs_drop :: < T > ( ) ;
2038
+
2039
2039
/// Refresh the iterator so that it reflects a removal from the given bucket.
2040
2040
///
2041
2041
/// For the iterator to remain valid, this method must be called once
@@ -2153,7 +2153,7 @@ impl<T> RawIter<T> {
2153
2153
}
2154
2154
2155
2155
unsafe fn drop_elements ( & mut self ) {
2156
- if mem :: needs_drop :: < T > ( ) && self . len ( ) != 0 {
2156
+ if Self :: DATA_NEEDS_DROP && self . len ( ) != 0 {
2157
2157
for item in self {
2158
2158
item. drop ( ) ;
2159
2159
}
0 commit comments