#pragma once #include #include #include #include #include "../macros.hpp" #include "../config/shared/complex/ComplexDataType.hpp" #include "../config/shared/Types.hpp" // Welcome to wonky fucking pointer + type hell // Enjoy your stay // giga hack to avoid including configManager here // NOLINTNEXTLINE void local__configValuePopulate(void* const** p, void* const** hlangp, std::type_index* ti, const std::string& val); std::type_index local__configValueTypeIdx(const std::string& val); template class CConfigValue { public: // creates an empty value. Deref'ing this will be a crash CConfigValue() = default; CConfigValue(const std::string& val) { #ifdef HYPRLAND_DEBUG // verify type // TODO: fix this or leave it idk I'm tired. // 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) || typeid(T) == typeid(Config::IComplexConfigValue)) && // (TYPE == typeid(Hyprlang::CUSTOMTYPE*) || TYPE == typeid(Config::IComplexConfigValue*) || 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(&m_p, &m_hlangp, &m_typeIndex, val); } T* ptr() const { return *rc(m_p); } T operator*() const { return *ptr(); } bool good() const { return m_p || m_hlangp; } private: void* const* m_p = nullptr; void* const* m_hlangp = nullptr; std::type_index m_typeIndex = typeid(void); }; template <> inline std::string* CConfigValue::ptr() const { RASSERT(false, "Impossible to implement ptr() of CConfigValue"); return nullptr; } template <> inline std::string CConfigValue::operator*() const { if (m_typeIndex == typeid(std::string)) return **rc(m_p); else if (m_typeIndex == typeid(const char*)) return std::string{*rc(m_hlangp)}; else RASSERT(false, "CConfigValue on a FUCKED type"); return "FUCK"; } template <> inline Config::INTEGER CConfigValue::operator*() const { if (m_typeIndex == typeid(bool)) return **rc(m_p); else if (m_typeIndex == typeid(Config::INTEGER)) return **rc(m_p); else RASSERT(false, "CConfigValue on a FUCKED type"); return -1; } template <> inline Config::IComplexConfigValue* CConfigValue::ptr() const { if (m_hlangp) return rc((*rc(m_hlangp))->getData()); else return *rc(m_p); }