-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrandom.hpp
66 lines (64 loc) · 1.72 KB
/
random.hpp
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//
// Created by pcvii on 3/14/2021.
//
#ifndef TOOLSLIBRARY_RANDOM_HPP
#define TOOLSLIBRARY_RANDOM_HPP
#include "tl/algorithm.hpp"
#include "tl/concepts.hpp"
#include <random>
namespace tl::random {
/**
* Random holder should be defined as a value.
* @tparam T type of value returned by operator()
* @see if we can make this passable to a std::transform
*/
template<tl::concepts::is_integral T> struct impl
{
private:
using unsigned_t = std::make_unsigned_t<T>;
std::random_device rd{};
mutable std::mt19937 gen{ rd() };
mutable std::uniform_int_distribution<std::size_t> dis{
std::numeric_limits<unsigned_t>::min(),
std::numeric_limits<unsigned_t>::max()
};
public:
auto
operator()([[maybe_unused]] const T &unused) const
{
return static_cast<T>(dis(gen));
}
};
/**
* Fill the range with random data.
* @tparam T type going into range.
* @param out range
*/
template<tl::concepts::is_range rangeT>
requires(
std::is_integral_v<
std::decay_t<typename rangeT::value_type>>) inline void iota(rangeT &out)
{
using T = std::decay_t<typename rangeT::value_type>;
static const auto random_T = impl<T>();
tl::algorithm::transform(out, std::begin(out), [](const T &unused) -> T {
return random_T(unused);
});
}
/**
* Get a std::array with random values.
* @tparam T type stored in std::array
* @tparam count is the total number of values in the array.
* @return std::array<T,count>
*/
template<tl::concepts::is_integral T, std::size_t count>
inline auto
iota()
{
static_assert(std::is_integral_v<T>);
std::array<T, count> out{};
iota(out);
return out;
}
}// namespace tl::random
#endif// TOOLSLIBRARY_RANDOM_HPP