aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorclyne <clyne@bitgloo.com>2021-02-05 11:20:43 -0500
committerGitHub <noreply@github.com>2021-02-05 11:20:43 -0500
commit3cee35d55370294b784199fcd635ca72fed9572e (patch)
treede80c6d82ab3c20eab15932f5b33b7b47a31636e
parent8fc7548c0330bfbf3860d4c0e8c17e20c37a3439 (diff)
Add get<T>() for converting values to numbers
-rw-r--r--ini_config.hpp52
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.
*/