qxLib
layered_configs_manager.h
Go to the documentation of this file.
1 /**
2 
3  @file layered_configs_manager.h
4  @author Khrapov
5  @date 12.05.2026
6  @copyright © Nick Khrapov, 2026. All right reserved.
7 
8 **/
9 #pragma once
10 
11 #include <qx/algo/contains.h>
12 #include <qx/algo/sort.h>
13 #include <qx/logger/logger.h>
14 #include <qx/patterns/singleton.h>
15 
16 #include <any>
17 #include <unordered_map>
18 
19 namespace qx
20 {
21 
22 namespace details
23 {
24 
26 {
27  cstring_view svEnvName;
28  cstring_view svFullCommandLineName;
29  cstring_view svShortCommandLineName;
30 
31  cstring_view svGroupName;
32  cstring_view svDescription;
33  bool bRequired = false;
34 
35  std::optional<std::any> (*pStringToT)(cstring_view svData);
36  cstring (*pTToString)(const std::any& data);
37  cstring_view svTypeName;
38 };
39 
40 } // namespace details
41 
42 /**
43 
44  @class layered_configs_manager
45  @brief A singleton that manages layered configuration variables
46  @details Doesn't support multithreading
47  @author Khrapov
48  @date 17.05.2026
49 
50 **/
51 class layered_configs_manager final : public singleton<layered_configs_manager>
52 {
53  template<class T>
55 
56 public:
57  /**
58  @brief Set app description. It will be shown in help message.
59  @param sAppDescription - app description
60  **/
61  void set_app_description(cstring sAppDescription) noexcept;
62 
63  /**
64  @brief Set command line arguments.
65  @details Should be called once at the beginning of the app before the first parse().
66  @param argc - number of command line arguments
67  @param argv - array of command line arguments
68  **/
69  void set_args(int argc, char* argv[]) noexcept;
70 
71  /**
72  @brief Show help message if "--help" or "-h" argument is present in command line arguments.
73  @details Should be called after set_args().
74  @retval - true if help message was shown. usually the app should exit after that
75  **/
76  bool show_help() const noexcept;
77 
78  /**
79  @brief Parse command line arguments, environment variables, and default values.
80  @details Should be called after set_args() and before get()/set() of any variable.
81  You can call it multiple times during the app lifetime, for example, to load variables from different DLLs.
82  @retval - true all required variables are present and have valid values
83  **/
84  bool parse() noexcept;
85 
86  /**
87  @brief Get variable value by runtime name.
88  @tparam T - type of variable
89  @param svRuntimeName - runtime name of variable
90  @retval - optional with variable value if it is present, has valid value and correct type
91  **/
92  template<class T>
93  std::optional<T> get(cstring_view svRuntimeName) const noexcept;
94 
95  /**
96  @brief Set variable value by runtime name. Only set if the variable type matches.
97  @tparam T - type of variable
98  @param svRuntimeName - runtime name of variable
99  @param value - new variable value
100  @retval - true if the value was set successfully
101  **/
102  template<class T>
103  bool set(cstring_view svRuntimeName, T value) noexcept;
104 
105  /**
106  @brief Clear all variables and command line arguments. You should call parse() after that to set variables again.
107  **/
108  void reset() noexcept;
109 
110 private:
111  /**
112  @brief Add a variable to the manager. Called from variable builders
113  @tparam T - type of variable
114  @param svRuntimeName - runtime name of variable
115  @param data - information about variable
116  @param defaultValue - default variable value
117  **/
118  template<class T>
119  void add_variable(
120  cstring_view svRuntimeName,
122  T defaultValue) noexcept;
123 
124 private:
125  cstring m_sAppDescription;
126  std::span<char* const> m_Args;
127 
128  std::unordered_map<cstring_view, details::layered_config_variable_data> m_VariableData;
129  std::unordered_map<cstring_view, std::any> m_DefaultVariables;
130  std::unordered_map<cstring_view, std::any> m_Variables;
131 };
132 
133 } // namespace qx
134 
A builder for creating layered_config_variable instances.
A singleton that manages layered configuration variables.
void reset() noexcept
Clear all variables and command line arguments. You should call parse() after that to set variables a...
std::optional< T > get(cstring_view svRuntimeName) const noexcept
Get variable value by runtime name.
void set_app_description(cstring sAppDescription) noexcept
Set app description. It will be shown in help message.
bool parse() noexcept
Parse command line arguments, environment variables, and default values.
bool set(cstring_view svRuntimeName, T value) noexcept
Set variable value by runtime name. Only set if the variable type matches.
bool show_help() const noexcept
Show help message if "--help" or "-h" argument is present in command line arguments.
void set_args(int argc, char *argv[]) noexcept
Set command line arguments.
Inherit the necessary singleton class from this.