OGLplus  (0.59.0) a C++ wrapper for rendering APIs

application_config.hpp
Go to the documentation of this file.
1 
9 #ifndef EAGINE_APPLICATION_CONFIG_HPP
10 #define EAGINE_APPLICATION_CONFIG_HPP
11 
12 #include "main_ctx_object.hpp"
13 #include "program_args.hpp"
14 #include "valid_if/decl.hpp"
15 #include "value_tree/wrappers.hpp"
16 #include <memory>
17 #include <vector>
18 
19 namespace eagine {
20 //------------------------------------------------------------------------------
21 class master_ctx;
22 class application_config_impl;
23 
30 public:
31  application_config(main_ctx_parent parent) noexcept
32  : main_ctx_object{EAGINE_ID(AppConfig), parent} {}
33 
35  auto is_set(string_view key, string_view tag = {}) noexcept -> bool {
36  if(const auto attr{_find_comp_attr(key, tag)}) {
37  bool flag{false};
38  if(attr.select_value(flag, application_config_tag())) {
39  return flag;
40  }
41  }
42  if(const auto arg{_find_prog_arg(key)}) {
43  bool result{true};
44  arg.parse_next(
45  result, application_config_tag(), log_debug_stream());
46  return result;
47  }
48  if(const auto opt_val{_eval_env_var(key)}) {
49  if(auto converted{from_string<bool>(extract(opt_val))}) {
50  return extract(converted);
51  }
52  }
53  return false;
54  }
55 
57  template <typename T>
58  auto fetch(string_view key, T& dest, string_view tag = {}) noexcept
59  -> bool {
60  if(const auto arg{_find_prog_arg(key)}) {
61  if(arg.parse_next(
62  dest, application_config_tag(), log_error_stream())) {
63  return true;
64  } else {
65  log_error("could not parse configuration value '${value}'")
66  .arg(EAGINE_ID(key), key)
67  .arg(EAGINE_ID(value), arg.get());
68  }
69  }
70  if(const auto opt_val{_eval_env_var(key)}) {
71  if(auto converted{from_string<T>(extract(opt_val))}) {
72  dest = std::move(extract(converted));
73  return true;
74  } else {
75  log_error("could not convert configuration value '${value}'")
76  .arg(EAGINE_ID(key), key)
77  .arg(EAGINE_ID(value), extract(opt_val));
78  }
79  }
80  if(const auto attr{_find_comp_attr(key, tag)}) {
81  if(attr.select_value(dest, application_config_tag())) {
82  return true;
83  } else {
84  log_error("could not fetch configuration value '${key}'")
85  .arg(EAGINE_ID(key), key);
86  }
87  }
88  return false;
89  }
90 
92  template <typename T, typename A>
93  auto fetch(
94  string_view key,
95  std::vector<T, A>& dest,
96  string_view tag = {}) noexcept {
97  const auto arg_name{_prog_arg_name(key)};
98  for(auto arg : _prog_args()) {
99  if(arg.is_tag(arg_name)) {
100  T temp{};
101  if(arg.parse_next(
102  temp, application_config_tag(), log_error_stream())) {
103  dest.emplace_back(std::move(temp));
104  } else {
105  log_error("could not parse configuration value '${value}'")
106  .arg(EAGINE_ID(key), key)
107  .arg(EAGINE_ID(value), arg.get());
108  return false;
109  }
110  }
111  }
112  if(const auto opt_val{_eval_env_var(key)}) {
113  if(auto converted{from_string<T>(extract(opt_val))}) {
114  dest.emplace_back(std::move(extract(converted)));
115  } else {
116  log_error("could not convert configuration value '${value}'")
117  .arg(EAGINE_ID(key), key)
118  .arg(EAGINE_ID(value), extract(opt_val));
119  return false;
120  }
121  }
122  if(const auto attr{_find_comp_attr(key, tag)}) {
123  const auto count = attr.value_count();
124  if(count > 0) {
125  dest.resize(dest.size() + std_size(count));
126  if(!attr.select_values(
127  tail(cover(dest), count), application_config_tag())) {
128  log_error("could not fetch configuration values '${key}'")
129  .arg(EAGINE_ID(key), key);
130  return false;
131  }
132  }
133  }
134  return true;
135  }
136 
138  template <typename T, typename P>
139  auto fetch(string_view key, valid_if<T, P>& dest, string_view tag) noexcept
140  -> bool {
141  T temp{};
142  if(fetch(key, temp, tag)) {
143  if(dest.is_valid(temp)) {
144  dest = std::move(temp);
145  return true;
146  } else {
147  log_error("value '${value}' is not valid for '${key}'")
148  .arg(EAGINE_ID(value), temp)
149  .arg(EAGINE_ID(key), key);
150  }
151  }
152  return false;
153  }
154 
156  template <typename T>
158  T temp{};
159  const auto fetched = fetch(key, temp);
160  return {std::move(temp), fetched};
161  }
162 
164  template <typename T>
165  auto init(string_view key, T& initial, string_view tag = {}) -> T {
166  fetch(key, initial, tag);
167  return initial;
168  }
169 
170 private:
171  std::shared_ptr<application_config_impl> _pimpl;
172  auto _impl() noexcept -> application_config_impl*;
173 
174  auto _find_comp_attr(string_view key, string_view tag) noexcept
175  -> valtree::compound_attribute;
176 
177  auto _prog_args() noexcept -> const program_args&;
178  auto _prog_arg_name(string_view key) noexcept -> std::string;
179  auto _find_prog_arg(string_view key) noexcept -> program_arg;
180  auto _eval_env_var(string_view key) noexcept
182 };
183 //------------------------------------------------------------------------------
184 template <typename T>
185 inline auto application_config_initial(
186  application_config& config,
187  string_view key,
188  T& initial,
189  string_view tag) -> T& {
190  config.init(key, initial, tag);
191  return initial;
192 }
193 //------------------------------------------------------------------------------
196 template <typename T, typename As = std::add_const_t<T>&>
198 public:
201  application_config& config,
202  string_view key,
203  string_view tag,
204  T initial = {}) noexcept
205  : _value{application_config_initial(config, key, initial, tag)} {}
206 
209  application_config& config,
210  string_view key,
211  T initial = {}) noexcept
212  : application_config_value{config, key, {}, initial} {}
213 
214  auto operator=(T new_value) -> auto& {
215  _value = std::move(new_value);
216  return *this;
217  }
218 
220  auto value() const noexcept -> As {
221  return _value;
222  }
223 
226  operator As() const noexcept {
227  return value();
228  }
229 
230  friend auto extract(const application_config_value& that) noexcept -> As {
231  return that.value();
232  }
233 
234 private:
235  T _value{};
236 };
237 //------------------------------------------------------------------------------
238 } // namespace eagine
239 
240 #if !EAGINE_LINK_LIBRARY || defined(EAGINE_IMPLEMENTING_LIBRARY)
241 #include <eagine/application_config.inl>
242 #endif
243 
244 #endif
Helper class used to initialize main context objects.
Definition: main_ctx_object.hpp:45
basic_string_span< const char > string_view
Alias for const string views.
Definition: string_span.hpp:116
#define EAGINE_ID(NAME)
Macro for constructing instances of eagine::identifier.
Definition: identifier.hpp:353
auto fetch(string_view key, valid_if< T, P > &dest, string_view tag) noexcept -> bool
Fetches the configuration value identified by key, into dest.
Definition: application_config.hpp:139
Base class for main context objects.
Definition: main_ctx_object.hpp:71
Common code is placed in this namespace.
Definition: eagine.hpp:21
Class for reading application configuration.
Definition: application_config.hpp:29
static constexpr auto cover(T *addr, S size) noexcept -> span_if_mutable< T >
Creates a span starting at the specified pointer and specified length.
Definition: span.hpp:465
static constexpr auto extract(api_result_value< Result, api_result_validity::never > &) noexcept -> Result &
Overload of extract for api_result_value.
Definition: c_api_wrap.hpp:270
auto fetch(string_view key, std::vector< T, A > &dest, string_view tag={}) noexcept
Fetches the configuration values identified by key, into dest.
Definition: application_config.hpp:93
application_config_value(application_config &config, string_view key, T initial={}) noexcept
Initialization from key and optional initial value.
Definition: application_config.hpp:208
auto operator=(named_logging_object &&) noexcept -> named_logging_object &=default
Move assignment operator.
auto log_debug_stream() noexcept
Returns a log entry stream for debug messages.
Definition: logger.hpp:360
auto value() const noexcept -> As
Returns the stored value converted to the As type.
Definition: application_config.hpp:220
static constexpr auto std_size(T v) noexcept
Converts argument to std size type.
Definition: types.hpp:52
auto get(string_view key, type_identity< T >={}) -> optionally_valid< T >
Returns the configuration value or type T, identified by key.
Definition: application_config.hpp:157
Class wrapping values that can be loaded from application_config.
Definition: application_config.hpp:197
auto fetch(string_view key, T &dest, string_view tag={}) noexcept -> bool
Fetches the configuration value identified by key, into dest.
Definition: application_config.hpp:58
static constexpr auto tail(basic_span< T, P, S > s, L l) noexcept -> basic_span< T, P, S >
Returns the last l elements from the back of a span.
Definition: span_algo.hpp:132
auto is_set(string_view key, string_view tag={}) noexcept -> bool
Checks is the boolean option identified by key is set to true.
Definition: application_config.hpp:35
Template type used mostly for function type-tag dispatching.
Definition: type_identity.hpp:19
auto log_error_stream() noexcept
Returns a log entry stream for error messages.
Definition: logger.hpp:367
auto init(string_view key, T &initial, string_view tag={}) -> T
Fetches the configuration value identified by key, into init.
Definition: application_config.hpp:165
application_config_value(application_config &config, string_view key, string_view tag, T initial={}) noexcept
Initialization from key, tag and optional initial value.
Definition: application_config.hpp:200
valid_if< T, valid_flag_policy > optionally_valid
Specialization of valid_if with flag indicating validity.
Definition: decl.hpp:300
auto log_error(string_view format) noexcept
Create a log message entry for error, with specified format.
Definition: logger.hpp:317

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).