ABSL_NAMESPACE_BEGIN
namespace container_internal {
+#ifdef ABSL_SWISSTABLE_ASSERT
+#error ABSL_SWISSTABLE_ASSERT cannot be directly set
+#else
+// We use this macro for assertions that users may see when the table is in an
+// invalid state that sanitizers may help diagnose.
+#define ABSL_SWISSTABLE_ASSERT(CONDITION) \
+ assert((CONDITION) && "Try enabling sanitizers.")
+#endif
+
template <typename AllocType>
void SwapAlloc(AllocType& lhs, AllocType& rhs,
std::true_type /* propagate_on_container_swap */) {
return n ? ~size_t{} >> countl_zero(n) : 1;
}
+template <size_t kSlotSize>
+size_t MaxValidCapacity() {
+ return NormalizeCapacity((std::numeric_limits<size_t>::max)() / 4 /
+ kSlotSize);
+}
+
+// Use a non-inlined function to avoid code bloat.
+[[noreturn]] void HashTableSizeOverflow();
+
// General notes on capacity/growth methods below:
// - We use 7/8th as maximum load factor. For 16-wide groups, that gives an
// average of two empty slots per group.
: ctrl_(EmptyGroup()),
settings_(0, HashtablezInfoHandle(), hash, eq, alloc) {
if (bucket_count) {
+ if (ABSL_PREDICT_FALSE(bucket_count >
+ MaxValidCapacity<sizeof(slot_type)>())) {
+ HashTableSizeOverflow();
+ }
capacity_ = NormalizeCapacity(bucket_count);
initialize_slots();
}
bool empty() const { return !size(); }
size_t size() const { return size_; }
size_t capacity() const { return capacity_; }
- size_t max_size() const { return (std::numeric_limits<size_t>::max)(); }
+ size_t max_size() const {
+ return CapacityToGrowth(MaxValidCapacity<sizeof(slot_type)>());
+ }
ABSL_ATTRIBUTE_REINITIALIZES void clear() {
// Iterating over this container is O(bucket_count()). When bucket_count()
auto m = NormalizeCapacity(n | GrowthToLowerboundCapacity(size()));
// n == 0 unconditionally rehashes as per the standard.
if (n == 0 || m > capacity_) {
+ if (ABSL_PREDICT_FALSE(m > MaxValidCapacity<sizeof(slot_type)>())) {
+ HashTableSizeOverflow();
+ }
resize(m);
// This is after resize, to ensure that we have completed the allocation
void reserve(size_t n) {
if (n > size() + growth_left()) {
+ if (ABSL_PREDICT_FALSE(n > max_size())) {
+ HashTableSizeOverflow();
+ }
size_t m = GrowthToLowerboundCapacity(n);
resize(NormalizeCapacity(m));
} // namespace absl
#undef ABSL_INTERNAL_ASSERT_IS_FULL
+#undef ABSL_SWISSTABLE_ASSERT
#endif // ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_