merge(3p/abseil_cpp): Merge upstream at 'ccdbb5941'
Change-Id: I6e85fc7b5f76bba1f1eef15e600a8acb64e97ef5
This commit is contained in:
commit
543379ce45
97 changed files with 3546 additions and 2316 deletions
10
third_party/abseil_cpp/absl/random/BUILD.bazel
vendored
10
third_party/abseil_cpp/absl/random/BUILD.bazel
vendored
|
|
@ -69,7 +69,7 @@ cc_library(
|
|||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/meta:type_traits",
|
||||
"//absl/random/internal:distributions",
|
||||
"//absl/random/internal:distribution_caller",
|
||||
"//absl/random/internal:fast_uniform_bits",
|
||||
"//absl/random/internal:fastmath",
|
||||
"//absl/random/internal:generate_real",
|
||||
|
|
@ -78,7 +78,6 @@ cc_library(
|
|||
"//absl/random/internal:uniform_helper",
|
||||
"//absl/random/internal:wide_multiply",
|
||||
"//absl/strings",
|
||||
"//absl/types:span",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
@ -116,11 +115,12 @@ cc_library(
|
|||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
":random",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:fast_type_id",
|
||||
"//absl/meta:type_traits",
|
||||
"//absl/random/internal:distribution_caller",
|
||||
"//absl/random/internal:fast_uniform_bits",
|
||||
"//absl/random/internal:mocking_bit_gen_base",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
@ -146,10 +146,11 @@ cc_library(
|
|||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
":distributions",
|
||||
":random",
|
||||
"//absl/base:fast_type_id",
|
||||
"//absl/container:flat_hash_map",
|
||||
"//absl/meta:type_traits",
|
||||
"//absl/random/internal:distribution_caller",
|
||||
"//absl/random/internal:mocking_bit_gen_base",
|
||||
"//absl/strings",
|
||||
"//absl/types:span",
|
||||
"//absl/types:variant",
|
||||
|
|
@ -411,6 +412,7 @@ cc_test(
|
|||
deps = [
|
||||
":bit_gen_ref",
|
||||
":random",
|
||||
"//absl/base:fast_type_id",
|
||||
"//absl/random/internal:sequence_urbg",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ absl_cc_library(
|
|||
absl::core_headers
|
||||
absl::random_internal_distribution_caller
|
||||
absl::random_internal_fast_uniform_bits
|
||||
absl::random_internal_mocking_bit_gen_base
|
||||
absl::type_traits
|
||||
)
|
||||
|
||||
|
|
@ -62,6 +61,7 @@ absl_cc_test(
|
|||
absl::random_bit_gen_ref
|
||||
absl::random_random
|
||||
absl::random_internal_sequence_urbg
|
||||
absl::fast_type_id
|
||||
gmock
|
||||
gtest_main
|
||||
)
|
||||
|
|
@ -69,16 +69,16 @@ absl_cc_test(
|
|||
# Internal-only target, do not depend on directly.
|
||||
absl_cc_library(
|
||||
NAME
|
||||
random_internal_mocking_bit_gen_base
|
||||
random_internal_mock_helpers
|
||||
HDRS
|
||||
"internal/mocking_bit_gen_base.h"
|
||||
"internal/mock_helpers.h"
|
||||
COPTS
|
||||
${ABSL_DEFAULT_COPTS}
|
||||
LINKOPTS
|
||||
${ABSL_DEFAULT_LINKOPTS}
|
||||
DEPS
|
||||
absl::random_random
|
||||
absl::strings
|
||||
absl::fast_type_id
|
||||
absl::optional
|
||||
)
|
||||
|
||||
# Internal-only target, do not depend on directly.
|
||||
|
|
@ -93,6 +93,7 @@ absl_cc_library(
|
|||
${ABSL_DEFAULT_LINKOPTS}
|
||||
DEPS
|
||||
absl::random_mocking_bit_gen
|
||||
absl::random_internal_mock_helpers
|
||||
TESTONLY
|
||||
)
|
||||
|
||||
|
|
@ -111,8 +112,8 @@ absl_cc_library(
|
|||
absl::raw_logging_internal
|
||||
absl::random_distributions
|
||||
absl::random_internal_distribution_caller
|
||||
absl::random_internal_mocking_bit_gen_base
|
||||
absl::random_internal_mock_overload_set
|
||||
absl::random_random
|
||||
absl::strings
|
||||
absl::span
|
||||
absl::type_traits
|
||||
|
|
@ -183,7 +184,7 @@ absl_cc_library(
|
|||
absl::config
|
||||
absl::core_headers
|
||||
absl::random_internal_generate_real
|
||||
absl::random_internal_distributions
|
||||
absl::random_internal_distribution_caller
|
||||
absl::random_internal_fast_uniform_bits
|
||||
absl::random_internal_fastmath
|
||||
absl::random_internal_iostream_state_saver
|
||||
|
|
@ -191,7 +192,6 @@ absl_cc_library(
|
|||
absl::random_internal_uniform_helper
|
||||
absl::random_internal_wide_multiply
|
||||
absl::strings
|
||||
absl::span
|
||||
absl::type_traits
|
||||
)
|
||||
|
||||
|
|
@ -534,27 +534,8 @@ absl_cc_library(
|
|||
${ABSL_DEFAULT_LINKOPTS}
|
||||
DEPS
|
||||
absl::config
|
||||
)
|
||||
|
||||
# Internal-only target, do not depend on directly.
|
||||
absl_cc_library(
|
||||
NAME
|
||||
random_internal_distributions
|
||||
HDRS
|
||||
"internal/distributions.h"
|
||||
COPTS
|
||||
${ABSL_DEFAULT_COPTS}
|
||||
LINKOPTS
|
||||
${ABSL_DEFAULT_LINKOPTS}
|
||||
DEPS
|
||||
absl::random_internal_distribution_caller
|
||||
absl::random_internal_fast_uniform_bits
|
||||
absl::random_internal_fastmath
|
||||
absl::random_internal_traits
|
||||
absl::random_internal_uniform_helper
|
||||
absl::span
|
||||
absl::strings
|
||||
absl::type_traits
|
||||
absl::utility
|
||||
absl::fast_type_id
|
||||
)
|
||||
|
||||
# Internal-only target, do not depend on directly.
|
||||
|
|
@ -745,7 +726,6 @@ absl_cc_library(
|
|||
absl::random_internal_salted_seed_seq
|
||||
absl::random_internal_seed_material
|
||||
absl::span
|
||||
absl::strings
|
||||
absl::type_traits
|
||||
)
|
||||
|
||||
|
|
@ -1174,9 +1154,7 @@ absl_cc_library(
|
|||
LINKOPTS
|
||||
${ABSL_DEFAULT_LINKOPTS}
|
||||
DEPS
|
||||
absl::core_headers
|
||||
absl::random_internal_fast_uniform_bits
|
||||
absl::random_internal_iostream_state_saver
|
||||
absl::config
|
||||
absl::random_internal_traits
|
||||
absl::type_traits
|
||||
)
|
||||
|
|
|
|||
111
third_party/abseil_cpp/absl/random/bit_gen_ref.h
vendored
111
third_party/abseil_cpp/absl/random/bit_gen_ref.h
vendored
|
|
@ -24,11 +24,11 @@
|
|||
#ifndef ABSL_RANDOM_BIT_GEN_REF_H_
|
||||
#define ABSL_RANDOM_BIT_GEN_REF_H_
|
||||
|
||||
#include "absl/base/internal/fast_type_id.h"
|
||||
#include "absl/base/macros.h"
|
||||
#include "absl/meta/type_traits.h"
|
||||
#include "absl/random/internal/distribution_caller.h"
|
||||
#include "absl/random/internal/fast_uniform_bits.h"
|
||||
#include "absl/random/internal/mocking_bit_gen_base.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
|
@ -51,6 +51,10 @@ struct is_urbg<
|
|||
typename std::decay<decltype(std::declval<URBG>()())>::type>::value>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename>
|
||||
struct DistributionCaller;
|
||||
class MockHelpers;
|
||||
|
||||
} // namespace random_internal
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -77,23 +81,50 @@ struct is_urbg<
|
|||
// }
|
||||
//
|
||||
class BitGenRef {
|
||||
public:
|
||||
using result_type = uint64_t;
|
||||
// SFINAE to detect whether the URBG type includes a member matching
|
||||
// bool InvokeMock(base_internal::FastTypeIdType, void*, void*).
|
||||
//
|
||||
// These live inside BitGenRef so that they have friend access
|
||||
// to MockingBitGen. (see similar methods in DistributionCaller).
|
||||
template <template <class...> class Trait, class AlwaysVoid, class... Args>
|
||||
struct detector : std::false_type {};
|
||||
template <template <class...> class Trait, class... Args>
|
||||
struct detector<Trait, absl::void_t<Trait<Args...>>, Args...>
|
||||
: std::true_type {};
|
||||
|
||||
BitGenRef(const absl::BitGenRef&) = default;
|
||||
BitGenRef(absl::BitGenRef&&) = default;
|
||||
BitGenRef& operator=(const absl::BitGenRef&) = default;
|
||||
BitGenRef& operator=(absl::BitGenRef&&) = default;
|
||||
template <class T>
|
||||
using invoke_mock_t = decltype(std::declval<T*>()->InvokeMock(
|
||||
std::declval<base_internal::FastTypeIdType>(), std::declval<void*>(),
|
||||
std::declval<void*>()));
|
||||
|
||||
template <typename T>
|
||||
using HasInvokeMock = typename detector<invoke_mock_t, void, T>::type;
|
||||
|
||||
public:
|
||||
BitGenRef(const BitGenRef&) = default;
|
||||
BitGenRef(BitGenRef&&) = default;
|
||||
BitGenRef& operator=(const BitGenRef&) = default;
|
||||
BitGenRef& operator=(BitGenRef&&) = default;
|
||||
|
||||
template <typename URBG, typename absl::enable_if_t<
|
||||
(!std::is_same<URBG, BitGenRef>::value &&
|
||||
random_internal::is_urbg<URBG>::value &&
|
||||
!HasInvokeMock<URBG>::value)>* = nullptr>
|
||||
BitGenRef(URBG& gen) // NOLINT
|
||||
: t_erased_gen_ptr_(reinterpret_cast<uintptr_t>(&gen)),
|
||||
mock_call_(NotAMock),
|
||||
generate_impl_fn_(ImplFn<URBG>) {}
|
||||
|
||||
template <typename URBG,
|
||||
typename absl::enable_if_t<
|
||||
(!std::is_same<URBG, BitGenRef>::value &&
|
||||
random_internal::is_urbg<URBG>::value)>* = nullptr>
|
||||
typename absl::enable_if_t<(!std::is_same<URBG, BitGenRef>::value &&
|
||||
random_internal::is_urbg<URBG>::value &&
|
||||
HasInvokeMock<URBG>::value)>* = nullptr>
|
||||
BitGenRef(URBG& gen) // NOLINT
|
||||
: mocked_gen_ptr_(MakeMockPointer(&gen)),
|
||||
t_erased_gen_ptr_(reinterpret_cast<uintptr_t>(&gen)),
|
||||
generate_impl_fn_(ImplFn<URBG>) {
|
||||
}
|
||||
: t_erased_gen_ptr_(reinterpret_cast<uintptr_t>(&gen)),
|
||||
mock_call_(&MockCall<URBG>),
|
||||
generate_impl_fn_(ImplFn<URBG>) {}
|
||||
|
||||
using result_type = uint64_t;
|
||||
|
||||
static constexpr result_type(min)() {
|
||||
return (std::numeric_limits<result_type>::min)();
|
||||
|
|
@ -106,14 +137,9 @@ class BitGenRef {
|
|||
result_type operator()() { return generate_impl_fn_(t_erased_gen_ptr_); }
|
||||
|
||||
private:
|
||||
friend struct absl::random_internal::DistributionCaller<absl::BitGenRef>;
|
||||
using impl_fn = result_type (*)(uintptr_t);
|
||||
using mocker_base_t = absl::random_internal::MockingBitGenBase;
|
||||
|
||||
// Convert an arbitrary URBG pointer into either a valid mocker_base_t
|
||||
// pointer or a nullptr.
|
||||
static inline mocker_base_t* MakeMockPointer(mocker_base_t* t) { return t; }
|
||||
static inline mocker_base_t* MakeMockPointer(void*) { return nullptr; }
|
||||
using mock_call_fn = bool (*)(uintptr_t, base_internal::FastTypeIdType, void*,
|
||||
void*);
|
||||
|
||||
template <typename URBG>
|
||||
static result_type ImplFn(uintptr_t ptr) {
|
||||
|
|
@ -123,29 +149,32 @@ class BitGenRef {
|
|||
return fast_uniform_bits(*reinterpret_cast<URBG*>(ptr));
|
||||
}
|
||||
|
||||
mocker_base_t* mocked_gen_ptr_;
|
||||
uintptr_t t_erased_gen_ptr_;
|
||||
impl_fn generate_impl_fn_;
|
||||
};
|
||||
|
||||
namespace random_internal {
|
||||
|
||||
template <>
|
||||
struct DistributionCaller<absl::BitGenRef> {
|
||||
template <typename DistrT, typename... Args>
|
||||
static typename DistrT::result_type Call(absl::BitGenRef* gen_ref,
|
||||
Args&&... args) {
|
||||
auto* mock_ptr = gen_ref->mocked_gen_ptr_;
|
||||
if (mock_ptr == nullptr) {
|
||||
DistrT dist(std::forward<Args>(args)...);
|
||||
return dist(*gen_ref);
|
||||
} else {
|
||||
return mock_ptr->template Call<DistrT>(std::forward<Args>(args)...);
|
||||
}
|
||||
// Get a type-erased InvokeMock pointer.
|
||||
template <typename URBG>
|
||||
static bool MockCall(uintptr_t gen_ptr, base_internal::FastTypeIdType type,
|
||||
void* result, void* arg_tuple) {
|
||||
return reinterpret_cast<URBG*>(gen_ptr)->InvokeMock(type, result,
|
||||
arg_tuple);
|
||||
}
|
||||
static bool NotAMock(uintptr_t, base_internal::FastTypeIdType, void*, void*) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool InvokeMock(base_internal::FastTypeIdType type, void* args_tuple,
|
||||
void* result) {
|
||||
if (mock_call_ == NotAMock) return false; // avoids an indirect call.
|
||||
return mock_call_(t_erased_gen_ptr_, type, args_tuple, result);
|
||||
}
|
||||
|
||||
uintptr_t t_erased_gen_ptr_;
|
||||
mock_call_fn mock_call_;
|
||||
impl_fn generate_impl_fn_;
|
||||
|
||||
template <typename>
|
||||
friend struct ::absl::random_internal::DistributionCaller; // for InvokeMock
|
||||
friend class ::absl::random_internal::MockHelpers; // for InvokeMock
|
||||
};
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
|
|
|
|||
|
|
@ -17,30 +17,31 @@
|
|||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/internal/fast_type_id.h"
|
||||
#include "absl/random/internal/sequence_urbg.h"
|
||||
#include "absl/random/random.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
||||
class ConstBitGen : public absl::random_internal::MockingBitGenBase {
|
||||
bool CallImpl(const std::type_info&, void*, void* result) override {
|
||||
class ConstBitGen {
|
||||
public:
|
||||
// URBG interface
|
||||
using result_type = absl::BitGen::result_type;
|
||||
|
||||
static constexpr result_type(min)() { return (absl::BitGen::min)(); }
|
||||
static constexpr result_type(max)() { return (absl::BitGen::max)(); }
|
||||
result_type operator()() { return 1; }
|
||||
|
||||
// InvokeMock method
|
||||
bool InvokeMock(base_internal::FastTypeIdType index, void*, void* result) {
|
||||
*static_cast<int*>(result) = 42;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
namespace random_internal {
|
||||
template <>
|
||||
struct DistributionCaller<ConstBitGen> {
|
||||
template <typename DistrT, typename FormatT, typename... Args>
|
||||
static typename DistrT::result_type Call(ConstBitGen* gen, Args&&... args) {
|
||||
return gen->template Call<DistrT, FormatT>(std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
} // namespace random_internal
|
||||
|
||||
namespace {
|
||||
|
||||
int FnTest(absl::BitGenRef gen_ref) { return absl::Uniform(gen_ref, 1, 7); }
|
||||
|
||||
template <typename T>
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
#include "absl/random/beta_distribution.h"
|
||||
#include "absl/random/exponential_distribution.h"
|
||||
#include "absl/random/gaussian_distribution.h"
|
||||
#include "absl/random/internal/distributions.h" // IWYU pragma: export
|
||||
#include "absl/random/internal/distribution_caller.h" // IWYU pragma: export
|
||||
#include "absl/random/internal/uniform_helper.h" // IWYU pragma: export
|
||||
#include "absl/random/log_uniform_int_distribution.h"
|
||||
#include "absl/random/poisson_distribution.h"
|
||||
|
|
|
|||
|
|
@ -45,21 +45,10 @@ cc_library(
|
|||
hdrs = ["distribution_caller.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = ["//absl/base:config"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "distributions",
|
||||
hdrs = ["distributions.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
":distribution_caller",
|
||||
":traits",
|
||||
":uniform_helper",
|
||||
"//absl/base",
|
||||
"//absl/meta:type_traits",
|
||||
"//absl/strings",
|
||||
"//absl/base:config",
|
||||
"//absl/base:fast_type_id",
|
||||
"//absl/utility",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
@ -221,7 +210,6 @@ cc_library(
|
|||
":seed_material",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/meta:type_traits",
|
||||
"//absl/strings",
|
||||
"//absl/types:optional",
|
||||
"//absl/types:span",
|
||||
],
|
||||
|
|
@ -497,12 +485,11 @@ cc_test(
|
|||
)
|
||||
|
||||
cc_library(
|
||||
name = "mocking_bit_gen_base",
|
||||
hdrs = ["mocking_bit_gen_base.h"],
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
name = "mock_helpers",
|
||||
hdrs = ["mock_helpers.h"],
|
||||
deps = [
|
||||
"//absl/random",
|
||||
"//absl/strings",
|
||||
"//absl/base:fast_type_id",
|
||||
"//absl/types:optional",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
@ -511,6 +498,7 @@ cc_library(
|
|||
testonly = 1,
|
||||
hdrs = ["mock_overload_set.h"],
|
||||
deps = [
|
||||
":mock_helpers",
|
||||
"//absl/random:mocking_bit_gen",
|
||||
"@com_google_googletest//:gtest",
|
||||
],
|
||||
|
|
@ -672,6 +660,8 @@ cc_library(
|
|||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
":traits",
|
||||
"//absl/base:config",
|
||||
"//absl/meta:type_traits",
|
||||
],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
#include <utility>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/fast_type_id.h"
|
||||
#include "absl/utility/utility.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
|
@ -30,14 +32,57 @@ namespace random_internal {
|
|||
// to intercept such calls.
|
||||
template <typename URBG>
|
||||
struct DistributionCaller {
|
||||
// Call the provided distribution type. The parameters are expected
|
||||
// to be explicitly specified.
|
||||
// DistrT is the distribution type.
|
||||
// SFINAE to detect whether the URBG type includes a member matching
|
||||
// bool InvokeMock(base_internal::FastTypeIdType, void*, void*).
|
||||
//
|
||||
// These live inside BitGenRef so that they have friend access
|
||||
// to MockingBitGen. (see similar methods in DistributionCaller).
|
||||
template <template <class...> class Trait, class AlwaysVoid, class... Args>
|
||||
struct detector : std::false_type {};
|
||||
template <template <class...> class Trait, class... Args>
|
||||
struct detector<Trait, absl::void_t<Trait<Args...>>, Args...>
|
||||
: std::true_type {};
|
||||
|
||||
template <class T>
|
||||
using invoke_mock_t = decltype(std::declval<T*>()->InvokeMock(
|
||||
std::declval<::absl::base_internal::FastTypeIdType>(),
|
||||
std::declval<void*>(), std::declval<void*>()));
|
||||
|
||||
using HasInvokeMock = typename detector<invoke_mock_t, void, URBG>::type;
|
||||
|
||||
// Default implementation of distribution caller.
|
||||
template <typename DistrT, typename... Args>
|
||||
static typename DistrT::result_type Call(URBG* urbg, Args&&... args) {
|
||||
static typename DistrT::result_type Impl(std::false_type, URBG* urbg,
|
||||
Args&&... args) {
|
||||
DistrT dist(std::forward<Args>(args)...);
|
||||
return dist(*urbg);
|
||||
}
|
||||
|
||||
// Mock implementation of distribution caller.
|
||||
// The underlying KeyT must match the KeyT constructed by MockOverloadSet.
|
||||
template <typename DistrT, typename... Args>
|
||||
static typename DistrT::result_type Impl(std::true_type, URBG* urbg,
|
||||
Args&&... args) {
|
||||
using ResultT = typename DistrT::result_type;
|
||||
using ArgTupleT = std::tuple<absl::decay_t<Args>...>;
|
||||
using KeyT = ResultT(DistrT, ArgTupleT);
|
||||
|
||||
ArgTupleT arg_tuple(std::forward<Args>(args)...);
|
||||
ResultT result;
|
||||
if (!urbg->InvokeMock(::absl::base_internal::FastTypeId<KeyT>(), &arg_tuple,
|
||||
&result)) {
|
||||
auto dist = absl::make_from_tuple<DistrT>(arg_tuple);
|
||||
result = dist(*urbg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Default implementation of distribution caller.
|
||||
template <typename DistrT, typename... Args>
|
||||
static typename DistrT::result_type Call(URBG* urbg, Args&&... args) {
|
||||
return Impl<DistrT, Args...>(HasInvokeMock{}, urbg,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace random_internal
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
// Copyright 2019 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_DISTRIBUTIONS_H_
|
||||
#define ABSL_RANDOM_INTERNAL_DISTRIBUTIONS_H_
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/meta/type_traits.h"
|
||||
#include "absl/random/internal/distribution_caller.h"
|
||||
#include "absl/random/internal/traits.h"
|
||||
#include "absl/random/internal/uniform_helper.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// In the absence of an explicitly provided return-type, the template
|
||||
// "uniform_inferred_return_t<A, B>" is used to derive a suitable type, based on
|
||||
// the data-types of the endpoint-arguments {A lo, B hi}.
|
||||
//
|
||||
// Given endpoints {A lo, B hi}, one of {A, B} will be chosen as the
|
||||
// return-type, if one type can be implicitly converted into the other, in a
|
||||
// lossless way. The template "is_widening_convertible" implements the
|
||||
// compile-time logic for deciding if such a conversion is possible.
|
||||
//
|
||||
// If no such conversion between {A, B} exists, then the overload for
|
||||
// absl::Uniform() will be discarded, and the call will be ill-formed.
|
||||
// Return-type for absl::Uniform() when the return-type is inferred.
|
||||
template <typename A, typename B>
|
||||
using uniform_inferred_return_t =
|
||||
absl::enable_if_t<absl::disjunction<is_widening_convertible<A, B>,
|
||||
is_widening_convertible<B, A>>::value,
|
||||
typename std::conditional<
|
||||
is_widening_convertible<A, B>::value, B, A>::type>;
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_DISTRIBUTIONS_H_
|
||||
127
third_party/abseil_cpp/absl/random/internal/mock_helpers.h
vendored
Normal file
127
third_party/abseil_cpp/absl/random/internal/mock_helpers.h
vendored
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
//
|
||||
// Copyright 2019 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_RANDOM_INTERNAL_MOCK_HELPERS_H_
|
||||
#define ABSL_RANDOM_INTERNAL_MOCK_HELPERS_H_
|
||||
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/base/internal/fast_type_id.h"
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
// MockHelpers works in conjunction with MockOverloadSet, MockingBitGen, and
|
||||
// BitGenRef to enable the mocking capability for absl distribution functions.
|
||||
//
|
||||
// MockingBitGen registers mocks based on the typeid of a mock signature, KeyT,
|
||||
// which is used to generate a unique id.
|
||||
//
|
||||
// KeyT is a signature of the form:
|
||||
// result_type(discriminator_type, std::tuple<args...>)
|
||||
// The mocked function signature will be composed from KeyT as:
|
||||
// result_type(args...)
|
||||
//
|
||||
class MockHelpers {
|
||||
using IdType = ::absl::base_internal::FastTypeIdType;
|
||||
|
||||
// Given a key signature type used to index the mock, extract the components.
|
||||
// KeyT is expected to have the form:
|
||||
// result_type(discriminator_type, arg_tuple_type)
|
||||
template <typename KeyT>
|
||||
struct KeySignature;
|
||||
|
||||
template <typename ResultT, typename DiscriminatorT, typename ArgTupleT>
|
||||
struct KeySignature<ResultT(DiscriminatorT, ArgTupleT)> {
|
||||
using result_type = ResultT;
|
||||
using discriminator_type = DiscriminatorT;
|
||||
using arg_tuple_type = ArgTupleT;
|
||||
};
|
||||
|
||||
// Detector for InvokeMock.
|
||||
template <class T>
|
||||
using invoke_mock_t = decltype(std::declval<T*>()->InvokeMock(
|
||||
std::declval<IdType>(), std::declval<void*>(), std::declval<void*>()));
|
||||
|
||||
// Empty implementation of InvokeMock.
|
||||
template <typename KeyT, typename ReturnT, typename ArgTupleT, typename URBG,
|
||||
typename... Args>
|
||||
static absl::optional<ReturnT> InvokeMockImpl(char, URBG*, Args&&...) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
// Non-empty implementation of InvokeMock.
|
||||
template <typename KeyT, typename ReturnT, typename ArgTupleT, typename URBG,
|
||||
typename = invoke_mock_t<URBG>, typename... Args>
|
||||
static absl::optional<ReturnT> InvokeMockImpl(int, URBG* urbg,
|
||||
Args&&... args) {
|
||||
ArgTupleT arg_tuple(std::forward<Args>(args)...);
|
||||
ReturnT result;
|
||||
if (urbg->InvokeMock(::absl::base_internal::FastTypeId<KeyT>(), &arg_tuple,
|
||||
&result)) {
|
||||
return result;
|
||||
}
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
public:
|
||||
// Invoke a mock for the KeyT (may or may not be a signature).
|
||||
//
|
||||
// KeyT is used to generate a typeid-based lookup key for the mock.
|
||||
// KeyT is a signature of the form:
|
||||
// result_type(discriminator_type, std::tuple<args...>)
|
||||
// The mocked function signature will be composed from KeyT as:
|
||||
// result_type(args...)
|
||||
//
|
||||
// An instance of arg_tuple_type must be constructable from Args..., since
|
||||
// the underlying mechanism requires a pointer to an argument tuple.
|
||||
template <typename KeyT, typename URBG, typename... Args>
|
||||
static auto MaybeInvokeMock(URBG* urbg, Args&&... args)
|
||||
-> absl::optional<typename KeySignature<KeyT>::result_type> {
|
||||
// Use function overloading to dispatch to the implemenation since
|
||||
// more modern patterns (e.g. require + constexpr) are not supported in all
|
||||
// compiler configurations.
|
||||
return InvokeMockImpl<KeyT, typename KeySignature<KeyT>::result_type,
|
||||
typename KeySignature<KeyT>::arg_tuple_type, URBG>(
|
||||
0, urbg, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// Acquire a mock for the KeyT (may or may not be a signature).
|
||||
//
|
||||
// KeyT is used to generate a typeid-based lookup for the mock.
|
||||
// KeyT is a signature of the form:
|
||||
// result_type(discriminator_type, std::tuple<args...>)
|
||||
// The mocked function signature will be composed from KeyT as:
|
||||
// result_type(args...)
|
||||
template <typename KeyT, typename MockURBG>
|
||||
static auto MockFor(MockURBG& m) -> decltype(
|
||||
std::declval<MockURBG>()
|
||||
.template RegisterMock<typename KeySignature<KeyT>::result_type,
|
||||
typename KeySignature<KeyT>::arg_tuple_type>(
|
||||
std::declval<IdType>())) {
|
||||
return m.template RegisterMock<typename KeySignature<KeyT>::result_type,
|
||||
typename KeySignature<KeyT>::arg_tuple_type>(
|
||||
::absl::base_internal::FastTypeId<KeyT>());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_MOCK_HELPERS_H_
|
||||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/random/internal/mock_helpers.h"
|
||||
#include "absl/random/mocking_bit_gen.h"
|
||||
|
||||
namespace absl {
|
||||
|
|
@ -35,17 +36,20 @@ struct MockSingleOverload;
|
|||
// EXPECT_CALL(mock_single_overload, Call(...))` will expand to a call to
|
||||
// `mock_single_overload.gmock_Call(...)`. Because expectations are stored on
|
||||
// the MockingBitGen (an argument passed inside `Call(...)`), this forwards to
|
||||
// arguments to Mocking::Register.
|
||||
// arguments to MockingBitGen::Register.
|
||||
//
|
||||
// The underlying KeyT must match the KeyT constructed by DistributionCaller.
|
||||
template <typename DistrT, typename Ret, typename... Args>
|
||||
struct MockSingleOverload<DistrT, Ret(MockingBitGen&, Args...)> {
|
||||
static_assert(std::is_same<typename DistrT::result_type, Ret>::value,
|
||||
"Overload signature must have return type matching the "
|
||||
"distributions result type.");
|
||||
"distribution result_type.");
|
||||
using KeyT = Ret(DistrT, std::tuple<Args...>);
|
||||
auto gmock_Call(
|
||||
absl::MockingBitGen& gen, // NOLINT(google-runtime-references)
|
||||
const ::testing::Matcher<Args>&... args)
|
||||
-> decltype(gen.Register<DistrT, Args...>(args...)) {
|
||||
return gen.Register<DistrT, Args...>(args...);
|
||||
const ::testing::Matcher<Args>&... matchers)
|
||||
-> decltype(MockHelpers::MockFor<KeyT>(gen).gmock_Call(matchers...)) {
|
||||
return MockHelpers::MockFor<KeyT>(gen).gmock_Call(matchers...);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -53,13 +57,15 @@ template <typename DistrT, typename Ret, typename Arg, typename... Args>
|
|||
struct MockSingleOverload<DistrT, Ret(Arg, MockingBitGen&, Args...)> {
|
||||
static_assert(std::is_same<typename DistrT::result_type, Ret>::value,
|
||||
"Overload signature must have return type matching the "
|
||||
"distributions result type.");
|
||||
"distribution result_type.");
|
||||
using KeyT = Ret(DistrT, std::tuple<Arg, Args...>);
|
||||
auto gmock_Call(
|
||||
const ::testing::Matcher<Arg>& arg,
|
||||
const ::testing::Matcher<Arg>& matcher,
|
||||
absl::MockingBitGen& gen, // NOLINT(google-runtime-references)
|
||||
const ::testing::Matcher<Args>&... args)
|
||||
-> decltype(gen.Register<DistrT, Arg, Args...>(arg, args...)) {
|
||||
return gen.Register<DistrT, Arg, Args...>(arg, args...);
|
||||
const ::testing::Matcher<Args>&... matchers)
|
||||
-> decltype(MockHelpers::MockFor<KeyT>(gen).gmock_Call(matcher,
|
||||
matchers...)) {
|
||||
return MockHelpers::MockFor<KeyT>(gen).gmock_Call(matcher, matchers...);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,85 +0,0 @@
|
|||
//
|
||||
// Copyright 2018 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_
|
||||
#define ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_
|
||||
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
|
||||
#include "absl/random/random.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace random_internal {
|
||||
|
||||
class MockingBitGenBase {
|
||||
template <typename>
|
||||
friend struct DistributionCaller;
|
||||
using generator_type = absl::BitGen;
|
||||
|
||||
public:
|
||||
// URBG interface
|
||||
using result_type = generator_type::result_type;
|
||||
static constexpr result_type(min)() { return (generator_type::min)(); }
|
||||
static constexpr result_type(max)() { return (generator_type::max)(); }
|
||||
result_type operator()() { return gen_(); }
|
||||
|
||||
virtual ~MockingBitGenBase() = default;
|
||||
|
||||
protected:
|
||||
// CallImpl is the type-erased virtual dispatch.
|
||||
// The type of dist is always distribution<T>,
|
||||
// The type of result is always distribution<T>::result_type.
|
||||
virtual bool CallImpl(const std::type_info& distr_type, void* dist_args,
|
||||
void* result) = 0;
|
||||
|
||||
template <typename DistrT, typename ArgTupleT>
|
||||
static const std::type_info& GetTypeId() {
|
||||
return typeid(std::pair<absl::decay_t<DistrT>, absl::decay_t<ArgTupleT>>);
|
||||
}
|
||||
|
||||
// Call the generating distribution function.
|
||||
// Invoked by DistributionCaller<>::Call<DistT>.
|
||||
// DistT is the distribution type.
|
||||
template <typename DistrT, typename... Args>
|
||||
typename DistrT::result_type Call(Args&&... args) {
|
||||
using distr_result_type = typename DistrT::result_type;
|
||||
using ArgTupleT = std::tuple<absl::decay_t<Args>...>;
|
||||
|
||||
ArgTupleT arg_tuple(std::forward<Args>(args)...);
|
||||
auto dist = absl::make_from_tuple<DistrT>(arg_tuple);
|
||||
|
||||
distr_result_type result{};
|
||||
bool found_match =
|
||||
CallImpl(GetTypeId<DistrT, ArgTupleT>(), &arg_tuple, &result);
|
||||
|
||||
if (!found_match) {
|
||||
result = dist(gen_);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
generator_type gen_;
|
||||
}; // namespace random_internal
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_
|
||||
|
|
@ -19,10 +19,13 @@
|
|||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/meta/type_traits.h"
|
||||
#include "absl/random/internal/traits.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
||||
template <typename IntType>
|
||||
class uniform_int_distribution;
|
||||
|
||||
|
|
@ -58,6 +61,26 @@ struct IntervalOpenOpenTag
|
|||
: public random_internal::TagTypeCompare<IntervalOpenOpenTag> {};
|
||||
|
||||
namespace random_internal {
|
||||
|
||||
// In the absence of an explicitly provided return-type, the template
|
||||
// "uniform_inferred_return_t<A, B>" is used to derive a suitable type, based on
|
||||
// the data-types of the endpoint-arguments {A lo, B hi}.
|
||||
//
|
||||
// Given endpoints {A lo, B hi}, one of {A, B} will be chosen as the
|
||||
// return-type, if one type can be implicitly converted into the other, in a
|
||||
// lossless way. The template "is_widening_convertible" implements the
|
||||
// compile-time logic for deciding if such a conversion is possible.
|
||||
//
|
||||
// If no such conversion between {A, B} exists, then the overload for
|
||||
// absl::Uniform() will be discarded, and the call will be ill-formed.
|
||||
// Return-type for absl::Uniform() when the return-type is inferred.
|
||||
template <typename A, typename B>
|
||||
using uniform_inferred_return_t =
|
||||
absl::enable_if_t<absl::disjunction<is_widening_convertible<A, B>,
|
||||
is_widening_convertible<B, A>>::value,
|
||||
typename std::conditional<
|
||||
is_widening_convertible<A, B>::value, B, A>::type>;
|
||||
|
||||
// The functions
|
||||
// uniform_lower_bound(tag, a, b)
|
||||
// and
|
||||
|
|
@ -149,12 +172,19 @@ uniform_upper_bound(Tag, FloatType, FloatType b) {
|
|||
return std::nextafter(b, (std::numeric_limits<FloatType>::max)());
|
||||
}
|
||||
|
||||
// UniformDistribution selects either absl::uniform_int_distribution
|
||||
// or absl::uniform_real_distribution depending on the NumType parameter.
|
||||
template <typename NumType>
|
||||
using UniformDistribution =
|
||||
typename std::conditional<std::is_integral<NumType>::value,
|
||||
absl::uniform_int_distribution<NumType>,
|
||||
absl::uniform_real_distribution<NumType>>::type;
|
||||
|
||||
// UniformDistributionWrapper is used as the underlying distribution type
|
||||
// by the absl::Uniform template function. It selects the proper Abseil
|
||||
// uniform distribution and provides constructor overloads that match the
|
||||
// expected parameter order as well as adjusting distribtuion bounds based
|
||||
// on the tag.
|
||||
template <typename NumType>
|
||||
struct UniformDistributionWrapper : public UniformDistribution<NumType> {
|
||||
template <typename TagType>
|
||||
|
|
|
|||
|
|
@ -27,6 +27,11 @@
|
|||
// More information about the Googletest testing framework is available at
|
||||
// https://github.com/google/googletest
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// absl::MockingBitGen mock;
|
||||
|
|
|
|||
188
third_party/abseil_cpp/absl/random/mocking_bit_gen.h
vendored
188
third_party/abseil_cpp/absl/random/mocking_bit_gen.h
vendored
|
|
@ -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,102 +96,132 @@ 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() override {
|
||||
~MockingBitGen() {
|
||||
for (const auto& del : deleters_) del();
|
||||
}
|
||||
|
||||
// URBG interface
|
||||
using result_type = absl::BitGen::result_type;
|
||||
|
||||
static constexpr result_type(min)() { return (absl::BitGen::min)(); }
|
||||
static constexpr result_type(max)() { return (absl::BitGen::max)(); }
|
||||
result_type operator()() { return gen_(); }
|
||||
|
||||
private:
|
||||
template <typename DistrT, typename... Args>
|
||||
using MockFnType =
|
||||
::testing::MockFunction<typename DistrT::result_type(Args...)>;
|
||||
|
||||
// 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; });
|
||||
}
|
||||
|
||||
return static_cast<MockFnType<DistrT, Args...>*>(mock.mock_fn)
|
||||
->gmock_Call(std::forward<Ms>(matchers)...);
|
||||
}
|
||||
|
||||
mutable std::vector<std::function<void()>> deleters_;
|
||||
|
||||
using match_impl_fn = void (*)(void* mock_fn, void* t_erased_dist_args,
|
||||
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;
|
||||
};
|
||||
|
||||
mutable absl::flat_hash_map<std::type_index, MockData> mocks_;
|
||||
// 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...)>;
|
||||
|
||||
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));
|
||||
// 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 ResultT, typename MockFnType, typename Tuple>
|
||||
struct MockFnCaller;
|
||||
// specialization for std::tuple.
|
||||
template <typename ResultT, typename MockFnType, typename... Args>
|
||||
struct MockFnCaller<ResultT, MockFnType, std::tuple<Args...>> {
|
||||
MockFnType* fn;
|
||||
inline ResultT operator()(Args... args) {
|
||||
return fn->Call(std::move(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>
|
||||
auto RegisterMock(base_internal::FastTypeIdType type)
|
||||
-> decltype(GetMockFnType(std::declval<ResultT>(),
|
||||
std::declval<ArgTupleT>()))& {
|
||||
using MockFnType = decltype(
|
||||
GetMockFnType(std::declval<ResultT>(), std::declval<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; });
|
||||
}
|
||||
return *static_cast<MockFnType*>(mock.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::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));
|
||||
}
|
||||
|
||||
// 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);
|
||||
mock_data->match_impl(mock_data->mock_fn, 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, MockData> mocks_;
|
||||
std::vector<std::function<void()>> deleters_;
|
||||
absl::BitGen gen_;
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Implementation Details Only Below
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace random_internal {
|
||||
|
||||
template <>
|
||||
struct DistributionCaller<absl::MockingBitGen> {
|
||||
template <typename DistrT, typename... Args>
|
||||
static typename DistrT::result_type Call(absl::MockingBitGen* gen,
|
||||
Args&&... args) {
|
||||
return gen->template Call<DistrT>(std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace random_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
|
|
|
|||
|
|
@ -96,7 +96,6 @@ template <typename URBG>
|
|||
void TestReproducibleVariateSequencesForNonsecureURBG() {
|
||||
const size_t kNumVariates = 1000;
|
||||
|
||||
// Master RNG instance.
|
||||
URBG rng;
|
||||
// Reused for both RNG instances.
|
||||
auto reusable_seed = absl::CreateSeedSeqFrom(&rng);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue