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_STATIC_ASSERT_RNG_RDRAND_ENGINE_RESULT_TYPE(ResultType) \ 43 VSMC_STATIC_ASSERT(((sizeof(ResultType) == sizeof(std::uint16_t) && \ 44 std::is_unsigned<ResultType>::value) || \ 45 (sizeof(ResultType) == sizeof(std::uint32_t) && \ 46 std::is_unsigned<ResultType>::value) || \ 47 (sizeof(ResultType) == sizeof(std::uint64_t) && \ 48 std::is_unsigned<ResultType>::value)), \ 49 "**RDRANDEngine** USED WITH ResultType OTHER THAN UNSIGNED 16/32/64 " \ 52 #define VSMC_STATIC_ASSERT_RNG_RDRAND_ENGINE \ 53 VSMC_STATIC_ASSERT_RNG_RDRAND_ENGINE_RESULT_TYPE(ResultType); 55 #define VSMC_RUNTIME_WARNING_RNG_RDRAND_ENGINE_NTRIAL(ntrial, NTrialMax) \ 56 VSMC_RUNTIME_WARNING((ntrial < NTrialMax), \ 57 "**RDRAND::generate** MAXIMUM NUMBER OF TRIALS EXCEEDED") 64 template <
typename UIntType, std::
size_t W>
65 inline bool rdrand(UIntType *, std::integral_constant<std::size_t, W>);
69 template <
typename UIntType>
71 UIntType *rand, std::integral_constant<std::size_t,
sizeof(std::uint16_t)>)
74 int cf = _rdrand16_step(&r);
75 *rand =
static_cast<UIntType
>(r);
82 template <
typename UIntType>
84 UIntType *rand, std::integral_constant<std::size_t,
sizeof(
std::uint32_t)>)
87 int cf = _rdrand32_step(&r);
88 *rand =
static_cast<UIntType
>(r);
95 template <
typename UIntType>
97 UIntType *rand, std::integral_constant<std::size_t,
sizeof(
std::uint64_t)>)
99 #if defined(VSMC_MSVC) || (defined(VSMC_INTEL) && VSMC_INTEL_VERSION < 1600) 102 unsigned long long r;
104 int cf = _rdrand64_step(&r);
105 *rand =
static_cast<UIntType
>(r);
112 template <
typename ResultType, std::
size_t NTrialMax = VSMC_RDRAND_NTRIAL_MAX>
124 template <
typename SeedSeq>
134 template <
typename SeedSeq>
142 return generate(std::integral_constant<bool, NTrialMax != 0>());
149 return std::numeric_limits<result_type>::min
VSMC_MNE();
154 return std::numeric_limits<result_type>::max
VSMC_MNE();
169 template <
typename CharT,
typename CharTraits>
171 std::basic_ostream<CharT, CharTraits> &os,
177 template <
typename CharT,
typename CharTraits>
179 std::basic_istream<CharT, CharTraits> &is,
189 std::size_t ntrial = 0;
192 bool success = rdrand<result_type>(&r,
193 std::integral_constant<std::size_t, sizeof(result_type)>());
194 if (success || ntrial > NTrialMax)
206 bool success = rdrand<result_type>(&r,
207 std::integral_constant<std::size_t, sizeof(result_type)>());
230 #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_STATIC_ASSERT_RNG_RDRAND_ENGINE
#define VSMC_RUNTIME_WARNING_RNG_RDRAND_ENGINE_NTRIAL(ntrial, NTrialMax)