diff options
Diffstat (limited to 'lib/configuration/configuration.h')
-rw-r--r-- | lib/configuration/configuration.h | 51 |
1 files changed, 24 insertions, 27 deletions
diff --git a/lib/configuration/configuration.h b/lib/configuration/configuration.h index cd3c244..30f258c 100644 --- a/lib/configuration/configuration.h +++ b/lib/configuration/configuration.h @@ -17,44 +17,34 @@ #include <unordered_map> #include <variant> -#if defined(__clang__) -#define consumable(X) [[clang::consumable(X)]] -#define return_typestate(X) [[clang::return_typestate(X)]] -#define callable_when(X) [[clang::callable_when(X)]] -#define param_typestate(X) [[clang::param_typestate(X)]] -#else -#define consumable(X) -#define return_typestate(X) -#define callable_when(X) -#define param_typestate(X) -#endif - -typedef std::variant<std::string, int, bool> conf_value_t; +using conf_value_t = std::variant<std::string, int, bool>; template <typename T> -concept concept_value_t = std::is_arithmetic<T>::value || std::is_same<T, bool>::value || std::is_constructible<T, std::string>::value; +concept concept_value_t = std::is_arithmetic_v<T> || std::is_same_v<T, bool> || std::is_constructible_v<T, std::string>; -class consumable(unconsumed) Configuration : private std::unordered_map<std::string, conf_value_t> +class Configuration : private std::unordered_map<std::string, conf_value_t> { friend std::ostream &operator<<(std::ostream &out, const Configuration &obj); public: - return_typestate(unconsumed) Configuration(); - return_typestate(unconsumed) Configuration(std::initializer_list<std::pair<std::string, conf_value_t>> l) noexcept; + using kv_pair = std::pair<std::string, conf_value_t>; + + Configuration(); + Configuration(std::initializer_list<std::pair<std::string, conf_value_t>> p_list) noexcept; Configuration(const Configuration &) = delete; Configuration &operator=(const Configuration &) = delete; - return_typestate(unconsumed) Configuration(Configuration && other param_typestate(unconsumed)) = default; + Configuration(Configuration &&other) = default; Configuration &operator=(Configuration &&) = delete; ~Configuration() = default; - callable_when(unconsumed) void read_file(const std::string &location); - callable_when(unconsumed) void read(std::basic_istream<char> & input); + bool read_file(const std::string &location); + void read(std::basic_istream<char> &input); template <typename T> - callable_when(unconsumed) [[nodiscard]] std::optional<T> value(const char *path) const + [[nodiscard]] std::optional<T> value(const char *path) const { if(use_global) { return instance()->value<T>(path); @@ -68,18 +58,18 @@ public: } template <concept_value_t T> - callable_when(unconsumed) [[nodiscard]] std::optional<T> value(const char *path) const + [[nodiscard]] std::optional<T> value(const char *p_path) const { if(use_global) { - return instance()->value<T>(path); + return instance()->value<T>(p_path); } - if(this->count(path) == 0) { + if(this->count(p_path) == 0) { return std::nullopt; } // path is guaranteed to exist - const auto value = at(path); + const auto value = at(p_path); if(std::holds_alternative<int>(value)) { if constexpr(std::is_arithmetic<T>::value) { @@ -91,6 +81,8 @@ public: } else if(std::holds_alternative<bool>(value)) { if constexpr(std::is_constructible<T, bool>::value) { return std::get<bool>(value); + } else if constexpr(std::is_arithmetic_v<T>) { + return static_cast<T>(std::get<bool>(value)); } else if constexpr(std::is_constructible<T, const char *>::value) { return std::get<bool>(value) ? T{ "true" } : T{ "false" }; } @@ -99,7 +91,9 @@ public: auto str = std::get<std::string>(value); try { - if constexpr(std::is_floating_point<T>::value) { + if constexpr(std::is_same_v<T, bool>) { + return (str == "true"); + } else if constexpr(std::is_floating_point<T>::value) { return static_cast<T>(std::stod(str)); } else if constexpr(std::is_arithmetic<T>::value) { return static_cast<T>(std::stol(str)); @@ -121,13 +115,16 @@ public: } template <typename T> - callable_when(unconsumed) T &shortcut(T & /* unused */, const char * /* unused */) const + T &shortcut(T & /* unused */, const char * /* unused */) const { return T{}; } static void move_global(std::unique_ptr<Configuration> && conf); +protected: + void insert_or_assign(const kv_pair &pair); + private: static Configuration *instance(); |