From fbf0fdab62ac6fcc72b935d505f6837e0884fdc3 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 20 Aug 2020 08:54:55 -0700 Subject: Export of internal Abseil changes -- 9f746b79e16d36dba908ed9e2a586d890fe54acc by Derek Mauro : Remove the Bazel mirror URL that we use in our WORKSPACE file This doesn't appear to be supported. We use --distdir caching in our tests. PiperOrigin-RevId: 327634738 -- e1f6f54830c415fc8bb8dc14483fae4cf9713d75 by Abseil Team : Removing comments following license() rules as they are rarely useful, redundant with LICENSE files, and tend to fall out of date. PiperOrigin-RevId: 327504063 -- b59c076638a57a74a3f8475f1dee8b536e32a15f by Gennadiy Rozental : Change GetAllFlags API to return a collection of mutable flag handles. This will make this interface on par with FindCommandLineFlag and allow to call CommandLineFlag::ParseFrom on the handle returned by GetAllFlags. PiperOrigin-RevId: 327499084 -- bbf56b3c4a1d908d95e5a52aba38b1984151efff by Gennadiy Rozental : Make raw_hash_set compile when AllocTraits::propagate_on_container_swap is false. PiperOrigin-RevId: 327371107 -- 837f62c85ea65c1d6b847a75816198c625fe62ff by Abseil Team : On macOS, `mem_alloc` is defined like this: rpc/types.h:86:#define mem_alloc(bsize) calloc(1, bsize) So if that file is included before container_memory.h, the variable mem_alloc may never get defined. This is fixed by using a different name. PiperOrigin-RevId: 327360224 -- aa8f5528382c0d01239ce75b645723aaf7e1ef46 by Gennadiy Rozental : Release of absl::GetAllFlags API. PiperOrigin-RevId: 327275943 GitOrigin-RevId: 9f746b79e16d36dba908ed9e2a586d890fe54acc Change-Id: I99c5c87dd1712bf8df9a52397b0c1e400a3c3447 --- absl/algorithm/BUILD.bazel | 2 +- absl/base/BUILD.bazel | 2 +- absl/container/BUILD.bazel | 2 +- absl/container/internal/container_memory.h | 14 +++-- absl/container/internal/raw_hash_set.h | 28 ++++++--- .../internal/raw_hash_set_allocator_test.cc | 71 ++++++++++++++++++++++ absl/debugging/BUILD.bazel | 2 +- absl/flags/BUILD.bazel | 4 +- absl/flags/CMakeLists.txt | 4 +- absl/flags/reflection.cc | 10 +++ absl/flags/reflection.h | 7 ++- absl/flags/reflection_test.cc | 31 ++++++++++ absl/functional/BUILD.bazel | 2 +- absl/hash/BUILD.bazel | 2 +- absl/memory/BUILD.bazel | 2 +- absl/meta/BUILD.bazel | 2 +- absl/numeric/BUILD.bazel | 2 +- absl/random/internal/BUILD.bazel | 2 +- absl/status/BUILD.bazel | 2 +- absl/synchronization/BUILD.bazel | 2 +- absl/time/BUILD.bazel | 2 +- absl/types/BUILD.bazel | 2 +- absl/utility/BUILD.bazel | 2 +- 23 files changed, 168 insertions(+), 31 deletions(-) (limited to 'absl') diff --git a/absl/algorithm/BUILD.bazel b/absl/algorithm/BUILD.bazel index 229cd713..a3002b7d 100644 --- a/absl/algorithm/BUILD.bazel +++ b/absl/algorithm/BUILD.bazel @@ -24,7 +24,7 @@ load( package(default_visibility = ["//visibility:public"]) -licenses(["notice"]) # Apache 2.0 +licenses(["notice"]) cc_library( name = "algorithm", diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index 2c4887b3..9d96abeb 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -24,7 +24,7 @@ load( package(default_visibility = ["//visibility:public"]) -licenses(["notice"]) # Apache 2.0 +licenses(["notice"]) cc_library( name = "atomic_hook", diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index cca5d441..8e72ad03 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -24,7 +24,7 @@ load( package(default_visibility = ["//visibility:public"]) -licenses(["notice"]) # Apache 2.0 +licenses(["notice"]) cc_library( name = "compressed_tuple", diff --git a/absl/container/internal/container_memory.h b/absl/container/internal/container_memory.h index d02c576d..e67529ec 100644 --- a/absl/container/internal/container_memory.h +++ b/absl/container/internal/container_memory.h @@ -57,8 +57,11 @@ void* Allocate(Alloc* alloc, size_t n) { using M = AlignedType; using A = typename absl::allocator_traits::template rebind_alloc; using AT = typename absl::allocator_traits::template rebind_traits; - A mem_alloc(*alloc); - void* p = AT::allocate(mem_alloc, (n + sizeof(M) - 1) / sizeof(M)); + // On macOS, "mem_alloc" is a #define with one argument defined in + // rpc/types.h, so we can't name the variable "mem_alloc" and initialize it + // with the "foo(bar)" syntax. + A my_mem_alloc(*alloc); + void* p = AT::allocate(my_mem_alloc, (n + sizeof(M) - 1) / sizeof(M)); assert(reinterpret_cast(p) % Alignment == 0 && "allocator does not respect alignment"); return p; @@ -73,8 +76,11 @@ void Deallocate(Alloc* alloc, void* p, size_t n) { using M = AlignedType; using A = typename absl::allocator_traits::template rebind_alloc; using AT = typename absl::allocator_traits::template rebind_traits; - A mem_alloc(*alloc); - AT::deallocate(mem_alloc, static_cast(p), + // On macOS, "mem_alloc" is a #define with one argument defined in + // rpc/types.h, so we can't name the variable "mem_alloc" and initialize it + // with the "foo(bar)" syntax. + A my_mem_alloc(*alloc); + AT::deallocate(my_mem_alloc, static_cast(p), (n + sizeof(M) - 1) / sizeof(M)); } diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 48a1a8c6..130da13c 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -122,6 +122,16 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace container_internal { +template +void SwapAlloc(AllocType& lhs, AllocType& rhs, + std::true_type /* propagate_on_container_swap */) { + using std::swap; + swap(lhs, rhs); +} +template +void SwapAlloc(AllocType& /*lhs*/, AllocType& /*rhs*/, + std::false_type /* propagate_on_container_swap */) {} + template class probe_seq { public: @@ -169,10 +179,14 @@ struct IsDecomposable< // TODO(alkis): Switch to std::is_nothrow_swappable when gcc/clang supports it. template -constexpr bool IsNoThrowSwappable() { +constexpr bool IsNoThrowSwappable(std::true_type = {} /* is_swappable */) { using std::swap; return noexcept(swap(std::declval(), std::declval())); } +template +constexpr bool IsNoThrowSwappable(std::false_type /* is_swappable */) { + return false; +} template int TrailingZeros(T x) { @@ -1231,8 +1245,8 @@ class raw_hash_set { void swap(raw_hash_set& that) noexcept( IsNoThrowSwappable() && IsNoThrowSwappable() && - (!AllocTraits::propagate_on_container_swap::value || - IsNoThrowSwappable())) { + IsNoThrowSwappable( + typename AllocTraits::propagate_on_container_swap{})) { using std::swap; swap(ctrl_, that.ctrl_); swap(slots_, that.slots_); @@ -1242,12 +1256,8 @@ class raw_hash_set { swap(hash_ref(), that.hash_ref()); swap(eq_ref(), that.eq_ref()); swap(infoz_, that.infoz_); - if (AllocTraits::propagate_on_container_swap::value) { - swap(alloc_ref(), that.alloc_ref()); - } else { - // If the allocators do not compare equal it is officially undefined - // behavior. We choose to do nothing. - } + SwapAlloc(alloc_ref(), that.alloc_ref(), + typename AllocTraits::propagate_on_container_swap{}); } void rehash(size_t n) { diff --git a/absl/container/internal/raw_hash_set_allocator_test.cc b/absl/container/internal/raw_hash_set_allocator_test.cc index 7ac4b9f7..1a036085 100644 --- a/absl/container/internal/raw_hash_set_allocator_test.cc +++ b/absl/container/internal/raw_hash_set_allocator_test.cc @@ -424,6 +424,77 @@ TEST_F(PropagateOnAll, Swap) { EXPECT_EQ(0, it->num_copies()); } +// This allocator is similar to std::pmr::polymorphic_allocator. +// Note the disabled assignment. +template +class PAlloc { + template + friend class PAlloc; + + public: + // types + using value_type = T; + + // traits + using propagate_on_container_swap = std::false_type; + + PAlloc() noexcept = default; + explicit PAlloc(size_t id) noexcept : id_(id) {} + PAlloc(const PAlloc&) noexcept = default; + PAlloc& operator=(const PAlloc&) noexcept = delete; + + template + PAlloc(const PAlloc& that) noexcept : id_(that.id_) {} // NOLINT + + template + struct rebind { + using other = PAlloc; + }; + + constexpr PAlloc select_on_container_copy_construction() const { return {}; } + + // public member functions + T* allocate(size_t) { return new T; } + void deallocate(T* p, size_t) { delete p; } + + friend bool operator==(const PAlloc& a, const PAlloc& b) { + return a.id_ == b.id_; + } + friend bool operator!=(const PAlloc& a, const PAlloc& b) { return !(a == b); } + + private: + size_t id_ = std::numeric_limits::max(); +}; + +TEST(NoPropagateOn, Swap) { + using PA = PAlloc; + using Table = raw_hash_set, PA>; + + Table t1(PA{1}), t2(PA{2}); + swap(t1, t2); + EXPECT_EQ(t1.get_allocator(), PA(1)); + EXPECT_EQ(t2.get_allocator(), PA(2)); +} + +TEST(NoPropagateOn, CopyConstruct) { + using PA = PAlloc; + using Table = raw_hash_set, PA>; + + Table t1(PA{1}), t2(t1); + EXPECT_EQ(t1.get_allocator(), PA(1)); + EXPECT_EQ(t2.get_allocator(), PA()); +} + +TEST(NoPropagateOn, Assignment) { + using PA = PAlloc; + using Table = raw_hash_set, PA>; + + Table t1(PA{1}), t2(PA{2}); + t1 = t2; + EXPECT_EQ(t1.get_allocator(), PA(1)); + EXPECT_EQ(t2.get_allocator(), PA(2)); +} + } // namespace } // namespace container_internal ABSL_NAMESPACE_END diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel index 9098ca4a..86faac9b 100644 --- a/absl/debugging/BUILD.bazel +++ b/absl/debugging/BUILD.bazel @@ -26,7 +26,7 @@ package( default_visibility = ["//visibility:public"], ) -licenses(["notice"]) # Apache 2.0 +licenses(["notice"]) cc_library( name = "stacktrace", diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel index 92bd4f15..62fb9a8b 100644 --- a/absl/flags/BUILD.bazel +++ b/absl/flags/BUILD.bazel @@ -24,7 +24,7 @@ load( package(default_visibility = ["//visibility:public"]) -licenses(["notice"]) # Apache 2.0 +licenses(["notice"]) cc_library( name = "path_util", @@ -179,6 +179,7 @@ cc_library( ":private_handle_accessor", "//absl/base:config", "//absl/base:core_headers", + "//absl/container:flat_hash_map", "//absl/strings", "//absl/synchronization", ], @@ -464,6 +465,7 @@ cc_test( ":flag", ":marshalling", ":reflection", + ":usage_internal", "//absl/memory", "//absl/strings", "@com_google_googletest//:gtest_main", diff --git a/absl/flags/CMakeLists.txt b/absl/flags/CMakeLists.txt index 343774de..28bd5a85 100644 --- a/absl/flags/CMakeLists.txt +++ b/absl/flags/CMakeLists.txt @@ -165,6 +165,7 @@ absl_cc_library( absl::flags_config absl::strings absl::synchronization + absl::flat_hash_map ) # Internal-only target, do not depend on directly. @@ -407,9 +408,10 @@ absl_cc_test( absl::flags_commandlineflag_internal absl::flags absl::flags_reflection + absl::flags_usage absl::memory absl::strings - gtest_main + gmock_main ) absl_cc_test( diff --git a/absl/flags/reflection.cc b/absl/flags/reflection.cc index e4145b34..d7060221 100644 --- a/absl/flags/reflection.cc +++ b/absl/flags/reflection.cc @@ -303,5 +303,15 @@ CommandLineFlag* FindCommandLineFlag(absl::string_view name) { return registry.FindFlagLocked(name); } +// -------------------------------------------------------------------- + +absl::flat_hash_map GetAllFlags() { + absl::flat_hash_map res; + flags_internal::ForEachFlag([&](CommandLineFlag& flag) { + res.insert({flag.Name(), &flag}); + }); + return res; +} + ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/flags/reflection.h b/absl/flags/reflection.h index 045f9784..4ce0ab6c 100644 --- a/absl/flags/reflection.h +++ b/absl/flags/reflection.h @@ -26,6 +26,7 @@ #include #include "absl/base/config.h" +#include "absl/container/flat_hash_map.h" #include "absl/flags/commandlineflag.h" #include "absl/flags/internal/commandlineflag.h" @@ -40,7 +41,11 @@ class FlagSaverImpl; // Returns the reflection handle of an Abseil flag of the specified name, or // `nullptr` if not found. This function will emit a warning if the name of a // 'retired' flag is specified. -CommandLineFlag* FindCommandLineFlag(absl::string_view name); +absl::CommandLineFlag* FindCommandLineFlag(absl::string_view name); + +// Returns current state of the Flags registry in a form of mapping from flag +// name to a flag reflection handle. +absl::flat_hash_map GetAllFlags(); //------------------------------------------------------------------------------ // FlagSaver diff --git a/absl/flags/reflection_test.cc b/absl/flags/reflection_test.cc index 2da0a0ec..1a1dcb4a 100644 --- a/absl/flags/reflection_test.cc +++ b/absl/flags/reflection_test.cc @@ -18,7 +18,9 @@ #include #include +#include "gmock/gmock.h" #include "gtest/gtest.h" +#include "absl/flags/declare.h" #include "absl/flags/flag.h" #include "absl/flags/internal/commandlineflag.h" #include "absl/flags/marshalling.h" @@ -30,6 +32,8 @@ ABSL_FLAG(int, int_flag, 1, "int_flag help"); ABSL_FLAG(std::string, string_flag, "dflt", "string_flag help"); ABSL_RETIRED_FLAG(bool, bool_retired_flag, false, "bool_retired_flag help"); +ABSL_DECLARE_FLAG(bool, help); + namespace { namespace flags = absl::flags_internal; @@ -61,6 +65,33 @@ TEST_F(ReflectionTest, TestFindCommandLineFlag) { // -------------------------------------------------------------------- +TEST_F(ReflectionTest, TestGetAllFlags) { + (void)absl::GetFlag(FLAGS_help); // Force linking of usage flags. + + auto all_flags = absl::GetAllFlags(); + EXPECT_NE(all_flags.find("int_flag"), all_flags.end()); + EXPECT_NE(all_flags.find("bool_retired_flag"), all_flags.end()); + EXPECT_NE(all_flags.find("help"), all_flags.end()); + EXPECT_EQ(all_flags.find("some_undefined_flag"), all_flags.end()); + + std::vector flag_names_first_attempt; + auto all_flags_1 = absl::GetAllFlags(); + for (auto f : all_flags_1) { + flag_names_first_attempt.push_back(f.first); + } + + std::vector flag_names_second_attempt; + auto all_flags_2 = absl::GetAllFlags(); + for (auto f : all_flags_2) { + flag_names_second_attempt.push_back(f.first); + } + + EXPECT_THAT(flag_names_first_attempt, + ::testing::UnorderedElementsAreArray(flag_names_second_attempt)); +} + +// -------------------------------------------------------------------- + struct CustomUDT { CustomUDT() : a(1), b(1) {} CustomUDT(int a_, int b_) : a(a_), b(b_) {} diff --git a/absl/functional/BUILD.bazel b/absl/functional/BUILD.bazel index 432546ce..ebd9b99b 100644 --- a/absl/functional/BUILD.bazel +++ b/absl/functional/BUILD.bazel @@ -24,7 +24,7 @@ load( package(default_visibility = ["//visibility:public"]) -licenses(["notice"]) # Apache 2.0 +licenses(["notice"]) cc_library( name = "bind_front", diff --git a/absl/hash/BUILD.bazel b/absl/hash/BUILD.bazel index 6c77f1a1..5b1e2d01 100644 --- a/absl/hash/BUILD.bazel +++ b/absl/hash/BUILD.bazel @@ -24,7 +24,7 @@ load( package(default_visibility = ["//visibility:public"]) -licenses(["notice"]) # Apache 2.0 +licenses(["notice"]) cc_library( name = "hash", diff --git a/absl/memory/BUILD.bazel b/absl/memory/BUILD.bazel index 2ba9d7cb..d2824a05 100644 --- a/absl/memory/BUILD.bazel +++ b/absl/memory/BUILD.bazel @@ -24,7 +24,7 @@ load( package(default_visibility = ["//visibility:public"]) -licenses(["notice"]) # Apache 2.0 +licenses(["notice"]) cc_library( name = "memory", diff --git a/absl/meta/BUILD.bazel b/absl/meta/BUILD.bazel index c06d2d97..5585fcca 100644 --- a/absl/meta/BUILD.bazel +++ b/absl/meta/BUILD.bazel @@ -24,7 +24,7 @@ load( package(default_visibility = ["//visibility:public"]) -licenses(["notice"]) # Apache 2.0 +licenses(["notice"]) cc_library( name = "type_traits", diff --git a/absl/numeric/BUILD.bazel b/absl/numeric/BUILD.bazel index da3af4d0..f808f5da 100644 --- a/absl/numeric/BUILD.bazel +++ b/absl/numeric/BUILD.bazel @@ -22,7 +22,7 @@ load( package(default_visibility = ["//visibility:public"]) -licenses(["notice"]) # Apache 2.0 +licenses(["notice"]) cc_library( name = "int128", diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index 000cc45b..8485e28b 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -30,7 +30,7 @@ package(default_visibility = [ "//absl/random:__pkg__", ]) -licenses(["notice"]) # Apache 2.0 +licenses(["notice"]) cc_library( name = "traits", diff --git a/absl/status/BUILD.bazel b/absl/status/BUILD.bazel index c4c5e497..81fa46c2 100644 --- a/absl/status/BUILD.bazel +++ b/absl/status/BUILD.bazel @@ -26,7 +26,7 @@ load( package(default_visibility = ["//visibility:public"]) -licenses(["notice"]) # Apache 2.0 +licenses(["notice"]) cc_library( name = "status", diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel index 1a5c02ab..4d4d6806 100644 --- a/absl/synchronization/BUILD.bazel +++ b/absl/synchronization/BUILD.bazel @@ -24,7 +24,7 @@ load( package(default_visibility = ["//visibility:public"]) -licenses(["notice"]) # Apache 2.0 +licenses(["notice"]) # Internal data structure for efficiently detecting mutex dependency cycles cc_library( diff --git a/absl/time/BUILD.bazel b/absl/time/BUILD.bazel index 1d69f598..991241a0 100644 --- a/absl/time/BUILD.bazel +++ b/absl/time/BUILD.bazel @@ -24,7 +24,7 @@ load( package(default_visibility = ["//visibility:public"]) -licenses(["notice"]) # Apache 2.0 +licenses(["notice"]) cc_library( name = "time", diff --git a/absl/types/BUILD.bazel b/absl/types/BUILD.bazel index 102affaf..83be9360 100644 --- a/absl/types/BUILD.bazel +++ b/absl/types/BUILD.bazel @@ -23,7 +23,7 @@ load( package(default_visibility = ["//visibility:public"]) -licenses(["notice"]) # Apache 2.0 +licenses(["notice"]) cc_library( name = "any", diff --git a/absl/utility/BUILD.bazel b/absl/utility/BUILD.bazel index 6881f939..02b2c407 100644 --- a/absl/utility/BUILD.bazel +++ b/absl/utility/BUILD.bazel @@ -24,7 +24,7 @@ load( package(default_visibility = ["//visibility:public"]) -licenses(["notice"]) # Apache 2.0 +licenses(["notice"]) cc_library( name = "utility", -- cgit v1.2.3