32 #ifndef VSMC_RNG_RDRAND_HPP 33 #define VSMC_RNG_RDRAND_HPP 36 #include <immintrin.h> 38 #ifndef VSMC_RDRAND_NTRIAL_MAX 39 #define VSMC_RDRAND_NTRIAL_MAX 0 42 #define VSMC_RUNTIME_WARNING_RNG_RDRAND_ENGINE_NTRIAL(ntrial, NTrialMax) \ 43 VSMC_RUNTIME_WARNING((ntrial < NTrialMax), \ 44 "**RDRAND::generate** MAXIMUM NUMBER OF TRIALS EXCEEDED") 51 template <
typename UIntType, std::
size_t W>
52 inline bool rdrand(UIntType *, std::integral_constant<std::size_t, W>);
56 template <
typename UIntType>
58 UIntType *rand, std::integral_constant<std::size_t,
sizeof(std::uint16_t)>)
61 int cf = _rdrand16_step(&r);
62 *rand =
static_cast<UIntType
>(r);
69 template <
typename UIntType>
71 UIntType *rand, std::integral_constant<std::size_t,
sizeof(
std::uint32_t)>)
74 int cf = _rdrand32_step(&r);
75 *rand =
static_cast<UIntType
>(r);
82 template <
typename UIntType>
84 UIntType *rand, std::integral_constant<std::size_t,
sizeof(
std::uint64_t)>)
86 #if defined(VSMC_MSVC) || (defined(VSMC_INTEL) && VSMC_INTEL_VERSION < 1600) 91 int cf = _rdrand64_step(&r);
92 *rand =
static_cast<UIntType
>(r);
99 template <
typename ResultType, std::
size_t NTrialMax = VSMC_RDRAND_NTRIAL_MAX>
102 static_assert(std::is_unsigned<ResultType>::value,
103 "**RDRANDEngine** USED WITH ResultType OTHER THAN UNSIGNED INTEGER " 106 static_assert(
sizeof(ResultType) ==
sizeof(std::uint16_t) ||
109 "**RDRANDEngine** USED WITH ResultType OF SIZE OTHER THAN 16, 32 OR " 117 template <
typename SeedSeq>
126 template <
typename SeedSeq>
134 return generate(std::integral_constant<bool, NTrialMax != 0>());
141 return std::numeric_limits<result_type>::min();
146 return std::numeric_limits<result_type>::max();
161 template <
typename CharT,
typename CharTraits>
163 std::basic_ostream<CharT, CharTraits> &os,
169 template <
typename CharT,
typename CharTraits>
171 std::basic_istream<CharT, CharTraits> &is,
181 std::size_t ntrial = 0;
184 bool success = rdrand<result_type>(&r,
185 std::integral_constant<std::size_t, sizeof(result_type)>());
186 if (success || ntrial > NTrialMax)
198 bool success = rdrand<result_type>(&r,
199 std::integral_constant<std::size_t, sizeof(result_type)>());
222 #endif // VSMC_RNG_RDRAND_HPP
friend bool operator==(const RDRANDEngine< ResultType, NTrialMax > &, const RDRANDEngine< ResultType, NTrialMax > &)
static constexpr result_type max()
friend bool operator!=(const RDRANDEngine< ResultType, NTrialMax > &, const RDRANDEngine< ResultType, NTrialMax > &)
static constexpr result_type min()
void seed(SeedSeq &, typename std::enable_if< internal::is_seed_seq< SeedSeq, result_type >::value >::type *=nullptr)
RDRANDEngine(SeedSeq &, typename std::enable_if< internal::is_seed_seq< SeedSeq, result_type, RDRANDEngine< ResultType, NTrialMax >>::value >::type *=nullptr)
friend std::basic_ostream< CharT, CharTraits > & operator<<(std::basic_ostream< CharT, CharTraits > &os, const RDRANDEngine< ResultType, NTrialMax > &)
void discard(std::size_t)
RDRANDEngine(result_type=0)
bool rdrand(UIntType *, std::integral_constant< std::size_t, W >)
Invoke the RDRAND instruction and return the carry flag.
friend std::basic_istream< CharT, CharTraits > & operator>>(std::basic_istream< CharT, CharTraits > &is, RDRANDEngine< ResultType, NTrialMax > &)
#define VSMC_RUNTIME_WARNING_RNG_RDRAND_ENGINE_NTRIAL(ntrial, NTrialMax)