diff options
26 files changed, 176 insertions, 73 deletions
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index 83d48f6b..f7d81013 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -305,6 +305,7 @@ cc_test( size = "medium", srcs = ["spinlock_test_common.cc"], copts = ABSL_TEST_COPTS, + tags = ["no_test_wasm"], deps = [ ":base", ":core_headers", @@ -343,6 +344,9 @@ cc_test( name = "config_test", srcs = ["config_test.cc"], copts = ABSL_TEST_COPTS, + tags = [ + "no_test_wasm", + ], deps = [ ":config", "//absl/synchronization:thread_pool", @@ -354,6 +358,9 @@ cc_test( name = "call_once_test", srcs = ["call_once_test.cc"], copts = ABSL_TEST_COPTS, + tags = [ + "no_test_wasm", + ], deps = [ ":base", ":core_headers", @@ -407,6 +414,9 @@ cc_test( "//absl:windows": [], "//conditions:default": ["-pthread"], }), + tags = [ + "no_test_wasm", + ], deps = [ ":base", ":core_headers", diff --git a/absl/base/attributes.h b/absl/base/attributes.h index cc933bba..e8500224 100644 --- a/absl/base/attributes.h +++ b/absl/base/attributes.h @@ -514,8 +514,7 @@ // ABSL_ATTRIBUTE_UNUSED // -// Prevents the compiler from complaining about or optimizing away variables -// that appear unused. +// Prevents the compiler from complaining about variables that appear unused. #if ABSL_HAVE_ATTRIBUTE(unused) || (defined(__GNUC__) && !defined(__clang__)) #undef ABSL_ATTRIBUTE_UNUSED #define ABSL_ATTRIBUTE_UNUSED __attribute__((__unused__)) diff --git a/absl/base/internal/unaligned_access.h b/absl/base/internal/unaligned_access.h index 5c7517ab..f9df3b78 100644 --- a/absl/base/internal/unaligned_access.h +++ b/absl/base/internal/unaligned_access.h @@ -65,6 +65,7 @@ void __sanitizer_unaligned_store64(void *p, uint64_t v); } // extern "C" namespace absl { +namespace base_internal { inline uint16_t UnalignedLoad16(const void *p) { return __sanitizer_unaligned_load16(p); @@ -90,22 +91,27 @@ inline void UnalignedStore64(void *p, uint64_t v) { __sanitizer_unaligned_store64(p, v); } +} // namespace base_internal } // namespace absl -#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) (absl::UnalignedLoad16(_p)) -#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) (absl::UnalignedLoad32(_p)) -#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) (absl::UnalignedLoad64(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \ + (absl::base_internal::UnalignedLoad16(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \ + (absl::base_internal::UnalignedLoad32(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \ + (absl::base_internal::UnalignedLoad64(_p)) #define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \ - (absl::UnalignedStore16(_p, _val)) + (absl::base_internal::UnalignedStore16(_p, _val)) #define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \ - (absl::UnalignedStore32(_p, _val)) + (absl::base_internal::UnalignedStore32(_p, _val)) #define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \ - (absl::UnalignedStore64(_p, _val)) + (absl::base_internal::UnalignedStore64(_p, _val)) #elif defined(UNDEFINED_BEHAVIOR_SANITIZER) namespace absl { +namespace base_internal { inline uint16_t UnalignedLoad16(const void *p) { uint16_t t; @@ -131,18 +137,22 @@ inline void UnalignedStore32(void *p, uint32_t v) { memcpy(p, &v, sizeof v); } inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); } +} // namespace base_internal } // namespace absl -#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) (absl::UnalignedLoad16(_p)) -#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) (absl::UnalignedLoad32(_p)) -#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) (absl::UnalignedLoad64(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \ + (absl::base_internal::UnalignedLoad16(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \ + (absl::base_internal::UnalignedLoad32(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \ + (absl::base_internal::UnalignedLoad64(_p)) #define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \ - (absl::UnalignedStore16(_p, _val)) + (absl::base_internal::UnalignedStore16(_p, _val)) #define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \ - (absl::UnalignedStore32(_p, _val)) + (absl::base_internal::UnalignedStore32(_p, _val)) #define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \ - (absl::UnalignedStore64(_p, _val)) + (absl::base_internal::UnalignedStore64(_p, _val)) #elif defined(__x86_64__) || defined(_M_X64) || defined(__i386) || \ defined(_M_IX86) || defined(__ppc__) || defined(__PPC__) || \ @@ -199,7 +209,7 @@ inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); } // so we do that. namespace absl { -namespace internal { +namespace base_internal { struct Unaligned16Struct { uint16_t value; @@ -211,22 +221,25 @@ struct Unaligned32Struct { uint8_t dummy; // To make the size non-power-of-two. } ABSL_ATTRIBUTE_PACKED; -} // namespace internal +} // namespace base_internal } // namespace absl -#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \ - ((reinterpret_cast<const ::absl::internal::Unaligned16Struct *>(_p))->value) -#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \ - ((reinterpret_cast<const ::absl::internal::Unaligned32Struct *>(_p))->value) +#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \ + ((reinterpret_cast<const ::absl::base_internal::Unaligned16Struct *>(_p)) \ + ->value) +#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \ + ((reinterpret_cast<const ::absl::base_internal::Unaligned32Struct *>(_p)) \ + ->value) -#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \ - ((reinterpret_cast< ::absl::internal::Unaligned16Struct *>(_p))->value = \ - (_val)) -#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \ - ((reinterpret_cast< ::absl::internal::Unaligned32Struct *>(_p))->value = \ - (_val)) +#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \ + ((reinterpret_cast< ::absl::base_internal::Unaligned16Struct *>(_p)) \ + ->value = (_val)) +#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \ + ((reinterpret_cast< ::absl::base_internal::Unaligned32Struct *>(_p)) \ + ->value = (_val)) namespace absl { +namespace base_internal { inline uint64_t UnalignedLoad64(const void *p) { uint64_t t; @@ -236,11 +249,13 @@ inline uint64_t UnalignedLoad64(const void *p) { inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); } +} // namespace base_internal } // namespace absl -#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) (absl::UnalignedLoad64(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \ + (absl::base_internal::UnalignedLoad64(_p)) #define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \ - (absl::UnalignedStore64(_p, _val)) + (absl::base_internal::UnalignedStore64(_p, _val)) #else @@ -252,6 +267,7 @@ inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); } // unaligned loads and stores. namespace absl { +namespace base_internal { inline uint16_t UnalignedLoad16(const void *p) { uint16_t t; @@ -277,18 +293,22 @@ inline void UnalignedStore32(void *p, uint32_t v) { memcpy(p, &v, sizeof v); } inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); } +} // namespace base_internal } // namespace absl -#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) (absl::UnalignedLoad16(_p)) -#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) (absl::UnalignedLoad32(_p)) -#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) (absl::UnalignedLoad64(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \ + (absl::base_internal::UnalignedLoad16(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \ + (absl::base_internal::UnalignedLoad32(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \ + (absl::base_internal::UnalignedLoad64(_p)) #define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \ - (absl::UnalignedStore16(_p, _val)) + (absl::base_internal::UnalignedStore16(_p, _val)) #define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \ - (absl::UnalignedStore32(_p, _val)) + (absl::base_internal::UnalignedStore32(_p, _val)) #define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \ - (absl::UnalignedStore64(_p, _val)) + (absl::base_internal::UnalignedStore64(_p, _val)) #endif diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index 265c5ec9..f2210e3c 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -67,6 +67,7 @@ cc_test( deps = [ ":fixed_array", "//absl/base:exception_testing", + "//absl/hash:hash_testing", "//absl/memory", "@com_google_googletest//:gtest_main", ], @@ -79,6 +80,7 @@ cc_test( deps = [ ":fixed_array", "//absl/base:exception_testing", + "//absl/hash:hash_testing", "//absl/memory", "@com_google_googletest//:gtest_main", ], @@ -130,6 +132,7 @@ cc_test( "//absl/base", "//absl/base:core_headers", "//absl/base:exception_testing", + "//absl/hash:hash_testing", "//absl/memory", "//absl/strings", "@com_google_googletest//:gtest_main", @@ -146,6 +149,7 @@ cc_test( "//absl/base", "//absl/base:core_headers", "//absl/base:exception_testing", + "//absl/hash:hash_testing", "//absl/memory", "//absl/strings", "@com_google_googletest//:gtest_main", diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index 455c6f6c..9e406902 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -47,6 +47,7 @@ list(APPEND CONTAINER_INTERNAL_HEADERS "internal/unordered_set_modifiers_test.h" ) + absl_library( TARGET absl_container diff --git a/absl/container/fixed_array.h b/absl/container/fixed_array.h index d716380a..fe67dcee 100644 --- a/absl/container/fixed_array.h +++ b/absl/container/fixed_array.h @@ -358,6 +358,13 @@ class FixedArray { friend bool operator>=(const FixedArray& lhs, const FixedArray& rhs) { return !(lhs < rhs); } + + template <typename H> + friend H AbslHashValue(H h, const FixedArray& v) { + return H::combine(H::combine_contiguous(std::move(h), v.data(), v.size()), + v.size()); + } + private: // StorageElement // diff --git a/absl/container/fixed_array_test.cc b/absl/container/fixed_array_test.cc index b07ebcb6..205ff41f 100644 --- a/absl/container/fixed_array_test.cc +++ b/absl/container/fixed_array_test.cc @@ -27,6 +27,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" #include "absl/base/internal/exception_testing.h" +#include "absl/hash/hash_testing.h" #include "absl/memory/memory.h" using ::testing::ElementsAreArray; @@ -867,4 +868,5 @@ TEST(FixedArrayTest, AddressSanitizerAnnotations4) { EXPECT_DEATH(raw[21] = ThreeInts(), "container-overflow"); } #endif // ADDRESS_SANITIZER + } // namespace diff --git a/absl/container/flat_hash_map.h b/absl/container/flat_hash_map.h index 13fbfba5..9e7f6821 100644 --- a/absl/container/flat_hash_map.h +++ b/absl/container/flat_hash_map.h @@ -206,7 +206,7 @@ class flat_hash_map : public absl::container_internal::raw_hash_map< // insertion) and a bool denoting whether the insertion took place. // // std::pair<iterator,bool> insert(T&& value): - // std::pair<iterator,bool> insert(init_type&& value ): + // std::pair<iterator,bool> insert(init_type&& value): // // Inserts a moveable value into the `flat_hash_map`. Returns a pair // consisting of an iterator to the inserted element (or to the element that @@ -215,14 +215,14 @@ class flat_hash_map : public absl::container_internal::raw_hash_map< // // iterator insert(const_iterator hint, const init_type& value): // iterator insert(const_iterator hint, T&& value): - // iterator insert(const_iterator hint, init_type&& value ); + // iterator insert(const_iterator hint, init_type&& value); // // Inserts a value, using the position of `hint` as a non-binding suggestion // for where to begin the insertion search. Returns an iterator to the // inserted element, or to the existing element that prevented the // insertion. // - // void insert(InputIterator first, InputIterator last ): + // void insert(InputIterator first, InputIterator last): // // Inserts a range of values [`first`, `last`). // @@ -230,7 +230,7 @@ class flat_hash_map : public absl::container_internal::raw_hash_map< // multiple keys compare equivalently, for `flat_hash_map` we guarantee the // first match is inserted. // - // void insert(std::initializer_list<init_type> ilist ): + // void insert(std::initializer_list<init_type> ilist): // // Inserts the elements within the initializer list `ilist`. // @@ -423,12 +423,12 @@ class flat_hash_map : public absl::container_internal::raw_hash_map< // iterators are invalidated. Otherwise iterators are not affected and // references are not invalidated. Overloads are listed below. // - // T& operator[](const Key& key ): + // T& operator[](const Key& key): // // Inserts an init_type object constructed in-place if the element with the // given key does not exist. // - // T& operator[]( Key&& key ): + // T& operator[](Key&& key): // // Inserts an init_type object constructed in-place provided that an element // with the given key does not exist. diff --git a/absl/container/flat_hash_set.h b/absl/container/flat_hash_set.h index ccd03a4a..98aead1a 100644 --- a/absl/container/flat_hash_set.h +++ b/absl/container/flat_hash_set.h @@ -213,7 +213,7 @@ class flat_hash_set // inserted element, or to the existing element that prevented the // insertion. // - // void insert(InputIterator first, InputIterator last ): + // void insert(InputIterator first, InputIterator last): // // Inserts a range of values [`first`, `last`). // @@ -221,7 +221,7 @@ class flat_hash_set // multiple keys compare equivalently, for `flat_hash_set` we guarantee the // first match is inserted. // - // void insert(std::initializer_list<T> ilist ): + // void insert(std::initializer_list<T> ilist): // // Inserts the elements within the initializer list `ilist`. // diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h index 0c0ffb0b..12756bb8 100644 --- a/absl/container/inlined_vector.h +++ b/absl/container/inlined_vector.h @@ -620,6 +620,12 @@ class InlinedVector { // Returns the allocator of this inlined vector. allocator_type get_allocator() const { return allocator(); } + template <typename H> + friend H AbslHashValue(H h, const InlinedVector& v) { + return H::combine(H::combine_contiguous(std::move(h), v.data(), v.size()), + v.size()); + } + private: static_assert(N > 0, "inlined vector with nonpositive size"); diff --git a/absl/container/inlined_vector_test.cc b/absl/container/inlined_vector_test.cc index 196a1bed..08dcd3ef 100644 --- a/absl/container/inlined_vector_test.cc +++ b/absl/container/inlined_vector_test.cc @@ -31,6 +31,7 @@ #include "absl/base/internal/raw_logging.h" #include "absl/base/macros.h" #include "absl/container/internal/test_instance_tracker.h" +#include "absl/hash/hash_testing.h" #include "absl/memory/memory.h" #include "absl/strings/str_cat.h" @@ -1788,4 +1789,5 @@ TEST(AllocatorSupportTest, SizeAllocConstructor) { EXPECT_THAT(v, AllOf(SizeIs(len), Each(0))); } } + } // anonymous namespace diff --git a/absl/container/internal/hash_function_defaults.h b/absl/container/internal/hash_function_defaults.h index dd6cd8f5..1f0d794d 100644 --- a/absl/container/internal/hash_function_defaults.h +++ b/absl/container/internal/hash_function_defaults.h @@ -83,11 +83,6 @@ struct StringHashEq { } }; }; - -#if defined(HAS_GLOBAL_STRING) -template <> -struct HashEq<std::string> : StringHashEq {}; -#endif template <> struct HashEq<std::string> : StringHashEq {}; template <> diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 0c0e5906..70da90f7 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -1330,8 +1330,7 @@ class raw_hash_set { void rehash(size_t n) { if (n == 0 && capacity_ == 0) return; if (n == 0 && size_ == 0) return destroy_slots(); - auto m = NormalizeCapacity(std::max( - n, static_cast<size_t>(std::ceil(size() / kMaxLoadFactor)))); + auto m = NormalizeCapacity(std::max(n, NumSlotsFast(size()))); // n == 0 unconditionally rehashes as per the standard. if (n == 0 || m > capacity_) { resize(m); @@ -1339,7 +1338,7 @@ class raw_hash_set { } void reserve(size_t n) { - rehash(static_cast<size_t>(std::ceil(n / kMaxLoadFactor))); + rehash(NumSlotsFast(n)); } // Extension API: support for heterogeneous keys. @@ -1518,6 +1517,13 @@ class raw_hash_set { slot_type&& slot; }; + // Computes std::ceil(n / kMaxLoadFactor). Faster than calling std::ceil. + static inline size_t NumSlotsFast(size_t n) { + return static_cast<size_t>( + (n * kMaxLoadFactorDenominator + (kMaxLoadFactorNumerator - 1)) / + kMaxLoadFactorNumerator); + } + // "erases" the object from the container, except that it doesn't actually // destroy the object. It only updates all the metadata of the class. // This can be used in conjunction with Policy::transfer to move the object to @@ -1825,7 +1831,10 @@ class raw_hash_set { } // On average each group has 2 empty slot (for the vectorized case). - static constexpr float kMaxLoadFactor = 14.0 / 16.0; + static constexpr int64_t kMaxLoadFactorNumerator = 14; + static constexpr int64_t kMaxLoadFactorDenominator = 16; + static constexpr float kMaxLoadFactor = + 1.0 * kMaxLoadFactorNumerator / kMaxLoadFactorDenominator; // TODO(alkis): Investigate removing some of these fields: // - ctrl/slots can be derived from each other diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index f59a19b4..cd33a3ac 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc @@ -1916,7 +1916,7 @@ TEST(Table, EffectiveLoadFactorInts) { } // Confirm that we assert if we try to erase() end(). -TEST(Table, EraseOfEndAsserts) { +TEST(TableDeathTest, EraseOfEndAsserts) { // Use an assert with side-effects to figure out if they are actually enabled. bool assert_enabled = false; assert([&]() { @@ -1928,7 +1928,7 @@ TEST(Table, EraseOfEndAsserts) { IntTable t; // Extra simple "regexp" as regexp support is highly varied across platforms. constexpr char kDeathMsg[] = "it != end"; - EXPECT_DEATH(t.erase(t.end()), kDeathMsg); + EXPECT_DEATH_IF_SUPPORTED(t.erase(t.end()), kDeathMsg); } #ifdef ADDRESS_SANITIZER diff --git a/absl/container/node_hash_map.h b/absl/container/node_hash_map.h index 3c7de1e8..6369ec3a 100644 --- a/absl/container/node_hash_map.h +++ b/absl/container/node_hash_map.h @@ -201,7 +201,7 @@ class node_hash_map // insertion) and a `bool` denoting whether the insertion took place. // // std::pair<iterator,bool> insert(T&& value): - // std::pair<iterator,bool> insert(init_type&& value ): + // std::pair<iterator,bool> insert(init_type&& value): // // Inserts a moveable value into the `node_hash_map`. Returns a `std::pair` // consisting of an iterator to the inserted element (or to the element that @@ -210,14 +210,14 @@ class node_hash_map // // iterator insert(const_iterator hint, const init_type& value): // iterator insert(const_iterator hint, T&& value): - // iterator insert(const_iterator hint, init_type&& value ); + // iterator insert(const_iterator hint, init_type&& value); // // Inserts a value, using the position of `hint` as a non-binding suggestion // for where to begin the insertion search. Returns an iterator to the // inserted element, or to the existing element that prevented the // insertion. // - // void insert(InputIterator first, InputIterator last ): + // void insert(InputIterator first, InputIterator last): // // Inserts a range of values [`first`, `last`). // @@ -225,7 +225,7 @@ class node_hash_map // multiple keys compare equivalently, for `node_hash_map` we guarantee the // first match is inserted. // - // void insert(std::initializer_list<init_type> ilist ): + // void insert(std::initializer_list<init_type> ilist): // // Inserts the elements within the initializer list `ilist`. // @@ -413,12 +413,12 @@ class node_hash_map // all iterators are invalidated. Otherwise iterators are not affected and // references are not invalidated. Overloads are listed below. // - // T& operator[](const Key& key ): + // T& operator[](const Key& key): // // Inserts an init_type object constructed in-place if the element with the // given key does not exist. // - // T& operator[]( Key&& key ): + // T& operator[](Key&& key): // // Inserts an init_type object constructed in-place provided that an element // with the given key does not exist. diff --git a/absl/container/node_hash_set.h b/absl/container/node_hash_set.h index 927a454c..90d4ce0c 100644 --- a/absl/container/node_hash_set.h +++ b/absl/container/node_hash_set.h @@ -207,7 +207,7 @@ class node_hash_set // inserted element, or to the existing element that prevented the // insertion. // - // void insert(InputIterator first, InputIterator last ): + // void insert(InputIterator first, InputIterator last): // // Inserts a range of values [`first`, `last`). // @@ -215,7 +215,7 @@ class node_hash_set // multiple keys compare equivalently, for `node_hash_set` we guarantee the // first match is inserted. // - // void insert(std::initializer_list<T> ilist ): + // void insert(std::initializer_list<T> ilist): // // Inserts the elements within the initializer list `ilist`. // diff --git a/absl/copts.bzl b/absl/copts.bzl index 717f5a45..5c508f17 100644 --- a/absl/copts.bzl +++ b/absl/copts.bzl @@ -53,6 +53,10 @@ LLVM_FLAGS = [ "-Wno-packed", "-Wno-padded", ### + # Google style does not use unsigned integers, though STL containers + # have unsigned types. + "-Wno-sign-compare", + ### "-Wno-float-conversion", "-Wno-float-equal", "-Wno-format-nonliteral", @@ -100,6 +104,7 @@ LLVM_TEST_FLAGS = [ "-Wno-c99-extensions", "-Wno-missing-noreturn", "-Wno-missing-prototypes", + "-Wno-missing-variable-declarations", "-Wno-null-conversion", "-Wno-shadow", "-Wno-shift-sign-overflow", @@ -111,6 +116,8 @@ LLVM_TEST_FLAGS = [ "-Wno-unused-template", "-Wno-used-but-marked-unused", "-Wno-zero-as-null-pointer-constant", + # gtest depends on this GNU extension being offered. + "-Wno-gnu-zero-variadic-macro-arguments", ] MSVC_FLAGS = [ diff --git a/absl/hash/internal/city.cc b/absl/hash/internal/city.cc index 591017ab..8f72dd1b 100644 --- a/absl/hash/internal/city.cc +++ b/absl/hash/internal/city.cc @@ -129,6 +129,7 @@ uint32_t CityHash32(const char *s, size_t len) { // len > 24 uint32_t h = len, g = c1 * len, f = g; + uint32_t a0 = Rotate32(Fetch32(s + len - 4) * c1, 17) * c2; uint32_t a1 = Rotate32(Fetch32(s + len - 8) * c1, 17) * c2; uint32_t a2 = Rotate32(Fetch32(s + len - 16) * c1, 17) * c2; @@ -151,28 +152,28 @@ uint32_t CityHash32(const char *s, size_t len) { f = f * 5 + 0xe6546b64; size_t iters = (len - 1) / 20; do { - uint32_t a0 = Rotate32(Fetch32(s) * c1, 17) * c2; - uint32_t a1 = Fetch32(s + 4); - uint32_t a2 = Rotate32(Fetch32(s + 8) * c1, 17) * c2; - uint32_t a3 = Rotate32(Fetch32(s + 12) * c1, 17) * c2; - uint32_t a4 = Fetch32(s + 16); - h ^= a0; + uint32_t b0 = Rotate32(Fetch32(s) * c1, 17) * c2; + uint32_t b1 = Fetch32(s + 4); + uint32_t b2 = Rotate32(Fetch32(s + 8) * c1, 17) * c2; + uint32_t b3 = Rotate32(Fetch32(s + 12) * c1, 17) * c2; + uint32_t b4 = Fetch32(s + 16); + h ^= b0; h = Rotate32(h, 18); h = h * 5 + 0xe6546b64; - f += a1; + f += b1; f = Rotate32(f, 19); f = f * c1; - g += a2; + g += b2; g = Rotate32(g, 18); g = g * 5 + 0xe6546b64; - h ^= a3 + a1; + h ^= b3 + b1; h = Rotate32(h, 19); h = h * 5 + 0xe6546b64; - g ^= a4; + g ^= b4; g = absl::gbswap_32(g) * 5; - h += a4 * 5; + h += b4 * 5; h = absl::gbswap_32(h); - f += a0; + f += b0; PERMUTE3(f, h, g); s += 20; } while (--iters != 0); diff --git a/absl/numeric/BUILD.bazel b/absl/numeric/BUILD.bazel index f49571eb..324ce669 100644 --- a/absl/numeric/BUILD.bazel +++ b/absl/numeric/BUILD.bazel @@ -49,6 +49,7 @@ cc_test( ":int128", "//absl/base", "//absl/base:core_headers", + "//absl/hash:hash_testing", "//absl/meta:type_traits", "@com_google_googletest//:gtest_main", ], diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h index 2d131b8b..79b62a75 100644 --- a/absl/numeric/int128.h +++ b/absl/numeric/int128.h @@ -192,6 +192,12 @@ class // Returns the highest value for a 128-bit unsigned integer. friend constexpr uint128 Uint128Max(); + // Support for absl::Hash. + template <typename H> + friend H AbslHashValue(H h, uint128 v) { + return H::combine(std::move(h), Uint128High64(v), Uint128Low64(v)); + } + private: constexpr uint128(uint64_t high, uint64_t low); diff --git a/absl/numeric/int128_test.cc b/absl/numeric/int128_test.cc index 1eb3e0ec..dfe3475a 100644 --- a/absl/numeric/int128_test.cc +++ b/absl/numeric/int128_test.cc @@ -23,6 +23,7 @@ #include "gtest/gtest.h" #include "absl/base/internal/cycleclock.h" +#include "absl/hash/hash_testing.h" #include "absl/meta/type_traits.h" #if defined(_MSC_VER) && _MSC_VER == 1900 diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel index 4f6a7074..f52e9d41 100644 --- a/absl/synchronization/BUILD.bazel +++ b/absl/synchronization/BUILD.bazel @@ -88,6 +88,9 @@ cc_test( size = "small", srcs = ["barrier_test.cc"], copts = ABSL_TEST_COPTS, + tags = [ + "no_test_wasm", + ], deps = [ ":synchronization", "//absl/time", @@ -100,6 +103,9 @@ cc_test( size = "small", srcs = ["blocking_counter_test.cc"], copts = ABSL_TEST_COPTS, + tags = [ + "no_test_wasm", + ], deps = [ ":synchronization", "//absl/time", @@ -209,6 +215,7 @@ cc_test( name = "per_thread_sem_test", size = "medium", copts = ABSL_TEST_COPTS, + tags = ["no_test_wasm"], deps = [ ":per_thread_sem_test_common", ":synchronization", diff --git a/absl/time/time.h b/absl/time/time.h index 2f0fda4c..50bf971d 100644 --- a/absl/time/time.h +++ b/absl/time/time.h @@ -163,6 +163,11 @@ class Duration { Duration& operator*=(float r) { return *this *= static_cast<double>(r); } Duration& operator/=(float r) { return *this /= static_cast<double>(r); } + template <typename H> + friend H AbslHashValue(H h, Duration d) { + return H::combine(std::move(h), d.rep_hi_, d.rep_lo_); + } + private: friend constexpr int64_t time_internal::GetRepHi(Duration d); friend constexpr uint32_t time_internal::GetRepLo(Duration d); @@ -611,6 +616,11 @@ class Time { // Returns the breakdown of this instant in the given TimeZone. Breakdown In(TimeZone tz) const; + template <typename H> + friend H AbslHashValue(H h, Time t) { + return H::combine(std::move(h), t.rep_); + } + private: friend constexpr Time time_internal::FromUnixDuration(Duration d); friend constexpr Duration time_internal::ToUnixDuration(Time t); @@ -1059,6 +1069,11 @@ class TimeZone { std::string name() const { return cz_.name(); } + template <typename H> + friend H AbslHashValue(H h, TimeZone tz) { + return H::combine(std::move(h), tz.cz_); + } + private: friend bool operator==(TimeZone a, TimeZone b) { return a.cz_ == b.cz_; } friend bool operator!=(TimeZone a, TimeZone b) { return a.cz_ != b.cz_; } diff --git a/absl/types/BUILD.bazel b/absl/types/BUILD.bazel index 7841a97d..32f690c9 100644 --- a/absl/types/BUILD.bazel +++ b/absl/types/BUILD.bazel @@ -136,6 +136,7 @@ cc_test( "//absl/base:exception_testing", "//absl/container:fixed_array", "//absl/container:inlined_vector", + "//absl/hash:hash_testing", "//absl/strings", "@com_google_googletest//:gtest_main", ], @@ -153,6 +154,7 @@ cc_test( "//absl/base:exception_testing", "//absl/container:fixed_array", "//absl/container:inlined_vector", + "//absl/hash:hash_testing", "//absl/strings", "@com_google_googletest//:gtest_main", ], diff --git a/absl/types/span.h b/absl/types/span.h index 3359ce50..911af0c5 100644 --- a/absl/types/span.h +++ b/absl/types/span.h @@ -485,6 +485,13 @@ class Span { : (base_internal::ThrowStdOutOfRange("pos > size()"), Span()); } + // Support for absl::Hash. + template <typename H> + friend H AbslHashValue(H h, Span v) { + return H::combine(H::combine_contiguous(std::move(h), v.data(), v.size()), + v.size()); + } + private: pointer ptr_; size_type len_; diff --git a/absl/types/span_test.cc b/absl/types/span_test.cc index fbce7e87..bd739ff2 100644 --- a/absl/types/span_test.cc +++ b/absl/types/span_test.cc @@ -29,6 +29,7 @@ #include "absl/base/internal/exception_testing.h" #include "absl/container/fixed_array.h" #include "absl/container/inlined_vector.h" +#include "absl/hash/hash_testing.h" #include "absl/strings/str_cat.h" namespace { |