32 #ifndef VSMC_RNG_RDRAND_HPP 33 #define VSMC_RNG_RDRAND_HPP 36 #include <immintrin.h> 38 #ifndef VSMC_RNG_RDRAND_NTRIAL_MAX 39 #define VSMC_RNG_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<int, W>);
56 template <
typename UIntType>
57 inline bool rdrand(UIntType *
rand, std::integral_constant<int, 16>)
60 int cf = _rdrand16_step(&r);
61 *rand =
static_cast<UIntType
>(r);
68 template <
typename UIntType>
69 inline bool rdrand(UIntType *
rand, std::integral_constant<int, 32>)
72 int cf = _rdrand32_step(&r);
73 *rand =
static_cast<UIntType
>(r);
80 template <
typename UIntType>
81 inline bool rdrand(UIntType *
rand, std::integral_constant<int, 64>)
83 #if defined(VSMC_MSVC) || (defined(VSMC_INTEL) && VSMC_INTEL_VERSION < 1600) 88 int cf = _rdrand64_step(&r);
89 *rand =
static_cast<UIntType
>(r);
96 template <
typename ResultType,
100 static_assert(std::is_unsigned<ResultType>::value,
101 "**RDRANDEngine** USED WITH ResultType OTHER THAN UNSIGNED INTEGER " 104 static_assert(std::numeric_limits<ResultType>::digits == 16 ||
105 std::numeric_limits<ResultType>::digits == 32 ||
106 std::numeric_limits<ResultType>::digits == 64,
107 "**RDRANDEngine** USED WITH ResultType OF SIZE OTHER THAN 16, 32 OR " 115 template <
typename SeedSeq>
124 template <
typename SeedSeq>
132 return generate(std::integral_constant<bool, NTrialMax != 0>());
139 return std::numeric_limits<result_type>::min();
144 return std::numeric_limits<result_type>::max();
159 template <
typename CharT,
typename CharTraits>
161 std::basic_ostream<CharT, CharTraits> &os,
167 template <
typename CharT,
typename CharTraits>
169 std::basic_istream<CharT, CharTraits> &is,
179 std::size_t ntrial = 0;
182 bool success = rdrand<result_type>(
183 &r, std::integral_constant<int,
184 std::numeric_limits<result_type>::digits>());
185 if (success || ntrial > NTrialMax)
197 bool success = rdrand<result_type>(
198 &r, std::integral_constant<int,
199 std::numeric_limits<result_type>::digits>());
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)
#define VSMC_RNG_RDRAND_NTRIAL_MAX
RDRANDEngine(result_type=0)
friend std::basic_istream< CharT, CharTraits > & operator>>(std::basic_istream< CharT, CharTraits > &is, RDRANDEngine< ResultType, NTrialMax > &)
bool rdrand(UIntType *, std::integral_constant< int, W >)
Invoke the RDRAND instruction and return the carry flag.
void rand(RNGType &rng, ArcsineDistribution< RealType > &dist, std::size_t N, RealType *r)
#define VSMC_RUNTIME_WARNING_RNG_RDRAND_ENGINE_NTRIAL(ntrial, NTrialMax)