forked from Starfield-Reverse-Engineering/CommonLibSF
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: REX 2 (Starfield-Reverse-Engineering#299)
- Loading branch information
1 parent
9a6f3fb
commit 07e5dfd
Showing
12 changed files
with
1,095 additions
and
276 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,273 +1,9 @@ | ||
#pragma once | ||
|
||
namespace REX | ||
{ | ||
template < | ||
class E, | ||
class U = std::underlying_type_t<E>> | ||
class Enum | ||
{ | ||
public: | ||
using enum_type = E; | ||
using underlying_type = U; | ||
|
||
static_assert(std::is_enum_v<E>, "Enum<E, ...> must be an enum"); | ||
static_assert(std::is_integral_v<U>, "Enum<..., U> must be an integral"); | ||
|
||
constexpr Enum() noexcept = default; | ||
constexpr Enum(const Enum&) noexcept = default; | ||
constexpr Enum(Enum&&) noexcept = default; | ||
|
||
template <class U2> // NOLINTNEXTLINE(google-explicit-constructor) | ||
constexpr Enum(Enum<E, U2> a_rhs) noexcept : | ||
_impl(static_cast<U>(a_rhs.get())) | ||
{} | ||
|
||
constexpr Enum(E a_value) noexcept : | ||
_impl(static_cast<U>(a_value)) | ||
{} | ||
|
||
~Enum() noexcept = default; | ||
|
||
constexpr Enum& operator=(const Enum&) noexcept = default; | ||
constexpr Enum& operator=(Enum&&) noexcept = default; | ||
|
||
template <class U2> | ||
constexpr Enum& operator=(Enum<E, U2> a_rhs) noexcept | ||
{ | ||
_impl = static_cast<U>(a_rhs.get()); | ||
} | ||
|
||
constexpr Enum& operator=(E a_value) noexcept | ||
{ | ||
_impl = static_cast<U>(a_value); | ||
return *this; | ||
} | ||
|
||
public: | ||
[[nodiscard]] explicit constexpr operator bool() const noexcept { return _impl != static_cast<U>(0); } | ||
|
||
[[nodiscard]] constexpr E operator*() const noexcept { return get(); } | ||
[[nodiscard]] constexpr E get() const noexcept { return static_cast<E>(_impl); } | ||
[[nodiscard]] constexpr U underlying() const noexcept { return _impl; } | ||
|
||
public: | ||
friend constexpr bool operator==(Enum a_lhs, Enum a_rhs) noexcept { return a_lhs.underlying() == a_rhs.underlying(); } | ||
friend constexpr bool operator==(Enum a_lhs, E a_rhs) noexcept { return a_lhs.underlying() == static_cast<U>(a_rhs); } | ||
friend constexpr bool operator==(E a_lhs, Enum a_rhs) noexcept { return static_cast<U>(a_lhs) == a_rhs.underlying(); } | ||
|
||
private: | ||
U _impl{ 0 }; | ||
}; | ||
|
||
template <class... Args> | ||
Enum(Args...) -> Enum< | ||
std::common_type_t<Args...>, | ||
std::underlying_type_t< | ||
std::common_type_t<Args...>>>; | ||
} | ||
|
||
namespace REX | ||
{ | ||
template < | ||
class E, | ||
class U = std::underlying_type_t<E>> | ||
class EnumSet | ||
{ | ||
public: | ||
using enum_type = E; | ||
using underlying_type = U; | ||
|
||
static_assert(std::is_enum_v<E>, "EnumSet<E, ...> must be an enum"); | ||
static_assert(std::is_integral_v<U>, "EnumSet<..., U> must be an integral"); | ||
|
||
constexpr EnumSet() noexcept = default; | ||
constexpr EnumSet(const EnumSet&) noexcept = default; | ||
constexpr EnumSet(EnumSet&&) noexcept = default; | ||
|
||
template <class U2> // NOLINTNEXTLINE(google-explicit-constructor) | ||
constexpr EnumSet(EnumSet<E, U2> a_rhs) noexcept : | ||
_impl(static_cast<U>(a_rhs.get())) | ||
{} | ||
|
||
template <class... Args> | ||
constexpr EnumSet(Args... a_values) noexcept | ||
requires(std::same_as<Args, E> && ...) | ||
: | ||
_impl((static_cast<U>(a_values) | ...)) | ||
{} | ||
|
||
~EnumSet() noexcept = default; | ||
|
||
constexpr EnumSet& operator=(const EnumSet&) noexcept = default; | ||
constexpr EnumSet& operator=(EnumSet&&) noexcept = default; | ||
|
||
template <class U2> | ||
constexpr EnumSet& operator=(EnumSet<E, U2> a_rhs) noexcept | ||
{ | ||
_impl = static_cast<U>(a_rhs.get()); | ||
} | ||
|
||
constexpr EnumSet& operator=(E a_value) noexcept | ||
{ | ||
_impl = static_cast<U>(a_value); | ||
return *this; | ||
} | ||
|
||
public: | ||
[[nodiscard]] explicit constexpr operator bool() const noexcept { return _impl != static_cast<U>(0); } | ||
|
||
[[nodiscard]] constexpr E operator*() const noexcept { return get(); } | ||
[[nodiscard]] constexpr E get() const noexcept { return static_cast<E>(_impl); } | ||
[[nodiscard]] constexpr U underlying() const noexcept { return _impl; } | ||
|
||
public: | ||
template <class... Args> | ||
constexpr EnumSet& set(Args... a_args) noexcept | ||
requires(std::same_as<Args, E> && ...) | ||
{ | ||
_impl |= (static_cast<U>(a_args) | ...); | ||
return *this; | ||
} | ||
|
||
template <class... Args> | ||
constexpr EnumSet& set(bool a_set, Args... a_args) noexcept | ||
requires(std::same_as<Args, E> && ...) | ||
{ | ||
if (a_set) | ||
_impl |= (static_cast<U>(a_args) | ...); | ||
else | ||
_impl &= ~(static_cast<U>(a_args) | ...); | ||
|
||
return *this; | ||
} | ||
|
||
template <class... Args> | ||
constexpr EnumSet& reset(Args... a_args) noexcept | ||
requires(std::same_as<Args, E> && ...) | ||
{ | ||
_impl &= ~(static_cast<U>(a_args) | ...); | ||
return *this; | ||
} | ||
|
||
constexpr EnumSet& reset() noexcept | ||
{ | ||
_impl = 0; | ||
return *this; | ||
} | ||
|
||
template <class... Args> | ||
[[nodiscard]] constexpr bool any(Args... a_args) const noexcept | ||
requires(std::same_as<Args, E> && ...) | ||
{ | ||
return (_impl & (static_cast<U>(a_args) | ...)) != static_cast<U>(0); | ||
} | ||
|
||
template <class... Args> | ||
[[nodiscard]] constexpr bool all(Args... a_args) const noexcept | ||
requires(std::same_as<Args, E> && ...) | ||
{ | ||
return (_impl & (static_cast<U>(a_args) | ...)) == (static_cast<U>(a_args) | ...); | ||
} | ||
|
||
template <class... Args> | ||
[[nodiscard]] constexpr bool none(Args... a_args) const noexcept | ||
requires(std::same_as<Args, E> && ...) | ||
{ | ||
return (_impl & (static_cast<U>(a_args) | ...)) == static_cast<U>(0); | ||
} | ||
|
||
public: | ||
friend constexpr bool operator==(EnumSet a_lhs, EnumSet a_rhs) noexcept { return a_lhs.underlying() == a_rhs.underlying(); } | ||
friend constexpr bool operator==(EnumSet a_lhs, E a_rhs) noexcept { return a_lhs.underlying() == static_cast<U>(a_rhs); } | ||
friend constexpr bool operator==(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<U>(a_lhs) == a_rhs.underlying(); } | ||
|
||
friend constexpr std::strong_ordering operator<=>(EnumSet a_lhs, EnumSet a_rhs) noexcept { return a_lhs.underlying() <=> a_rhs.underlying(); } | ||
friend constexpr std::strong_ordering operator<=>(EnumSet a_lhs, E a_rhs) noexcept { return a_lhs.underlying() <=> static_cast<U>(a_rhs); } | ||
friend constexpr std::strong_ordering operator<=>(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<U>(a_lhs) <=> a_rhs.underlying(); } | ||
|
||
friend constexpr EnumSet operator&(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() & a_rhs.underlying()); } | ||
friend constexpr EnumSet operator&(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() & static_cast<U>(a_rhs)); } | ||
friend constexpr EnumSet operator&(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) & a_rhs.underlying()); } | ||
|
||
friend constexpr EnumSet& operator&=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs & a_rhs; } | ||
friend constexpr EnumSet& operator&=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs & a_rhs; } | ||
|
||
friend constexpr EnumSet operator|(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() | a_rhs.underlying()); } | ||
friend constexpr EnumSet operator|(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() | static_cast<U>(a_rhs)); } | ||
friend constexpr EnumSet operator|(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) | a_rhs.underlying()); } | ||
|
||
friend constexpr EnumSet& operator|=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs | a_rhs; } | ||
friend constexpr EnumSet& operator|=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs | a_rhs; } | ||
|
||
friend constexpr EnumSet operator^(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() ^ a_rhs.underlying()); } | ||
friend constexpr EnumSet operator^(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() ^ static_cast<U>(a_rhs)); } | ||
friend constexpr EnumSet operator^(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) ^ a_rhs.underlying()); } | ||
|
||
friend constexpr EnumSet& operator^=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs ^ a_rhs; } | ||
friend constexpr EnumSet& operator^=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs ^ a_rhs; } | ||
|
||
friend constexpr EnumSet operator+(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() + a_rhs.underlying()); } | ||
friend constexpr EnumSet operator+(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() + static_cast<U>(a_rhs)); } | ||
friend constexpr EnumSet operator+(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) + a_rhs.underlying()); } | ||
|
||
friend constexpr EnumSet& operator+=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs + a_rhs; } | ||
friend constexpr EnumSet& operator+=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs + a_rhs; } | ||
|
||
friend constexpr EnumSet operator-(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() - a_rhs.underlying()); } | ||
friend constexpr EnumSet operator-(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() - static_cast<U>(a_rhs)); } | ||
friend constexpr EnumSet operator-(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) - a_rhs.underlying()); } | ||
|
||
friend constexpr EnumSet& operator-=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs - a_rhs; } | ||
friend constexpr EnumSet& operator-=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs - a_rhs; } | ||
|
||
friend constexpr EnumSet operator<<(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() << a_rhs.underlying()); } | ||
friend constexpr EnumSet operator<<(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() << static_cast<U>(a_rhs)); } | ||
friend constexpr EnumSet operator<<(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) << a_rhs.underlying()); } | ||
|
||
friend constexpr EnumSet& operator<<=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs << a_rhs; } | ||
friend constexpr EnumSet& operator<<=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs << a_rhs; } | ||
|
||
friend constexpr EnumSet operator>>(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() >> a_rhs.underlying()); } | ||
friend constexpr EnumSet operator>>(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() >> static_cast<U>(a_rhs)); } | ||
friend constexpr EnumSet operator>>(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) >> a_rhs.underlying()); } | ||
|
||
friend constexpr EnumSet& operator>>=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs >> a_rhs; } | ||
friend constexpr EnumSet& operator>>=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs >> a_rhs; } | ||
|
||
friend constexpr EnumSet& operator~(EnumSet& a_lhs) noexcept { return a_lhs = ~a_lhs.underlying(); } | ||
|
||
private: | ||
U _impl{ 0 }; | ||
}; | ||
|
||
template <class... Args> | ||
EnumSet(Args...) -> EnumSet< | ||
std::common_type_t<Args...>, | ||
std::underlying_type_t< | ||
std::common_type_t<Args...>>>; | ||
} | ||
|
||
namespace REX | ||
{ | ||
template <class T> | ||
class Singleton | ||
{ | ||
public: | ||
static T* GetSingleton() | ||
{ | ||
static T singleton; | ||
return std::addressof(singleton); | ||
} | ||
|
||
protected: | ||
Singleton() = default; | ||
~Singleton() = default; | ||
|
||
Singleton(const Singleton&) = delete; | ||
Singleton(Singleton&&) = delete; | ||
|
||
Singleton& operator=(const Singleton&) = delete; | ||
Singleton& operator=(Singleton&&) = delete; | ||
}; | ||
} | ||
#include "REX/REX/Enum.h" | ||
#include "REX/REX/EnumSet.h" | ||
#include "REX/REX/INI.h" | ||
#include "REX/REX/JSON.h" | ||
#include "REX/REX/Setting.h" | ||
#include "REX/REX/Singleton.h" | ||
#include "REX/REX/TOML.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#pragma once | ||
|
||
namespace REX | ||
{ | ||
template < | ||
class E, | ||
class U = std::underlying_type_t<E>> | ||
class Enum | ||
{ | ||
public: | ||
using enum_type = E; | ||
using underlying_type = U; | ||
|
||
static_assert(std::is_enum_v<E>, "Enum<E, ...> must be an enum"); | ||
static_assert(std::is_integral_v<U>, "Enum<..., U> must be an integral"); | ||
|
||
constexpr Enum() noexcept = default; | ||
constexpr Enum(const Enum&) noexcept = default; | ||
constexpr Enum(Enum&&) noexcept = default; | ||
|
||
template <class U2> // NOLINTNEXTLINE(google-explicit-constructor) | ||
constexpr Enum(Enum<E, U2> a_rhs) noexcept : | ||
_impl(static_cast<U>(a_rhs.get())) | ||
{} | ||
|
||
constexpr Enum(E a_value) noexcept : | ||
_impl(static_cast<U>(a_value)) | ||
{} | ||
|
||
~Enum() noexcept = default; | ||
|
||
constexpr Enum& operator=(const Enum&) noexcept = default; | ||
constexpr Enum& operator=(Enum&&) noexcept = default; | ||
|
||
template <class U2> | ||
constexpr Enum& operator=(Enum<E, U2> a_rhs) noexcept | ||
{ | ||
_impl = static_cast<U>(a_rhs.get()); | ||
} | ||
|
||
constexpr Enum& operator=(E a_value) noexcept | ||
{ | ||
_impl = static_cast<U>(a_value); | ||
return *this; | ||
} | ||
|
||
public: | ||
[[nodiscard]] explicit constexpr operator bool() const noexcept { return _impl != static_cast<U>(0); } | ||
|
||
[[nodiscard]] constexpr E operator*() const noexcept { return get(); } | ||
[[nodiscard]] constexpr E get() const noexcept { return static_cast<E>(_impl); } | ||
[[nodiscard]] constexpr U underlying() const noexcept { return _impl; } | ||
|
||
public: | ||
friend constexpr bool operator==(Enum a_lhs, Enum a_rhs) noexcept { return a_lhs.underlying() == a_rhs.underlying(); } | ||
friend constexpr bool operator==(Enum a_lhs, E a_rhs) noexcept { return a_lhs.underlying() == static_cast<U>(a_rhs); } | ||
friend constexpr bool operator==(E a_lhs, Enum a_rhs) noexcept { return static_cast<U>(a_lhs) == a_rhs.underlying(); } | ||
|
||
private: | ||
U _impl{ 0 }; | ||
}; | ||
|
||
template <class... Args> | ||
Enum(Args...) -> Enum< | ||
std::common_type_t<Args...>, | ||
std::underlying_type_t< | ||
std::common_type_t<Args...>>>; | ||
} |
Oops, something went wrong.