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 (c) 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) = nullptr;
36  cstring (*pTToString)(const std::any& data) = nullptr;
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  Non-positive argc or null argv clears the command line arguments.
67  @param argc - number of command line arguments
68  @param argv - array of command line arguments
69  **/
70  void set_args(int argc, char* argv[]) noexcept;
71 
72  /**
73  @brief Show help message if "--help" or "-h" argument is present in command line arguments.
74  @details Should be called after set_args().
75  @retval - true if help message was shown. usually the app should exit after that
76  **/
77  bool show_help() const noexcept;
78 
79  /**
80  @brief Parse command line arguments, environment variables, and default values.
81  @details Should be called after set_args() and before get()/set() of any variable.
82  You can call it multiple times during the app lifetime, for example, to load variables from different DLLs.
83  @retval - true all required variables are present and have valid values
84  **/
85  bool parse() noexcept;
86 
87  /**
88  @brief Get variable value by runtime name.
89  @tparam T - type of variable
90  @param svRuntimeName - runtime name of variable
91  @retval - optional with variable value if it is present, has valid value and correct type
92  **/
93  template<class T>
94  std::optional<T> get(cstring_view svRuntimeName) const noexcept;
95 
96  /**
97  @brief Set variable value by runtime name. Only set if the variable type matches.
98  @tparam T - type of variable
99  @param svRuntimeName - runtime name of variable
100  @param value - new variable value
101  @retval - true if the value was set successfully
102  **/
103  template<class T>
104  bool set(cstring_view svRuntimeName, T value) noexcept;
105 
106  /**
107  @brief Clear all variables and command line arguments. You should call parse() after that to set variables again.
108  **/
109  void reset() noexcept;
110 
111 private:
112  /**
113  @brief Add a variable to the manager. Called from variable builders
114  @tparam T - type of variable
115  @param svRuntimeName - runtime name of variable
116  @param data - information about variable
117  @param defaultValue - default variable value
118  **/
119  template<class T>
120  void add_variable(
121  cstring_view svRuntimeName,
123  T defaultValue) noexcept;
124 
125 private:
126  cstring m_sAppDescription;
127  std::span<char* const> m_Args;
128 
129  std::unordered_map<cstring_view, details::layered_config_variable_data> m_VariableData;
130  std::unordered_map<cstring_view, std::any> m_DefaultVariables;
131  std::unordered_map<cstring_view, std::any> m_Variables;
132 };
133 
134 } // namespace qx
135 
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.