mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
AK: Make IntrusiveList work with NonnullRefPtr's
This commit is contained in:
parent
3857148028
commit
88b97f5367
Notes:
sideshowbarker
2024-07-18 19:15:23 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/88b97f53676 Pull-request: https://github.com/SerenityOS/serenity/pull/6543
1 changed files with 33 additions and 6 deletions
|
@ -33,15 +33,32 @@
|
|||
|
||||
namespace AK {
|
||||
|
||||
namespace Detail {
|
||||
template<typename T, typename Container = RawPtr<T>>
|
||||
class IntrusiveListNode;
|
||||
|
||||
template<typename T, typename Container>
|
||||
struct SubstituteIntrusiveListNodeContainerType {
|
||||
using Type = Container;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct SubstituteIntrusiveListNodeContainerType<T, NonnullRefPtr<T>> {
|
||||
using Type = RefPtr<T>;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T, typename Container = RawPtr<T>>
|
||||
using IntrusiveListNode = Detail::IntrusiveListNode<T, typename Detail::SubstituteIntrusiveListNodeContainerType<T, Container>::Type>;
|
||||
|
||||
template<typename T, typename Container>
|
||||
class IntrusiveListStorage {
|
||||
private:
|
||||
friend class IntrusiveListNode<T, Container>;
|
||||
friend class Detail::IntrusiveListNode<T, Container>;
|
||||
|
||||
template<class T_, typename Container_, IntrusiveListNode<T_, Container_> T_::*member>
|
||||
friend class IntrusiveList;
|
||||
|
||||
IntrusiveListNode<T, Container>* m_first { nullptr };
|
||||
IntrusiveListNode<T, Container>* m_last { nullptr };
|
||||
};
|
||||
|
@ -132,6 +149,8 @@ template<typename Contained>
|
|||
struct SelfReferenceIfNeeded<Contained, true> {
|
||||
};
|
||||
|
||||
namespace Detail {
|
||||
|
||||
template<typename T, typename Container>
|
||||
class IntrusiveListNode {
|
||||
public:
|
||||
|
@ -141,15 +160,22 @@ 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::*`)
|
||||
// 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 IntrusiveList;
|
||||
friend class ::AK::IntrusiveList;
|
||||
#endif
|
||||
|
||||
IntrusiveListStorage<T, Container>* m_storage = nullptr;
|
||||
IntrusiveListNode<T, Container>* m_next = nullptr;
|
||||
IntrusiveListNode<T, Container>* m_prev = nullptr;
|
||||
SelfReferenceIfNeeded<Container, IsRaw> m_self;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<class T, typename Container, IntrusiveListNode<T, Container> T::*member>
|
||||
inline typename IntrusiveList<T, Container, member>::Iterator& IntrusiveList<T, Container, member>::Iterator::erase()
|
||||
{
|
||||
|
@ -309,6 +335,8 @@ 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()
|
||||
{
|
||||
|
@ -341,12 +369,11 @@ inline bool IntrusiveListNode<T, Container>::is_in_list() const
|
|||
return m_storage != nullptr;
|
||||
}
|
||||
|
||||
// Specialise IntrusiveList(Node) for NonnullRefPtr
|
||||
}
|
||||
|
||||
// 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<typename T>
|
||||
struct IntrusiveListNode<T, NonnullRefPtr<T>> : public IntrusiveListNode<T, RefPtr<T>> {
|
||||
};
|
||||
|
||||
template<class T, IntrusiveListNode<T, NonnullRefPtr<T>> T::*member>
|
||||
class IntrusiveList<T, NonnullRefPtr<T>, member> : public IntrusiveList<T, RefPtr<T>, member> {
|
||||
|
|
Loading…
Reference in a new issue