Skip to content

Commit

Permalink
Merge pull request #32 from shad0wshayd3-FO4/dev-rex
Browse files Browse the repository at this point in the history
feat: REX 2
  • Loading branch information
shad0wshayd3 authored Nov 15, 2024
2 parents b4cf559 + d350461 commit d583832
Show file tree
Hide file tree
Showing 13 changed files with 1,103 additions and 261 deletions.
6 changes: 6 additions & 0 deletions CommonLibF4/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
cmake_minimum_required(VERSION 3.21)

option(F4SE_SUPPORT_XBYAK "Enables trampoline support for Xbyak." OFF)
option(REX_OPTION_INI "Enables ini config support for REX." OFF)
option(REX_OPTION_JSON "Enables json config support for REX." OFF)
option(REX_OPTION_TOML "Enables toml config support for REX." OFF)

project(
CommonLibF4
Expand Down Expand Up @@ -39,6 +42,9 @@ target_compile_definitions(
WINVER=0x0601 # windows 7, minimum supported version by fallout 4
_WIN32_WINNT=0x0601
"$<$<BOOL:${F4SE_SUPPORT_XBYAK}>:F4SE_SUPPORT_XBYAK=1>"
"$<$<BOOL:${REX_OPTION_INI}>:REX_OPTION_INI=1>"
"$<$<BOOL:${REX_OPTION_JSON}>:REX_OPTION_JSON=1>"
"$<$<BOOL:${REX_OPTION_TOML}>:REX_OPTION_TOML=1>"
)

target_compile_features(
Expand Down
8 changes: 8 additions & 0 deletions CommonLibF4/cmake/sourcelist.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,13 @@ set(SOURCES
include/REX/PS4.h
include/REX/PS4/SCEPAD.h
include/REX/REX.h
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
include/REX/W32.h
include/REX/W32/ADVAPI32.h
include/REX/W32/BASE.h
Expand Down Expand Up @@ -446,5 +453,6 @@ set(SOURCES
src/REL/Module.cpp
src/REL/Relocation.cpp
src/REL/Version.cpp
src/REX/REX.cpp
src/REX/W32.cpp
)
10 changes: 6 additions & 4 deletions CommonLibF4/include/F4SE/Impl/PCH.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <ctime>
#include <execution>
#include <filesystem>
#include <fstream>
#include <functional>
#include <initializer_list>
#include <intrin.h>
Expand Down Expand Up @@ -41,15 +42,16 @@ static_assert(
std::is_integral_v<std::time_t> && sizeof(std::time_t) == sizeof(std::size_t),
"wrap std::time_t instead");

#include "REX/REX/Enum.h"
#include "REX/REX/EnumSet.h"
#include "REX/W32/KERNEL32.h"
#include "REX/W32/USER32.h"

#pragma warning(push, 0)
#include <mmio/mmio.hpp>
#include <spdlog/spdlog.h>
#pragma warning(pop)

#include "REX/REX.h"
#include "REX/W32/KERNEL32.h"
#include "REX/W32/USER32.h"

namespace F4SE
{
using namespace std::literals;
Expand Down
263 changes: 7 additions & 256 deletions CommonLibF4/include/REX/REX.h
Original file line number Diff line number Diff line change
@@ -1,258 +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& 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"
Loading

0 comments on commit d583832

Please sign in to comment.