36#ifndef DETERMINISTIC_RANDOM_H
37#define DETERMINISTIC_RANDOM_H
41#define _NODISCARD [[nodiscard]]
46#ifndef DOXYGEN_SHOULD_SKIP_THIS
49 template <
class _Diff,
class _Urng>
class _Rng_from_urng
52 using _Ty0 = std::make_unsigned_t<_Diff>;
53 using _Ty1 =
typename _Urng::result_type;
56 std::conditional_t<
sizeof(_Ty1) <
sizeof(_Ty0), _Ty0, _Ty1>;
58 explicit _Rng_from_urng(_Urng& _Func)
59 : _Ref(_Func), _Bits(
sizeof(
char) *
sizeof(_Udiff)),
62 for (; (_Urng::max)() - (_Urng::min)() < _Bmask; _Bmask >>= 1) {
67 _Diff operator()(_Diff _Index)
73 while (_Mask < _Udiff(_Index - 1)) {
83 if (_Ret / _Index < _Mask / _Index ||
84 _Mask % _Index == _Udiff(_Index - 1)) {
85 return static_cast<_Diff
>(_Ret % _Index);
90 _Udiff _Get_all_bits()
94 for (
size_t _Num = 0; _Num <
sizeof(char) *
sizeof(_Udiff);
104 _Rng_from_urng(
const _Rng_from_urng&) =
delete;
105 _Rng_from_urng& operator=(
const _Rng_from_urng&) =
delete;
111 _Udiff _Val = _Ref() - (_Urng::min)();
113 if (_Val <= _Bmask) {
125 template <
class _Ty =
int>
class uniform_int
128 using result_type = _Ty;
132 using distribution_type = uniform_int;
134 explicit param_type(result_type _Min0 = 0, result_type _Max0 = 9)
139 _NODISCARD
bool operator==(
const param_type& _Right)
const
141 return _Min == _Right._Min && _Max == _Right._Max;
144 _NODISCARD
bool operator!=(
const param_type& _Right)
const
146 return !(*
this == _Right);
149 _NODISCARD result_type a()
const
154 _NODISCARD result_type b()
const
159 void _Init(_Ty _Min0, _Ty _Max0)
161 assert(_Min0 <= _Max0);
171 explicit uniform_int(_Ty _Min0 = 0, _Ty _Max0 = 9) : _Par(_Min0, _Max0)
175 explicit uniform_int(
const param_type& _Par0) : _Par(_Par0)
179 _NODISCARD result_type a()
const
184 _NODISCARD result_type b()
const
189 _NODISCARD param_type param()
const
194 void param(
const param_type& _Par0)
199 _NODISCARD result_type(min)()
const
204 _NODISCARD result_type(max)()
const
213 template <
class _Engine>
214 _NODISCARD result_type operator()(_Engine& _Eng)
const
216 return _Eval(_Eng, _Par._Min, _Par._Max);
219 template <
class _Engine>
220 _NODISCARD result_type operator()(_Engine& _Eng,
221 const param_type& _Par0)
const
223 return _Eval(_Eng, _Par0._Min, _Par0._Max);
226 template <
class _Engine>
227 _NODISCARD result_type operator()(_Engine& _Eng, result_type _Nx)
const
229 return _Eval(_Eng, 0, _Nx - 1);
232 template <
class _Elem,
class _Traits>
233 std::basic_istream<_Elem, _Traits>& _Read(
234 std::basic_istream<_Elem, _Traits>& _Istr)
238 _Istr >> _Min0 >> _Max0;
239 _Par._Init(_Min0, _Max0);
243 template <
class _Elem,
class _Traits>
244 std::basic_ostream<_Elem, _Traits>& _Write(
245 std::basic_ostream<_Elem, _Traits>& _Ostr)
const
247 return _Ostr << _Par._Min <<
' ' << _Par._Max;
251 using _Uty = std::make_unsigned_t<_Ty>;
253 template <
class _Engine>
254 result_type _Eval(_Engine& _Eng, _Ty _Min, _Ty _Max)
const
256 _Rng_from_urng<_Uty, _Engine> _Rng(_Eng);
258 const _Uty _Umin = _Adjust(_Uty(_Min));
259 const _Uty _Umax = _Adjust(_Uty(_Max));
263 if (_Umax - _Umin == _Uty(-1)) {
264 _Uret =
static_cast<_Uty
>(_Rng._Get_all_bits());
267 _Uret =
static_cast<_Uty
>(
268 _Rng(
static_cast<_Uty
>(_Umax - _Umin + 1)));
271 return _Ty(_Adjust(
static_cast<_Uty
>(_Uret + _Umin)));
274 static _Uty _Adjust(_Uty _Uval)
276 return _Adjust(_Uval, std::is_signed<_Ty>());
279 static _Uty _Adjust(_Uty _Uval, std::true_type)
281 const _Uty _Adjuster = (_Uty(-1) >> 1) + 1;
283 if (_Uval < _Adjuster) {
284 return static_cast<_Uty
>(_Uval + _Adjuster);
287 return static_cast<_Uty
>(_Uval - _Adjuster);
291 static _Uty _Adjust(_Uty _Uval, std::false_type)
299 template <
class _Elem,
class _Traits,
class _Ty>
300 std::basic_istream<_Elem, _Traits>& operator>>(
301 std::basic_istream<_Elem, _Traits>& _Istr, uniform_int<_Ty>& _Dist)
303 return _Dist._Read(_Istr);
306 template <
class _Elem,
class _Traits,
class _Ty>
307 std::basic_ostream<_Elem, _Traits>& operator<<(
308 std::basic_ostream<_Elem, _Traits>& _Ostr,
309 const uniform_int<_Ty>& _Dist)
311 return _Dist._Write(_Ostr);
315 template <
class _Ty =
int>
316 class uniform_int_distribution :
public uniform_int<_Ty>
322 using _Mybase = uniform_int<_Ty>;
323 using _Mypbase =
typename _Mybase::param_type;
324 using result_type =
typename _Mybase::result_type;
326 struct param_type :
public _Mypbase
328 using distribution_type = uniform_int_distribution;
331 result_type _Min0 = 0,
332 result_type _Max0 = (std::numeric_limits<_Ty>::max)())
333 : _Mypbase(_Min0, _Max0)
337 param_type(
const _Mypbase& _Right) : _Mypbase(_Right)
342 explicit uniform_int_distribution(
343 _Ty _Min0 = 0, _Ty _Max0 = (std::numeric_limits<_Ty>::max)())
344 : _Mybase(_Min0, _Max0)
348 explicit uniform_int_distribution(
const param_type& _Par0)
355 _NODISCARD
bool operator==(
const uniform_int_distribution<_Ty>& _Left,
356 const uniform_int_distribution<_Ty>& _Right)
358 return _Left.param() == _Right.param();
362 _NODISCARD
bool operator!=(
const uniform_int_distribution<_Ty>& _Left,
363 const uniform_int_distribution<_Ty>& _Right)
365 return !(_Left == _Right);
372#ifndef DOXYGEN_SHOULD_SKIP_THIS
374#define _NRAND(eng, resty) \
375 (std::generate_canonical<resty, static_cast<size_t>(-1)>(eng))
378 template <
class _Ty =
double>
class uniform_real
381 using result_type = _Ty;
385 using distribution_type = uniform_real;
387 explicit param_type(_Ty _Min0 = _Ty{0}, _Ty _Max0 = _Ty{1})
392 _NODISCARD
bool operator==(
const param_type& _Right)
const
394 return _Min == _Right._Min && _Max == _Right._Max;
397 _NODISCARD
bool operator!=(
const param_type& _Right)
const
399 return !(*
this == _Right);
402 _NODISCARD result_type a()
const
407 _NODISCARD result_type b()
const
412 void _Init(_Ty _Min0, _Ty _Max0)
426 explicit uniform_real(_Ty _Min0 = _Ty{0}, _Ty _Max0 = _Ty{1})
431 explicit uniform_real(
const param_type& _Par0) : _Par(_Par0)
435 _NODISCARD result_type a()
const
440 _NODISCARD result_type b()
const
445 _NODISCARD param_type param()
const
450 void param(
const param_type& _Par0)
455 _NODISCARD result_type(min)()
const
460 _NODISCARD result_type(max)()
const
469 template <
class _Engine>
470 _NODISCARD result_type operator()(_Engine& _Eng)
const
472 return _Eval(_Eng, _Par);
475 template <
class _Engine>
476 _NODISCARD result_type operator()(_Engine& _Eng,
477 const param_type& _Par0)
const
479 return _Eval(_Eng, _Par0);
482 template <
class _Elem,
class _Traits>
483 std::basic_istream<_Elem, _Traits>& _Read(
484 std::basic_istream<_Elem, _Traits>& _Istr)
490 _Par._Init(_Min0, _Max0);
494 template <
class _Elem,
class _Traits>
495 std::basic_ostream<_Elem, _Traits>& _Write(
496 std::basic_ostream<_Elem, _Traits>& _Ostr)
const
498 _Out(_Ostr, _Par._Min);
499 _Out(_Ostr, _Par._Max);
504 template <
class _Engine>
505 result_type _Eval(_Engine& _Eng,
const param_type& _Par0)
const
507 return _NRAND(_Eng, _Ty) * (_Par0._Max - _Par0._Min) + _Par0._Min;
513 template <
class _Elem,
class _Traits,
class _Ty>
514 std::basic_istream<_Elem, _Traits>& operator>>(
515 std::basic_istream<_Elem, _Traits>& _Istr, uniform_real<_Ty>& _Dist)
517 return _Dist._Read(_Istr);
520 template <
class _Elem,
class _Traits,
class _Ty>
521 std::basic_ostream<_Elem, _Traits>&
operator<<(
522 std::basic_ostream<_Elem, _Traits>& _Ostr,
523 const uniform_real<_Ty>& _Dist)
525 return _Dist._Write(_Ostr);
529 template <
class _Ty =
double>
530 class uniform_real_distribution :
public uniform_real<_Ty>
535 using _Mybase = uniform_real<_Ty>;
536 using _Mypbase =
typename _Mybase::param_type;
537 using result_type =
typename _Mybase::result_type;
539 struct param_type :
public _Mypbase
541 using distribution_type = uniform_real_distribution;
543 explicit param_type(_Ty _Min0 = _Ty{0}, _Ty _Max0 = _Ty{1})
544 : _Mypbase(_Min0, _Max0)
548 param_type(
const _Mypbase& _Right) : _Mypbase(_Right)
553 explicit uniform_real_distribution(_Ty _Min0 = _Ty{0},
555 : _Mybase(_Min0, _Max0)
559 explicit uniform_real_distribution(
const param_type& _Par0)
566 _NODISCARD
bool operator==(
const uniform_real_distribution<_Ty>& _Left,
567 const uniform_real_distribution<_Ty>& _Right)
569 return _Left.param() == _Right.param();
573 _NODISCARD
bool operator!=(
const uniform_real_distribution<_Ty>& _Left,
574 const uniform_real_distribution<_Ty>& _Right)
576 return !(_Left == _Right);
Definition: deterministicRandom.h:44
std::ostream & operator<<(std::ostream &os, const PolicyStats &policyStats)
Overload of the stream output operator for the PolicyStats class.
Definition: policyStats.cpp:197