Ensure compile-time evaluation of accesses

On gcc and clang, optimization flags are no longer required for get() and contains() to be evaluated at compile-time.
master
Clyne 4 years ago committed by GitHub
parent 3cee35d553
commit 3a504f8682
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -27,15 +27,15 @@ struct string_container {
using char_type = T; using char_type = T;
char_type data[N]; char_type data[N];
constexpr string_container(const char_type (&s)[N]) noexcept { consteval string_container(const char_type (&s)[N]) noexcept {
auto dst = data; auto dst = data;
for (auto src = s; src != s + N; ++src) for (auto src = s; src != s + N; ++src)
*dst++ = *src; *dst++ = *src;
} }
constexpr operator const char_type *() const noexcept { consteval operator const char_type *() const noexcept {
return data; return data;
} }
constexpr auto size() const noexcept { consteval auto size() const noexcept {
return N; return N;
} }
consteval auto begin() const noexcept { consteval auto begin() const noexcept {
@ -76,7 +76,7 @@ class ini_config
} }
template<std::integral int_type> template<std::integral int_type>
constexpr static int_type from_string(const char_type *str) noexcept { consteval static int_type from_string(const char_type *str) noexcept {
int_type ret = 0; int_type ret = 0;
bool neg = *str == '-'; bool neg = *str == '-';
if (neg) if (neg)
@ -86,7 +86,7 @@ class ini_config
return !neg ? ret : -ret; return !neg ? ret : -ret;
} }
template<std::floating_point float_type> template<std::floating_point float_type>
constexpr static float_type from_string(const char_type *str) noexcept { consteval static float_type from_string(const char_type *str) noexcept {
float_type ret = 0; float_type ret = 0;
bool neg = *str == '-'; bool neg = *str == '-';
if (neg) if (neg)
@ -292,6 +292,7 @@ public:
get_next(); get_next();
return copy; return copy;
} }
// BUG: iter < end() == false at element before end()
constexpr auto operator<=>(const iterator& other) const noexcept { constexpr auto operator<=>(const iterator& other) const noexcept {
return m_pos <=> other.m_pos; return m_pos <=> other.m_pos;
} }
@ -381,7 +382,7 @@ public:
* Finds and returns the value paired with the given key. * Finds and returns the value paired with the given key.
* Returns an empty string on failure. * Returns an empty string on failure.
*/ */
constexpr auto get(const char_type *key) const noexcept { consteval auto get(const char_type *key) const noexcept {
for (auto kvp : *this) { for (auto kvp : *this) {
if (stringmatch(kvp.first, key)) if (stringmatch(kvp.first, key))
return kvp.second; return kvp.second;
@ -394,14 +395,14 @@ public:
* Returns zero on failure. * Returns zero on failure.
*/ */
template<typename T> requires(std::integral<T> || std::floating_point<T>) template<typename T> requires(std::integral<T> || std::floating_point<T>)
constexpr T get(const char_type *key) const noexcept { consteval T get(const char_type *key) const noexcept {
return from_string<T>(get(key)); return from_string<T>(get(key));
} }
/** /**
* Finds and returns the value paired with the given key, in the given section. * Finds and returns the value paired with the given key, in the given section.
* Returns an empty string on failure. * Returns an empty string on failure.
*/ */
constexpr auto get(const char_type *sec, const char_type *key) const noexcept { consteval auto get(const char_type *sec, const char_type *key) const noexcept {
for (auto kvp : section(sec)) { for (auto kvp : section(sec)) {
if (stringmatch(kvp.first, key)) if (stringmatch(kvp.first, key))
return kvp.second; return kvp.second;
@ -414,21 +415,14 @@ public:
* Returns zero on failure. * Returns zero on failure.
*/ */
template<typename T> requires(std::integral<T> || std::floating_point<T>) template<typename T> requires(std::integral<T> || std::floating_point<T>)
constexpr T get(const char_type *sec, const char_type *key) const noexcept { consteval T get(const char_type *sec, const char_type *key) const noexcept {
return from_string<T>(get(sec, key)); return from_string<T>(get(sec, key));
} }
/**
* Array-style access to values. Searches all sections.
* Returns an empty string on failure.
*/
constexpr auto operator[](const char_type *key) const noexcept {
return get(key);
}
constexpr bool contains(const char_type *key) const noexcept { consteval bool contains(const char_type *key) const noexcept {
return *get(key) != '\0'; return *get(key) != '\0';
} }
constexpr bool contains(const char_type *sec, const char_type *key) const noexcept { consteval bool contains(const char_type *sec, const char_type *key) const noexcept {
return *get(sec, key) != '\0'; return *get(sec, key) != '\0';
} }
}; };
@ -439,7 +433,7 @@ public:
* _ini suffix definition. * _ini suffix definition.
*/ */
template <ini_config::string_container Input> template <ini_config::string_container Input>
constexpr auto operator ""_ini() consteval auto operator ""_ini()
{ {
return ini_config::ini_config<Input>(); return ini_config::ini_config<Input>();
} }

Loading…
Cancel
Save