1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#pragma once


#include <cassert><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <type_traits><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include "internal/dev_env.hpp"


namespace uni {


template<class Engine>
struct random_adaptor {
    using result_type = typename Engine::result_type;
    using signed_result_type = typename std::make_signed_t<result_type>;

  private:
    Engine engine;

  public:
    static constexpr result_type MIN = Engine::min();
    static constexpr result_type MAX = Engine::max();

    static constexpr result_type min() noexcept(NO_EXCEPT) { return MIN; }
    static constexpr result_type max() noexcept(NO_EXCEPT) { return MAX; }

    constexpr random_adaptor(unsigned long seed = 3141592653UL) noexcept(NO_EXCEPT) { this->engine.seed(seed); };

    inline constexpr result_type operator()() noexcept(NO_EXCEPT) {
        return this->engine();
    }

    inline constexpr result_type operator()(const result_type sup) noexcept(NO_EXCEPT) {
        assert(0 < sup);
        return this->engine() % sup;
    }
    inline constexpr signed_result_type operator()(const signed_result_type min, const signed_result_type sup) noexcept(NO_EXCEPT) {
        assert(min < sup);
        return min + (*this)(sup - min);
    };

    template<class T = double>
    inline constexpr auto real() noexcept(NO_EXCEPT) {
        const auto v = static_cast<T>((this->engine() + 0.5) / (1.0 + this->max()));
        return static_cast<T>((this->operator()() + v) / (1.0 + this->max()));
    }
};


} // namespace uni