summaryrefslogtreecommitdiff
path: root/src/config/ConfigValue.hpp
blob: 1da359b60f0ec01ead8307d163e4c5b1f541aede (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#pragma once

#include <string>
#include <typeindex>
#include <hyprlang.hpp>
#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 <typename T>
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<T>, got {} but has {}", typeid(T).name(), TYPE.name());
#endif

        local__configValuePopulate(&p_, val);
    }

    T* ptr() const {
        return *rc<T* const*>(p_);
    }

    T operator*() const {
        return *ptr();
    }

  private:
    void* const* p_ = nullptr;
};

template <>
inline std::string* CConfigValue<std::string>::ptr() const {
    RASSERT(false, "Impossible to implement ptr() of CConfigValue<std::string>");
    return nullptr;
}

template <>
inline std::string CConfigValue<std::string>::operator*() const {
    return std::string{*rc<const Hyprlang::STRING*>(p_)};
}

template <>
inline Hyprlang::STRING* CConfigValue<Hyprlang::STRING>::ptr() const {
    return rc<Hyprlang::STRING*>(*p_);
}

template <>
inline Hyprlang::STRING CConfigValue<Hyprlang::STRING>::operator*() const {
    return *rc<const Hyprlang::STRING*>(p_);
}

template <>
inline Hyprlang::CUSTOMTYPE* CConfigValue<Hyprlang::CUSTOMTYPE>::ptr() const {
    return *rc<Hyprlang::CUSTOMTYPE* const*>(p_);
}

template <>
inline Hyprlang::CUSTOMTYPE CConfigValue<Hyprlang::CUSTOMTYPE>::operator*() const {
    RASSERT(false, "Impossible to implement operator* of CConfigValue<Hyprlang::CUSTOMTYPE>, use ptr()");
    return *ptr();
}