Test the single size bit when checking emptiness of small SwissTables.

Small SwissTables (`capacity <= 1`) have `size() <= 1`, yet small-table paths checked `empty()` via `data_ < kSizeOneNoMetadata`, requiring a 64-bit unsigned comparison instead of testing the single `kSizeOneNoMetadata` bit. In addition, `is_soo()` redundantly checked `cap.IsValid() && fits_in_soo(cap.capacity())` even though `SooCapacity() == kMaxSmallCapacity` and `HashtableCapacity::is_small()` already rejects `kInvalid` and `kSelfMovedFrom`.

Add `empty_when_small()` (`(data_ & kSizeOneNoMetadata) == 0`) and use it across small-table lookup, insertion, merge, clear, and destruction paths where `is_small()` already holds, compiling to a 32-bit `testl` on x86 and a single `tbz`/`tbnz` on ARM64. Simplify `is_soo()` to `SooEnabled() && maybe_invalid_capacity().is_small()` and remove the unused `fits_in_soo()` helper.

PiperOrigin-RevId: 1005230808
diff --git a/absl/container/internal/raw_hash_set.cc b/absl/container/internal/raw_hash_set.cc
index baed443..e60b237 100644
--- a/absl/container/internal/raw_hash_set.cc
+++ b/absl/container/internal/raw_hash_set.cc
@@ -852,7 +852,7 @@
   ABSL_SWISSTABLE_ASSERT(c.capacity() > 0);
   if (policy.destroy_slot != nullptr) {
     if (c.is_small()) {
-      if (!c.empty()) {
+      if (!c.empty_when_small()) {
         static_assert(kMaxSmallCapacity == 1);
         policy.destroy_slot(&c, c.single_non_soo_slot());
       }
@@ -948,7 +948,7 @@
   if (c.is_small()) {
     // In the small case, we keep the backing array allocation because the
     // memory overhead is small compared to the potential benefits of reuse.
-    if (!c.empty()) {
+    if (!c.empty_when_small()) {
       if (destroy_slot != nullptr) {
         destroy_slot(&c, SingleSlotAddress<kSooEnabled>(c));
       }
@@ -2039,7 +2039,7 @@
                                void* hasher, HashForKeyFn get_hash) {
   ABSL_SWISSTABLE_ASSERT(common.is_small());
   ABSL_SWISSTABLE_ASSERT(!policy.soo_enabled);
-  const bool is_empty = common.empty();
+  const bool is_empty = common.empty_when_small();
   if (common.capacity() == 1 && is_empty) {
     IncrementSmallSizeNonSoo(common, policy);
     // Compute before `RecordInsertMissCold` to avoid reloading `control_`.
@@ -2052,7 +2052,7 @@
     return res;
   }
 
-  const size_t size = common.size();
+  const size_t size = is_empty ? 0 : 1;
   const bool has_infoz =
       is_empty ? (policy.is_hashtablez_enabled && ShouldSampleNextTable())
                : common.has_infoz();
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index ba34be9..e9cdbd2 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -853,6 +853,12 @@
   void decrement_size() { data_ -= kSizeOneNoMetadata; }
   // Returns true if the table is empty.
   bool empty() const { return data_ < kSizeOneNoMetadata; }
+  // Returns true if a small table (capacity <= 1) is empty.
+  bool empty_when_small() const {
+    ABSL_SWISSTABLE_ASSERT(is_small());
+    ABSL_SWISSTABLE_ASSERT(size() <= 1);
+    return (data_ & kSizeOneNoMetadata) == 0;
+  }
 
   // Returns true if an empty SOO table has already queried should_sample_soo().
   bool soo_has_tried_sampling() const {
@@ -1419,6 +1425,7 @@
     inline_data_.decrement_size();
   }
   bool empty() const { return inline_data_.empty(); }
+  bool empty_when_small() const { return inline_data_.empty_when_small(); }
   void set_soo_has_tried_sampling() {
     inline_data_.set_soo_has_tried_sampling();
   }
@@ -2515,18 +2522,15 @@
     return SizeToCapacity(MaxValidSize());
   }
 
-  // Whether `size` fits in the SOO capacity of this table.
-  bool fits_in_soo(size_t size) const {
-    return SooEnabled() && size <= SooCapacity();
-  }
   // Whether this table is in SOO mode or non-SOO mode.
   bool is_soo() const {
-    HashtableCapacity cap = maybe_invalid_capacity();
-    return cap.IsValid() && fits_in_soo(cap.capacity());
+    static_assert(SooCapacity() == kMaxSmallCapacity);
+    return SooEnabled() && maybe_invalid_capacity().is_small();
   }
-  bool is_full_soo() const { return is_soo() && !empty(); }
+  bool is_full_soo() const { return is_soo() && !empty_when_small(); }
 
   bool is_small() const { return common().is_small(); }
+  bool empty_when_small() const { return common().empty_when_small(); }
 
   // Give an early error when key_type is not hashable/eq.
   auto KeyTypeCanBeHashed(const Hash& h, const key_type& k) -> decltype(h(k));
@@ -3351,7 +3355,7 @@
     };
 
     if (src.is_small()) {
-      if (src.empty()) return;
+      if (src.empty_when_small()) return;
       if (insert_slot(src.single_slot()))
         src.erase_meta_only_small();
       return;
@@ -3613,7 +3617,9 @@
   // SOO functionality.
   template <class K>
   ABSL_ATTRIBUTE_ALWAYS_INLINE iterator find_small(const K& key) {
-    return empty() || !equal_to(key, single_slot()) ? end() : single_iterator();
+    return empty_when_small() || !equal_to(key, single_slot())
+               ? end()
+               : single_iterator();
   }
 
   template <class K>
@@ -3687,8 +3693,8 @@
         kIsDefaultAlloc && BackingArrayAlignment(alignof(slot_type)) ==
                                kStandardBackingArrayAlignment;
     if constexpr (SooEnabled()) {
-      if (is_small() &&
-          (PolicyTraits::template destroy_is_trivial<Alloc>() || empty())) {
+      if (is_small() && (PolicyTraits::template destroy_is_trivial<Alloc>() ||
+                         empty_when_small())) {
         return;
       }
     } else {
@@ -3850,7 +3856,7 @@
   find_or_prepare_insert_soo(const K& key) {
     bool force_sampling;
     slot_type* slot = single_slot();
-    if (empty()) {
+    if (empty_when_small()) {
       if (!should_sample_soo()) {
         common().set_full_soo();
         return {slot, true};
@@ -3880,7 +3886,7 @@
     if constexpr (SooEnabled()) {
       return find_or_prepare_insert_soo(key);
     }
-    if (!empty()) {
+    if (!empty_when_small()) {
       if (equal_to(key, single_slot())) {
         return {single_slot(), false};
       }