]> code.bitgloo.com Git - clyne/ini-config.git/commitdiff
Add get<T>() for converting values to numbers
authorclyne <clyne@bitgloo.com>
Fri, 5 Feb 2021 16:20:43 +0000 (11:20 -0500)
committerGitHub <noreply@github.com>
Fri, 5 Feb 2021 16:20:43 +0000 (11:20 -0500)
ini_config.hpp

index db30f0f4f2a2c9a4abedb65bc0de886f4c3a094d..77f99095e912bdcab011fb8cd6d9c84d6ef57ae0 100644 (file)
@@ -14,6 +14,8 @@
 #include <iterator> // std::forward_iterator
 #endif
 
+#include <concepts> // std::integral, std::floating_point
+
 namespace ini_config {
 
 /**
@@ -73,6 +75,34 @@ class ini_config
         return in + 1;
     }
 
+    template<std::integral int_type>
+    constexpr static int_type from_string(const char_type *str) noexcept {
+        int_type ret = 0;
+        bool neg = *str == '-';
+        if (neg)
+            ++str;
+        for (; *str && *str >= '0' && *str <= '9'; ++str)
+            ret = ret * 10 + (*str - '0');
+        return !neg ? ret : -ret;
+    }
+    template<std::floating_point float_type>
+    constexpr static float_type from_string(const char_type *str) noexcept {
+        float_type ret = 0;
+        bool neg = *str == '-';
+        if (neg)
+            ++str;
+        for (; *str && *str >= '0' && *str <= '9'; ++str)
+            ret = ret * 10 + (*str - '0');
+        if (*str == '.') {
+            float_type dec = 0.1;
+            for (++str; *str && *str >= '0' && *str <= '9'; ++str) {
+                ret += (*str - '0') * dec;
+                dec /= 10;
+            }
+        }
+        return !neg ? ret : -ret;
+    }
+
     // Validates INI syntax, returning the count of chars
     // needed to store all section names, keys, and values
     consteval static unsigned int verify_and_size() {
@@ -348,7 +378,7 @@ public:
     }
 
     /**
-     * Finds and returns the pair with the given key.
+     * Finds and returns the value paired with the given key.
      * Returns an empty string on failure.
      */
     constexpr auto get(const char_type *key) const noexcept {
@@ -359,7 +389,16 @@ public:
         return "";
     }
     /**
-     * Finds and returns the pair with the given key, in the given section.
+     * Finds and returns the value paired with the given key,
+     * converting it to the specified integral or floating-point type.
+     * Returns zero on failure.
+     */
+    template<typename T> requires(std::integral<T> || std::floating_point<T>)
+    constexpr T get(const char_type *key) const noexcept {
+        return from_string<T>(get(key));
+    }
+    /**
+     * Finds and returns the value paired with the given key, in the given section.
      * Returns an empty string on failure.
      */
     constexpr auto get(const char_type *sec, const char_type *key) const noexcept {
@@ -369,6 +408,15 @@ public:
         }
         return "";
     }
+    /**
+     * Finds and returns the value paired with the given key in the given section,
+     * converting it to the specified integral or floating-point type.
+     * Returns zero on failure.
+     */
+    template<typename T> requires(std::integral<T> || std::floating_point<T>)
+    constexpr T get(const char_type *sec, const char_type *key) const noexcept {
+        return from_string<T>(get(sec, key));
+    }
     /**
      * Array-style access to values. Searches all sections.
      * Returns an empty string on failure.