File indexing completed on 2025-12-16 09:40:55
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_
0018 #define ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_
0019
0020 #include <utility>
0021 #include <type_traits>
0022
0023 #include "absl/base/config.h"
0024 #include "absl/base/internal/fast_type_id.h"
0025 #include "absl/utility/utility.h"
0026
0027 namespace absl {
0028 ABSL_NAMESPACE_BEGIN
0029 namespace random_internal {
0030
0031
0032
0033
0034 template <typename URBG>
0035 struct DistributionCaller {
0036 static_assert(!std::is_pointer<URBG>::value,
0037 "You must pass a reference, not a pointer.");
0038
0039
0040
0041
0042
0043 template <template <class...> class Trait, class AlwaysVoid, class... Args>
0044 struct detector : std::false_type {};
0045 template <template <class...> class Trait, class... Args>
0046 struct detector<Trait, absl::void_t<Trait<Args...>>, Args...>
0047 : std::true_type {};
0048
0049 template <class T>
0050 using invoke_mock_t = decltype(std::declval<T*>()->InvokeMock(
0051 std::declval<::absl::base_internal::FastTypeIdType>(),
0052 std::declval<void*>(), std::declval<void*>()));
0053
0054 using HasInvokeMock = typename detector<invoke_mock_t, void, URBG>::type;
0055
0056
0057 template <typename DistrT, typename... Args>
0058 static typename DistrT::result_type Impl(std::false_type, URBG* urbg,
0059 Args&&... args) {
0060 DistrT dist(std::forward<Args>(args)...);
0061 return dist(*urbg);
0062 }
0063
0064
0065
0066 template <typename DistrT, typename... Args>
0067 static typename DistrT::result_type Impl(std::true_type, URBG* urbg,
0068 Args&&... args) {
0069 using ResultT = typename DistrT::result_type;
0070 using ArgTupleT = std::tuple<absl::decay_t<Args>...>;
0071 using KeyT = ResultT(DistrT, ArgTupleT);
0072
0073 ArgTupleT arg_tuple(std::forward<Args>(args)...);
0074 ResultT result;
0075 if (!urbg->InvokeMock(::absl::base_internal::FastTypeId<KeyT>(), &arg_tuple,
0076 &result)) {
0077 auto dist = absl::make_from_tuple<DistrT>(arg_tuple);
0078 result = dist(*urbg);
0079 }
0080 return result;
0081 }
0082
0083
0084 template <typename DistrT, typename... Args>
0085 static typename DistrT::result_type Call(URBG* urbg, Args&&... args) {
0086 return Impl<DistrT, Args...>(HasInvokeMock{}, urbg,
0087 std::forward<Args>(args)...);
0088 }
0089 };
0090
0091 }
0092 ABSL_NAMESPACE_END
0093 }
0094
0095 #endif