diff options
author | Abseil Team <absl-team@google.com> | 2021-02-17 09:48:49 -0800 |
---|---|---|
committer | Andy Getz <durandal@google.com> | 2021-02-18 02:38:12 -0500 |
commit | b315753c0b8b4aa4e3e1479375eddb518393bab6 (patch) | |
tree | 07255ad54a6555677f3b54f2b0c7bcec9c320be5 /absl/random | |
parent | 143a27800eb35f4568b9be51647726281916aac9 (diff) |
Export of internal Abseil changes
--
2247e59ee5696e61c7cb24dce479db572980032d by Derek Mauro <dmauro@google.com>:
Ensure ThreadIdentity::WaiterState data has the correct alignment
PiperOrigin-RevId: 357969866
--
79bb81a2e6723b186536ad4b4f25cd7ee83f3e72 by Laramie Leavitt <lar@google.com>:
Rework absl::MockingBitGen internal mock registry.
Use a virtual base class with template-specialized derived classes to implement match method rather than taking the address of a function specialization and using casts everywhere.
This combines several of the previously type-erased pointers into a single object, eliminates the separate cleanup container previously used, and eliminates some gratuitous static_cast<>s.
PiperOrigin-RevId: 357827438
--
a2eb53d002c9b376360a70b2b0f6a18a1de1e16f by Todd Lipcon <tlipcon@google.com>:
Reduce runtime of sequence_lock_test
PiperOrigin-RevId: 357785571
--
dd1175ff13b560f01c4aaa64bc6759a5300e391c by Abseil Team <absl-team@google.com>:
Don't assume that compiling for Windows means that MSVC or clang-cl is being used.
PiperOrigin-RevId: 357760052
--
251a9cbede52e729b3a25911b6e225b779c285a8 by Andy Getzendanner <durandal@google.com>:
Internal change.
PiperOrigin-RevId: 357702979
GitOrigin-RevId: 2247e59ee5696e61c7cb24dce479db572980032d
Change-Id: Icd366d3775d88d623695209b5f328dbd69f01d27
Diffstat (limited to 'absl/random')
-rw-r--r-- | absl/random/internal/BUILD.bazel | 9 | ||||
-rw-r--r-- | absl/random/mocking_bit_gen.h | 87 |
2 files changed, 49 insertions, 47 deletions
diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index 4e778aee..612b1505 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -75,7 +75,8 @@ cc_library( ], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS + select({ - "//absl:windows": ["-DEFAULTLIB:bcrypt.lib"], + "//absl:msvc_compiler": ["-DEFAULTLIB:bcrypt.lib"], + "//absl:clang-cl_compiler": ["-DEFAULTLIB:bcrypt.lib"], "//conditions:default": [], }), deps = [ @@ -98,7 +99,8 @@ cc_library( ], copts = ABSL_DEFAULT_COPTS, linkopts = select({ - "//absl:windows": [], + "//absl:msvc_compiler": [], + "//absl:clang-cl_compiler": [], "//absl:wasm": [], "//conditions:default": ["-pthread"], }) + ABSL_DEFAULT_LINKOPTS, @@ -325,7 +327,8 @@ cc_library( "randen_hwaes.h", ], copts = ABSL_DEFAULT_COPTS + ABSL_RANDOM_RANDEN_COPTS + select({ - "//absl:windows": [], + "//absl:msvc_compiler": [], + "//absl:clang-cl_compiler": [], "//conditions:default": ["-Wno-pass-failed"], }), linkopts = ABSL_DEFAULT_LINKOPTS, diff --git a/absl/random/mocking_bit_gen.h b/absl/random/mocking_bit_gen.h index 6d2f2c83..6815ca44 100644 --- a/absl/random/mocking_bit_gen.h +++ b/absl/random/mocking_bit_gen.h @@ -104,10 +104,7 @@ class BitGenRef; class MockingBitGen { public: MockingBitGen() = default; - - ~MockingBitGen() { - for (const auto& del : deleters_) del(); - } + ~MockingBitGen() = default; // URBG interface using result_type = absl::BitGen::result_type; @@ -117,14 +114,6 @@ class MockingBitGen { result_type operator()() { return gen_(); } private: - using match_impl_fn = void (*)(void* mock_fn, void* t_erased_arg_tuple, - void* t_erased_result); - - struct MockData { - void* mock_fn = nullptr; - match_impl_fn match_impl = nullptr; - }; - // GetMockFnType returns the testing::MockFunction for a result and tuple. // This method only exists for type deduction and is otherwise unimplemented. template <typename ResultT, typename... Args> @@ -136,17 +125,46 @@ class MockingBitGen { // NOTE: MockFnCaller is essentially equivalent to the lambda: // [fn](auto... args) { return fn->Call(std::move(args)...)} // however that fails to build on some supported platforms. - template <typename ResultT, typename MockFnType, typename Tuple> + template <typename MockFnType, typename ResultT, typename Tuple> struct MockFnCaller; + // specialization for std::tuple. - template <typename ResultT, typename MockFnType, typename... Args> - struct MockFnCaller<ResultT, MockFnType, std::tuple<Args...>> { + template <typename MockFnType, typename ResultT, typename... Args> + struct MockFnCaller<MockFnType, ResultT, std::tuple<Args...>> { MockFnType* fn; inline ResultT operator()(Args... args) { return fn->Call(std::move(args)...); } }; + // FunctionHolder owns a particular ::testing::MockFunction associated with + // a mocked type signature, and implement the type-erased Apply call, which + // applies type-erased arguments to the mock. + class FunctionHolder { + public: + virtual ~FunctionHolder() = default; + + // Call is a dispatch function which converts the + // generic type-erased parameters into a specific mock invocation call. + virtual void Apply(/*ArgTupleT*/ void* args_tuple, + /*ResultT*/ void* result) = 0; + }; + + template <typename MockFnType, typename ResultT, typename ArgTupleT> + class FunctionHolderImpl final : public FunctionHolder { + public: + void Apply(void* args_tuple, void* result) override { + // Requires tuple_args to point to a ArgTupleT, which is a + // std::tuple<Args...> used to invoke the mock function. Requires result + // to point to a ResultT, which is the result of the call. + *static_cast<ResultT*>(result) = + absl::apply(MockFnCaller<MockFnType, ResultT, ArgTupleT>{&mock_fn_}, + *static_cast<ArgTupleT*>(args_tuple)); + } + + MockFnType mock_fn_; + }; + // MockingBitGen::RegisterMock // // RegisterMock<ResultT, ArgTupleT>(FastTypeIdType) is the main extension @@ -161,33 +179,14 @@ class MockingBitGen { auto RegisterMock(base_internal::FastTypeIdType type) -> decltype(GetMockFnType(std::declval<ResultT>(), std::declval<ArgTupleT>()))& { - using MockFnType = decltype( - GetMockFnType(std::declval<ResultT>(), std::declval<ArgTupleT>())); + using MockFnType = decltype(GetMockFnType(std::declval<ResultT>(), + std::declval<ArgTupleT>())); + using ImplT = FunctionHolderImpl<MockFnType, ResultT, ArgTupleT>; auto& mock = mocks_[type]; - if (!mock.mock_fn) { - auto* mock_fn = new MockFnType; - mock.mock_fn = mock_fn; - mock.match_impl = &MatchImpl<ResultT, ArgTupleT>; - deleters_.emplace_back([mock_fn] { delete mock_fn; }); + if (!mock) { + mock = absl::make_unique<ImplT>(); } - return *static_cast<MockFnType*>(mock.mock_fn); - } - - // MockingBitGen::MatchImpl<> is a dispatch function which converts the - // generic type-erased parameters into a specific mock invocation call. - // Requires tuple_args to point to a ArgTupleT, which is a std::tuple<Args...> - // used to invoke the mock function. - // Requires result to point to a ResultT, which is the result of the call. - template <typename ResultT, typename ArgTupleT> - static void MatchImpl(/*MockFnType<ResultT, Args...>*/ void* mock_fn, - /*ArgTupleT*/ void* args_tuple, - /*ResultT*/ void* result) { - using MockFnType = decltype( - GetMockFnType(std::declval<ResultT>(), std::declval<ArgTupleT>())); - *static_cast<ResultT*>(result) = absl::apply( - MockFnCaller<ResultT, MockFnType, ArgTupleT>{ - static_cast<MockFnType*>(mock_fn)}, - *static_cast<ArgTupleT*>(args_tuple)); + return static_cast<ImplT*>(mock.get())->mock_fn_; } // MockingBitGen::InvokeMock @@ -206,13 +205,13 @@ class MockingBitGen { // Trigger a mock, if there exists one that matches `param`. auto it = mocks_.find(type); if (it == mocks_.end()) return false; - auto* mock_data = static_cast<MockData*>(&it->second); - mock_data->match_impl(mock_data->mock_fn, args_tuple, result); + it->second->Apply(args_tuple, result); return true; } - absl::flat_hash_map<base_internal::FastTypeIdType, MockData> mocks_; - std::vector<std::function<void()>> deleters_; + absl::flat_hash_map<base_internal::FastTypeIdType, + std::unique_ptr<FunctionHolder>> + mocks_; absl::BitGen gen_; template <typename> |