early-access version 3352
This commit is contained in:
parent
3ee566278a
commit
8c756f4f3a
@ -514,7 +514,7 @@ endif()
|
|||||||
# against all the src files. This should be used before making a pull request.
|
# against all the src files. This should be used before making a pull request.
|
||||||
# =======================================================================
|
# =======================================================================
|
||||||
|
|
||||||
set(CLANG_FORMAT_POSTFIX "-12")
|
set(CLANG_FORMAT_POSTFIX "-15")
|
||||||
find_program(CLANG_FORMAT
|
find_program(CLANG_FORMAT
|
||||||
NAMES clang-format${CLANG_FORMAT_POSTFIX}
|
NAMES clang-format${CLANG_FORMAT_POSTFIX}
|
||||||
clang-format
|
clang-format
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 3351.
|
This is the source code for early-access 3352.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
template <typename VaType, size_t AddressSpaceBits>
|
template <typename VaType, size_t AddressSpaceBits>
|
||||||
concept AddressSpaceValid = std::is_unsigned_v<VaType> && sizeof(VaType) * 8 >= AddressSpaceBits;
|
concept AddressSpaceValid = std::is_unsigned_v<VaType> && sizeof(VaType) * 8 >=
|
||||||
|
AddressSpaceBits;
|
||||||
|
|
||||||
struct EmptyStruct {};
|
struct EmptyStruct {};
|
||||||
|
|
||||||
@ -21,7 +22,7 @@ struct EmptyStruct {};
|
|||||||
*/
|
*/
|
||||||
template <typename VaType, VaType UnmappedVa, typename PaType, PaType UnmappedPa,
|
template <typename VaType, VaType UnmappedVa, typename PaType, PaType UnmappedPa,
|
||||||
bool PaContigSplit, size_t AddressSpaceBits, typename ExtraBlockInfo = EmptyStruct>
|
bool PaContigSplit, size_t AddressSpaceBits, typename ExtraBlockInfo = EmptyStruct>
|
||||||
requires AddressSpaceValid<VaType, AddressSpaceBits>
|
requires AddressSpaceValid<VaType, AddressSpaceBits>
|
||||||
class FlatAddressSpaceMap {
|
class FlatAddressSpaceMap {
|
||||||
public:
|
public:
|
||||||
/// The maximum VA that this AS can technically reach
|
/// The maximum VA that this AS can technically reach
|
||||||
@ -109,7 +110,7 @@ private:
|
|||||||
* initial, fast linear pass and a subsequent slower pass that iterates until it finds a free block
|
* initial, fast linear pass and a subsequent slower pass that iterates until it finds a free block
|
||||||
*/
|
*/
|
||||||
template <typename VaType, VaType UnmappedVa, size_t AddressSpaceBits>
|
template <typename VaType, VaType UnmappedVa, size_t AddressSpaceBits>
|
||||||
requires AddressSpaceValid<VaType, AddressSpaceBits>
|
requires AddressSpaceValid<VaType, AddressSpaceBits>
|
||||||
class FlatAllocator
|
class FlatAllocator
|
||||||
: public FlatAddressSpaceMap<VaType, UnmappedVa, bool, false, false, AddressSpaceBits> {
|
: public FlatAddressSpaceMap<VaType, UnmappedVa, bool, false, false, AddressSpaceBits> {
|
||||||
private:
|
private:
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires std::is_unsigned_v<T>
|
requires std::is_unsigned_v<T>
|
||||||
[[nodiscard]] constexpr T AlignUp(T value, size_t size) {
|
[[nodiscard]] constexpr T AlignUp(T value, size_t size) {
|
||||||
auto mod{static_cast<T>(value % size)};
|
auto mod{static_cast<T>(value % size)};
|
||||||
value -= mod;
|
value -= mod;
|
||||||
@ -18,31 +18,31 @@ requires std::is_unsigned_v<T>
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires std::is_unsigned_v<T>
|
requires std::is_unsigned_v<T>
|
||||||
[[nodiscard]] constexpr T AlignUpLog2(T value, size_t align_log2) {
|
[[nodiscard]] constexpr T AlignUpLog2(T value, size_t align_log2) {
|
||||||
return static_cast<T>((value + ((1ULL << align_log2) - 1)) >> align_log2 << align_log2);
|
return static_cast<T>((value + ((1ULL << align_log2) - 1)) >> align_log2 << align_log2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires std::is_unsigned_v<T>
|
requires std::is_unsigned_v<T>
|
||||||
[[nodiscard]] constexpr T AlignDown(T value, size_t size) {
|
[[nodiscard]] constexpr T AlignDown(T value, size_t size) {
|
||||||
return static_cast<T>(value - value % size);
|
return static_cast<T>(value - value % size);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires std::is_unsigned_v<T>
|
requires std::is_unsigned_v<T>
|
||||||
[[nodiscard]] constexpr bool Is4KBAligned(T value) {
|
[[nodiscard]] constexpr bool Is4KBAligned(T value) {
|
||||||
return (value & 0xFFF) == 0;
|
return (value & 0xFFF) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires std::is_unsigned_v<T>
|
requires std::is_unsigned_v<T>
|
||||||
[[nodiscard]] constexpr bool IsWordAligned(T value) {
|
[[nodiscard]] constexpr bool IsWordAligned(T value) {
|
||||||
return (value & 0b11) == 0;
|
return (value & 0b11) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires std::is_integral_v<T>
|
requires std::is_integral_v<T>
|
||||||
[[nodiscard]] constexpr bool IsAligned(T value, size_t alignment) {
|
[[nodiscard]] constexpr bool IsAligned(T value, size_t alignment) {
|
||||||
using U = typename std::make_unsigned_t<T>;
|
using U = typename std::make_unsigned_t<T>;
|
||||||
const U mask = static_cast<U>(alignment - 1);
|
const U mask = static_cast<U>(alignment - 1);
|
||||||
@ -50,7 +50,7 @@ requires std::is_integral_v<T>
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
requires std::is_integral_v<T>
|
requires std::is_integral_v<T>
|
||||||
[[nodiscard]] constexpr T DivideUp(T x, U y) {
|
[[nodiscard]] constexpr T DivideUp(T x, U y) {
|
||||||
return (x + (y - 1)) / y;
|
return (x + (y - 1)) / y;
|
||||||
}
|
}
|
||||||
@ -73,11 +73,11 @@ public:
|
|||||||
constexpr AlignmentAllocator(const AlignmentAllocator<T2, Align>&) noexcept {}
|
constexpr AlignmentAllocator(const AlignmentAllocator<T2, Align>&) noexcept {}
|
||||||
|
|
||||||
[[nodiscard]] T* allocate(size_type n) {
|
[[nodiscard]] T* allocate(size_type n) {
|
||||||
return static_cast<T*>(::operator new (n * sizeof(T), std::align_val_t{Align}));
|
return static_cast<T*>(::operator new(n * sizeof(T), std::align_val_t{Align}));
|
||||||
}
|
}
|
||||||
|
|
||||||
void deallocate(T* p, size_type n) {
|
void deallocate(T* p, size_type n) {
|
||||||
::operator delete (p, n * sizeof(T), std::align_val_t{Align});
|
::operator delete(p, n * sizeof(T), std::align_val_t{Align});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T2>
|
template <typename T2>
|
||||||
|
@ -75,7 +75,7 @@ extern "C" void AnnotateHappensAfter(const char*, int, void*);
|
|||||||
#if defined(AE_VCPP) || defined(AE_ICC)
|
#if defined(AE_VCPP) || defined(AE_ICC)
|
||||||
#define AE_FORCEINLINE __forceinline
|
#define AE_FORCEINLINE __forceinline
|
||||||
#elif defined(AE_GCC)
|
#elif defined(AE_GCC)
|
||||||
//#define AE_FORCEINLINE __attribute__((always_inline))
|
// #define AE_FORCEINLINE __attribute__((always_inline))
|
||||||
#define AE_FORCEINLINE inline
|
#define AE_FORCEINLINE inline
|
||||||
#else
|
#else
|
||||||
#define AE_FORCEINLINE inline
|
#define AE_FORCEINLINE inline
|
||||||
|
@ -45,19 +45,19 @@ template <typename T>
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires std::is_unsigned_v<T>
|
requires std::is_unsigned_v<T>
|
||||||
[[nodiscard]] constexpr bool IsPow2(T value) {
|
[[nodiscard]] constexpr bool IsPow2(T value) {
|
||||||
return std::has_single_bit(value);
|
return std::has_single_bit(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires std::is_integral_v<T>
|
requires std::is_integral_v<T>
|
||||||
[[nodiscard]] T NextPow2(T value) {
|
[[nodiscard]] T NextPow2(T value) {
|
||||||
return static_cast<T>(1ULL << ((8U * sizeof(T)) - std::countl_zero(value - 1U)));
|
return static_cast<T>(1ULL << ((8U * sizeof(T)) - std::countl_zero(value - 1U)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t bit_index, typename T>
|
template <size_t bit_index, typename T>
|
||||||
requires std::is_integral_v<T>
|
requires std::is_integral_v<T>
|
||||||
[[nodiscard]] constexpr bool Bit(const T value) {
|
[[nodiscard]] constexpr bool Bit(const T value) {
|
||||||
static_assert(bit_index < BitSize<T>(), "bit_index must be smaller than size of T");
|
static_assert(bit_index < BitSize<T>(), "bit_index must be smaller than size of T");
|
||||||
return ((value >> bit_index) & T(1)) == T(1);
|
return ((value >> bit_index) & T(1)) == T(1);
|
||||||
|
@ -16,9 +16,9 @@ concept IsContiguousContainer = std::contiguous_iterator<typename T::iterator>;
|
|||||||
// is available on all supported platforms.
|
// is available on all supported platforms.
|
||||||
template <typename Derived, typename Base>
|
template <typename Derived, typename Base>
|
||||||
concept DerivedFrom = requires {
|
concept DerivedFrom = requires {
|
||||||
std::is_base_of_v<Base, Derived>;
|
std::is_base_of_v<Base, Derived>;
|
||||||
std::is_convertible_v<const volatile Derived*, const volatile Base*>;
|
std::is_convertible_v<const volatile Derived*, const volatile Base*>;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Replace with std::convertible_to when libc++ implements it.
|
// TODO: Replace with std::convertible_to when libc++ implements it.
|
||||||
template <typename From, typename To>
|
template <typename From, typename To>
|
||||||
|
@ -10,14 +10,14 @@ namespace Common {
|
|||||||
|
|
||||||
/// Ceiled integer division.
|
/// Ceiled integer division.
|
||||||
template <typename N, typename D>
|
template <typename N, typename D>
|
||||||
requires std::is_integral_v<N> && std::is_unsigned_v<D>
|
requires std::is_integral_v<N> && std::is_unsigned_v<D>
|
||||||
[[nodiscard]] constexpr N DivCeil(N number, D divisor) {
|
[[nodiscard]] constexpr N DivCeil(N number, D divisor) {
|
||||||
return static_cast<N>((static_cast<D>(number) + divisor - 1) / divisor);
|
return static_cast<N>((static_cast<D>(number) + divisor - 1) / divisor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ceiled integer division with logarithmic divisor in base 2
|
/// Ceiled integer division with logarithmic divisor in base 2
|
||||||
template <typename N, typename D>
|
template <typename N, typename D>
|
||||||
requires std::is_integral_v<N> && std::is_unsigned_v<D>
|
requires std::is_integral_v<N> && std::is_unsigned_v<D>
|
||||||
[[nodiscard]] constexpr N DivCeilLog2(N value, D alignment_log2) {
|
[[nodiscard]] constexpr N DivCeilLog2(N value, D alignment_log2) {
|
||||||
return static_cast<N>((static_cast<D>(value) + (D(1) << alignment_log2) - 1) >> alignment_log2);
|
return static_cast<N>((static_cast<D>(value) + (D(1) << alignment_log2) - 1) >> alignment_log2);
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ struct no_init_t {
|
|||||||
* Additionally, this requires E to be trivially destructible
|
* Additionally, this requires E to be trivially destructible
|
||||||
*/
|
*/
|
||||||
template <typename T, typename E, bool = std::is_trivially_destructible_v<T>>
|
template <typename T, typename E, bool = std::is_trivially_destructible_v<T>>
|
||||||
requires std::is_trivially_destructible_v<E>
|
requires std::is_trivially_destructible_v<E>
|
||||||
struct expected_storage_base {
|
struct expected_storage_base {
|
||||||
constexpr expected_storage_base() : m_val{T{}}, m_has_val{true} {}
|
constexpr expected_storage_base() : m_val{T{}}, m_has_val{true} {}
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ struct expected_storage_base {
|
|||||||
* Additionally, this requires E to be trivially destructible
|
* Additionally, this requires E to be trivially destructible
|
||||||
*/
|
*/
|
||||||
template <typename T, typename E>
|
template <typename T, typename E>
|
||||||
requires std::is_trivially_destructible_v<E>
|
requires std::is_trivially_destructible_v<E>
|
||||||
struct expected_storage_base<T, E, true> {
|
struct expected_storage_base<T, E, true> {
|
||||||
constexpr expected_storage_base() : m_val{T{}}, m_has_val{true} {}
|
constexpr expected_storage_base() : m_val{T{}}, m_has_val{true} {}
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ struct expected_operations_base : expected_storage_base<T, E> {
|
|||||||
* Additionally, this requires E to be trivially copy constructible
|
* Additionally, this requires E to be trivially copy constructible
|
||||||
*/
|
*/
|
||||||
template <typename T, typename E, bool = std::is_trivially_copy_constructible_v<T>>
|
template <typename T, typename E, bool = std::is_trivially_copy_constructible_v<T>>
|
||||||
requires std::is_trivially_copy_constructible_v<E>
|
requires std::is_trivially_copy_constructible_v<E>
|
||||||
struct expected_copy_base : expected_operations_base<T, E> {
|
struct expected_copy_base : expected_operations_base<T, E> {
|
||||||
using expected_operations_base<T, E>::expected_operations_base;
|
using expected_operations_base<T, E>::expected_operations_base;
|
||||||
};
|
};
|
||||||
@ -261,7 +261,7 @@ struct expected_copy_base : expected_operations_base<T, E> {
|
|||||||
* Additionally, this requires E to be trivially copy constructible
|
* Additionally, this requires E to be trivially copy constructible
|
||||||
*/
|
*/
|
||||||
template <typename T, typename E>
|
template <typename T, typename E>
|
||||||
requires std::is_trivially_copy_constructible_v<E>
|
requires std::is_trivially_copy_constructible_v<E>
|
||||||
struct expected_copy_base<T, E, false> : expected_operations_base<T, E> {
|
struct expected_copy_base<T, E, false> : expected_operations_base<T, E> {
|
||||||
using expected_operations_base<T, E>::expected_operations_base;
|
using expected_operations_base<T, E>::expected_operations_base;
|
||||||
|
|
||||||
@ -289,7 +289,7 @@ struct expected_copy_base<T, E, false> : expected_operations_base<T, E> {
|
|||||||
* Additionally, this requires E to be trivially move constructible
|
* Additionally, this requires E to be trivially move constructible
|
||||||
*/
|
*/
|
||||||
template <typename T, typename E, bool = std::is_trivially_move_constructible_v<T>>
|
template <typename T, typename E, bool = std::is_trivially_move_constructible_v<T>>
|
||||||
requires std::is_trivially_move_constructible_v<E>
|
requires std::is_trivially_move_constructible_v<E>
|
||||||
struct expected_move_base : expected_copy_base<T, E> {
|
struct expected_move_base : expected_copy_base<T, E> {
|
||||||
using expected_copy_base<T, E>::expected_copy_base;
|
using expected_copy_base<T, E>::expected_copy_base;
|
||||||
};
|
};
|
||||||
@ -299,7 +299,7 @@ struct expected_move_base : expected_copy_base<T, E> {
|
|||||||
* Additionally, this requires E to be trivially move constructible
|
* Additionally, this requires E to be trivially move constructible
|
||||||
*/
|
*/
|
||||||
template <typename T, typename E>
|
template <typename T, typename E>
|
||||||
requires std::is_trivially_move_constructible_v<E>
|
requires std::is_trivially_move_constructible_v<E>
|
||||||
struct expected_move_base<T, E, false> : expected_copy_base<T, E> {
|
struct expected_move_base<T, E, false> : expected_copy_base<T, E> {
|
||||||
using expected_copy_base<T, E>::expected_copy_base;
|
using expected_copy_base<T, E>::expected_copy_base;
|
||||||
|
|
||||||
@ -330,9 +330,9 @@ template <typename T, typename E,
|
|||||||
bool = std::conjunction_v<std::is_trivially_copy_assignable<T>,
|
bool = std::conjunction_v<std::is_trivially_copy_assignable<T>,
|
||||||
std::is_trivially_copy_constructible<T>,
|
std::is_trivially_copy_constructible<T>,
|
||||||
std::is_trivially_destructible<T>>>
|
std::is_trivially_destructible<T>>>
|
||||||
requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
|
requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
|
||||||
std::is_trivially_copy_constructible<E>,
|
std::is_trivially_copy_constructible<E>,
|
||||||
std::is_trivially_destructible<E>>
|
std::is_trivially_destructible<E>>
|
||||||
struct expected_copy_assign_base : expected_move_base<T, E> {
|
struct expected_copy_assign_base : expected_move_base<T, E> {
|
||||||
using expected_move_base<T, E>::expected_move_base;
|
using expected_move_base<T, E>::expected_move_base;
|
||||||
};
|
};
|
||||||
@ -342,9 +342,9 @@ struct expected_copy_assign_base : expected_move_base<T, E> {
|
|||||||
* Additionally, this requires E to be trivially copy assignable
|
* Additionally, this requires E to be trivially copy assignable
|
||||||
*/
|
*/
|
||||||
template <typename T, typename E>
|
template <typename T, typename E>
|
||||||
requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
|
requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
|
||||||
std::is_trivially_copy_constructible<E>,
|
std::is_trivially_copy_constructible<E>,
|
||||||
std::is_trivially_destructible<E>>
|
std::is_trivially_destructible<E>>
|
||||||
struct expected_copy_assign_base<T, E, false> : expected_move_base<T, E> {
|
struct expected_copy_assign_base<T, E, false> : expected_move_base<T, E> {
|
||||||
using expected_move_base<T, E>::expected_move_base;
|
using expected_move_base<T, E>::expected_move_base;
|
||||||
|
|
||||||
@ -371,9 +371,9 @@ template <typename T, typename E,
|
|||||||
bool = std::conjunction_v<std::is_trivially_move_assignable<T>,
|
bool = std::conjunction_v<std::is_trivially_move_assignable<T>,
|
||||||
std::is_trivially_move_constructible<T>,
|
std::is_trivially_move_constructible<T>,
|
||||||
std::is_trivially_destructible<T>>>
|
std::is_trivially_destructible<T>>>
|
||||||
requires std::conjunction_v<std::is_trivially_move_assignable<E>,
|
requires std::conjunction_v<std::is_trivially_move_assignable<E>,
|
||||||
std::is_trivially_move_constructible<E>,
|
std::is_trivially_move_constructible<E>,
|
||||||
std::is_trivially_destructible<E>>
|
std::is_trivially_destructible<E>>
|
||||||
struct expected_move_assign_base : expected_copy_assign_base<T, E> {
|
struct expected_move_assign_base : expected_copy_assign_base<T, E> {
|
||||||
using expected_copy_assign_base<T, E>::expected_copy_assign_base;
|
using expected_copy_assign_base<T, E>::expected_copy_assign_base;
|
||||||
};
|
};
|
||||||
@ -383,9 +383,9 @@ struct expected_move_assign_base : expected_copy_assign_base<T, E> {
|
|||||||
* Additionally, this requires E to be trivially move assignable
|
* Additionally, this requires E to be trivially move assignable
|
||||||
*/
|
*/
|
||||||
template <typename T, typename E>
|
template <typename T, typename E>
|
||||||
requires std::conjunction_v<std::is_trivially_move_assignable<E>,
|
requires std::conjunction_v<std::is_trivially_move_assignable<E>,
|
||||||
std::is_trivially_move_constructible<E>,
|
std::is_trivially_move_constructible<E>,
|
||||||
std::is_trivially_destructible<E>>
|
std::is_trivially_destructible<E>>
|
||||||
struct expected_move_assign_base<T, E, false> : expected_copy_assign_base<T, E> {
|
struct expected_move_assign_base<T, E, false> : expected_copy_assign_base<T, E> {
|
||||||
using expected_copy_assign_base<T, E>::expected_copy_assign_base;
|
using expected_copy_assign_base<T, E>::expected_copy_assign_base;
|
||||||
|
|
||||||
@ -412,7 +412,7 @@ struct expected_move_assign_base<T, E, false> : expected_copy_assign_base<T, E>
|
|||||||
*/
|
*/
|
||||||
template <typename T, typename E, bool EnableCopy = std::is_copy_constructible_v<T>,
|
template <typename T, typename E, bool EnableCopy = std::is_copy_constructible_v<T>,
|
||||||
bool EnableMove = std::is_move_constructible_v<T>>
|
bool EnableMove = std::is_move_constructible_v<T>>
|
||||||
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
|
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
|
||||||
struct expected_delete_ctor_base {
|
struct expected_delete_ctor_base {
|
||||||
expected_delete_ctor_base() = default;
|
expected_delete_ctor_base() = default;
|
||||||
expected_delete_ctor_base(const expected_delete_ctor_base&) = default;
|
expected_delete_ctor_base(const expected_delete_ctor_base&) = default;
|
||||||
@ -422,7 +422,7 @@ struct expected_delete_ctor_base {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename E>
|
template <typename T, typename E>
|
||||||
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
|
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
|
||||||
struct expected_delete_ctor_base<T, E, true, false> {
|
struct expected_delete_ctor_base<T, E, true, false> {
|
||||||
expected_delete_ctor_base() = default;
|
expected_delete_ctor_base() = default;
|
||||||
expected_delete_ctor_base(const expected_delete_ctor_base&) = default;
|
expected_delete_ctor_base(const expected_delete_ctor_base&) = default;
|
||||||
@ -432,7 +432,7 @@ struct expected_delete_ctor_base<T, E, true, false> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename E>
|
template <typename T, typename E>
|
||||||
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
|
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
|
||||||
struct expected_delete_ctor_base<T, E, false, true> {
|
struct expected_delete_ctor_base<T, E, false, true> {
|
||||||
expected_delete_ctor_base() = default;
|
expected_delete_ctor_base() = default;
|
||||||
expected_delete_ctor_base(const expected_delete_ctor_base&) = delete;
|
expected_delete_ctor_base(const expected_delete_ctor_base&) = delete;
|
||||||
@ -442,7 +442,7 @@ struct expected_delete_ctor_base<T, E, false, true> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename E>
|
template <typename T, typename E>
|
||||||
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
|
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
|
||||||
struct expected_delete_ctor_base<T, E, false, false> {
|
struct expected_delete_ctor_base<T, E, false, false> {
|
||||||
expected_delete_ctor_base() = default;
|
expected_delete_ctor_base() = default;
|
||||||
expected_delete_ctor_base(const expected_delete_ctor_base&) = delete;
|
expected_delete_ctor_base(const expected_delete_ctor_base&) = delete;
|
||||||
@ -460,8 +460,8 @@ template <
|
|||||||
typename T, typename E,
|
typename T, typename E,
|
||||||
bool EnableCopy = std::conjunction_v<std::is_copy_constructible<T>, std::is_copy_assignable<T>>,
|
bool EnableCopy = std::conjunction_v<std::is_copy_constructible<T>, std::is_copy_assignable<T>>,
|
||||||
bool EnableMove = std::conjunction_v<std::is_move_constructible<T>, std::is_move_assignable<T>>>
|
bool EnableMove = std::conjunction_v<std::is_move_constructible<T>, std::is_move_assignable<T>>>
|
||||||
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
|
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
|
||||||
std::is_copy_assignable<E>, std::is_move_assignable<E>>
|
std::is_copy_assignable<E>, std::is_move_assignable<E>>
|
||||||
struct expected_delete_assign_base {
|
struct expected_delete_assign_base {
|
||||||
expected_delete_assign_base() = default;
|
expected_delete_assign_base() = default;
|
||||||
expected_delete_assign_base(const expected_delete_assign_base&) = default;
|
expected_delete_assign_base(const expected_delete_assign_base&) = default;
|
||||||
@ -471,8 +471,8 @@ struct expected_delete_assign_base {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename E>
|
template <typename T, typename E>
|
||||||
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
|
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
|
||||||
std::is_copy_assignable<E>, std::is_move_assignable<E>>
|
std::is_copy_assignable<E>, std::is_move_assignable<E>>
|
||||||
struct expected_delete_assign_base<T, E, true, false> {
|
struct expected_delete_assign_base<T, E, true, false> {
|
||||||
expected_delete_assign_base() = default;
|
expected_delete_assign_base() = default;
|
||||||
expected_delete_assign_base(const expected_delete_assign_base&) = default;
|
expected_delete_assign_base(const expected_delete_assign_base&) = default;
|
||||||
@ -482,8 +482,8 @@ struct expected_delete_assign_base<T, E, true, false> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename E>
|
template <typename T, typename E>
|
||||||
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
|
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
|
||||||
std::is_copy_assignable<E>, std::is_move_assignable<E>>
|
std::is_copy_assignable<E>, std::is_move_assignable<E>>
|
||||||
struct expected_delete_assign_base<T, E, false, true> {
|
struct expected_delete_assign_base<T, E, false, true> {
|
||||||
expected_delete_assign_base() = default;
|
expected_delete_assign_base() = default;
|
||||||
expected_delete_assign_base(const expected_delete_assign_base&) = default;
|
expected_delete_assign_base(const expected_delete_assign_base&) = default;
|
||||||
@ -493,8 +493,8 @@ struct expected_delete_assign_base<T, E, false, true> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename E>
|
template <typename T, typename E>
|
||||||
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
|
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
|
||||||
std::is_copy_assignable<E>, std::is_move_assignable<E>>
|
std::is_copy_assignable<E>, std::is_move_assignable<E>>
|
||||||
struct expected_delete_assign_base<T, E, false, false> {
|
struct expected_delete_assign_base<T, E, false, false> {
|
||||||
expected_delete_assign_base() = default;
|
expected_delete_assign_base() = default;
|
||||||
expected_delete_assign_base(const expected_delete_assign_base&) = default;
|
expected_delete_assign_base(const expected_delete_assign_base&) = default;
|
||||||
|
@ -242,19 +242,21 @@ public:
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept HasRedBlackKeyType = requires {
|
concept HasRedBlackKeyType = requires {
|
||||||
{ std::is_same<typename T::RedBlackKeyType, void>::value } -> std::convertible_to<bool>;
|
{
|
||||||
};
|
std::is_same<typename T::RedBlackKeyType, void>::value
|
||||||
|
} -> std::convertible_to<bool>;
|
||||||
|
};
|
||||||
|
|
||||||
namespace impl {
|
namespace impl {
|
||||||
|
|
||||||
template <typename T, typename Default>
|
template <typename T, typename Default>
|
||||||
consteval auto* GetRedBlackKeyType() {
|
consteval auto* GetRedBlackKeyType() {
|
||||||
if constexpr (HasRedBlackKeyType<T>) {
|
if constexpr (HasRedBlackKeyType<T>) {
|
||||||
return static_cast<typename T::RedBlackKeyType*>(nullptr);
|
return static_cast<typename T::RedBlackKeyType*>(nullptr);
|
||||||
} else {
|
} else {
|
||||||
return static_cast<Default*>(nullptr);
|
return static_cast<Default*>(nullptr);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace impl
|
} // namespace impl
|
||||||
|
|
||||||
|
@ -9,17 +9,19 @@
|
|||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
requires(!std::is_array_v<T>) std::unique_ptr<T> make_unique_for_overwrite() {
|
requires(!std::is_array_v<T>)
|
||||||
|
std::unique_ptr<T> make_unique_for_overwrite() {
|
||||||
return std::unique_ptr<T>(new T);
|
return std::unique_ptr<T>(new T);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
requires std::is_unbounded_array_v<T> std::unique_ptr<T> make_unique_for_overwrite(std::size_t n) {
|
requires std::is_unbounded_array_v<T>
|
||||||
|
std::unique_ptr<T> make_unique_for_overwrite(std::size_t n) {
|
||||||
return std::unique_ptr<T>(new std::remove_extent_t<T>[n]);
|
return std::unique_ptr<T>(new std::remove_extent_t<T>[n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class... Args>
|
template <class T, class... Args>
|
||||||
requires std::is_bounded_array_v<T>
|
requires std::is_bounded_array_v<T>
|
||||||
void make_unique_for_overwrite(Args&&...) = delete;
|
void make_unique_for_overwrite(Args&&...) = delete;
|
||||||
|
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
@ -18,9 +18,9 @@ namespace ranges {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept range = requires(T& t) {
|
concept range = requires(T& t) {
|
||||||
begin(t);
|
begin(t);
|
||||||
end(t);
|
end(t);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept input_range = range<T>;
|
concept input_range = range<T>;
|
||||||
@ -421,7 +421,7 @@ struct generate_fn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename R, std::copy_constructible F>
|
template <typename R, std::copy_constructible F>
|
||||||
requires std::invocable<F&> && ranges::output_range<R>
|
requires std::invocable<F&> && ranges::output_range<R>
|
||||||
constexpr ranges::iterator_t<R> operator()(R&& r, F gen) const {
|
constexpr ranges::iterator_t<R> operator()(R&& r, F gen) const {
|
||||||
return operator()(ranges::begin(r), ranges::end(r), std::move(gen));
|
return operator()(ranges::begin(r), ranges::end(r), std::move(gen));
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,7 @@ public:
|
|||||||
using callback_type = Callback;
|
using callback_type = Callback;
|
||||||
|
|
||||||
template <typename C>
|
template <typename C>
|
||||||
requires constructible_from<Callback, C>
|
requires constructible_from<Callback, C>
|
||||||
explicit stop_callback(const stop_token& st,
|
explicit stop_callback(const stop_token& st,
|
||||||
C&& cb) noexcept(is_nothrow_constructible_v<Callback, C>)
|
C&& cb) noexcept(is_nothrow_constructible_v<Callback, C>)
|
||||||
: m_stop_state(st.m_stop_state) {
|
: m_stop_state(st.m_stop_state) {
|
||||||
@ -222,7 +222,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
template <typename C>
|
template <typename C>
|
||||||
requires constructible_from<Callback, C>
|
requires constructible_from<Callback, C>
|
||||||
explicit stop_callback(stop_token&& st,
|
explicit stop_callback(stop_token&& st,
|
||||||
C&& cb) noexcept(is_nothrow_constructible_v<Callback, C>)
|
C&& cb) noexcept(is_nothrow_constructible_v<Callback, C>)
|
||||||
: m_stop_state(move(st.m_stop_state)) {
|
: m_stop_state(move(st.m_stop_state)) {
|
||||||
|
@ -131,7 +131,8 @@ public:
|
|||||||
* @param default_val Intial value of the setting, and default value of the setting
|
* @param default_val Intial value of the setting, and default value of the setting
|
||||||
* @param name Label for the setting
|
* @param name Label for the setting
|
||||||
*/
|
*/
|
||||||
explicit Setting(const Type& default_val, const std::string& name) requires(!ranged)
|
explicit Setting(const Type& default_val, const std::string& name)
|
||||||
|
requires(!ranged)
|
||||||
: value{default_val}, default_value{default_val}, label{name} {}
|
: value{default_val}, default_value{default_val}, label{name} {}
|
||||||
virtual ~Setting() = default;
|
virtual ~Setting() = default;
|
||||||
|
|
||||||
@ -144,7 +145,8 @@ public:
|
|||||||
* @param name Label for the setting
|
* @param name Label for the setting
|
||||||
*/
|
*/
|
||||||
explicit Setting(const Type& default_val, const Type& min_val, const Type& max_val,
|
explicit Setting(const Type& default_val, const Type& min_val, const Type& max_val,
|
||||||
const std::string& name) requires(ranged)
|
const std::string& name)
|
||||||
|
requires(ranged)
|
||||||
: value{default_val},
|
: value{default_val},
|
||||||
default_value{default_val}, maximum{max_val}, minimum{min_val}, label{name} {}
|
default_value{default_val}, maximum{max_val}, minimum{min_val}, label{name} {}
|
||||||
|
|
||||||
@ -232,7 +234,8 @@ public:
|
|||||||
* @param default_val Intial value of the setting, and default value of the setting
|
* @param default_val Intial value of the setting, and default value of the setting
|
||||||
* @param name Label for the setting
|
* @param name Label for the setting
|
||||||
*/
|
*/
|
||||||
explicit SwitchableSetting(const Type& default_val, const std::string& name) requires(!ranged)
|
explicit SwitchableSetting(const Type& default_val, const std::string& name)
|
||||||
|
requires(!ranged)
|
||||||
: Setting<Type>{default_val, name} {}
|
: Setting<Type>{default_val, name} {}
|
||||||
virtual ~SwitchableSetting() = default;
|
virtual ~SwitchableSetting() = default;
|
||||||
|
|
||||||
@ -245,7 +248,8 @@ public:
|
|||||||
* @param name Label for the setting
|
* @param name Label for the setting
|
||||||
*/
|
*/
|
||||||
explicit SwitchableSetting(const Type& default_val, const Type& min_val, const Type& max_val,
|
explicit SwitchableSetting(const Type& default_val, const Type& min_val, const Type& max_val,
|
||||||
const std::string& name) requires(ranged)
|
const std::string& name)
|
||||||
|
requires(ranged)
|
||||||
: Setting<Type, true>{default_val, min_val, max_val, name} {}
|
: Setting<Type, true>{default_val, min_val, max_val, name} {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,12 +103,12 @@ concept IsRBEntry = CheckRBEntry<T>::value;
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept HasRBEntry = requires(T& t, const T& ct) {
|
concept HasRBEntry = requires(T& t, const T& ct) {
|
||||||
{ t.GetRBEntry() } -> std::same_as<RBEntry<T>&>;
|
{ t.GetRBEntry() } -> std::same_as<RBEntry<T>&>;
|
||||||
{ ct.GetRBEntry() } -> std::same_as<const RBEntry<T>&>;
|
{ ct.GetRBEntry() } -> std::same_as<const RBEntry<T>&>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
class RBHead {
|
class RBHead {
|
||||||
private:
|
private:
|
||||||
T* m_rbh_root = nullptr;
|
T* m_rbh_root = nullptr;
|
||||||
@ -130,90 +130,90 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
[[nodiscard]] constexpr RBEntry<T>& RB_ENTRY(T* t) {
|
[[nodiscard]] constexpr RBEntry<T>& RB_ENTRY(T* t) {
|
||||||
return t->GetRBEntry();
|
return t->GetRBEntry();
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
[[nodiscard]] constexpr const RBEntry<T>& RB_ENTRY(const T* t) {
|
[[nodiscard]] constexpr const RBEntry<T>& RB_ENTRY(const T* t) {
|
||||||
return t->GetRBEntry();
|
return t->GetRBEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
[[nodiscard]] constexpr T* RB_LEFT(T* t) {
|
[[nodiscard]] constexpr T* RB_LEFT(T* t) {
|
||||||
return RB_ENTRY(t).Left();
|
return RB_ENTRY(t).Left();
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
[[nodiscard]] constexpr const T* RB_LEFT(const T* t) {
|
[[nodiscard]] constexpr const T* RB_LEFT(const T* t) {
|
||||||
return RB_ENTRY(t).Left();
|
return RB_ENTRY(t).Left();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
[[nodiscard]] constexpr T* RB_RIGHT(T* t) {
|
[[nodiscard]] constexpr T* RB_RIGHT(T* t) {
|
||||||
return RB_ENTRY(t).Right();
|
return RB_ENTRY(t).Right();
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
[[nodiscard]] constexpr const T* RB_RIGHT(const T* t) {
|
[[nodiscard]] constexpr const T* RB_RIGHT(const T* t) {
|
||||||
return RB_ENTRY(t).Right();
|
return RB_ENTRY(t).Right();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
[[nodiscard]] constexpr T* RB_PARENT(T* t) {
|
[[nodiscard]] constexpr T* RB_PARENT(T* t) {
|
||||||
return RB_ENTRY(t).Parent();
|
return RB_ENTRY(t).Parent();
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
[[nodiscard]] constexpr const T* RB_PARENT(const T* t) {
|
[[nodiscard]] constexpr const T* RB_PARENT(const T* t) {
|
||||||
return RB_ENTRY(t).Parent();
|
return RB_ENTRY(t).Parent();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr void RB_SET_LEFT(T* t, T* e) {
|
constexpr void RB_SET_LEFT(T* t, T* e) {
|
||||||
RB_ENTRY(t).SetLeft(e);
|
RB_ENTRY(t).SetLeft(e);
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr void RB_SET_RIGHT(T* t, T* e) {
|
constexpr void RB_SET_RIGHT(T* t, T* e) {
|
||||||
RB_ENTRY(t).SetRight(e);
|
RB_ENTRY(t).SetRight(e);
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr void RB_SET_PARENT(T* t, T* e) {
|
constexpr void RB_SET_PARENT(T* t, T* e) {
|
||||||
RB_ENTRY(t).SetParent(e);
|
RB_ENTRY(t).SetParent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
[[nodiscard]] constexpr bool RB_IS_BLACK(const T* t) {
|
[[nodiscard]] constexpr bool RB_IS_BLACK(const T* t) {
|
||||||
return RB_ENTRY(t).IsBlack();
|
return RB_ENTRY(t).IsBlack();
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
[[nodiscard]] constexpr bool RB_IS_RED(const T* t) {
|
[[nodiscard]] constexpr bool RB_IS_RED(const T* t) {
|
||||||
return RB_ENTRY(t).IsRed();
|
return RB_ENTRY(t).IsRed();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
[[nodiscard]] constexpr RBColor RB_COLOR(const T* t) {
|
[[nodiscard]] constexpr RBColor RB_COLOR(const T* t) {
|
||||||
return RB_ENTRY(t).Color();
|
return RB_ENTRY(t).Color();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr void RB_SET_COLOR(T* t, RBColor c) {
|
constexpr void RB_SET_COLOR(T* t, RBColor c) {
|
||||||
RB_ENTRY(t).SetColor(c);
|
RB_ENTRY(t).SetColor(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr void RB_SET(T* elm, T* parent) {
|
constexpr void RB_SET(T* elm, T* parent) {
|
||||||
auto& rb_entry = RB_ENTRY(elm);
|
auto& rb_entry = RB_ENTRY(elm);
|
||||||
rb_entry.SetParent(parent);
|
rb_entry.SetParent(parent);
|
||||||
@ -223,14 +223,14 @@ constexpr void RB_SET(T* elm, T* parent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr void RB_SET_BLACKRED(T* black, T* red) {
|
constexpr void RB_SET_BLACKRED(T* black, T* red) {
|
||||||
RB_SET_COLOR(black, RBColor::RB_BLACK);
|
RB_SET_COLOR(black, RBColor::RB_BLACK);
|
||||||
RB_SET_COLOR(red, RBColor::RB_RED);
|
RB_SET_COLOR(red, RBColor::RB_RED);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr void RB_ROTATE_LEFT(RBHead<T>& head, T* elm, T*& tmp) {
|
constexpr void RB_ROTATE_LEFT(RBHead<T>& head, T* elm, T*& tmp) {
|
||||||
tmp = RB_RIGHT(elm);
|
tmp = RB_RIGHT(elm);
|
||||||
if (RB_SET_RIGHT(elm, RB_LEFT(tmp)); RB_RIGHT(elm) != nullptr) {
|
if (RB_SET_RIGHT(elm, RB_LEFT(tmp)); RB_RIGHT(elm) != nullptr) {
|
||||||
@ -252,7 +252,7 @@ constexpr void RB_ROTATE_LEFT(RBHead<T>& head, T* elm, T*& tmp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr void RB_ROTATE_RIGHT(RBHead<T>& head, T* elm, T*& tmp) {
|
constexpr void RB_ROTATE_RIGHT(RBHead<T>& head, T* elm, T*& tmp) {
|
||||||
tmp = RB_LEFT(elm);
|
tmp = RB_LEFT(elm);
|
||||||
if (RB_SET_LEFT(elm, RB_RIGHT(tmp)); RB_LEFT(elm) != nullptr) {
|
if (RB_SET_LEFT(elm, RB_RIGHT(tmp)); RB_LEFT(elm) != nullptr) {
|
||||||
@ -274,7 +274,7 @@ constexpr void RB_ROTATE_RIGHT(RBHead<T>& head, T* elm, T*& tmp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr void RB_REMOVE_COLOR(RBHead<T>& head, T* parent, T* elm) {
|
constexpr void RB_REMOVE_COLOR(RBHead<T>& head, T* parent, T* elm) {
|
||||||
T* tmp;
|
T* tmp;
|
||||||
while ((elm == nullptr || RB_IS_BLACK(elm)) && elm != head.Root()) {
|
while ((elm == nullptr || RB_IS_BLACK(elm)) && elm != head.Root()) {
|
||||||
@ -358,7 +358,7 @@ constexpr void RB_REMOVE_COLOR(RBHead<T>& head, T* parent, T* elm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr T* RB_REMOVE(RBHead<T>& head, T* elm) {
|
constexpr T* RB_REMOVE(RBHead<T>& head, T* elm) {
|
||||||
T* child = nullptr;
|
T* child = nullptr;
|
||||||
T* parent = nullptr;
|
T* parent = nullptr;
|
||||||
@ -451,7 +451,7 @@ constexpr T* RB_REMOVE(RBHead<T>& head, T* elm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr void RB_INSERT_COLOR(RBHead<T>& head, T* elm) {
|
constexpr void RB_INSERT_COLOR(RBHead<T>& head, T* elm) {
|
||||||
T *parent = nullptr, *tmp = nullptr;
|
T *parent = nullptr, *tmp = nullptr;
|
||||||
while ((parent = RB_PARENT(elm)) != nullptr && RB_IS_RED(parent)) {
|
while ((parent = RB_PARENT(elm)) != nullptr && RB_IS_RED(parent)) {
|
||||||
@ -499,7 +499,7 @@ constexpr void RB_INSERT_COLOR(RBHead<T>& head, T* elm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename Compare>
|
template <typename T, typename Compare>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr T* RB_INSERT(RBHead<T>& head, T* elm, Compare cmp) {
|
constexpr T* RB_INSERT(RBHead<T>& head, T* elm, Compare cmp) {
|
||||||
T* parent = nullptr;
|
T* parent = nullptr;
|
||||||
T* tmp = head.Root();
|
T* tmp = head.Root();
|
||||||
@ -534,7 +534,7 @@ constexpr T* RB_INSERT(RBHead<T>& head, T* elm, Compare cmp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename Compare>
|
template <typename T, typename Compare>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr T* RB_FIND(RBHead<T>& head, T* elm, Compare cmp) {
|
constexpr T* RB_FIND(RBHead<T>& head, T* elm, Compare cmp) {
|
||||||
T* tmp = head.Root();
|
T* tmp = head.Root();
|
||||||
|
|
||||||
@ -553,7 +553,7 @@ constexpr T* RB_FIND(RBHead<T>& head, T* elm, Compare cmp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename Compare>
|
template <typename T, typename Compare>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr T* RB_NFIND(RBHead<T>& head, T* elm, Compare cmp) {
|
constexpr T* RB_NFIND(RBHead<T>& head, T* elm, Compare cmp) {
|
||||||
T* tmp = head.Root();
|
T* tmp = head.Root();
|
||||||
T* res = nullptr;
|
T* res = nullptr;
|
||||||
@ -574,7 +574,7 @@ constexpr T* RB_NFIND(RBHead<T>& head, T* elm, Compare cmp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename U, typename Compare>
|
template <typename T, typename U, typename Compare>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr T* RB_FIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
|
constexpr T* RB_FIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
|
||||||
T* tmp = head.Root();
|
T* tmp = head.Root();
|
||||||
|
|
||||||
@ -593,7 +593,7 @@ constexpr T* RB_FIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename U, typename Compare>
|
template <typename T, typename U, typename Compare>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr T* RB_NFIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
|
constexpr T* RB_NFIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
|
||||||
T* tmp = head.Root();
|
T* tmp = head.Root();
|
||||||
T* res = nullptr;
|
T* res = nullptr;
|
||||||
@ -614,7 +614,7 @@ constexpr T* RB_NFIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename Compare>
|
template <typename T, typename Compare>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr T* RB_FIND_EXISTING(RBHead<T>& head, T* elm, Compare cmp) {
|
constexpr T* RB_FIND_EXISTING(RBHead<T>& head, T* elm, Compare cmp) {
|
||||||
T* tmp = head.Root();
|
T* tmp = head.Root();
|
||||||
|
|
||||||
@ -631,7 +631,7 @@ constexpr T* RB_FIND_EXISTING(RBHead<T>& head, T* elm, Compare cmp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename U, typename Compare>
|
template <typename T, typename U, typename Compare>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr T* RB_FIND_EXISTING_KEY(RBHead<T>& head, const U& key, Compare cmp) {
|
constexpr T* RB_FIND_EXISTING_KEY(RBHead<T>& head, const U& key, Compare cmp) {
|
||||||
T* tmp = head.Root();
|
T* tmp = head.Root();
|
||||||
|
|
||||||
@ -648,7 +648,7 @@ constexpr T* RB_FIND_EXISTING_KEY(RBHead<T>& head, const U& key, Compare cmp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr T* RB_NEXT(T* elm) {
|
constexpr T* RB_NEXT(T* elm) {
|
||||||
if (RB_RIGHT(elm)) {
|
if (RB_RIGHT(elm)) {
|
||||||
elm = RB_RIGHT(elm);
|
elm = RB_RIGHT(elm);
|
||||||
@ -669,7 +669,7 @@ constexpr T* RB_NEXT(T* elm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr T* RB_PREV(T* elm) {
|
constexpr T* RB_PREV(T* elm) {
|
||||||
if (RB_LEFT(elm)) {
|
if (RB_LEFT(elm)) {
|
||||||
elm = RB_LEFT(elm);
|
elm = RB_LEFT(elm);
|
||||||
@ -690,7 +690,7 @@ constexpr T* RB_PREV(T* elm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr T* RB_MIN(RBHead<T>& head) {
|
constexpr T* RB_MIN(RBHead<T>& head) {
|
||||||
T* tmp = head.Root();
|
T* tmp = head.Root();
|
||||||
T* parent = nullptr;
|
T* parent = nullptr;
|
||||||
@ -704,7 +704,7 @@ constexpr T* RB_MIN(RBHead<T>& head) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires HasRBEntry<T>
|
requires HasRBEntry<T>
|
||||||
constexpr T* RB_MAX(RBHead<T>& head) {
|
constexpr T* RB_MAX(RBHead<T>& head) {
|
||||||
T* tmp = head.Root();
|
T* tmp = head.Root();
|
||||||
T* parent = nullptr;
|
T* parent = nullptr;
|
||||||
|
@ -348,9 +348,7 @@ public:
|
|||||||
// _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all
|
// _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all
|
||||||
// component names (x<->r) and permutations (xy<->yx)
|
// component names (x<->r) and permutations (xy<->yx)
|
||||||
#define _DEFINE_SWIZZLER2(a, b, name) \
|
#define _DEFINE_SWIZZLER2(a, b, name) \
|
||||||
[[nodiscard]] constexpr Vec2<T> name() const { \
|
[[nodiscard]] constexpr Vec2<T> name() const { return Vec2<T>(a, b); }
|
||||||
return Vec2<T>(a, b); \
|
|
||||||
}
|
|
||||||
#define DEFINE_SWIZZLER2(a, b, a2, b2, a3, b3, a4, b4) \
|
#define DEFINE_SWIZZLER2(a, b, a2, b2, a3, b3, a4, b4) \
|
||||||
_DEFINE_SWIZZLER2(a, b, a##b); \
|
_DEFINE_SWIZZLER2(a, b, a##b); \
|
||||||
_DEFINE_SWIZZLER2(a, b, a2##b2); \
|
_DEFINE_SWIZZLER2(a, b, a2##b2); \
|
||||||
@ -543,9 +541,7 @@ public:
|
|||||||
// DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and
|
// DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and
|
||||||
// permutations (xy<->yx)
|
// permutations (xy<->yx)
|
||||||
#define _DEFINE_SWIZZLER2(a, b, name) \
|
#define _DEFINE_SWIZZLER2(a, b, name) \
|
||||||
[[nodiscard]] constexpr Vec2<T> name() const { \
|
[[nodiscard]] constexpr Vec2<T> name() const { return Vec2<T>(a, b); }
|
||||||
return Vec2<T>(a, b); \
|
|
||||||
}
|
|
||||||
#define DEFINE_SWIZZLER2_COMP1(a, a2) \
|
#define DEFINE_SWIZZLER2_COMP1(a, a2) \
|
||||||
_DEFINE_SWIZZLER2(a, a, a##a); \
|
_DEFINE_SWIZZLER2(a, a, a##a); \
|
||||||
_DEFINE_SWIZZLER2(a, a, a2##a2)
|
_DEFINE_SWIZZLER2(a, a, a2##a2)
|
||||||
@ -570,9 +566,7 @@ public:
|
|||||||
#undef _DEFINE_SWIZZLER2
|
#undef _DEFINE_SWIZZLER2
|
||||||
|
|
||||||
#define _DEFINE_SWIZZLER3(a, b, c, name) \
|
#define _DEFINE_SWIZZLER3(a, b, c, name) \
|
||||||
[[nodiscard]] constexpr Vec3<T> name() const { \
|
[[nodiscard]] constexpr Vec3<T> name() const { return Vec3<T>(a, b, c); }
|
||||||
return Vec3<T>(a, b, c); \
|
|
||||||
}
|
|
||||||
#define DEFINE_SWIZZLER3_COMP1(a, a2) \
|
#define DEFINE_SWIZZLER3_COMP1(a, a2) \
|
||||||
_DEFINE_SWIZZLER3(a, a, a, a##a##a); \
|
_DEFINE_SWIZZLER3(a, a, a, a##a##a); \
|
||||||
_DEFINE_SWIZZLER3(a, a, a, a2##a2##a2)
|
_DEFINE_SWIZZLER3(a, a, a, a2##a2##a2)
|
||||||
@ -641,8 +635,8 @@ template <typename T>
|
|||||||
|
|
||||||
// linear interpolation via float: 0.0=begin, 1.0=end
|
// linear interpolation via float: 0.0=begin, 1.0=end
|
||||||
template <typename X>
|
template <typename X>
|
||||||
[[nodiscard]] constexpr decltype(X{} * float{} + X{} * float{})
|
[[nodiscard]] constexpr decltype(X{} * float{} + X{} * float{}) Lerp(const X& begin, const X& end,
|
||||||
Lerp(const X& begin, const X& end, const float t) {
|
const float t) {
|
||||||
return begin * (1.f - t) + end * t;
|
return begin * (1.f - t) + end * t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,9 +24,7 @@ private:
|
|||||||
friend class ::Kernel::KClassTokenGenerator; \
|
friend class ::Kernel::KClassTokenGenerator; \
|
||||||
static constexpr inline auto ObjectType = ::Kernel::KClassTokenGenerator::ObjectType::CLASS; \
|
static constexpr inline auto ObjectType = ::Kernel::KClassTokenGenerator::ObjectType::CLASS; \
|
||||||
static constexpr inline const char* const TypeName = #CLASS; \
|
static constexpr inline const char* const TypeName = #CLASS; \
|
||||||
static constexpr inline ClassTokenType ClassToken() { \
|
static constexpr inline ClassTokenType ClassToken() { return ::Kernel::ClassToken<CLASS>; } \
|
||||||
return ::Kernel::ClassToken<CLASS>; \
|
|
||||||
} \
|
|
||||||
\
|
\
|
||||||
public: \
|
public: \
|
||||||
YUZU_NON_COPYABLE(CLASS); \
|
YUZU_NON_COPYABLE(CLASS); \
|
||||||
@ -37,15 +35,9 @@ public:
|
|||||||
constexpr ClassTokenType Token = ClassToken(); \
|
constexpr ClassTokenType Token = ClassToken(); \
|
||||||
return TypeObj(TypeName, Token); \
|
return TypeObj(TypeName, Token); \
|
||||||
} \
|
} \
|
||||||
static constexpr const char* GetStaticTypeName() { \
|
static constexpr const char* GetStaticTypeName() { return TypeName; } \
|
||||||
return TypeName; \
|
virtual TypeObj GetTypeObj() ATTRIBUTE { return GetStaticTypeObj(); } \
|
||||||
} \
|
virtual const char* GetTypeName() ATTRIBUTE { return GetStaticTypeName(); } \
|
||||||
virtual TypeObj GetTypeObj() ATTRIBUTE { \
|
|
||||||
return GetStaticTypeObj(); \
|
|
||||||
} \
|
|
||||||
virtual const char* GetTypeName() ATTRIBUTE { \
|
|
||||||
return GetStaticTypeName(); \
|
|
||||||
} \
|
|
||||||
\
|
\
|
||||||
private: \
|
private: \
|
||||||
constexpr bool operator!=(const TypeObj& rhs)
|
constexpr bool operator!=(const TypeObj& rhs)
|
||||||
@ -245,8 +237,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
requires(std::derived_from<T, U> ||
|
requires(std::derived_from<T, U> || std::derived_from<U, T>)
|
||||||
std::derived_from<U, T>) constexpr KScopedAutoObject(KScopedAutoObject<U>&& rhs) {
|
constexpr KScopedAutoObject(KScopedAutoObject<U>&& rhs) {
|
||||||
if constexpr (std::derived_from<U, T>) {
|
if constexpr (std::derived_from<U, T>) {
|
||||||
// Upcast.
|
// Upcast.
|
||||||
m_obj = rhs.m_obj;
|
m_obj = rhs.m_obj;
|
||||||
|
@ -112,7 +112,7 @@ Result KCapabilities::SetSyscallMaskCapability(const u32 cap, u32& set_svc) {
|
|||||||
|
|
||||||
// Set SVCs.
|
// Set SVCs.
|
||||||
for (size_t i = 0; i < decltype(SyscallMask::mask)::bits; i++) {
|
for (size_t i = 0; i < decltype(SyscallMask::mask)::bits; i++) {
|
||||||
const u32 svc_id = static_cast<u32>(decltype(SyscallMask::mask)::bits* index + i);
|
const u32 svc_id = static_cast<u32>(decltype(SyscallMask::mask)::bits * index + i);
|
||||||
if (mask & (1U << i)) {
|
if (mask & (1U << i)) {
|
||||||
R_UNLESS(this->SetSvcAllowed(svc_id), ResultOutOfRange);
|
R_UNLESS(this->SetSvcAllowed(svc_id), ResultOutOfRange);
|
||||||
}
|
}
|
||||||
|
@ -17,35 +17,41 @@ namespace Kernel {
|
|||||||
class KThread;
|
class KThread;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept KPriorityQueueAffinityMask = !std::is_reference_v<T> && requires(T & t) {
|
concept KPriorityQueueAffinityMask = !
|
||||||
{ t.GetAffinityMask() } -> Common::ConvertibleTo<u64>;
|
std::is_reference_v<T>&& requires(T& t) {
|
||||||
{t.SetAffinityMask(0)};
|
{ t.GetAffinityMask() } -> Common::ConvertibleTo<u64>;
|
||||||
|
{ t.SetAffinityMask(0) };
|
||||||
|
|
||||||
{ t.GetAffinity(0) } -> std::same_as<bool>;
|
{ t.GetAffinity(0) } -> std::same_as<bool>;
|
||||||
{t.SetAffinity(0, false)};
|
{ t.SetAffinity(0, false) };
|
||||||
{t.SetAll()};
|
{ t.SetAll() };
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept KPriorityQueueMember = !std::is_reference_v<T> && requires(T & t) {
|
concept KPriorityQueueMember = !
|
||||||
{typename T::QueueEntry()};
|
std::is_reference_v<T>&& requires(T& t) {
|
||||||
{(typename T::QueueEntry()).Initialize()};
|
{ typename T::QueueEntry() };
|
||||||
{(typename T::QueueEntry()).SetPrev(std::addressof(t))};
|
{ (typename T::QueueEntry()).Initialize() };
|
||||||
{(typename T::QueueEntry()).SetNext(std::addressof(t))};
|
{ (typename T::QueueEntry()).SetPrev(std::addressof(t)) };
|
||||||
{ (typename T::QueueEntry()).GetNext() } -> std::same_as<T*>;
|
{ (typename T::QueueEntry()).SetNext(std::addressof(t)) };
|
||||||
{ (typename T::QueueEntry()).GetPrev() } -> std::same_as<T*>;
|
{ (typename T::QueueEntry()).GetNext() } -> std::same_as<T*>;
|
||||||
{ t.GetPriorityQueueEntry(0) } -> std::same_as<typename T::QueueEntry&>;
|
{ (typename T::QueueEntry()).GetPrev() } -> std::same_as<T*>;
|
||||||
|
{
|
||||||
|
t.GetPriorityQueueEntry(0)
|
||||||
|
} -> std::same_as<typename T::QueueEntry&>;
|
||||||
|
|
||||||
{t.GetAffinityMask()};
|
{ t.GetAffinityMask() };
|
||||||
{ std::remove_cvref_t<decltype(t.GetAffinityMask())>() } -> KPriorityQueueAffinityMask;
|
{
|
||||||
|
std::remove_cvref_t<decltype(t.GetAffinityMask())>()
|
||||||
|
} -> KPriorityQueueAffinityMask;
|
||||||
|
|
||||||
{ t.GetActiveCore() } -> Common::ConvertibleTo<s32>;
|
{ t.GetActiveCore() } -> Common::ConvertibleTo<s32>;
|
||||||
{ t.GetPriority() } -> Common::ConvertibleTo<s32>;
|
{ t.GetPriority() } -> Common::ConvertibleTo<s32>;
|
||||||
{ t.IsDummyThread() } -> Common::ConvertibleTo<bool>;
|
{ t.IsDummyThread() } -> Common::ConvertibleTo<bool>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Member, size_t NumCores_, int LowestPriority, int HighestPriority>
|
template <typename Member, size_t NumCores_, int LowestPriority, int HighestPriority>
|
||||||
requires KPriorityQueueMember<Member>
|
requires KPriorityQueueMember<Member>
|
||||||
class KPriorityQueue {
|
class KPriorityQueue {
|
||||||
public:
|
public:
|
||||||
using AffinityMaskType = std::remove_cv_t<
|
using AffinityMaskType = std::remove_cv_t<
|
||||||
|
@ -9,13 +9,14 @@
|
|||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept KLockable = !std::is_reference_v<T> && requires(T & t) {
|
concept KLockable = !
|
||||||
{ t.Lock() } -> std::same_as<void>;
|
std::is_reference_v<T>&& requires(T& t) {
|
||||||
{ t.Unlock() } -> std::same_as<void>;
|
{ t.Lock() } -> std::same_as<void>;
|
||||||
};
|
{ t.Unlock() } -> std::same_as<void>;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires KLockable<T>
|
requires KLockable<T>
|
||||||
class [[nodiscard]] KScopedLock {
|
class [[nodiscard]] KScopedLock {
|
||||||
public:
|
public:
|
||||||
explicit KScopedLock(T* l) : lock_ptr(l) {
|
explicit KScopedLock(T* l) : lock_ptr(l) {
|
||||||
|
@ -677,7 +677,7 @@ private:
|
|||||||
union SyncObjectBuffer {
|
union SyncObjectBuffer {
|
||||||
std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> sync_objects{};
|
std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> sync_objects{};
|
||||||
std::array<Handle,
|
std::array<Handle,
|
||||||
Svc::ArgumentHandleCountMax*(sizeof(KSynchronizationObject*) / sizeof(Handle))>
|
Svc::ArgumentHandleCountMax * (sizeof(KSynchronizationObject*) / sizeof(Handle))>
|
||||||
handles;
|
handles;
|
||||||
constexpr SyncObjectBuffer() {}
|
constexpr SyncObjectBuffer() {}
|
||||||
};
|
};
|
||||||
@ -698,10 +698,8 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires(
|
requires(std::same_as<T, KThread> || std::same_as<T, RedBlackKeyType>)
|
||||||
std::same_as<T, KThread> ||
|
static constexpr int Compare(const T& lhs, const KThread& rhs) {
|
||||||
std::same_as<T, RedBlackKeyType>) static constexpr int Compare(const T& lhs,
|
|
||||||
const KThread& rhs) {
|
|
||||||
const u64 l_key = lhs.GetConditionVariableKey();
|
const u64 l_key = lhs.GetConditionVariableKey();
|
||||||
const u64 r_key = rhs.GetConditionVariableKey();
|
const u64 r_key = rhs.GetConditionVariableKey();
|
||||||
|
|
||||||
|
@ -70,10 +70,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires(std::same_as<T, KThreadLocalPage> ||
|
requires(std::same_as<T, KThreadLocalPage> || std::same_as<T, RedBlackKeyType>)
|
||||||
std::same_as<T, RedBlackKeyType>) static constexpr int Compare(const T& lhs,
|
static constexpr int Compare(const T& lhs, const KThreadLocalPage& rhs) {
|
||||||
const KThreadLocalPage&
|
|
||||||
rhs) {
|
|
||||||
const VAddr lval = GetRedBlackKey(lhs);
|
const VAddr lval = GetRedBlackKey(lhs);
|
||||||
const VAddr rval = GetRedBlackKey(rhs);
|
const VAddr rval = GetRedBlackKey(rhs);
|
||||||
|
|
||||||
|
@ -60,7 +60,8 @@ public:
|
|||||||
DriverResult SendRawData(std::span<const u8> buffer);
|
DriverResult SendRawData(std::span<const u8> buffer);
|
||||||
|
|
||||||
template <typename Output>
|
template <typename Output>
|
||||||
requires std::is_trivially_copyable_v<Output> DriverResult SendData(const Output& output) {
|
requires std::is_trivially_copyable_v<Output>
|
||||||
|
DriverResult SendData(const Output& output) {
|
||||||
std::array<u8, sizeof(Output)> buffer;
|
std::array<u8, sizeof(Output)> buffer;
|
||||||
std::memcpy(buffer.data(), &output, sizeof(Output));
|
std::memcpy(buffer.data(), &output, sizeof(Output));
|
||||||
return SendRawData(buffer);
|
return SendRawData(buffer);
|
||||||
@ -115,8 +116,8 @@ public:
|
|||||||
* @returns output object containing the response
|
* @returns output object containing the response
|
||||||
*/
|
*/
|
||||||
template <typename Output>
|
template <typename Output>
|
||||||
requires std::is_trivially_copyable_v<Output> DriverResult ReadSPI(SpiAddress addr,
|
requires std::is_trivially_copyable_v<Output>
|
||||||
Output& output) {
|
DriverResult ReadSPI(SpiAddress addr, Output& output) {
|
||||||
std::array<u8, sizeof(Output)> buffer;
|
std::array<u8, sizeof(Output)> buffer;
|
||||||
output = {};
|
output = {};
|
||||||
|
|
||||||
|
@ -59,6 +59,13 @@ std::string Image(EmitContext& ctx, IR::TextureInstInfo info,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsTextureMsaa(EmitContext& ctx, const IR::TextureInstInfo& info) {
|
||||||
|
if (info.type == TextureType::Buffer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ctx.info.texture_descriptors.at(info.descriptor_index).is_multisample;
|
||||||
|
}
|
||||||
|
|
||||||
std::string_view TextureType(IR::TextureInstInfo info, bool is_ms = false) {
|
std::string_view TextureType(IR::TextureInstInfo info, bool is_ms = false) {
|
||||||
if (info.is_depth) {
|
if (info.is_depth) {
|
||||||
switch (info.type) {
|
switch (info.type) {
|
||||||
@ -535,7 +542,8 @@ void EmitImageQueryDimensions(EmitContext& ctx, IR::Inst& inst, const IR::Value&
|
|||||||
ScalarS32 lod, [[maybe_unused]] const IR::Value& skip_mips) {
|
ScalarS32 lod, [[maybe_unused]] const IR::Value& skip_mips) {
|
||||||
const auto info{inst.Flags<IR::TextureInstInfo>()};
|
const auto info{inst.Flags<IR::TextureInstInfo>()};
|
||||||
const std::string texture{Texture(ctx, info, index)};
|
const std::string texture{Texture(ctx, info, index)};
|
||||||
const std::string_view type{TextureType(info)};
|
const bool is_msaa{IsTextureMsaa(ctx, info)};
|
||||||
|
const std::string_view type{TextureType(info, is_msaa)};
|
||||||
ctx.Add("TXQ {},{},{},{};", inst, lod, texture, type);
|
ctx.Add("TXQ {},{},{},{};", inst, lod, texture, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,13 @@ std::string Image(EmitContext& ctx, const IR::TextureInstInfo& info, const IR::V
|
|||||||
return fmt::format("img{}{}", def.binding, index_offset);
|
return fmt::format("img{}{}", def.binding, index_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsTextureMsaa(EmitContext& ctx, const IR::TextureInstInfo& info) {
|
||||||
|
if (info.type == TextureType::Buffer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ctx.info.texture_descriptors.at(info.descriptor_index).is_multisample;
|
||||||
|
}
|
||||||
|
|
||||||
std::string CastToIntVec(std::string_view value, const IR::TextureInstInfo& info) {
|
std::string CastToIntVec(std::string_view value, const IR::TextureInstInfo& info) {
|
||||||
switch (info.type) {
|
switch (info.type) {
|
||||||
case TextureType::Color1D:
|
case TextureType::Color1D:
|
||||||
@ -463,26 +470,33 @@ void EmitImageQueryDimensions(EmitContext& ctx, IR::Inst& inst, const IR::Value&
|
|||||||
std::string_view lod, const IR::Value& skip_mips_val) {
|
std::string_view lod, const IR::Value& skip_mips_val) {
|
||||||
const auto info{inst.Flags<IR::TextureInstInfo>()};
|
const auto info{inst.Flags<IR::TextureInstInfo>()};
|
||||||
const auto texture{Texture(ctx, info, index)};
|
const auto texture{Texture(ctx, info, index)};
|
||||||
|
const bool is_msaa{IsTextureMsaa(ctx, info)};
|
||||||
const bool skip_mips{skip_mips_val.U1()};
|
const bool skip_mips{skip_mips_val.U1()};
|
||||||
const auto mips{
|
const auto mips{skip_mips ? "0u" : fmt::format("uint(textureQueryLevels({}))", texture)};
|
||||||
[&] { return skip_mips ? "0u" : fmt::format("uint(textureQueryLevels({}))", texture); }};
|
if (is_msaa && !skip_mips) {
|
||||||
|
throw NotImplementedException("EmitImageQueryDimensions MSAA QueryLevels");
|
||||||
|
}
|
||||||
|
if (info.type == TextureType::Buffer && !skip_mips) {
|
||||||
|
throw NotImplementedException("EmitImageQueryDimensions TextureType::Buffer QueryLevels");
|
||||||
|
}
|
||||||
|
const bool uses_lod{!is_msaa && info.type != TextureType::Buffer};
|
||||||
|
const auto lod_str{uses_lod ? fmt::format(",int({})", lod) : ""};
|
||||||
switch (info.type) {
|
switch (info.type) {
|
||||||
case TextureType::Color1D:
|
case TextureType::Color1D:
|
||||||
return ctx.AddU32x4("{}=uvec4(uint(textureSize({},int({}))),0u,0u,{});", inst, texture, lod,
|
return ctx.AddU32x4("{}=uvec4(uint(textureSize({}{})),0u,0u,{});", inst, texture, lod_str,
|
||||||
mips());
|
mips);
|
||||||
case TextureType::ColorArray1D:
|
case TextureType::ColorArray1D:
|
||||||
case TextureType::Color2D:
|
case TextureType::Color2D:
|
||||||
case TextureType::ColorCube:
|
case TextureType::ColorCube:
|
||||||
case TextureType::Color2DRect:
|
case TextureType::Color2DRect:
|
||||||
return ctx.AddU32x4("{}=uvec4(uvec2(textureSize({},int({}))),0u,{});", inst, texture, lod,
|
return ctx.AddU32x4("{}=uvec4(uvec2(textureSize({}{})),0u,{});", inst, texture, lod_str,
|
||||||
mips());
|
mips);
|
||||||
case TextureType::ColorArray2D:
|
case TextureType::ColorArray2D:
|
||||||
case TextureType::Color3D:
|
case TextureType::Color3D:
|
||||||
case TextureType::ColorArrayCube:
|
case TextureType::ColorArrayCube:
|
||||||
return ctx.AddU32x4("{}=uvec4(uvec3(textureSize({},int({}))),{});", inst, texture, lod,
|
return ctx.AddU32x4("{}=uvec4(uvec3(textureSize({}{})),{});", inst, texture, lod_str, mips);
|
||||||
mips());
|
|
||||||
case TextureType::Buffer:
|
case TextureType::Buffer:
|
||||||
throw NotImplementedException("EmitImageQueryDimensions Texture buffers");
|
return ctx.AddU32x4("{}=uvec4(uint(textureSize({})),0u,0u,{});", inst, texture, mips);
|
||||||
}
|
}
|
||||||
throw LogicError("Unspecified image type {}", info.type.Value());
|
throw LogicError("Unspecified image type {}", info.type.Value());
|
||||||
}
|
}
|
||||||
|
@ -201,6 +201,13 @@ Id Image(EmitContext& ctx, const IR::Value& index, IR::TextureInstInfo info) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsTextureMsaa(EmitContext& ctx, const IR::TextureInstInfo& info) {
|
||||||
|
if (info.type == TextureType::Buffer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ctx.textures.at(info.descriptor_index).is_multisample;
|
||||||
|
}
|
||||||
|
|
||||||
Id Decorate(EmitContext& ctx, IR::Inst* inst, Id sample) {
|
Id Decorate(EmitContext& ctx, IR::Inst* inst, Id sample) {
|
||||||
const auto info{inst->Flags<IR::TextureInstInfo>()};
|
const auto info{inst->Flags<IR::TextureInstInfo>()};
|
||||||
if (info.relaxed_precision != 0) {
|
if (info.relaxed_precision != 0) {
|
||||||
@ -452,24 +459,26 @@ Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& i
|
|||||||
const Id zero{ctx.u32_zero_value};
|
const Id zero{ctx.u32_zero_value};
|
||||||
const bool skip_mips{skip_mips_val.U1()};
|
const bool skip_mips{skip_mips_val.U1()};
|
||||||
const auto mips{[&] { return skip_mips ? zero : ctx.OpImageQueryLevels(ctx.U32[1], image); }};
|
const auto mips{[&] { return skip_mips ? zero : ctx.OpImageQueryLevels(ctx.U32[1], image); }};
|
||||||
|
const bool is_msaa{IsTextureMsaa(ctx, info)};
|
||||||
|
const bool uses_lod{!is_msaa && info.type != TextureType::Buffer};
|
||||||
|
const auto query{[&](Id type) {
|
||||||
|
return uses_lod ? ctx.OpImageQuerySizeLod(type, image, lod)
|
||||||
|
: ctx.OpImageQuerySize(type, image);
|
||||||
|
}};
|
||||||
switch (info.type) {
|
switch (info.type) {
|
||||||
case TextureType::Color1D:
|
case TextureType::Color1D:
|
||||||
return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySizeLod(ctx.U32[1], image, lod),
|
return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[1]), zero, zero, mips());
|
||||||
zero, zero, mips());
|
|
||||||
case TextureType::ColorArray1D:
|
case TextureType::ColorArray1D:
|
||||||
case TextureType::Color2D:
|
case TextureType::Color2D:
|
||||||
case TextureType::ColorCube:
|
case TextureType::ColorCube:
|
||||||
case TextureType::Color2DRect:
|
case TextureType::Color2DRect:
|
||||||
return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySizeLod(ctx.U32[2], image, lod),
|
return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[2]), zero, mips());
|
||||||
zero, mips());
|
|
||||||
case TextureType::ColorArray2D:
|
case TextureType::ColorArray2D:
|
||||||
case TextureType::Color3D:
|
case TextureType::Color3D:
|
||||||
case TextureType::ColorArrayCube:
|
case TextureType::ColorArrayCube:
|
||||||
return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySizeLod(ctx.U32[3], image, lod),
|
return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[3]), mips());
|
||||||
mips());
|
|
||||||
case TextureType::Buffer:
|
case TextureType::Buffer:
|
||||||
return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySize(ctx.U32[1], image), zero,
|
return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[1]), zero, zero, mips());
|
||||||
zero, mips());
|
|
||||||
}
|
}
|
||||||
throw LogicError("Unspecified image type {}", info.type.Value());
|
throw LogicError("Unspecified image type {}", info.type.Value());
|
||||||
}
|
}
|
||||||
|
@ -1288,6 +1288,7 @@ void EmitContext::DefineTextures(const Info& info, u32& binding, u32& scaling_in
|
|||||||
.pointer_type = pointer_type,
|
.pointer_type = pointer_type,
|
||||||
.image_type = image_type,
|
.image_type = image_type,
|
||||||
.count = desc.count,
|
.count = desc.count,
|
||||||
|
.is_multisample = desc.is_multisample,
|
||||||
});
|
});
|
||||||
if (profile.supported_spirv >= 0x00010400) {
|
if (profile.supported_spirv >= 0x00010400) {
|
||||||
interfaces.push_back(id);
|
interfaces.push_back(id);
|
||||||
|
@ -35,6 +35,7 @@ struct TextureDefinition {
|
|||||||
Id pointer_type;
|
Id pointer_type;
|
||||||
Id image_type;
|
Id image_type;
|
||||||
u32 count;
|
u32 count;
|
||||||
|
bool is_multisample;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TextureBufferDefinition {
|
struct TextureBufferDefinition {
|
||||||
|
@ -409,7 +409,8 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires(sizeof(T) <= sizeof(u32) && std::is_trivially_copyable_v<T>) struct Flags {
|
requires(sizeof(T) <= sizeof(u32) && std::is_trivially_copyable_v<T>)
|
||||||
|
struct Flags {
|
||||||
Flags() = default;
|
Flags() = default;
|
||||||
Flags(T proxy_) : proxy{proxy_} {}
|
Flags(T proxy_) : proxy{proxy_} {}
|
||||||
|
|
||||||
|
@ -101,9 +101,8 @@ public:
|
|||||||
TypedValue() = default;
|
TypedValue() = default;
|
||||||
|
|
||||||
template <IR::Type other_type>
|
template <IR::Type other_type>
|
||||||
requires((other_type & type_) != IR::Type::Void) explicit(false)
|
requires((other_type & type_) != IR::Type::Void)
|
||||||
TypedValue(const TypedValue<other_type>& value)
|
explicit(false) TypedValue(const TypedValue<other_type>& value) : Value(value) {}
|
||||||
: Value(value) {}
|
|
||||||
|
|
||||||
explicit TypedValue(const Value& value) : Value(value) {
|
explicit TypedValue(const Value& value) : Value(value) {
|
||||||
if ((value.Type() & type_) == IR::Type::Void) {
|
if ((value.Type() & type_) == IR::Type::Void) {
|
||||||
@ -194,16 +193,16 @@ public:
|
|||||||
void ReplaceOpcode(IR::Opcode opcode);
|
void ReplaceOpcode(IR::Opcode opcode);
|
||||||
|
|
||||||
template <typename FlagsType>
|
template <typename FlagsType>
|
||||||
requires(sizeof(FlagsType) <= sizeof(u32) && std::is_trivially_copyable_v<FlagsType>)
|
requires(sizeof(FlagsType) <= sizeof(u32) && std::is_trivially_copyable_v<FlagsType>)
|
||||||
[[nodiscard]] FlagsType Flags() const noexcept {
|
[[nodiscard]] FlagsType Flags() const noexcept {
|
||||||
FlagsType ret;
|
FlagsType ret;
|
||||||
std::memcpy(reinterpret_cast<char*>(&ret), &flags, sizeof(ret));
|
std::memcpy(reinterpret_cast<char*>(&ret), &flags, sizeof(ret));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename FlagsType>
|
template <typename FlagsType>
|
||||||
requires(sizeof(FlagsType) <= sizeof(u32) &&
|
requires(sizeof(FlagsType) <= sizeof(u32) && std::is_trivially_copyable_v<FlagsType>)
|
||||||
std::is_trivially_copyable_v<FlagsType>) void SetFlags(FlagsType value) noexcept {
|
void SetFlags(FlagsType value) noexcept {
|
||||||
std::memcpy(&flags, &value, sizeof(value));
|
std::memcpy(&flags, &value, sizeof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
namespace Shader {
|
namespace Shader {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires std::is_destructible_v<T>
|
requires std::is_destructible_v<T>
|
||||||
class ObjectPool {
|
class ObjectPool {
|
||||||
public:
|
public:
|
||||||
explicit ObjectPool(size_t chunk_size = 8192) : new_chunk_size{chunk_size} {
|
explicit ObjectPool(size_t chunk_size = 8192) : new_chunk_size{chunk_size} {
|
||||||
@ -18,7 +18,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
requires std::is_constructible_v<T, Args...>
|
requires std::is_constructible_v<T, Args...>
|
||||||
[[nodiscard]] T* Create(Args&&... args) {
|
[[nodiscard]] T* Create(Args&&... args) {
|
||||||
return std::construct_at(Memory(), std::forward<Args>(args)...);
|
return std::construct_at(Memory(), std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,7 @@ public:
|
|||||||
explicit DescriptorTable(Tegra::MemoryManager& gpu_memory_) : gpu_memory{gpu_memory_} {}
|
explicit DescriptorTable(Tegra::MemoryManager& gpu_memory_) : gpu_memory{gpu_memory_} {}
|
||||||
|
|
||||||
[[nodiscard]] bool Synchronize(GPUVAddr gpu_addr, u32 limit) {
|
[[nodiscard]] bool Synchronize(GPUVAddr gpu_addr, u32 limit) {
|
||||||
[[likely]] if (current_gpu_addr == gpu_addr && current_limit == limit) {
|
[[likely]] if (current_gpu_addr == gpu_addr && current_limit == limit) { return false; }
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Refresh(gpu_addr, limit);
|
Refresh(gpu_addr, limit);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ struct SlotId {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
requires std::is_nothrow_move_assignable_v<T> && std::is_nothrow_move_constructible_v<T>
|
requires std::is_nothrow_move_assignable_v<T> && std::is_nothrow_move_constructible_v<T>
|
||||||
class SlotVector {
|
class SlotVector {
|
||||||
public:
|
public:
|
||||||
class Iterator {
|
class Iterator {
|
||||||
|
Loading…
Reference in New Issue
Block a user