diff include/core/ini.h @ 120:275da698697d

config: template-ify INI now it's... slightly less ugly :')
author Paper <mrpapersonic@gmail.com>
date Wed, 08 Nov 2023 18:13:37 -0500
parents 254b1d2b7096
children bc218c9d2ea6
line wrap: on
line diff
--- a/include/core/ini.h	Wed Nov 08 13:50:00 2023 -0500
+++ b/include/core/ini.h	Wed Nov 08 18:13:37 2023 -0500
@@ -3,12 +3,75 @@
 
 #define MINI_CASE_SENSITIVE
 #include "mini/ini.h"
+#include "core/strings.h"
+#include "gui/translate/anime.h"
+#include "gui/translate/config.h"
+#include <type_traits>
+#include <string>
 
 namespace INI {
 
-std::string GetIniString(const mINI::INIStructure& ini, const std::string& section,
-	                     const std::string& value, const std::string& def = "");
+/* very simple tutorial on how to give anyone who reads
+   your code an aneurysm */
+template< class... >  
+using void_t = void;
+
+template <typename T, typename = void>
+struct is_toutf8string_available : std::false_type {};
+
+template<typename T>
+struct is_toutf8string_available<T,
+		void_t<decltype(Strings::ToUtf8String(std::declval<T>()))>> : std::true_type {};
+
+template <typename T, typename = void>
+struct is_translation_available : std::false_type {};
+
+template<typename T>
+struct is_translation_available<T,
+		void_t<decltype(Translate::ToString(std::declval<T>()))>> : std::true_type {};
+
+template<typename T>
+T GetIniValue(const mINI::INIStructure& ini, const std::string& section,
+	          const std::string& value, const T& def) {
+	if (!ini.has(section) || !ini.get(section).has(value))
+		return def;
+
+	const std::string val = ini.get(section).get(value);
+
+	if constexpr (std::is_arithmetic<T>::value) {
+		/* Integer? */
+		if constexpr (std::is_same<T, bool>::value) {
+			/* Boolean? */
+			return Strings::ToBool(val);
+		} else if constexpr (std::is_unsigned<T>::value) {
+			/* Unsigned? */
+			return Strings::ToUnsignedInt(val);
+		} else {
+			/* Always fall back to long long */
+			return Strings::ToInt(val);
+		}
+	} else {
+		return val;
+	}
+}
+
+/* this should be able to handle most of our custom types */
+template<typename T>
+void SetIniValue(mINI::INIStructure& ini, const std::string& section,
+	             const std::string& key, const T& value) {
+	auto& ini_key = ini[section][key];
+
+	if constexpr (is_translation_available<T>::value) {
+		ini_key = Translate::ToString(value);
+	} else if constexpr (std::is_same<T, std::string>::value) {
+		ini_key = value;
+	} else if constexpr (std::is_arithmetic<T>::value && !std::is_same<T, bool>::value) {
+		ini_key = std::to_string(value);
+	} else if constexpr (is_toutf8string_available<T>::value) {
+		ini_key = Strings::ToUtf8String(value);
+	}
+}
 
 }
 
-#endif
\ No newline at end of file
+#endif