Skip to content
This repository was archived by the owner on Sep 16, 2025. It is now read-only.

Commit 07e5dfd

Browse files
authored
feat: REX 2 (#299)
1 parent 9a6f3fb commit 07e5dfd

File tree

12 files changed

+1095
-276
lines changed

12 files changed

+1095
-276
lines changed

CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ if(TARGET CommonLibSF)
77
endif()
88

99
# options if not defined
10+
option(REX_OPTION_INI "Enables ini config support for REX." OFF)
11+
option(REX_OPTION_JSON "Enables json config support for REX." OFF)
12+
option(REX_OPTION_TOML "Enables toml config support for REX." OFF)
1013
option(SFSE_SUPPORT_XBYAK "Enables trampoline support for xbyak." OFF)
1114
option(SFSE_BUILD_TESTS "Builds the tests." OFF)
1215

@@ -55,6 +58,9 @@ function(configure_target TARGET_NAME)
5558
PUBLIC
5659
WINVER=0x0A00 # windows 10, minimum supported version by starfield
5760
_WIN32_WINNT=0x0A00
61+
"$<$<BOOL:${REX_OPTION_INI}>:REX_OPTION_INI=1>"
62+
"$<$<BOOL:${REX_OPTION_JSON}>:REX_OPTION_JSON=1>"
63+
"$<$<BOOL:${REX_OPTION_TOML}>:REX_OPTION_TOML=1>"
5864
$<$<BOOL:${SFSE_SUPPORT_XBYAK}>:SFSE_SUPPORT_XBYAK=1>
5965
WIN32_LEAN_AND_MEAN
6066
NOMINMAX

include/REX/REX.h

Lines changed: 7 additions & 271 deletions
Original file line numberDiff line numberDiff line change
@@ -1,273 +1,9 @@
11
#pragma once
22

3-
namespace REX
4-
{
5-
template <
6-
class E,
7-
class U = std::underlying_type_t<E>>
8-
class Enum
9-
{
10-
public:
11-
using enum_type = E;
12-
using underlying_type = U;
13-
14-
static_assert(std::is_enum_v<E>, "Enum<E, ...> must be an enum");
15-
static_assert(std::is_integral_v<U>, "Enum<..., U> must be an integral");
16-
17-
constexpr Enum() noexcept = default;
18-
constexpr Enum(const Enum&) noexcept = default;
19-
constexpr Enum(Enum&&) noexcept = default;
20-
21-
template <class U2> // NOLINTNEXTLINE(google-explicit-constructor)
22-
constexpr Enum(Enum<E, U2> a_rhs) noexcept :
23-
_impl(static_cast<U>(a_rhs.get()))
24-
{}
25-
26-
constexpr Enum(E a_value) noexcept :
27-
_impl(static_cast<U>(a_value))
28-
{}
29-
30-
~Enum() noexcept = default;
31-
32-
constexpr Enum& operator=(const Enum&) noexcept = default;
33-
constexpr Enum& operator=(Enum&&) noexcept = default;
34-
35-
template <class U2>
36-
constexpr Enum& operator=(Enum<E, U2> a_rhs) noexcept
37-
{
38-
_impl = static_cast<U>(a_rhs.get());
39-
}
40-
41-
constexpr Enum& operator=(E a_value) noexcept
42-
{
43-
_impl = static_cast<U>(a_value);
44-
return *this;
45-
}
46-
47-
public:
48-
[[nodiscard]] explicit constexpr operator bool() const noexcept { return _impl != static_cast<U>(0); }
49-
50-
[[nodiscard]] constexpr E operator*() const noexcept { return get(); }
51-
[[nodiscard]] constexpr E get() const noexcept { return static_cast<E>(_impl); }
52-
[[nodiscard]] constexpr U underlying() const noexcept { return _impl; }
53-
54-
public:
55-
friend constexpr bool operator==(Enum a_lhs, Enum a_rhs) noexcept { return a_lhs.underlying() == a_rhs.underlying(); }
56-
friend constexpr bool operator==(Enum a_lhs, E a_rhs) noexcept { return a_lhs.underlying() == static_cast<U>(a_rhs); }
57-
friend constexpr bool operator==(E a_lhs, Enum a_rhs) noexcept { return static_cast<U>(a_lhs) == a_rhs.underlying(); }
58-
59-
private:
60-
U _impl{ 0 };
61-
};
62-
63-
template <class... Args>
64-
Enum(Args...) -> Enum<
65-
std::common_type_t<Args...>,
66-
std::underlying_type_t<
67-
std::common_type_t<Args...>>>;
68-
}
69-
70-
namespace REX
71-
{
72-
template <
73-
class E,
74-
class U = std::underlying_type_t<E>>
75-
class EnumSet
76-
{
77-
public:
78-
using enum_type = E;
79-
using underlying_type = U;
80-
81-
static_assert(std::is_enum_v<E>, "EnumSet<E, ...> must be an enum");
82-
static_assert(std::is_integral_v<U>, "EnumSet<..., U> must be an integral");
83-
84-
constexpr EnumSet() noexcept = default;
85-
constexpr EnumSet(const EnumSet&) noexcept = default;
86-
constexpr EnumSet(EnumSet&&) noexcept = default;
87-
88-
template <class U2> // NOLINTNEXTLINE(google-explicit-constructor)
89-
constexpr EnumSet(EnumSet<E, U2> a_rhs) noexcept :
90-
_impl(static_cast<U>(a_rhs.get()))
91-
{}
92-
93-
template <class... Args>
94-
constexpr EnumSet(Args... a_values) noexcept
95-
requires(std::same_as<Args, E> && ...)
96-
:
97-
_impl((static_cast<U>(a_values) | ...))
98-
{}
99-
100-
~EnumSet() noexcept = default;
101-
102-
constexpr EnumSet& operator=(const EnumSet&) noexcept = default;
103-
constexpr EnumSet& operator=(EnumSet&&) noexcept = default;
104-
105-
template <class U2>
106-
constexpr EnumSet& operator=(EnumSet<E, U2> a_rhs) noexcept
107-
{
108-
_impl = static_cast<U>(a_rhs.get());
109-
}
110-
111-
constexpr EnumSet& operator=(E a_value) noexcept
112-
{
113-
_impl = static_cast<U>(a_value);
114-
return *this;
115-
}
116-
117-
public:
118-
[[nodiscard]] explicit constexpr operator bool() const noexcept { return _impl != static_cast<U>(0); }
119-
120-
[[nodiscard]] constexpr E operator*() const noexcept { return get(); }
121-
[[nodiscard]] constexpr E get() const noexcept { return static_cast<E>(_impl); }
122-
[[nodiscard]] constexpr U underlying() const noexcept { return _impl; }
123-
124-
public:
125-
template <class... Args>
126-
constexpr EnumSet& set(Args... a_args) noexcept
127-
requires(std::same_as<Args, E> && ...)
128-
{
129-
_impl |= (static_cast<U>(a_args) | ...);
130-
return *this;
131-
}
132-
133-
template <class... Args>
134-
constexpr EnumSet& set(bool a_set, Args... a_args) noexcept
135-
requires(std::same_as<Args, E> && ...)
136-
{
137-
if (a_set)
138-
_impl |= (static_cast<U>(a_args) | ...);
139-
else
140-
_impl &= ~(static_cast<U>(a_args) | ...);
141-
142-
return *this;
143-
}
144-
145-
template <class... Args>
146-
constexpr EnumSet& reset(Args... a_args) noexcept
147-
requires(std::same_as<Args, E> && ...)
148-
{
149-
_impl &= ~(static_cast<U>(a_args) | ...);
150-
return *this;
151-
}
152-
153-
constexpr EnumSet& reset() noexcept
154-
{
155-
_impl = 0;
156-
return *this;
157-
}
158-
159-
template <class... Args>
160-
[[nodiscard]] constexpr bool any(Args... a_args) const noexcept
161-
requires(std::same_as<Args, E> && ...)
162-
{
163-
return (_impl & (static_cast<U>(a_args) | ...)) != static_cast<U>(0);
164-
}
165-
166-
template <class... Args>
167-
[[nodiscard]] constexpr bool all(Args... a_args) const noexcept
168-
requires(std::same_as<Args, E> && ...)
169-
{
170-
return (_impl & (static_cast<U>(a_args) | ...)) == (static_cast<U>(a_args) | ...);
171-
}
172-
173-
template <class... Args>
174-
[[nodiscard]] constexpr bool none(Args... a_args) const noexcept
175-
requires(std::same_as<Args, E> && ...)
176-
{
177-
return (_impl & (static_cast<U>(a_args) | ...)) == static_cast<U>(0);
178-
}
179-
180-
public:
181-
friend constexpr bool operator==(EnumSet a_lhs, EnumSet a_rhs) noexcept { return a_lhs.underlying() == a_rhs.underlying(); }
182-
friend constexpr bool operator==(EnumSet a_lhs, E a_rhs) noexcept { return a_lhs.underlying() == static_cast<U>(a_rhs); }
183-
friend constexpr bool operator==(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<U>(a_lhs) == a_rhs.underlying(); }
184-
185-
friend constexpr std::strong_ordering operator<=>(EnumSet a_lhs, EnumSet a_rhs) noexcept { return a_lhs.underlying() <=> a_rhs.underlying(); }
186-
friend constexpr std::strong_ordering operator<=>(EnumSet a_lhs, E a_rhs) noexcept { return a_lhs.underlying() <=> static_cast<U>(a_rhs); }
187-
friend constexpr std::strong_ordering operator<=>(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<U>(a_lhs) <=> a_rhs.underlying(); }
188-
189-
friend constexpr EnumSet operator&(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() & a_rhs.underlying()); }
190-
friend constexpr EnumSet operator&(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() & static_cast<U>(a_rhs)); }
191-
friend constexpr EnumSet operator&(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) & a_rhs.underlying()); }
192-
193-
friend constexpr EnumSet& operator&=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs & a_rhs; }
194-
friend constexpr EnumSet& operator&=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs & a_rhs; }
195-
196-
friend constexpr EnumSet operator|(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() | a_rhs.underlying()); }
197-
friend constexpr EnumSet operator|(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() | static_cast<U>(a_rhs)); }
198-
friend constexpr EnumSet operator|(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) | a_rhs.underlying()); }
199-
200-
friend constexpr EnumSet& operator|=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs | a_rhs; }
201-
friend constexpr EnumSet& operator|=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs | a_rhs; }
202-
203-
friend constexpr EnumSet operator^(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() ^ a_rhs.underlying()); }
204-
friend constexpr EnumSet operator^(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() ^ static_cast<U>(a_rhs)); }
205-
friend constexpr EnumSet operator^(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) ^ a_rhs.underlying()); }
206-
207-
friend constexpr EnumSet& operator^=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs ^ a_rhs; }
208-
friend constexpr EnumSet& operator^=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs ^ a_rhs; }
209-
210-
friend constexpr EnumSet operator+(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() + a_rhs.underlying()); }
211-
friend constexpr EnumSet operator+(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() + static_cast<U>(a_rhs)); }
212-
friend constexpr EnumSet operator+(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) + a_rhs.underlying()); }
213-
214-
friend constexpr EnumSet& operator+=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs + a_rhs; }
215-
friend constexpr EnumSet& operator+=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs + a_rhs; }
216-
217-
friend constexpr EnumSet operator-(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() - a_rhs.underlying()); }
218-
friend constexpr EnumSet operator-(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() - static_cast<U>(a_rhs)); }
219-
friend constexpr EnumSet operator-(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) - a_rhs.underlying()); }
220-
221-
friend constexpr EnumSet& operator-=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs - a_rhs; }
222-
friend constexpr EnumSet& operator-=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs - a_rhs; }
223-
224-
friend constexpr EnumSet operator<<(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() << a_rhs.underlying()); }
225-
friend constexpr EnumSet operator<<(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() << static_cast<U>(a_rhs)); }
226-
friend constexpr EnumSet operator<<(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) << a_rhs.underlying()); }
227-
228-
friend constexpr EnumSet& operator<<=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs << a_rhs; }
229-
friend constexpr EnumSet& operator<<=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs << a_rhs; }
230-
231-
friend constexpr EnumSet operator>>(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() >> a_rhs.underlying()); }
232-
friend constexpr EnumSet operator>>(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() >> static_cast<U>(a_rhs)); }
233-
friend constexpr EnumSet operator>>(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) >> a_rhs.underlying()); }
234-
235-
friend constexpr EnumSet& operator>>=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs >> a_rhs; }
236-
friend constexpr EnumSet& operator>>=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs >> a_rhs; }
237-
238-
friend constexpr EnumSet& operator~(EnumSet& a_lhs) noexcept { return a_lhs = ~a_lhs.underlying(); }
239-
240-
private:
241-
U _impl{ 0 };
242-
};
243-
244-
template <class... Args>
245-
EnumSet(Args...) -> EnumSet<
246-
std::common_type_t<Args...>,
247-
std::underlying_type_t<
248-
std::common_type_t<Args...>>>;
249-
}
250-
251-
namespace REX
252-
{
253-
template <class T>
254-
class Singleton
255-
{
256-
public:
257-
static T* GetSingleton()
258-
{
259-
static T singleton;
260-
return std::addressof(singleton);
261-
}
262-
263-
protected:
264-
Singleton() = default;
265-
~Singleton() = default;
266-
267-
Singleton(const Singleton&) = delete;
268-
Singleton(Singleton&&) = delete;
269-
270-
Singleton& operator=(const Singleton&) = delete;
271-
Singleton& operator=(Singleton&&) = delete;
272-
};
273-
}
3+
#include "REX/REX/Enum.h"
4+
#include "REX/REX/EnumSet.h"
5+
#include "REX/REX/INI.h"
6+
#include "REX/REX/JSON.h"
7+
#include "REX/REX/Setting.h"
8+
#include "REX/REX/Singleton.h"
9+
#include "REX/REX/TOML.h"

include/REX/REX/Enum.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#pragma once
2+
3+
namespace REX
4+
{
5+
template <
6+
class E,
7+
class U = std::underlying_type_t<E>>
8+
class Enum
9+
{
10+
public:
11+
using enum_type = E;
12+
using underlying_type = U;
13+
14+
static_assert(std::is_enum_v<E>, "Enum<E, ...> must be an enum");
15+
static_assert(std::is_integral_v<U>, "Enum<..., U> must be an integral");
16+
17+
constexpr Enum() noexcept = default;
18+
constexpr Enum(const Enum&) noexcept = default;
19+
constexpr Enum(Enum&&) noexcept = default;
20+
21+
template <class U2> // NOLINTNEXTLINE(google-explicit-constructor)
22+
constexpr Enum(Enum<E, U2> a_rhs) noexcept :
23+
_impl(static_cast<U>(a_rhs.get()))
24+
{}
25+
26+
constexpr Enum(E a_value) noexcept :
27+
_impl(static_cast<U>(a_value))
28+
{}
29+
30+
~Enum() noexcept = default;
31+
32+
constexpr Enum& operator=(const Enum&) noexcept = default;
33+
constexpr Enum& operator=(Enum&&) noexcept = default;
34+
35+
template <class U2>
36+
constexpr Enum& operator=(Enum<E, U2> a_rhs) noexcept
37+
{
38+
_impl = static_cast<U>(a_rhs.get());
39+
}
40+
41+
constexpr Enum& operator=(E a_value) noexcept
42+
{
43+
_impl = static_cast<U>(a_value);
44+
return *this;
45+
}
46+
47+
public:
48+
[[nodiscard]] explicit constexpr operator bool() const noexcept { return _impl != static_cast<U>(0); }
49+
50+
[[nodiscard]] constexpr E operator*() const noexcept { return get(); }
51+
[[nodiscard]] constexpr E get() const noexcept { return static_cast<E>(_impl); }
52+
[[nodiscard]] constexpr U underlying() const noexcept { return _impl; }
53+
54+
public:
55+
friend constexpr bool operator==(Enum a_lhs, Enum a_rhs) noexcept { return a_lhs.underlying() == a_rhs.underlying(); }
56+
friend constexpr bool operator==(Enum a_lhs, E a_rhs) noexcept { return a_lhs.underlying() == static_cast<U>(a_rhs); }
57+
friend constexpr bool operator==(E a_lhs, Enum a_rhs) noexcept { return static_cast<U>(a_lhs) == a_rhs.underlying(); }
58+
59+
private:
60+
U _impl{ 0 };
61+
};
62+
63+
template <class... Args>
64+
Enum(Args...) -> Enum<
65+
std::common_type_t<Args...>,
66+
std::underlying_type_t<
67+
std::common_type_t<Args...>>>;
68+
}

0 commit comments

Comments
 (0)