From 14c8373eb0656e0190997ef2630d716aea4e7ef8 Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Thu, 9 Sep 2021 15:27:19 +0430 Subject: [PATCH] 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. --- AK/IntrusiveRedBlackTree.h | 43 ++++++++++++++++++-------- Kernel/Memory/PageDirectory.cpp | 4 +-- Tests/AK/TestIntrusiveRedBlackTree.cpp | 6 ++-- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/AK/IntrusiveRedBlackTree.h b/AK/IntrusiveRedBlackTree.h index 6190f6b27a5..56424ec8465 100644 --- a/AK/IntrusiveRedBlackTree.h +++ b/AK/IntrusiveRedBlackTree.h @@ -9,17 +9,24 @@ #include #include -namespace AK { +namespace AK::Detail { -namespace Detail { template> class IntrusiveRedBlackTreeNode; -} + +struct ExtractIntrusiveRedBlackTreeTypes { + template + static K key(IntrusiveRedBlackTreeNode T::*x); + template + static V value(IntrusiveRedBlackTreeNode T::*x); + template + static Container container(IntrusiveRedBlackTreeNode T::*x); +}; template> -using IntrusiveRedBlackTreeNode = Detail::IntrusiveRedBlackTreeNode::Type>; +using SubstitutedIntrusiveRedBlackTreeNode = IntrusiveRedBlackTreeNode::Type>; -template V::*member> +template V::*member> class IntrusiveRedBlackTree : public BaseRedBlackTree { public: @@ -30,7 +37,7 @@ public: } using BaseTree = BaseRedBlackTree; - using TreeNode = IntrusiveRedBlackTreeNode; + using TreeNode = SubstitutedIntrusiveRedBlackTreeNode; Container find(K key) { @@ -161,8 +168,6 @@ private: } }; -namespace Detail { - template class IntrusiveRedBlackTreeNode : public BaseRedBlackTree::Node { public: @@ -185,20 +190,18 @@ public: #ifndef __clang__ private: - template TV::*member> - friend class ::AK::IntrusiveRedBlackTree; + template TV::*member> + friend class ::AK::Detail::IntrusiveRedBlackTree; #endif bool m_in_tree { false }; [[no_unique_address]] SelfReferenceIfNeeded 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> V::*member> +template> V::*member> class IntrusiveRedBlackTree, member> : public IntrusiveRedBlackTree, member> { public: [[nodiscard]] NonnullRefPtr find(K key) const { return IntrusiveRedBlackTree, member>::find(key).release_nonnull(); } @@ -207,5 +210,19 @@ public: } +namespace AK { + +template> +using IntrusiveRedBlackTreeNode = Detail::SubstitutedIntrusiveRedBlackTreeNode; + +template +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; diff --git a/Kernel/Memory/PageDirectory.cpp b/Kernel/Memory/PageDirectory.cpp index 133bfc91651..e277e634547 100644 --- a/Kernel/Memory/PageDirectory.cpp +++ b/Kernel/Memory/PageDirectory.cpp @@ -17,9 +17,9 @@ extern u8 end_of_kernel_image[]; namespace Kernel::Memory { -static Singleton, &PageDirectory::m_tree_node>> s_cr3_map; +static Singleton> s_cr3_map; -static IntrusiveRedBlackTree, &PageDirectory::m_tree_node>& cr3_map() +static IntrusiveRedBlackTree<&PageDirectory::m_tree_node>& cr3_map() { VERIFY_INTERRUPTS_DISABLED(); return *s_cr3_map; diff --git a/Tests/AK/TestIntrusiveRedBlackTree.cpp b/Tests/AK/TestIntrusiveRedBlackTree.cpp index a27e8abb186..6492c577704 100644 --- a/Tests/AK/TestIntrusiveRedBlackTree.cpp +++ b/Tests/AK/TestIntrusiveRedBlackTree.cpp @@ -20,7 +20,7 @@ public: IntrusiveRedBlackTreeNode> m_tree_node; int m_some_value; }; -using IntrusiveRBTree = IntrusiveRedBlackTree, &IntrusiveTest::m_tree_node>; +using IntrusiveRBTree = IntrusiveRedBlackTree<&IntrusiveTest::m_tree_node>; TEST_CASE(construct) { @@ -123,7 +123,7 @@ public: IntrusiveRedBlackTreeNode> m_tree_node; }; -using IntrusiveRefPtrRBTree = IntrusiveRedBlackTree, &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> m_tree_node; }; -using IntrusiveNonnullRefPtrRBTree = IntrusiveRedBlackTree, &IntrusiveNonnullRefPtrTest::m_tree_node>; +using IntrusiveNonnullRefPtrRBTree = IntrusiveRedBlackTree<&IntrusiveNonnullRefPtrTest::m_tree_node>; TEST_CASE(intrusive_nonnull_ref_ptr_intrusive) {