early-access version 1310

This commit is contained in:
pineappleEA
2021-01-12 10:22:33 +01:00
parent ebc2449a41
commit 4219fd41b9
49 changed files with 308 additions and 342 deletions

View File

@@ -11,16 +11,16 @@ namespace Common {
/// Ceiled integer division.
template <typename N, typename D>
requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr auto DivCeil(
N number, D divisor) {
return (static_cast<D>(number) + divisor - 1) / divisor;
requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr N DivCeil(N number,
D divisor) {
return static_cast<N>((static_cast<D>(number) + divisor - 1) / divisor);
}
/// Ceiled integer division with logarithmic divisor in base 2
template <typename N, typename D>
requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr auto DivCeilLog2(
requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr N DivCeilLog2(
N value, D alignment_log2) {
return (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);
}
} // namespace Common

View File

@@ -1,18 +1,6 @@
/*
* Copyright (c) 2018-2020 Atmosph<70>re-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
@@ -30,7 +18,7 @@ class IntrusiveRedBlackTreeImpl;
struct IntrusiveRedBlackTreeNode {
private:
RB_ENTRY(IntrusiveRedBlackTreeNode) entry;
RB_ENTRY(IntrusiveRedBlackTreeNode) entry{};
friend class impl::IntrusiveRedBlackTreeImpl;
@@ -38,8 +26,7 @@ private:
friend class IntrusiveRedBlackTree;
public:
constexpr IntrusiveRedBlackTreeNode() : entry() { /* ... */
}
constexpr IntrusiveRedBlackTreeNode() = default;
};
template <class T, class Traits, class Comparator>
@@ -80,18 +67,16 @@ public:
using iterator_category = std::bidirectional_iterator_tag;
using value_type = typename IntrusiveRedBlackTreeImpl::value_type;
using difference_type = typename IntrusiveRedBlackTreeImpl::difference_type;
using pointer = typename std::conditional<Const, IntrusiveRedBlackTreeImpl::const_pointer,
IntrusiveRedBlackTreeImpl::pointer>::type;
using reference =
typename std::conditional<Const, IntrusiveRedBlackTreeImpl::const_reference,
IntrusiveRedBlackTreeImpl::reference>::type;
using pointer = std::conditional_t<Const, IntrusiveRedBlackTreeImpl::const_pointer,
IntrusiveRedBlackTreeImpl::pointer>;
using reference = std::conditional_t<Const, IntrusiveRedBlackTreeImpl::const_reference,
IntrusiveRedBlackTreeImpl::reference>;
private:
pointer node;
public:
explicit Iterator(pointer n) : node(n) { /* ... */
}
explicit Iterator(pointer n) : node(n) {}
bool operator==(const Iterator& rhs) const {
return this->node == rhs.node;
@@ -137,12 +122,11 @@ public:
};
protected:
/* Generate static implementations for non-comparison operations for IntrusiveRedBlackTreeRoot.
*/
// Generate static implementations for non-comparison operations for IntrusiveRedBlackTreeRoot.
RB_GENERATE_WITHOUT_COMPARE_STATIC(IntrusiveRedBlackTreeRoot, IntrusiveRedBlackTreeNode, entry);
private:
/* Define accessors using RB_* functions. */
// Define accessors using RB_* functions.
constexpr void InitializeImpl() {
RB_INIT(&this->root);
}
@@ -174,12 +158,12 @@ public:
return RB_PREV(IntrusiveRedBlackTreeRoot, nullptr, node);
}
static IntrusiveRedBlackTreeNode const* GetNext(IntrusiveRedBlackTreeNode const* node) {
static IntrusiveRedBlackTreeNode const* GetNext(const IntrusiveRedBlackTreeNode* node) {
return static_cast<const IntrusiveRedBlackTreeNode*>(
GetNext(const_cast<IntrusiveRedBlackTreeNode*>(node)));
}
static IntrusiveRedBlackTreeNode const* GetPrev(IntrusiveRedBlackTreeNode const* node) {
static IntrusiveRedBlackTreeNode const* GetPrev(const IntrusiveRedBlackTreeNode* node) {
return static_cast<const IntrusiveRedBlackTreeNode*>(
GetPrev(const_cast<IntrusiveRedBlackTreeNode*>(node)));
}
@@ -189,7 +173,7 @@ public:
this->InitializeImpl();
}
/* Iterator accessors. */
// Iterator accessors.
iterator begin() {
return iterator(this->GetMinImpl());
}
@@ -222,7 +206,7 @@ public:
return const_iterator(&ref);
}
/* Content management. */
// Content management.
bool empty() const {
return this->EmptyImpl();
}
@@ -273,8 +257,7 @@ consteval auto* GetLightCompareType() {
} // namespace impl
template <typename T, typename Default>
using LightCompareType =
typename std::remove_pointer<decltype(impl::GetLightCompareType<T, Default>())>::type;
using LightCompareType = std::remove_pointer_t<decltype(impl::GetLightCompareType<T, Default>())>;
template <class T, class Traits, class Comparator>
class IntrusiveRedBlackTree {
@@ -283,7 +266,7 @@ public:
using ImplType = impl::IntrusiveRedBlackTreeImpl;
private:
ImplType impl;
ImplType impl{};
public:
struct IntrusiveRedBlackTreeRootWithCompare : ImplType::IntrusiveRedBlackTreeRoot {};
@@ -311,27 +294,25 @@ public:
friend class IntrusiveRedBlackTree<T, Traits, Comparator>;
using ImplIterator =
typename std::conditional<Const, ImplType::const_iterator, ImplType::iterator>::type;
std::conditional_t<Const, ImplType::const_iterator, ImplType::iterator>;
using iterator_category = std::bidirectional_iterator_tag;
using value_type = typename IntrusiveRedBlackTree::value_type;
using difference_type = typename IntrusiveRedBlackTree::difference_type;
using pointer = typename std::conditional<Const, IntrusiveRedBlackTree::const_pointer,
IntrusiveRedBlackTree::pointer>::type;
using reference = typename std::conditional<Const, IntrusiveRedBlackTree::const_reference,
IntrusiveRedBlackTree::reference>::type;
using pointer = std::conditional_t<Const, IntrusiveRedBlackTree::const_pointer,
IntrusiveRedBlackTree::pointer>;
using reference = std::conditional_t<Const, IntrusiveRedBlackTree::const_reference,
IntrusiveRedBlackTree::reference>;
private:
ImplIterator iterator;
private:
explicit Iterator(ImplIterator it) : iterator(it) { /* ... */
}
explicit Iterator(ImplIterator it) : iterator(it) {}
explicit Iterator(typename std::conditional<Const, ImplType::const_iterator,
ImplType::iterator>::type::pointer ptr)
: iterator(ptr) { /* ... */
}
: iterator(ptr) {}
ImplIterator GetImplIterator() const {
return this->iterator;
@@ -382,7 +363,7 @@ public:
};
private:
/* Generate static implementations for comparison operations for IntrusiveRedBlackTreeRoot. */
// Generate static implementations for comparison operations for IntrusiveRedBlackTreeRoot.
RB_GENERATE_WITH_COMPARE_STATIC(IntrusiveRedBlackTreeRootWithCompare, IntrusiveRedBlackTreeNode,
entry, CompareImpl, LightCompareImpl);
@@ -396,14 +377,14 @@ private:
return Comparator::Compare(*static_cast<const_light_pointer>(elm), *Traits::GetParent(rhs));
}
/* Define accessors using RB_* functions. */
// Define accessors using RB_* functions.
IntrusiveRedBlackTreeNode* InsertImpl(IntrusiveRedBlackTreeNode* node) {
return RB_INSERT(IntrusiveRedBlackTreeRootWithCompare,
static_cast<IntrusiveRedBlackTreeRootWithCompare*>(&this->impl.root),
node);
}
IntrusiveRedBlackTreeNode* FindImpl(IntrusiveRedBlackTreeNode const* node) const {
IntrusiveRedBlackTreeNode* FindImpl(const IntrusiveRedBlackTreeNode* node) const {
return RB_FIND(
IntrusiveRedBlackTreeRootWithCompare,
const_cast<IntrusiveRedBlackTreeRootWithCompare*>(
@@ -411,7 +392,7 @@ private:
const_cast<IntrusiveRedBlackTreeNode*>(node));
}
IntrusiveRedBlackTreeNode* NFindImpl(IntrusiveRedBlackTreeNode const* node) const {
IntrusiveRedBlackTreeNode* NFindImpl(const IntrusiveRedBlackTreeNode* node) const {
return RB_NFIND(
IntrusiveRedBlackTreeRootWithCompare,
const_cast<IntrusiveRedBlackTreeRootWithCompare*>(
@@ -436,10 +417,9 @@ private:
}
public:
constexpr IntrusiveRedBlackTree() : impl() { /* ... */
}
constexpr IntrusiveRedBlackTree() = default;
/* Iterator accessors. */
// Iterator accessors.
iterator begin() {
return iterator(this->impl.begin());
}
@@ -472,7 +452,7 @@ public:
return const_iterator(this->impl.iterator_to(*Traits::GetNode(std::addressof(ref))));
}
/* Content management. */
// Content management.
bool empty() const {
return this->impl.empty();
}
@@ -548,12 +528,12 @@ private:
return GetParentPointer<Member, Derived>(node);
}
static constexpr Derived const* GetParent(IntrusiveRedBlackTreeNode const* node) {
static constexpr Derived const* GetParent(const IntrusiveRedBlackTreeNode* node) {
return GetParentPointer<Member, Derived>(node);
}
private:
static constexpr TYPED_STORAGE(Derived) DerivedStorage = {};
static constexpr TypedStorage<Derived> DerivedStorage = {};
static_assert(GetParent(GetNode(GetPointer(DerivedStorage))) == GetPointer(DerivedStorage));
};
@@ -569,7 +549,7 @@ public:
using TreeTypeImpl = impl::IntrusiveRedBlackTreeImpl;
static constexpr bool IsValid() {
TYPED_STORAGE(Derived) DerivedStorage = {};
TypedStorage<Derived> DerivedStorage = {};
return GetParent(GetNode(GetPointer(DerivedStorage))) == GetPointer(DerivedStorage);
}
@@ -591,7 +571,7 @@ private:
return GetParentPointer<Member, Derived>(node);
}
static constexpr Derived const* GetParent(IntrusiveRedBlackTreeNode const* node) {
static constexpr Derived const* GetParent(const IntrusiveRedBlackTreeNode* node) {
return GetParentPointer<Member, Derived>(node);
}
};
@@ -639,7 +619,7 @@ private:
return static_cast<Derived*>(node);
}
static constexpr Derived const* GetParent(IntrusiveRedBlackTreeNode const* node) {
static constexpr Derived const* GetParent(const IntrusiveRedBlackTreeNode* node) {
return static_cast<const Derived*>(node);
}
};

View File

@@ -1,18 +1,6 @@
/*
* Copyright (c) 2018-2020 Atmosph<70>re-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
@@ -22,22 +10,24 @@
#include "common/common_types.h"
namespace Common {
namespace detail {
template <typename T, size_t Size, size_t Align>
struct TypedStorage {
typename std::aligned_storage<Size, Align>::type _storage;
struct TypedStorageImpl {
std::aligned_storage_t<Size, Align> storage_;
};
#define TYPED_STORAGE(...) TypedStorage<__VA_ARGS__, sizeof(__VA_ARGS__), alignof(__VA_ARGS__)>
} // namespace detail
template <typename T>
static constexpr T* GetPointer(TYPED_STORAGE(T) & ts) {
return static_cast<T*>(static_cast<void*>(std::addressof(ts._storage)));
using TypedStorage = detail::TypedStorageImpl<T, sizeof(T), alignof(T)>;
template <typename T>
static constexpr T* GetPointer(TypedStorage<T>& ts) {
return static_cast<T*>(static_cast<void*>(std::addressof(ts.storage_)));
}
template <typename T>
static constexpr const T* GetPointer(const TYPED_STORAGE(T) & ts) {
return static_cast<const T*>(static_cast<const void*>(std::addressof(ts._storage)));
static constexpr const T* GetPointer(const TypedStorage<T>& ts) {
return static_cast<const T*>(static_cast<const void*>(std::addressof(ts.storage_)));
}
namespace impl {
@@ -73,8 +63,7 @@ struct OffsetOfUnionHolder {
};
template <typename ParentType, typename MemberType>
union UnionImpl<ParentType, MemberType, MaxDepth> { /* Empty ... */
};
union UnionImpl<ParentType, MemberType, MaxDepth> {};
};
template <typename ParentType, typename MemberType>
@@ -83,13 +72,11 @@ struct OffsetOfCalculator {
typename OffsetOfUnionHolder<sizeof(MemberType)>::template UnionImpl<ParentType, MemberType,
0>;
union Union {
char c;
char c{};
UnionHolder first_union;
TYPED_STORAGE(ParentType) parent;
TypedStorage<ParentType> parent;
/* This coerces the active member to be c. */
constexpr Union() : c() { /* ... */
}
constexpr Union() : c() {}
};
static constexpr Union U = {};