VIPRA Documentation
Loading...
Searching...
No Matches
param_reader.hpp
1#pragma once
2
3#include <map>
4#include <optional>
5#include <random>
6#include <type_traits>
7#include <vector>
8
9#include "vipra/concepts/numeric.hpp"
10
11#include "vipra/random/random.hpp"
12#include "vipra/util/crtp.hpp"
13
14namespace VIPRA::Modules {
15
20template <typename module_t>
21class ParamReader : public Util::CRTP<ParamReader<module_t>> {
22 public:
23 template <typename data_t>
24 auto get_param(std::string const& type, std::string const& moduleName,
25 std::string const& paramName, VIPRA::Random::Engine& engine) const
26 -> std::optional<std::remove_cvref_t<data_t>>
27 {
28 using base_data_t = std::remove_cvref_t<data_t>;
29
30 auto singleValue =
31 this->self().template get<base_data_t>({type, moduleName, paramName});
32 if ( singleValue ) {
33 return singleValue;
34 }
35
36 auto arrayValue = this->self().template get<std::vector<base_data_t>>(
37 {type, moduleName, paramName});
38 if ( arrayValue ) {
39 return get_discrete_value<base_data_t>(arrayValue.value(), engine);
40 }
41
42 auto mapValue = this->self().template get<std::map<std::string, base_data_t>>(
43 {type, moduleName, paramName});
44 if ( mapValue ) {
45 if constexpr ( Concepts::Numeric<base_data_t> ) {
46 // NOTE(rolland): strings cannot be ranges
47 return get_range_value<base_data_t>(mapValue.value(), engine);
48 }
49 else {
50 return std::nullopt;
51 }
52 }
53
54 return std::nullopt;
55 }
56
57 private:
58 template <typename data_t>
59 auto get_discrete_value(std::vector<data_t> const& data,
60 VIPRA::Random::Engine& engine) const -> data_t
61 {
62 std::uniform_int_distribution<size_t> dist(0, data.size() - 1);
63 return data[dist(engine)];
64 }
65
66 template <typename data_t>
68 auto get_range_value(std::map<std::string, data_t> const& data,
69 VIPRA::Random::Engine& engine) const -> data_t
70 {
71 if constexpr ( std::is_floating_point_v<data_t> ) {
72 std::uniform_real_distribution<data_t> dist(data.at("min"), data.at("max"));
73 return dist(engine);
74 }
75 else if constexpr ( std::is_integral_v<data_t> ) {
76 std::uniform_int_distribution<data_t> dist(data.at("min"), data.at("max"));
77 return dist(engine);
78 }
79 else {
80 static_assert(false, "Invalid Type");
81 }
82 }
83};
84
85} // namespace VIPRA::Modules
Base ParamReader Module.
Definition param_reader.hpp:21
Psuedo Random number engine.
Definition random.hpp:22
Definition crtp.hpp:6
Checks that a type is a numeric type.
Definition numeric.hpp:13