forked from Ryan-rsm-McKenzie/CommonLibSSE
-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #150 from shad0wshayd3-TES5/dev-rex
feat: REX 2
- Loading branch information
Showing
13 changed files
with
1,100 additions
and
272 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
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,272 +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.