diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2021-09-09 16:30:59 +0430 |
---|---|---|
committer | Idan Horowitz <idan.horowitz@gmail.com> | 2021-09-10 18:05:46 +0300 |
commit | 5a0cdb15b07ef87cbab6203fad8c0dcea3634f67 (patch) | |
tree | c7d38b2113aa030893f1f22560faf8e288f00940 /AK | |
parent | 93cf01ad7db21ec5f48a46e206356ea791158fca (diff) | |
download | serenity-5a0cdb15b07ef87cbab6203fad8c0dcea3634f67.zip |
AK+Everywhere: Reduce the number of template parameters of IntrusiveList
This makes the user-facing type only take the node member pointer, and
lets the compiler figure out the other needed types from that.
Diffstat (limited to 'AK')
-rw-r--r-- | AK/IntrusiveList.h | 104 | ||||
-rw-r--r-- | AK/IntrusiveListRelaxedConst.h | 9 | ||||
-rw-r--r-- | AK/Queue.h | 2 |
3 files changed, 67 insertions, 48 deletions
diff --git a/AK/IntrusiveList.h b/AK/IntrusiveList.h index d7dc93c9b3..b485443980 100644 --- a/AK/IntrusiveList.h +++ b/AK/IntrusiveList.h @@ -13,29 +13,34 @@ #include <AK/Noncopyable.h> #include <AK/StdLibExtras.h> -namespace AK { +namespace AK::Detail { -namespace Detail { template<typename T, typename Container = RawPtr<T>> class IntrusiveListNode; -} + +struct ExtractIntrusiveListTypes { + template<typename V, typename Container, typename T> + static V value(IntrusiveListNode<V, Container> T::*x); + template<typename V, typename Container, typename T> + static Container container(IntrusiveListNode<V, Container> T::*x); +}; template<typename T, typename Container = RawPtr<T>> -using IntrusiveListNode = Detail::IntrusiveListNode<T, typename Detail::SubstituteIntrusiveContainerType<T, Container>::Type>; +using SubstitutedIntrusiveListNode = IntrusiveListNode<T, typename Detail::SubstituteIntrusiveContainerType<T, Container>::Type>; template<typename T, typename Container> class IntrusiveListStorage { private: - friend class Detail::IntrusiveListNode<T, Container>; + friend class IntrusiveListNode<T, Container>; - template<class T_, typename Container_, IntrusiveListNode<T_, Container_> T_::*member> + template<class T_, typename Container_, SubstitutedIntrusiveListNode<T_, Container_> T_::*member> friend class IntrusiveList; - IntrusiveListNode<T, Container>* m_first { nullptr }; - IntrusiveListNode<T, Container>* m_last { nullptr }; + SubstitutedIntrusiveListNode<T, Container>* m_first { nullptr }; + SubstitutedIntrusiveListNode<T, Container>* m_last { nullptr }; }; -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> class IntrusiveList { AK_MAKE_NONCOPYABLE(IntrusiveList); AK_MAKE_NONMOVABLE(IntrusiveList); @@ -144,12 +149,10 @@ private: static T* prev(T* current); static const T* next(const T* current); static const T* prev(const T* current); - static T* node_to_value(IntrusiveListNode<T, Container>& node); + static T* node_to_value(SubstitutedIntrusiveListNode<T, Container>& node); IntrusiveListStorage<T, Container> m_storage; }; -namespace Detail { - template<typename T, typename Container> class IntrusiveListNode { public: @@ -159,23 +162,21 @@ public: static constexpr bool IsRaw = IsPointer<Container>; - // Note: For some reason, clang does not consider `member` as declared here, and as declared above (`IntrusiveListNode<T, Container> T::*`) + // Note: For some reason, clang does not consider `member` as declared here, and as declared above (`SubstitutedIntrusiveListNode<T, Container> T::*`) // to be of equal types. so for now, just make the members public on clang. #ifndef __clang__ private: - template<class T_, typename Container_, IntrusiveListNode<T_, Container_> T_::*member> - friend class ::AK::IntrusiveList; + template<class T_, typename Container_, SubstitutedIntrusiveListNode<T_, Container_> T_::*member> + friend class ::AK::Detail::IntrusiveList; #endif IntrusiveListStorage<T, Container>* m_storage = nullptr; - IntrusiveListNode<T, Container>* m_next = nullptr; - IntrusiveListNode<T, Container>* m_prev = nullptr; + SubstitutedIntrusiveListNode<T, Container>* m_next = nullptr; + SubstitutedIntrusiveListNode<T, Container>* m_prev = nullptr; [[no_unique_address]] SelfReferenceIfNeeded<Container, IsRaw> m_self; }; -} - -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline typename IntrusiveList<T, Container, member>::Iterator& IntrusiveList<T, Container, member>::Iterator::erase() { auto old = m_value; @@ -184,26 +185,26 @@ inline typename IntrusiveList<T, Container, member>::Iterator& IntrusiveList<T, return *this; } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline IntrusiveList<T, Container, member>::~IntrusiveList() { clear(); } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline void IntrusiveList<T, Container, member>::clear() { while (m_storage.m_first) m_storage.m_first->remove(); } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline bool IntrusiveList<T, Container, member>::is_empty() const { return m_storage.m_first == nullptr; } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline size_t IntrusiveList<T, Container, member>::size_slow() const { size_t size = 0; @@ -214,7 +215,7 @@ inline size_t IntrusiveList<T, Container, member>::size_slow() const return size; } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline void IntrusiveList<T, Container, member>::append(T& n) { remove(n); @@ -233,7 +234,7 @@ inline void IntrusiveList<T, Container, member>::append(T& n) m_storage.m_first = &nnode; } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline void IntrusiveList<T, Container, member>::prepend(T& n) { remove(n); @@ -252,7 +253,7 @@ inline void IntrusiveList<T, Container, member>::prepend(T& n) m_storage.m_last = &nnode; } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline void IntrusiveList<T, Container, member>::insert_before(T& bn, T& n) { remove(n); @@ -274,7 +275,7 @@ inline void IntrusiveList<T, Container, member>::insert_before(T& bn, T& n) new_node.m_self.reference = &n; } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline void IntrusiveList<T, Container, member>::remove(T& n) { auto& nnode = n.*member; @@ -282,20 +283,20 @@ inline void IntrusiveList<T, Container, member>::remove(T& n) nnode.remove(); } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline bool IntrusiveList<T, Container, member>::contains(const T& n) const { auto& nnode = n.*member; return nnode.m_storage == &m_storage; } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline Container IntrusiveList<T, Container, member>::first() const { return m_storage.m_first ? node_to_value(*m_storage.m_first) : nullptr; } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline Container IntrusiveList<T, Container, member>::take_first() { if (Container ptr = first()) { @@ -305,7 +306,7 @@ inline Container IntrusiveList<T, Container, member>::take_first() return nullptr; } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline Container IntrusiveList<T, Container, member>::take_last() { if (Container ptr = last()) { @@ -315,13 +316,13 @@ inline Container IntrusiveList<T, Container, member>::take_last() return nullptr; } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline Container IntrusiveList<T, Container, member>::last() const { return m_storage.m_last ? node_to_value(*m_storage.m_last) : nullptr; } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline const T* IntrusiveList<T, Container, member>::next(const T* current) { auto& nextnode = (current->*member).m_next; @@ -329,7 +330,7 @@ inline const T* IntrusiveList<T, Container, member>::next(const T* current) return nextstruct; } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline const T* IntrusiveList<T, Container, member>::prev(const T* current) { auto& prevnode = (current->*member).m_prev; @@ -337,7 +338,7 @@ inline const T* IntrusiveList<T, Container, member>::prev(const T* current) return prevstruct; } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline T* IntrusiveList<T, Container, member>::next(T* current) { auto& nextnode = (current->*member).m_next; @@ -345,7 +346,7 @@ inline T* IntrusiveList<T, Container, member>::next(T* current) return nextstruct; } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline T* IntrusiveList<T, Container, member>::prev(T* current) { auto& prevnode = (current->*member).m_prev; @@ -353,26 +354,26 @@ inline T* IntrusiveList<T, Container, member>::prev(T* current) return prevstruct; } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline typename IntrusiveList<T, Container, member>::Iterator IntrusiveList<T, Container, member>::begin() { return m_storage.m_first ? Iterator(node_to_value(*m_storage.m_first)) : Iterator(); } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline typename IntrusiveList<T, Container, member>::ReverseIterator IntrusiveList<T, Container, member>::rbegin() { return m_storage.m_last ? ReverseIterator(node_to_value(*m_storage.m_last)) : ReverseIterator(); } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> inline typename IntrusiveList<T, Container, member>::ConstIterator IntrusiveList<T, Container, member>::begin() const { return m_storage.m_first ? ConstIterator(node_to_value(*m_storage.m_first)) : ConstIterator(); } -template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> -inline T* IntrusiveList<T, Container, member>::node_to_value(IntrusiveListNode<T, Container>& node) +template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member> +inline T* IntrusiveList<T, Container, member>::node_to_value(SubstitutedIntrusiveListNode<T, Container>& node) { // Note: Since this might seem odd, here's an explanation on what this function actually does: // `node` is a reference that resides in some part of the actual value (of type T), the @@ -383,8 +384,6 @@ inline T* IntrusiveList<T, Container, member>::node_to_value(IntrusiveListNode<T return bit_cast<T*>(bit_cast<unsigned char*>(&node) - bit_cast<unsigned char*>(member)); } -namespace Detail { - template<typename T, typename Container> inline IntrusiveListNode<T, Container>::~IntrusiveListNode() { @@ -416,13 +415,11 @@ inline bool IntrusiveListNode<T, Container>::is_in_list() const return m_storage != nullptr; } -} - // Specialise IntrusiveList for NonnullRefPtr // By default, intrusive lists cannot contain null entries anyway, so switch to RefPtr // and just make the user-facing functions deref the pointers. -template<class T, IntrusiveListNode<T, NonnullRefPtr<T>> T::*member> +template<class T, SubstitutedIntrusiveListNode<T, NonnullRefPtr<T>> T::*member> class IntrusiveList<T, NonnullRefPtr<T>, member> : public IntrusiveList<T, RefPtr<T>, member> { public: [[nodiscard]] NonnullRefPtr<T> first() const { return *IntrusiveList<T, RefPtr<T>, member>::first(); } @@ -434,5 +431,18 @@ public: } +namespace AK { + +template<typename T, typename Container = RawPtr<T>> +using IntrusiveListNode = Detail::SubstitutedIntrusiveListNode<T, Container>; + +template<auto member> +using IntrusiveList = Detail::IntrusiveList< + decltype(Detail::ExtractIntrusiveListTypes::value(member)), + decltype(Detail::ExtractIntrusiveListTypes::container(member)), + member>; + +} + using AK::IntrusiveList; using AK::IntrusiveListNode; diff --git a/AK/IntrusiveListRelaxedConst.h b/AK/IntrusiveListRelaxedConst.h index 9c431972e0..da94b1cc00 100644 --- a/AK/IntrusiveListRelaxedConst.h +++ b/AK/IntrusiveListRelaxedConst.h @@ -9,6 +9,7 @@ #include <AK/IntrusiveList.h> namespace AK { +namespace Detail { template<class T, typename Container, IntrusiveListNode<T, Container> T::*member> class IntrusiveListRelaxedConst : public IntrusiveList<T, Container, member> { @@ -26,4 +27,12 @@ public: } +template<auto member> +using IntrusiveListRelaxedConst = Detail::IntrusiveListRelaxedConst< + decltype(Detail::ExtractIntrusiveListTypes::value(member)), + decltype(Detail::ExtractIntrusiveListTypes::container(member)), + member>; + +} + using AK::IntrusiveListRelaxedConst; diff --git a/AK/Queue.h b/AK/Queue.h index c87750a879..448856a665 100644 --- a/AK/Queue.h +++ b/AK/Queue.h @@ -76,7 +76,7 @@ private: IntrusiveListNode<QueueSegment> node; }; - IntrusiveList<QueueSegment, RawPtr<QueueSegment>, &QueueSegment::node> m_segments; + IntrusiveList<&QueueSegment::node> m_segments; size_t m_index_into_first { 0 }; size_t m_size { 0 }; }; |