@@ -1233,8 +1233,10 @@ class BtreeNodePeer {
1233
1233
}
1234
1234
1235
1235
template <typename Btree>
1236
- constexpr static bool UsesGenerations () {
1237
- return Btree::params_type::kEnableGenerations ;
1236
+ constexpr static bool FieldTypeEqualsSlotType () {
1237
+ return std::is_same<
1238
+ typename btree_node<typename Btree::params_type>::field_type,
1239
+ typename btree_node<typename Btree::params_type>::slot_type>::value;
1238
1240
}
1239
1241
};
1240
1242
@@ -1463,7 +1465,7 @@ class SizedBtreeSet
1463
1465
using Base = typename SizedBtreeSet::btree_set_container;
1464
1466
1465
1467
public:
1466
- SizedBtreeSet () {}
1468
+ SizedBtreeSet () = default ;
1467
1469
using Base::Base;
1468
1470
};
1469
1471
@@ -1509,10 +1511,9 @@ TEST(Btree, MovesComparisonsCopiesSwapsTracking) {
1509
1511
EXPECT_EQ (BtreeNodePeer::GetNumSlotsPerNode<decltype (set61)>(), 61 );
1510
1512
EXPECT_EQ (BtreeNodePeer::GetNumSlotsPerNode<decltype (set100)>(), 100 );
1511
1513
if (sizeof (void *) == 8 ) {
1512
- EXPECT_EQ (
1513
- BtreeNodePeer::GetNumSlotsPerNode<absl::btree_set<int32_t >>(),
1514
- // When we have generations, there is one fewer slot.
1515
- BtreeNodePeer::UsesGenerations<absl::btree_set<int32_t >>() ? 60 : 61 );
1514
+ EXPECT_EQ (BtreeNodePeer::GetNumSlotsPerNode<absl::btree_set<int32_t >>(),
1515
+ // When we have generations, there is one fewer slot.
1516
+ BtreeGenerationsEnabled () ? 60 : 61 );
1516
1517
}
1517
1518
1518
1519
// Test key insertion/deletion in random order.
@@ -1568,10 +1569,9 @@ TEST(Btree, MovesComparisonsCopiesSwapsTrackingThreeWayCompare) {
1568
1569
EXPECT_EQ (BtreeNodePeer::GetNumSlotsPerNode<decltype (set61)>(), 61 );
1569
1570
EXPECT_EQ (BtreeNodePeer::GetNumSlotsPerNode<decltype (set100)>(), 100 );
1570
1571
if (sizeof (void *) == 8 ) {
1571
- EXPECT_EQ (
1572
- BtreeNodePeer::GetNumSlotsPerNode<absl::btree_set<int32_t >>(),
1573
- // When we have generations, there is one fewer slot.
1574
- BtreeNodePeer::UsesGenerations<absl::btree_set<int32_t >>() ? 60 : 61 );
1572
+ EXPECT_EQ (BtreeNodePeer::GetNumSlotsPerNode<absl::btree_set<int32_t >>(),
1573
+ // When we have generations, there is one fewer slot.
1574
+ BtreeGenerationsEnabled () ? 60 : 61 );
1575
1575
}
1576
1576
1577
1577
// Test key insertion/deletion in random order.
@@ -3226,7 +3226,7 @@ TEST(Btree, MutatedKeysCaught) {
3226
3226
#ifndef _MSC_VER
3227
3227
// This test crashes on MSVC.
3228
3228
TEST (Btree, InvalidIteratorUse) {
3229
- if (!BtreeNodePeer::UsesGenerations<absl::btree_set< int >> ())
3229
+ if (!BtreeGenerationsEnabled ())
3230
3230
GTEST_SKIP () << " Generation validation for iterators is disabled." ;
3231
3231
3232
3232
// Invalid memory use can trigger heap-use-after-free in ASan or invalidated
@@ -3569,6 +3569,41 @@ TEST(Btree, InvalidPointerUse) {
3569
3569
EXPECT_DEATH (std::cout << *ptr, " heap-use-after-free" );
3570
3570
}
3571
3571
3572
+ template <typename Set>
3573
+ void TestBasicFunctionality (Set set) {
3574
+ using value_type = typename Set::value_type;
3575
+ for (int i = 0 ; i < 100 ; ++i) { set.insert (value_type (i)); }
3576
+ for (int i = 50 ; i < 100 ; ++i) { set.erase (value_type (i)); }
3577
+ auto it = set.begin ();
3578
+ for (int i = 0 ; i < 50 ; ++i, ++it) {
3579
+ ASSERT_EQ (set.find (value_type (i)), it) << i;
3580
+ }
3581
+ }
3582
+
3583
+ template <size_t align>
3584
+ struct alignas (align) OveralignedKey {
3585
+ explicit OveralignedKey (int i) : key (i) {}
3586
+ bool operator <(const OveralignedKey &other) const { return key < other.key ; }
3587
+ int key = 0 ;
3588
+ };
3589
+
3590
+ TEST (Btree, OveralignedKey) {
3591
+ // Test basic functionality with both even and odd numbers of slots per node.
3592
+ // The goal here is to detect cases where alignment may be incorrect.
3593
+ TestBasicFunctionality (
3594
+ SizedBtreeSet<OveralignedKey<16 >, /* TargetValuesPerNode=*/ 8 >());
3595
+ TestBasicFunctionality (
3596
+ SizedBtreeSet<OveralignedKey<16 >, /* TargetValuesPerNode=*/ 9 >());
3597
+ }
3598
+
3599
+ TEST (Btree, FieldTypeEqualsSlotType) {
3600
+ // This breaks if we try to do layout_type::Pointer<slot_type> because
3601
+ // slot_type is the same as field_type.
3602
+ using set_type = absl::btree_set<uint8_t >;
3603
+ static_assert (BtreeNodePeer::FieldTypeEqualsSlotType<set_type>(), " " );
3604
+ TestBasicFunctionality (set_type ());
3605
+ }
3606
+
3572
3607
} // namespace
3573
3608
} // namespace container_internal
3574
3609
ABSL_NAMESPACE_END
0 commit comments