From 3cee35d55370294b784199fcd635ca72fed9572e Mon Sep 17 00:00:00 2001 From: clyne Date: Fri, 5 Feb 2021 11:20:43 -0500 Subject: [PATCH] Add get() for converting values to numbers --- ini_config.hpp | 52 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file 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 // std::forward_iterator #endif +#include // std::integral, std::floating_point + namespace ini_config { /** @@ -73,6 +75,34 @@ class ini_config return in + 1; } + template + 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 + 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 requires(std::integral || std::floating_point) + constexpr T get(const char_type *key) const noexcept { + return from_string(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 requires(std::integral || std::floating_point) + constexpr T get(const char_type *sec, const char_type *key) const noexcept { + return from_string(get(sec, key)); + } /** * Array-style access to values. Searches all sections. * Returns an empty string on failure.