diff options
author | clyne <clyne@bitgloo.com> | 2021-02-05 11:20:43 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-05 11:20:43 -0500 |
commit | 3cee35d55370294b784199fcd635ca72fed9572e (patch) | |
tree | de80c6d82ab3c20eab15932f5b33b7b47a31636e | |
parent | 8fc7548c0330bfbf3860d4c0e8c17e20c37a3439 (diff) |
Add get<T>() for converting values to numbers
-rw-r--r-- | ini_config.hpp | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/ini_config.hpp b/ini_config.hpp index db30f0f..77f9909 100644 --- a/ini_config.hpp +++ b/ini_config.hpp @@ -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 { @@ -370,6 +409,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. */ |