diff options
Diffstat (limited to 'lib/configuration/configuration.h')
-rw-r--r-- | lib/configuration/configuration.h | 77 |
1 files changed, 49 insertions, 28 deletions
diff --git a/lib/configuration/configuration.h b/lib/configuration/configuration.h index 4459dd0..3d0a49d 100644 --- a/lib/configuration/configuration.h +++ b/lib/configuration/configuration.h @@ -10,11 +10,11 @@ #define SMOLBOTE_CONFIGURATION_H #include <QAction> -#include <QString> #include <initializer_list> #include <memory> #include <optional> #include <string> +#include <type_traits> #include <unordered_map> #include <variant> #include <vector> @@ -33,23 +33,37 @@ typedef std::variant<std::string, int, bool> conf_value_t; +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; + class consumable(unconsumed) Configuration : private std::unordered_map<std::string, conf_value_t> { friend std::ostream &operator<<(std::ostream &out, const Configuration &obj); public: return_typestate(unconsumed) explicit Configuration(); - return_typestate(unconsumed) explicit Configuration(std::initializer_list<std::pair<std::string, conf_value_t>> l) noexcept; - - explicit Configuration(Configuration && other param_typestate(unconsumed)) = default; + return_typestate(unconsumed) explicit Configuration(Configuration && other param_typestate(unconsumed)) = default; ~Configuration() = default; + callable_when(unconsumed) void read_file(const std::string &location); callable_when(unconsumed) void read(std::basic_istream<char> & input); template <typename T> - callable_when(unconsumed) std::optional<T> value(const char *path) const + callable_when(unconsumed) [[nodiscard]] std::optional<T> value(const char *path) const + { + if(use_global) + return instance()->value<T>(path); + + if(count(path) == 0) + return std::nullopt; + + return std::get<T>(at(path)); + } + + template <concept_value_t T> + callable_when(unconsumed) [[nodiscard]] std::optional<T> value(const char *path) const { if(use_global) return instance()->value<T>(path); @@ -61,33 +75,39 @@ public: // path is guaranteed to exist const auto value = at(path); - if constexpr(std::is_same_v<T, QString> || std::is_same_v<T, std::string>) { - auto r = [&value]() { - if(std::holds_alternative<std::string>(value)) - return std::get<std::string>(value); - else if(std::holds_alternative<int>(value)) - return std::to_string(std::get<int>(value)); + if(std::holds_alternative<int>(value)) { + if constexpr(std::is_arithmetic<T>::value) + return static_cast<T>(std::get<int>(value)); + else if constexpr(std::is_constructible<T, std::string>::value) + return T{ std::to_string(std::get<int>(value)) }; + + } 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_constructible<T, const char *>::value) { + if(std::get<bool>(value)) + return T{ "true" }; else - return std::get<bool>(value) ? std::string("true") : std::string("false"); - }(); + return T{ "false" }; + } - if(r.front() == '~') - r.replace(0, 1, m_homePath); + } else if(std::holds_alternative<std::string>(value)) { + auto str = std::get<std::string>(value); + if(str.front() == '~') + str.replace(0, 1, m_homePath); - if constexpr(std::is_same_v<T, QString>) - return std::make_optional(QString::fromStdString(r)); - else - return std::make_optional(r); - - } else if constexpr(std::is_same_v<T, QStringList>) { - return std::make_optional(QString::fromStdString(std::get<std::string>(value)).split(';')); + if constexpr(std::is_constructible<T, std::string>::value) + return T{ str }; + } - } else if(std::holds_alternative<T>(value)) { - return std::optional<T>(std::get<T>(value)); - } else - return std::nullopt; + return std::nullopt; + } - } // std::optional<T> value(path) const + template <typename T> + callable_when(unconsumed) T &shortcut(T &, const char *) const + { + return T{}; + } static void move_global(std::unique_ptr<Configuration> && conf); @@ -98,7 +118,8 @@ private: const bool use_global = false; }; -void setShortcut(QAction *action, const char *name); +#include "qt_specialization.h" + std::ostream &operator<<(std::ostream &out, const Configuration &obj); #endif // SMOLBOTE_CONFIGURATION_H |