summaryrefslogtreecommitdiff
path: root/absl/random
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2021-02-17 09:48:49 -0800
committerGravatar Andy Getz <durandal@google.com>2021-02-18 02:38:12 -0500
commitb315753c0b8b4aa4e3e1479375eddb518393bab6 (patch)
tree07255ad54a6555677f3b54f2b0c7bcec9c320be5 /absl/random
parent143a27800eb35f4568b9be51647726281916aac9 (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.bazel9
-rw-r--r--absl/random/mocking_bit_gen.h87
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>