#pragma once
#include <random>
// C++11随机数
class random_help
{
private:
std::default_random_engine _engine;
std::mt19937_64 _mt19937_gen;
std::random_device _rd;
private:
// noncopyable
random_help(random_help&&)=delete;
random_help& operator=(random_help&&)=delete;
random_help(random_help const&)=delete;
random_help& operator=(random_help const&)=delete;
public:
random_help()
:_mt19937_gen(_rd())
{}
~random_help()
{}
template<class _Ty1, class _Ty2, typename std::enable_if<std::is_integral<_Ty1>::value && std::enable_if<std::is_integral<_Ty1>::value, bool>::type = true>
auto operator()(_Ty1 min_, _Ty2 max_)->decltype(min_ + max_)
{
if (min_ == max_)
return min_;
using _Ty = decltype(min_ + max_);
_Ty _min = static_cast<_Ty>(min_);
_Ty _max = static_cast<_Ty>(max_);
if (_min > _max)
{
std::swap(_min, _max);
}
return std::uniform_int_distribution<_Ty>(_min, _max)(_mt19937_gen);
}
template<class _Ty1, class _Ty2, typename std::enable_if<std::is_floating_point<_Ty1>::value && std::enable_if<std::is_floating_point<_Ty1>::value, bool>::type = true>
auto operator()(_Ty1 min_, _Ty2 max_)->decltype(min_ + max_)
{
if (min_ == max_)
return min_;
using _Ty = decltype(min_ + max_);
_Ty _min = static_cast<_Ty>(min_);
_Ty _max = static_cast<_Ty>(max_);
if (_min > _max)
{
std::swap(_min, _max);
}
// uniform_real_distribution 是 [ ),用std::nextafter修正使取到[ ]
if (std::is_same<float, _Ty>::value || std::is_same<unsigned float, _Ty>::value)
return std::uniform_real_distribution<_Ty>(_min, std::nextafter(_max, FLT_MAX))(_mt19937_gen);
else if (std::is_same<double, _Ty>::value || std::is_same<unsigned double, _Ty>::value)
return std::uniform_real_distribution<_Ty>(_min, std::nextafter(_max, DBL_MAX))(_mt19937_gen);
else // if (std::is_same<long double, _Ty>::value || std::is_same<unsigned long double, _Ty>::value)
return std::uniform_real_distribution<_Ty>(_min, std::nextafter(_max, LDBL_MAX))(_mt19937_gen);
}
};