@@ -37,6 +37,107 @@ class GenericConfiguration : public IConfiguration<E> {
3737 using SettingVariant = typename IConfiguration<E>::SettingVariant;
3838 using DefaultConfigMap = std::unordered_map<E, SettingVariant>;
3939
40+ /* *
41+ * @brief Get the default type for a specific enum value
42+ *
43+ * @param enum_value The enum value to get the type for
44+ * @return std::string A string representation of the type
45+ */
46+ std::string GetDefaultValueType (E enum_value) const
47+ {
48+ auto it = defaults_.find (enum_value);
49+ if (it == defaults_.end ()) {
50+ throw std::runtime_error (" No default setting found for this enum value" );
51+ }
52+
53+ return std::visit ([](const auto & setting) -> std::string {
54+ using ValueType = std::decay_t <decltype (setting.Value ())>;
55+
56+ if constexpr (std::is_same_v<ValueType, int >) {
57+ return " int" ;
58+ }
59+ else if constexpr (std::is_same_v<ValueType, float >) {
60+ return " float" ;
61+ }
62+ else if constexpr (std::is_same_v<ValueType, double >) {
63+ return " double" ;
64+ }
65+ else if constexpr (std::is_same_v<ValueType, std::string>) {
66+ return " string" ;
67+ }
68+ else if constexpr (std::is_same_v<ValueType, bool >) {
69+ return " bool" ;
70+ }
71+ else {
72+ return " unknown" ;
73+ }
74+ },
75+ it->second );
76+ }
77+
78+ /* *
79+ * @brief Function to check if a type matches the default type
80+ *
81+ * @param enum_value The enum value to check
82+ * @return The expected type as a string
83+ */
84+ std::function<std::string(E)> GetTypeChecker () const
85+ {
86+ return [this ](E enum_value) -> std::string {
87+ return this ->GetDefaultValueType (enum_value);
88+ };
89+ }
90+
91+ /* *
92+ * @brief Check if the given type matches the default type for the enum value
93+ *
94+ * @tparam T The type to check
95+ * @param enum_value The enum value to check against
96+ * @return true if the types match
97+ * @return false if the types don't match
98+ */
99+ template <typename T>
100+ bool IsCorrectType (E enum_value) const
101+ {
102+ std::string type_name;
103+
104+ if constexpr (std::is_same_v<T, int >) {
105+ type_name = " int" ;
106+ }
107+ else if constexpr (std::is_same_v<T, float >) {
108+ type_name = " float" ;
109+ }
110+ else if constexpr (std::is_same_v<T, double >) {
111+ type_name = " double" ;
112+ }
113+ else if constexpr (std::is_same_v<T, std::string>) {
114+ type_name = " string" ;
115+ }
116+ else if constexpr (std::is_same_v<T, bool >) {
117+ type_name = " bool" ;
118+ }
119+ else {
120+ type_name = " unknown" ;
121+ }
122+
123+ return type_name == GetDefaultValueType (enum_value);
124+ }
125+
126+ /* *
127+ * @brief Type-safe getter with runtime type checking against defaults
128+ * This method is provided for backward compatibility or advanced use cases
129+ *
130+ * @tparam EnumValue The enum value to retrieve
131+ * @tparam T The requested type
132+ * @return The setting value with the correct type
133+ * @throws std::runtime_error if the type doesn't match the default type
134+ */
135+ template <E EnumValue, typename T>
136+ const T& GetTypedValue () const
137+ {
138+ return GetSetting (EnumValue).template Value <T>();
139+ }
140+
40141 /* *
41142 * @brief Constructor with filepath and default configurations
42143 *
@@ -82,6 +183,26 @@ class GenericConfiguration : public IConfiguration<E> {
82183 throw std::runtime_error (" Configuration not found" );
83184 }
84185
186+ /* *
187+ * @brief Const version of GetSettingVariant
188+ */
189+ SettingVariant GetSettingVariant (E config_name) const
190+ {
191+ // Check if setting exists in active settings
192+ auto it = settings_.find (config_name);
193+ if (it != settings_.end ()) {
194+ return it->second ;
195+ }
196+
197+ // Fall back to defaults if not in active settings
198+ auto default_it = defaults_.find (config_name);
199+ if (default_it != defaults_.end ()) {
200+ return default_it->second ;
201+ }
202+
203+ throw std::runtime_error (" Configuration not found" );
204+ }
205+
85206 /* *
86207 * @brief Implementation of UpdateSettingInt from IConfiguration
87208 */
@@ -122,6 +243,17 @@ class GenericConfiguration : public IConfiguration<E> {
122243 return UpdateSettingImpl<bool >(config_name, value);
123244 }
124245
246+ /* *
247+ * @brief Get a setting with type checking based on defaults
248+ *
249+ * @param config_name The configuration name
250+ * @return GenericSetting<E> A type-safe wrapper for the setting
251+ */
252+ GenericSetting<E> GetSetting (E config_name) override
253+ {
254+ return GenericSetting<E>(GetSettingVariant (config_name), config_name, GetTypeChecker ());
255+ }
256+
125257 /* *
126258 * @brief Save the configuration to file
127259 *
@@ -152,6 +284,16 @@ class GenericConfiguration : public IConfiguration<E> {
152284 return settings_;
153285 }
154286
287+ /* *
288+ * @brief Get the default settings map
289+ *
290+ * @return const DefaultConfigMap& The default settings
291+ */
292+ const DefaultConfigMap& GetDefaults () const
293+ {
294+ return defaults_;
295+ }
296+
155297 /* *
156298 * @brief Update settings directly (useful for serializers)
157299 *
@@ -162,6 +304,43 @@ class GenericConfiguration : public IConfiguration<E> {
162304 settings_ = new_settings;
163305 }
164306
307+ /* *
308+ * @brief Type-safe update method that checks at runtime if the type matches the default
309+ *
310+ * @tparam EnumValue Enum value to update
311+ * @tparam T Type of the value
312+ * @param value New value
313+ * @return true if update was successful
314+ * @throws std::runtime_error if the type doesn't match the default type
315+ */
316+ template <E EnumValue, typename T>
317+ bool UpdateTypedSetting (T value)
318+ {
319+ if (!IsCorrectType<T>(EnumValue)) {
320+ throw std::runtime_error (" Type mismatch: The provided type doesn't match the type in default configuration" );
321+ }
322+
323+ return UpdateSettingImpl<T>(EnumValue, value);
324+ }
325+
326+ /* *
327+ * @brief Update a setting with a more natural syntax
328+ *
329+ * @tparam T Type of the value
330+ * @param config_name The configuration name
331+ * @param value The new value
332+ * @return true if successful
333+ */
334+ template <typename T>
335+ bool UpdateSettingValue (E config_name, T value)
336+ {
337+ if (!IsCorrectType<T>(config_name)) {
338+ throw std::runtime_error (" Type mismatch: The provided type doesn't match the type in default configuration" );
339+ }
340+
341+ return UpdateSettingImpl<T>(config_name, value);
342+ }
343+
165344private:
166345 /* *
167346 * @brief Implementation of setting update logic
0 commit comments