Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:40:55

0001 //
0002 // Copyright 2018 The Abseil Authors.
0003 //
0004 // Licensed under the Apache License, Version 2.0 (the "License");
0005 // you may not use this file except in compliance with the License.
0006 // You may obtain a copy of the License at
0007 //
0008 //      https://www.apache.org/licenses/LICENSE-2.0
0009 //
0010 // Unless required by applicable law or agreed to in writing, software
0011 // distributed under the License is distributed on an "AS IS" BASIS,
0012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013 // See the License for the specific language governing permissions and
0014 // limitations under the License.
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 // DistributionCaller provides an opportunity to overload the general
0032 // mechanism for calling a distribution, allowing for mock-RNG classes
0033 // to intercept such calls.
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   // SFINAE to detect whether the URBG type includes a member matching
0039   // bool InvokeMock(base_internal::FastTypeIdType, void*, void*).
0040   //
0041   // These live inside BitGenRef so that they have friend access
0042   // to MockingBitGen. (see similar methods in DistributionCaller).
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   // Default implementation of distribution caller.
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   // Mock implementation of distribution caller.
0065   // The underlying KeyT must match the KeyT constructed by MockOverloadSet.
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   // Default implementation of distribution caller.
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 }  // namespace random_internal
0092 ABSL_NAMESPACE_END
0093 }  // namespace absl
0094 
0095 #endif  // ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_