mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-11 13:36:13 +03:00
AK+Kernel: Reduce the number of template parameters of IntrusiveRBTree
This makes the user-facing type only take the node member pointer, and lets the compiler figure out the other needed types from that.
This commit is contained in:
parent
5a0cdb15b0
commit
14c8373eb0
Notes:
sideshowbarker
2024-07-18 04:20:26 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/14c8373eb06 Pull-request: https://github.com/SerenityOS/serenity/pull/9910 Reviewed-by: https://github.com/IdanHo ✅
@ -9,17 +9,24 @@
|
||||
#include <AK/IntrusiveDetails.h>
|
||||
#include <AK/RedBlackTree.h>
|
||||
|
||||
namespace AK {
|
||||
namespace AK::Detail {
|
||||
|
||||
namespace Detail {
|
||||
template<Integral K, typename V, typename Container = RawPtr<V>>
|
||||
class IntrusiveRedBlackTreeNode;
|
||||
}
|
||||
|
||||
struct ExtractIntrusiveRedBlackTreeTypes {
|
||||
template<typename K, typename V, typename Container, typename T>
|
||||
static K key(IntrusiveRedBlackTreeNode<K, V, Container> T::*x);
|
||||
template<typename K, typename V, typename Container, typename T>
|
||||
static V value(IntrusiveRedBlackTreeNode<K, V, Container> T::*x);
|
||||
template<typename K, typename V, typename Container, typename T>
|
||||
static Container container(IntrusiveRedBlackTreeNode<K, V, Container> T::*x);
|
||||
};
|
||||
|
||||
template<Integral K, typename V, typename Container = RawPtr<V>>
|
||||
using IntrusiveRedBlackTreeNode = Detail::IntrusiveRedBlackTreeNode<K, V, typename Detail::SubstituteIntrusiveContainerType<V, Container>::Type>;
|
||||
using SubstitutedIntrusiveRedBlackTreeNode = IntrusiveRedBlackTreeNode<K, V, typename Detail::SubstituteIntrusiveContainerType<V, Container>::Type>;
|
||||
|
||||
template<Integral K, typename V, typename Container, IntrusiveRedBlackTreeNode<K, V, Container> V::*member>
|
||||
template<Integral K, typename V, typename Container, SubstitutedIntrusiveRedBlackTreeNode<K, V, Container> V::*member>
|
||||
class IntrusiveRedBlackTree : public BaseRedBlackTree<K> {
|
||||
|
||||
public:
|
||||
@ -30,7 +37,7 @@ public:
|
||||
}
|
||||
|
||||
using BaseTree = BaseRedBlackTree<K>;
|
||||
using TreeNode = IntrusiveRedBlackTreeNode<K, V, Container>;
|
||||
using TreeNode = SubstitutedIntrusiveRedBlackTreeNode<K, V, Container>;
|
||||
|
||||
Container find(K key)
|
||||
{
|
||||
@ -161,8 +168,6 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
namespace Detail {
|
||||
|
||||
template<Integral K, typename V, typename Container>
|
||||
class IntrusiveRedBlackTreeNode : public BaseRedBlackTree<K>::Node {
|
||||
public:
|
||||
@ -185,20 +190,18 @@ public:
|
||||
|
||||
#ifndef __clang__
|
||||
private:
|
||||
template<Integral TK, typename TV, typename TContainer, IntrusiveRedBlackTreeNode<TK, TV, TContainer> TV::*member>
|
||||
friend class ::AK::IntrusiveRedBlackTree;
|
||||
template<Integral TK, typename TV, typename TContainer, SubstitutedIntrusiveRedBlackTreeNode<TK, TV, TContainer> TV::*member>
|
||||
friend class ::AK::Detail::IntrusiveRedBlackTree;
|
||||
#endif
|
||||
|
||||
bool m_in_tree { false };
|
||||
[[no_unique_address]] SelfReferenceIfNeeded<Container, IsRaw> m_self;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// Specialise IntrusiveRedBlackTree for NonnullRefPtr
|
||||
// By default, red black trees cannot contain null entries anyway, so switch to RefPtr
|
||||
// and just make the user-facing functions deref the pointers.
|
||||
template<Integral K, typename V, IntrusiveRedBlackTreeNode<K, V, NonnullRefPtr<V>> V::*member>
|
||||
template<Integral K, typename V, SubstitutedIntrusiveRedBlackTreeNode<K, V, NonnullRefPtr<V>> V::*member>
|
||||
class IntrusiveRedBlackTree<K, V, NonnullRefPtr<V>, member> : public IntrusiveRedBlackTree<K, V, RefPtr<V>, member> {
|
||||
public:
|
||||
[[nodiscard]] NonnullRefPtr<V> find(K key) const { return IntrusiveRedBlackTree<K, V, RefPtr<V>, member>::find(key).release_nonnull(); }
|
||||
@ -207,5 +210,19 @@ public:
|
||||
|
||||
}
|
||||
|
||||
namespace AK {
|
||||
|
||||
template<Integral K, typename V, typename Container = RawPtr<K>>
|
||||
using IntrusiveRedBlackTreeNode = Detail::SubstitutedIntrusiveRedBlackTreeNode<K, V, Container>;
|
||||
|
||||
template<auto member>
|
||||
using IntrusiveRedBlackTree = Detail::IntrusiveRedBlackTree<
|
||||
decltype(Detail::ExtractIntrusiveRedBlackTreeTypes::key(member)),
|
||||
decltype(Detail::ExtractIntrusiveRedBlackTreeTypes::value(member)),
|
||||
decltype(Detail::ExtractIntrusiveRedBlackTreeTypes::container(member)),
|
||||
member>;
|
||||
|
||||
}
|
||||
|
||||
using AK::IntrusiveRedBlackTree;
|
||||
using AK::IntrusiveRedBlackTreeNode;
|
||||
|
@ -17,9 +17,9 @@ extern u8 end_of_kernel_image[];
|
||||
|
||||
namespace Kernel::Memory {
|
||||
|
||||
static Singleton<IntrusiveRedBlackTree<FlatPtr, PageDirectory, RawPtr<PageDirectory>, &PageDirectory::m_tree_node>> s_cr3_map;
|
||||
static Singleton<IntrusiveRedBlackTree<&PageDirectory::m_tree_node>> s_cr3_map;
|
||||
|
||||
static IntrusiveRedBlackTree<FlatPtr, PageDirectory, RawPtr<PageDirectory>, &PageDirectory::m_tree_node>& cr3_map()
|
||||
static IntrusiveRedBlackTree<&PageDirectory::m_tree_node>& cr3_map()
|
||||
{
|
||||
VERIFY_INTERRUPTS_DISABLED();
|
||||
return *s_cr3_map;
|
||||
|
@ -20,7 +20,7 @@ public:
|
||||
IntrusiveRedBlackTreeNode<int, IntrusiveTest, RawPtr<IntrusiveTest>> m_tree_node;
|
||||
int m_some_value;
|
||||
};
|
||||
using IntrusiveRBTree = IntrusiveRedBlackTree<int, IntrusiveTest, RawPtr<IntrusiveTest>, &IntrusiveTest::m_tree_node>;
|
||||
using IntrusiveRBTree = IntrusiveRedBlackTree<&IntrusiveTest::m_tree_node>;
|
||||
|
||||
TEST_CASE(construct)
|
||||
{
|
||||
@ -123,7 +123,7 @@ public:
|
||||
|
||||
IntrusiveRedBlackTreeNode<int, IntrusiveRefPtrTest, RefPtr<IntrusiveRefPtrTest>> m_tree_node;
|
||||
};
|
||||
using IntrusiveRefPtrRBTree = IntrusiveRedBlackTree<int, IntrusiveRefPtrTest, RefPtr<IntrusiveRefPtrTest>, &IntrusiveRefPtrTest::m_tree_node>;
|
||||
using IntrusiveRefPtrRBTree = IntrusiveRedBlackTree<&IntrusiveRefPtrTest::m_tree_node>;
|
||||
|
||||
TEST_CASE(intrusive_ref_ptr_no_ref_leaks)
|
||||
{
|
||||
@ -173,7 +173,7 @@ public:
|
||||
|
||||
IntrusiveRedBlackTreeNode<int, IntrusiveNonnullRefPtrTest, NonnullRefPtr<IntrusiveNonnullRefPtrTest>> m_tree_node;
|
||||
};
|
||||
using IntrusiveNonnullRefPtrRBTree = IntrusiveRedBlackTree<int, IntrusiveNonnullRefPtrTest, NonnullRefPtr<IntrusiveNonnullRefPtrTest>, &IntrusiveNonnullRefPtrTest::m_tree_node>;
|
||||
using IntrusiveNonnullRefPtrRBTree = IntrusiveRedBlackTree<&IntrusiveNonnullRefPtrTest::m_tree_node>;
|
||||
|
||||
TEST_CASE(intrusive_nonnull_ref_ptr_intrusive)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user