diff options
author | Colin Cross <ccross@android.com> | 2022-04-13 03:15:00 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2022-04-13 03:15:00 +0000 |
commit | 6c9587948173932b64d97c288a947e43d2a2ac14 (patch) | |
tree | 2ce94d7f0804ccb77d1fa9b2a1bca00eecdff1e2 /third_party/abseil-cpp/absl/random/mocking_bit_gen.h | |
parent | f60eaea2240ba9e1c508e8e0c91d39ee9fc47be5 (diff) | |
parent | 43d8f56cdc20240b37c36bf417dd0d6999bce738 (diff) | |
download | webrtc-android13-qpr2-s1-release.tar.gz |
Merge changes I0ab600cd,I1e74c64a am: 798f3afdf6 am: 2f9c4b2c3b am: a9167328fc am: 7563023510 am: 43d8f56cdcandroid-13.0.0_r83android-13.0.0_r82android-13.0.0_r81android-13.0.0_r80android-13.0.0_r79android-13.0.0_r78android-13.0.0_r77android-13.0.0_r76android-13.0.0_r75android-13.0.0_r74android-13.0.0_r73android-13.0.0_r72android-13.0.0_r71android-13.0.0_r70android-13.0.0_r69android-13.0.0_r68android-13.0.0_r67android-13.0.0_r66android-13.0.0_r65android-13.0.0_r64android-13.0.0_r63android-13.0.0_r62android-13.0.0_r61android-13.0.0_r60android-13.0.0_r59android-13.0.0_r58android-13.0.0_r56android-13.0.0_r54android-13.0.0_r53android-13.0.0_r52android-13.0.0_r51android-13.0.0_r50android-13.0.0_r49android-13.0.0_r48android-13.0.0_r47android-13.0.0_r46android-13.0.0_r45android-13.0.0_r44android-13.0.0_r43android-13.0.0_r42android-13.0.0_r41android-13.0.0_r40android-13.0.0_r39android-13.0.0_r38android-13.0.0_r37android-13.0.0_r36android-13.0.0_r35android-13.0.0_r34android-13.0.0_r33android-13.0.0_r32android13-qpr3-s9-releaseandroid13-qpr3-s8-releaseandroid13-qpr3-s7-releaseandroid13-qpr3-s6-releaseandroid13-qpr3-s5-releaseandroid13-qpr3-s4-releaseandroid13-qpr3-s3-releaseandroid13-qpr3-s2-releaseandroid13-qpr3-s14-releaseandroid13-qpr3-s13-releaseandroid13-qpr3-s12-releaseandroid13-qpr3-s11-releaseandroid13-qpr3-s10-releaseandroid13-qpr3-s1-releaseandroid13-qpr3-releaseandroid13-qpr3-c-s8-releaseandroid13-qpr3-c-s7-releaseandroid13-qpr3-c-s6-releaseandroid13-qpr3-c-s5-releaseandroid13-qpr3-c-s4-releaseandroid13-qpr3-c-s3-releaseandroid13-qpr3-c-s2-releaseandroid13-qpr3-c-s12-releaseandroid13-qpr3-c-s11-releaseandroid13-qpr3-c-s10-releaseandroid13-qpr3-c-s1-releaseandroid13-qpr2-s9-releaseandroid13-qpr2-s8-releaseandroid13-qpr2-s7-releaseandroid13-qpr2-s6-releaseandroid13-qpr2-s5-releaseandroid13-qpr2-s3-releaseandroid13-qpr2-s2-releaseandroid13-qpr2-s12-releaseandroid13-qpr2-s11-releaseandroid13-qpr2-s10-releaseandroid13-qpr2-s1-releaseandroid13-qpr2-releaseandroid13-qpr2-b-s1-releaseandroid13-d4-s2-releaseandroid13-d4-s1-releaseandroid13-d4-release
Original change: https://android-review.googlesource.com/c/platform/external/webrtc/+/2062410
Change-Id: I1aa9f459b825711b800cc65782979943a9151ec7
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'third_party/abseil-cpp/absl/random/mocking_bit_gen.h')
-rw-r--r-- | third_party/abseil-cpp/absl/random/mocking_bit_gen.h | 204 |
1 files changed, 124 insertions, 80 deletions
diff --git a/third_party/abseil-cpp/absl/random/mocking_bit_gen.h b/third_party/abseil-cpp/absl/random/mocking_bit_gen.h index 36cef91113..7b2b80eb35 100644 --- a/third_party/abseil-cpp/absl/random/mocking_bit_gen.h +++ b/third_party/abseil-cpp/absl/random/mocking_bit_gen.h @@ -33,17 +33,16 @@ #include <memory> #include <tuple> #include <type_traits> -#include <typeindex> -#include <typeinfo> #include <utility> #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "absl/base/internal/fast_type_id.h" #include "absl/container/flat_hash_map.h" #include "absl/meta/type_traits.h" #include "absl/random/distributions.h" #include "absl/random/internal/distribution_caller.h" -#include "absl/random/internal/mocking_bit_gen_base.h" +#include "absl/random/random.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_join.h" #include "absl/types/span.h" @@ -54,11 +53,12 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace random_internal { - -template <typename, typename> -struct MockSingleOverload; +template <typename> +struct DistributionCaller; +class MockHelpers; } // namespace random_internal +class BitGenRef; // MockingBitGen // @@ -96,100 +96,144 @@ struct MockSingleOverload; // At this time, only mock distributions supplied within the Abseil random // library are officially supported. // -class MockingBitGen : public absl::random_internal::MockingBitGenBase { +// EXPECT_CALL and ON_CALL need to be made within the same DLL component as +// the call to absl::Uniform and related methods, otherwise mocking will fail +// since the underlying implementation creates a type-specific pointer which +// will be distinct across different DLL boundaries. +// +class MockingBitGen { public: - MockingBitGen() {} + MockingBitGen() = default; + ~MockingBitGen() = default; - ~MockingBitGen() override; + // URBG interface + using result_type = absl::BitGen::result_type; - private: - template <typename DistrT, typename... Args> - using MockFnType = - ::testing::MockFunction<typename DistrT::result_type(Args...)>; + static constexpr result_type(min)() { return (absl::BitGen::min)(); } + static constexpr result_type(max)() { return (absl::BitGen::max)(); } + result_type operator()() { return gen_(); } - // MockingBitGen::Register - // - // Register<DistrT, FormatT, ArgTupleT> is the main extension point for - // extending the MockingBitGen framework. It provides a mechanism to install a - // mock expectation for the distribution `distr_t` onto the MockingBitGen - // context. - // - // The returned MockFunction<...> type can be used to setup additional - // distribution parameters of the expectation. - template <typename DistrT, typename... Args, typename... Ms> - decltype(std::declval<MockFnType<DistrT, Args...>>().gmock_Call( - std::declval<Ms>()...)) - Register(Ms&&... matchers) { - auto& mock = - mocks_[std::type_index(GetTypeId<DistrT, std::tuple<Args...>>())]; - - if (!mock.mock_fn) { - auto* mock_fn = new MockFnType<DistrT, Args...>; - mock.mock_fn = mock_fn; - mock.match_impl = &MatchImpl<DistrT, Args...>; - deleters_.emplace_back([mock_fn] { delete mock_fn; }); + private: + // 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> + static auto GetMockFnType(ResultT, std::tuple<Args...>) + -> ::testing::MockFunction<ResultT(Args...)>; + + // MockFnCaller is a helper method for use with absl::apply to + // apply an ArgTupleT to a compatible MockFunction. + // 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 MockFnType, typename ResultT, typename Tuple> + struct MockFnCaller; + + // specialization for std::tuple. + 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)...); } + }; - return static_cast<MockFnType<DistrT, Args...>*>(mock.mock_fn) - ->gmock_Call(std::forward<Ms>(matchers)...); - } + // 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; + }; - mutable std::vector<std::function<void()>> deleters_; + 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)); + } - using match_impl_fn = void (*)(void* mock_fn, void* t_erased_dist_args, - void* t_erased_result); - struct MockData { - void* mock_fn = nullptr; - match_impl_fn match_impl = nullptr; + MockFnType mock_fn_; }; - mutable absl::flat_hash_map<std::type_index, MockData> mocks_; - - template <typename DistrT, typename... Args> - static void MatchImpl(void* mock_fn, void* dist_args, void* result) { - using result_type = typename DistrT::result_type; - *static_cast<result_type*>(result) = absl::apply( - [mock_fn](Args... args) -> result_type { - return (*static_cast<MockFnType<DistrT, Args...>*>(mock_fn)) - .Call(std::move(args)...); - }, - *static_cast<std::tuple<Args...>*>(dist_args)); + // MockingBitGen::RegisterMock + // + // RegisterMock<ResultT, ArgTupleT>(FastTypeIdType) is the main extension + // point for extending the MockingBitGen framework. It provides a mechanism to + // install a mock expectation for a function like ResultT(Args...) keyed by + // type_idex onto the MockingBitGen context. The key is that the type_index + // used to register must match the type index used to call the mock. + // + // The returned MockFunction<...> type can be used to setup additional + // distribution parameters of the expectation. + template <typename ResultT, typename ArgTupleT, typename SelfT> + auto RegisterMock(SelfT&, base_internal::FastTypeIdType type) + -> decltype(GetMockFnType(std::declval<ResultT>(), + std::declval<ArgTupleT>()))& { + using MockFnType = decltype(GetMockFnType(std::declval<ResultT>(), + std::declval<ArgTupleT>())); + + using WrappedFnType = absl::conditional_t< + std::is_same<SelfT, ::testing::NiceMock<absl::MockingBitGen>>::value, + ::testing::NiceMock<MockFnType>, + absl::conditional_t< + std::is_same<SelfT, + ::testing::NaggyMock<absl::MockingBitGen>>::value, + ::testing::NaggyMock<MockFnType>, + absl::conditional_t< + std::is_same<SelfT, + ::testing::StrictMock<absl::MockingBitGen>>::value, + ::testing::StrictMock<MockFnType>, MockFnType>>>; + + using ImplT = FunctionHolderImpl<WrappedFnType, ResultT, ArgTupleT>; + auto& mock = mocks_[type]; + if (!mock) { + mock = absl::make_unique<ImplT>(); + } + return static_cast<ImplT*>(mock.get())->mock_fn_; } - // Looks for an appropriate mock - Returns the mocked result if one is found. - // Otherwise, returns a random value generated by the underlying URBG. - bool CallImpl(const std::type_info& key_type, void* dist_args, - void* result) override { + // MockingBitGen::InvokeMock + // + // InvokeMock(FastTypeIdType, args, result) is the entrypoint for invoking + // mocks registered on MockingBitGen. + // + // When no mocks are registered on the provided FastTypeIdType, returns false. + // Otherwise attempts to invoke the mock function ResultT(Args...) that + // was previously registered via the type_index. + // 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. + inline bool InvokeMock(base_internal::FastTypeIdType type, void* args_tuple, + void* result) { // Trigger a mock, if there exists one that matches `param`. - auto it = mocks_.find(std::type_index(key_type)); + 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, dist_args, result); + it->second->Apply(args_tuple, result); return true; } - template <typename, typename> - friend struct ::absl::random_internal::MockSingleOverload; - friend struct ::absl::random_internal::DistributionCaller< - absl::MockingBitGen>; -}; + absl::flat_hash_map<base_internal::FastTypeIdType, + std::unique_ptr<FunctionHolder>> + mocks_; + absl::BitGen gen_; -// ----------------------------------------------------------------------------- -// Implementation Details Only Below -// ----------------------------------------------------------------------------- - -namespace random_internal { - -template <> -struct DistributionCaller<absl::MockingBitGen> { - template <typename DistrT, typename FormatT, typename... Args> - static typename DistrT::result_type Call(absl::MockingBitGen* gen, - Args&&... args) { - return gen->template Call<DistrT, FormatT>(std::forward<Args>(args)...); - } + template <typename> + friend struct ::absl::random_internal::DistributionCaller; // for InvokeMock + friend class ::absl::BitGenRef; // for InvokeMock + friend class ::absl::random_internal::MockHelpers; // for RegisterMock, + // InvokeMock }; -} // namespace random_internal ABSL_NAMESPACE_END } // namespace absl |