Created
March 24, 2017 08:43
-
-
Save dtoma/53cff994a7f2b2dfab9242c490876377 to your computer and use it in GitHub Desktop.
ini configuration reader
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <algorithm> | |
#include <optional> | |
#include <type_traits> | |
#include <unordered_map> | |
#include <vector> | |
#include <cstdio> | |
// http://tristanbrindle.com/posts/a-quicker-study-on-tokenising/ | |
template <typename Iterator, typename Lambda> | |
void for_each_token(Iterator&& first, Iterator&& last, char separator, Lambda&& lambda) { | |
while (first != last) { | |
const auto pos = std::find(first, last, separator); | |
lambda(first, pos); | |
if (pos == last) { | |
break; | |
} | |
first = std::next(pos); | |
} | |
} | |
template<class T> struct always_false : std::false_type {}; | |
struct Config { | |
std::unordered_map<std::string, std::string> config_values = { | |
{"foo", "bar"}, | |
{"bar", "4242"}, | |
{"array", "one,two,three,four"} | |
}; | |
template <typename T> | |
std::optional<T> get(std::string const& key, std::optional<T> default_value = {}) { | |
if (this->config_values.find(key) != std::end(this->config_values)) { | |
if constexpr(std::is_same_v<T, int>) { | |
return std::stoi(this->config_values.at(key)); | |
} else if constexpr(std::is_same_v<T, std::string>) { | |
return this->config_values.at(key); | |
} else if constexpr(std::is_same_v<T, std::vector<std::string>>) { | |
auto v = this->config_values.at(key); | |
std::vector<std::string> ret; | |
for_each_token(std::begin(v), std::end(v), ',', [&ret](auto begin, auto end) { | |
ret.emplace_back(begin, end); | |
}); | |
return ret; | |
} else { | |
static_assert(always_false<T>::value, "supported types are int, std::string, std::vector<std::string>"); | |
} | |
} else { | |
return default_value; | |
} | |
} | |
}; | |
int main() { | |
Config c; | |
auto v = c.get<std::string>("foo"); | |
printf("foo:%15s\n", v.value_or("No value found for this key").c_str()); | |
auto v2 = c.get<int>("bar"); | |
printf("bar:%15i\n", v2.value_or(0)); | |
auto v3 = c.get<std::string>("doesnotexist", "defaultvalue"); | |
printf("doesnotexist:%15s\n", v3.value_or("No value found for this key").c_str()); | |
auto v4 = c.get<std::vector<std::string>>("array"); | |
for (auto e : v4.value_or(std::vector<std::string>{})) { | |
printf("%s ", e.c_str()); | |
} printf("\n"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment