Validate section tags; add cbegin, cend, and contains

master
Clyne 4 years ago committed by GitHub
parent 6a5265be03
commit 8fc7548c03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -73,6 +73,8 @@ class ini_config
return in + 1; return in + 1;
} }
// Validates INI syntax, returning the count of chars
// needed to store all section names, keys, and values
consteval static unsigned int verify_and_size() { consteval static unsigned int verify_and_size() {
unsigned int sizechars = 0; unsigned int sizechars = 0;
@ -89,7 +91,10 @@ class ini_config
if (*p == '[') { if (*p == '[') {
do { do {
++sizechars; ++sizechars;
} while (*++p != ']'); ++p;
} while (!iseol(*p) && *p != ']');
if (iseol(*p))
throw "Bad section tag!";
++sizechars; // Null terminator ++sizechars; // Null terminator
continue; continue;
} }
@ -130,6 +135,7 @@ class ini_config
return sizechars; return sizechars;
} }
// Counts how many key-value pairs are in the text
consteval static unsigned int kvpcount() noexcept { consteval static unsigned int kvpcount() noexcept {
unsigned int count = 0; unsigned int count = 0;
@ -148,6 +154,7 @@ class ini_config
return count; return count;
} }
// A compact buffer for section names, keys, and values
char_type kvp_buffer[verify_and_size() + 1] = {}; char_type kvp_buffer[verify_and_size() + 1] = {};
consteval void fill_kvp_buffer() noexcept { consteval void fill_kvp_buffer() noexcept {
@ -209,8 +216,7 @@ public:
constexpr const auto& get_next() noexcept { constexpr const auto& get_next() noexcept {
if (*m_pos == '\0') { if (*m_pos == '\0') {
// At the end // At the end
if (m_current.first != nullptr) m_current.first = nullptr;
m_current.first = nullptr;
} else { } else {
// Enter new section(s) if necessary // Enter new section(s) if necessary
while (*m_pos == '[') { while (*m_pos == '[') {
@ -264,6 +270,10 @@ public:
} }
}; };
/**
* Constructs the ini_config object, populating the section/key/value
* buffer.
*/
consteval ini_config() noexcept consteval ini_config() noexcept
#ifdef TCSULLIVAN_INI_CONFIG_CHECK_FORWARD_ITERATOR #ifdef TCSULLIVAN_INI_CONFIG_CHECK_FORWARD_ITERATOR
requires(std::forward_iterator<iterator>) requires(std::forward_iterator<iterator>)
@ -278,33 +288,42 @@ public:
consteval auto size() const noexcept { consteval auto size() const noexcept {
return kvpcount(); return kvpcount();
} }
constexpr auto begin() const noexcept { constexpr auto begin() const noexcept {
return iterator(kvp_buffer); return iterator(kvp_buffer);
} }
constexpr auto cbegin() const noexcept {
return begin();
}
constexpr auto end() const noexcept {
return iterator(kvp_buffer + sizeof(kvp_buffer) / sizeof(char_type) - 1);
}
constexpr auto cend() const noexcept {
return end();
}
/** /**
* Returns beginning iterator for the given section. * Returns beginning iterator for the given section.
*/ */
constexpr auto begin(const char_type *section) const noexcept { constexpr auto begin(const char_type *section) const noexcept {
for (auto it = begin(); it != end(); ++it) { auto it = begin();
do {
if (it->section != nullptr && stringmatch(it->section, section)) if (it->section != nullptr && stringmatch(it->section, section))
return it; break;
} } while (++it != end());
return end(); return it;
}
constexpr auto end() const noexcept {
return iterator(kvp_buffer + sizeof(kvp_buffer) / sizeof(char_type) - 1);
} }
/**
/**
* Returns end iterator for the given section. * Returns end iterator for the given section.
*/ */
constexpr auto end(const char_type *section) const noexcept { constexpr auto end(const char_type *section) const noexcept {
for (auto it = begin(); it != end(); ++it) { auto it = begin(section);
if (it->section != nullptr && stringmatch(it->section, section)) { while (++it != end()) {
for (++it; it != end() && stringmatch(it->section, section); ++it); if (!stringmatch(it->section, section))
return it; break;
}
} }
return end(); return it;
} }
class section_view { class section_view {
@ -357,6 +376,13 @@ public:
constexpr auto operator[](const char_type *key) const noexcept { constexpr auto operator[](const char_type *key) const noexcept {
return get(key); return get(key);
} }
constexpr bool contains(const char_type *key) const noexcept {
return *get(key) != '\0';
}
constexpr bool contains(const char_type *sec, const char_type *key) const noexcept {
return *get(sec, key) != '\0';
}
}; };
} // namespace ini_config } // namespace ini_config

Loading…
Cancel
Save