#pragma once #include #include #include #include "../macros.hpp" // giga hack to avoid including configManager here // NOLINTNEXTLINE void local__configValuePopulate(void* const** p, const std::string& val); std::type_index local__configValueTypeIdx(const std::string& val); template class CConfigValue { public: CConfigValue(const std::string& val) { #ifdef HYPRLAND_DEBUG // verify type const auto TYPE = local__configValueTypeIdx(val); // exceptions const bool STRINGEX = (typeid(T) == typeid(std::string) && TYPE == typeid(Hyprlang::STRING)); const bool CUSTOMEX = (typeid(T) == typeid(Hyprlang::CUSTOMTYPE) && (TYPE == typeid(Hyprlang::CUSTOMTYPE*) || TYPE == typeid(void*) /* dunno why it does this? */)); RASSERT(typeid(T) == TYPE || STRINGEX || CUSTOMEX, "Mismatched type in CConfigValue, got {} but has {}", typeid(T).name(), TYPE.name()); #endif local__configValuePopulate(&p_, val); } T* ptr() const { return *rc(p_); } T operator*() const { return *ptr(); } private: void* const* p_ = nullptr; }; template <> inline std::string* CConfigValue::ptr() const { RASSERT(false, "Impossible to implement ptr() of CConfigValue"); return nullptr; } template <> inline std::string CConfigValue::operator*() const { return std::string{*rc(p_)}; } template <> inline Hyprlang::STRING* CConfigValue::ptr() const { return rc(*p_); } template <> inline Hyprlang::STRING CConfigValue::operator*() const { return *rc(p_); } template <> inline Hyprlang::CUSTOMTYPE* CConfigValue::ptr() const { return *rc(p_); } template <> inline Hyprlang::CUSTOMTYPE CConfigValue::operator*() const { RASSERT(false, "Impossible to implement operator* of CConfigValue, use ptr()"); return *ptr(); }