Skip to content

Commit

Permalink
feat: add BSTTuple (#186)
Browse files Browse the repository at this point in the history
  • Loading branch information
powerof3 authored Oct 22, 2023
1 parent 5b5bda7 commit 33a52a6
Show file tree
Hide file tree
Showing 5 changed files with 477 additions and 4 deletions.
7 changes: 4 additions & 3 deletions CommonLibSF/include/RE/A/ActorValueStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "RE/B/BSLock.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTTuple.h"

namespace RE
{
Expand All @@ -17,9 +18,9 @@ namespace RE
{
public:
// members
BSTArray<void*> baseValues; // 00 - BSTTuple<std::uint32_t, float>
BSTArray<void*> modifiers; // 10 - BSTTuple<std::uint32_t, Modifiers>
BSReadWriteLock avLock; // 20
BSTArray<BSTTuple<std::uint32_t, float>> baseValues; // 00
BSTArray<BSTTuple<std::uint32_t, Modifiers>> modifiers; // 10
BSReadWriteLock avLock; // 20
};
static_assert(sizeof(ActorValueStorage) == 0x28);
}
4 changes: 3 additions & 1 deletion CommonLibSF/include/RE/B/BGSPropertySheet.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include "RE/B/BGSTypedFormValuePair.h"
#include "RE/B/BSTTuple3.h"
#include "RE/B/BaseFormComponent.h"

namespace RE
Expand All @@ -16,7 +18,7 @@ namespace RE
void InitializeDataComponent() override; // 02 - { return; }

// members
std::uint64_t /* BSTArray<BSTTuple<TESForm*, BGSTypedFormValuePair::SharedVal>>* */ unk08;
BSTArray<BSTTuple3<TESForm*, TESForm*, BGSTypedFormValuePair::SharedVal>>* properties; // 08
};
static_assert(sizeof(BGSPropertySheet) == 0x10);
}
11 changes: 11 additions & 0 deletions CommonLibSF/include/RE/B/BGSTypedFormValuePair.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

namespace RE::BGSTypedFormValuePair
{
union SharedVal
{
std::uint32_t i;
float f;
};
static_assert(sizeof(SharedVal) == 0x4);
}
213 changes: 213 additions & 0 deletions CommonLibSF/include/RE/B/BSTTuple.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
#pragma once

#include "RE/M/MemoryManager.h"

namespace RE
{
template <class T1, class T2>
struct BSTTuple
{
public:
using first_type = T1;
using second_type = T2;

BSTTuple() //
noexcept(std::is_nothrow_default_constructible_v<first_type>&&
std::is_nothrow_default_constructible_v<second_type>) //
requires(std::is_default_constructible_v<first_type> &&
std::is_default_constructible_v<second_type>)
:
first(),
second()
{}

explicit(!std::is_convertible_v<const first_type&, first_type> ||
!std::is_convertible_v<const second_type&, second_type>) //
BSTTuple(const first_type& a_first, const second_type& a_second) //
noexcept(std::is_nothrow_copy_constructible_v<first_type>&&
std::is_nothrow_copy_constructible_v<second_type>) //
requires(std::is_copy_constructible_v<first_type> &&
std::is_copy_constructible_v<second_type>)
:
first(a_first),
second(a_second)
{}

template <class U1, class U2>
explicit(!std::is_convertible_v<U1&&, first_type> ||
!std::is_convertible_v<U2&&, second_type>) //
BSTTuple(U1&& a_first, U2&& a_second) //
noexcept(std::is_nothrow_constructible_v<first_type, U1&&>&&
std::is_nothrow_constructible_v<second_type, U2&&>) //
requires(std::is_constructible_v<first_type, U1 &&> &&
std::is_constructible_v<second_type, U2 &&>)
:
first(std::forward<U1>(a_first)),
second(std::forward<U2>(a_second))
{}

template <class U1, class U2>
explicit(!std::is_convertible_v<const U1&, first_type> ||
!std::is_convertible_v<const U2&, second_type>) //
BSTTuple(const BSTTuple<U1, U2>& a_rhs) //
noexcept(std::is_nothrow_constructible_v<first_type, const U1&>&&
std::is_nothrow_constructible_v<second_type, const U2&>) //
requires(std::is_constructible_v<first_type, const U1&> &&
std::is_constructible_v<second_type, const U2&>)
:
first(a_rhs.first),
second(a_rhs.second)
{}

template <class U1, class U2>
explicit(!std::is_convertible_v<U1&&, first_type> ||
!std::is_convertible_v<U2&&, second_type>) //
BSTTuple(BSTTuple<U1, U2>&& a_rhs) //
noexcept(std::is_nothrow_constructible_v<first_type, U1&&>&&
std::is_nothrow_constructible_v<second_type, U2&&>) //
requires(std::is_constructible_v<first_type, U1 &&> &&
std::is_constructible_v<second_type, U2 &&>)
:
first(std::forward<U1>(a_rhs.first)),
second(std::forward<U2>(a_rhs.second))
{}

template <
class... Args1,
class... Args2>
BSTTuple(std::piecewise_construct_t, std::tuple<Args1...> a_firstArgs, std::tuple<Args2...> a_secondArgs) :
BSTTuple(a_firstArgs, a_secondArgs, std::index_sequence_for<Args1...>(), std::index_sequence_for<Args2...>())
{}

private:
template <
class Tuple1,
class Tuple2,
std::size_t... I1,
std::size_t... I2>
BSTTuple(Tuple1& a_firstArgs, Tuple2& a_secondArgs, std::index_sequence<I1...>, std::index_sequence<I2...>) :
first(std::get<I1>(std::move(a_firstArgs))...),
second(std::get<I2>(std::move(a_secondArgs))...)
{}

public:
BSTTuple(const BSTTuple&) = default;
BSTTuple(BSTTuple&&) = default;

~BSTTuple() = default;

BSTTuple& operator=(const BSTTuple& a_rhs) //
noexcept(std::is_nothrow_copy_assignable_v<first_type>&&
std::is_nothrow_copy_assignable_v<second_type>) //
requires(std::is_copy_assignable_v<first_type> &&
std::is_copy_assignable_v<second_type>)
{
if (this != std::addressof(a_rhs)) {
first = a_rhs.first;
second = a_rhs.second;
}
return *this;
}

template <class U1, class U2>
BSTTuple& operator=(const BSTTuple<U1, U2>& a_rhs) //
noexcept(std::is_nothrow_assignable_v<first_type&, const U1&>&&
std::is_nothrow_assignable_v<second_type&, const U2&>) //
requires(std::is_assignable_v<first_type&, const U1&> &&
std::is_assignable_v<second_type&, const U2&>)
{
first = a_rhs.first;
second = a_rhs.second;
return *this;
}

BSTTuple& operator=(BSTTuple&& a_rhs) //
noexcept(std::is_nothrow_move_assignable_v<first_type>&&
std::is_nothrow_move_assignable_v<second_type>) //
requires(std::is_move_assignable_v<first_type> &&
std::is_move_assignable_v<second_type>)
{
if (this != std::addressof(a_rhs)) {
first = std::move(a_rhs.first);
second = std::move(a_rhs.second);
}
return *this;
}

template <class U1, class U2>
BSTTuple& operator=(BSTTuple<U1, U2>&& a_rhs) //
noexcept(std::is_nothrow_assignable_v<first_type&, U1>&&
std::is_nothrow_assignable_v<second_type&, U2>) //
requires(std::is_assignable_v<first_type&, U1> &&
std::is_assignable_v<second_type&, U2>)
{
first = std::move(a_rhs.first);
second = std::move(a_rhs.second);
return *this;
}

SF_HEAP_REDEFINE_NEW(BSTTuple<T1, T2>);

void swap(BSTTuple& a_rhs) //
noexcept(std::is_nothrow_swappable_v<first_type>&&
std::is_nothrow_swappable_v<second_type>)
{
using std::swap;
if (this != std::addressof(a_rhs)) {
swap(first, a_rhs.first);
swap(second, a_rhs.second);
}
}

// members
first_type first; // 00
second_type second; // ??
};

template <class T1, class T2>
[[nodiscard]] auto make_pair(T1&& a_first, T2&& a_second)
{
using result_t =
BSTTuple<
std::decay_t<T1>,
std::decay_t<T2>>;
return result_t(std::forward<T1>(a_first), std::forward<T2>(a_second));
}

template <class T1, class T2>
[[nodiscard]] auto make_tuple(T1&& a_first, T2&& a_second)
{
using result_t =
BSTTuple<
std::decay_t<T1>,
std::decay_t<T2>>;
return result_t(std::forward<T1>(a_first), std::forward<T2>(a_second));
}

template <class T1, class T2>
[[nodiscard]] bool operator==(const BSTTuple<T1, T2>& a_lhs, const BSTTuple<T1, T2>& a_rhs)
{
return a_lhs.first == a_rhs.first && a_lhs.second == a_rhs.second;
}

template <class T1, class T2>
[[nodiscard]] bool operator<(const BSTTuple<T1, T2>& a_lhs, const BSTTuple<T1, T2>& a_rhs)
{
return a_lhs.first < a_rhs.first ? true :
a_rhs.first < a_lhs.first ? false :
a_lhs.second < a_rhs.second ? true :
false;
}

template <class T1, class T2>
void swap(BSTTuple<T1, T2>& a_lhs, BSTTuple<T1, T2>& a_rhs) //
noexcept(noexcept(a_lhs.swap(a_rhs))) //
requires(std::is_swappable_v<T1> &&
std::is_swappable_v<T2>)
{
a_lhs.swap(a_rhs);
}

template <class T1, class T2>
BSTTuple(T1, T2) -> BSTTuple<T1, T2>;
}
Loading

0 comments on commit 33a52a6

Please sign in to comment.