util/IntrusiveList: add hook class SafeLinkIntrusiveListHook
Similar to boost::intrusive::safe_link.
This commit is contained in:
parent
8fe8f09027
commit
1048f23680
@ -65,21 +65,15 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A variant of #IntrusiveListHook which auto-unlinks itself from the
|
* A variant of #IntrusiveListHook which keeps track of whether it is
|
||||||
* list upon destruction. As a side effect, it has an is_linked()
|
* currently in a list.
|
||||||
* method.
|
|
||||||
*/
|
*/
|
||||||
class AutoUnlinkIntrusiveListHook : public IntrusiveListHook {
|
class SafeLinkIntrusiveListHook : public IntrusiveListHook {
|
||||||
public:
|
public:
|
||||||
AutoUnlinkIntrusiveListHook() noexcept {
|
SafeLinkIntrusiveListHook() noexcept {
|
||||||
siblings.next = nullptr;
|
siblings.next = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
~AutoUnlinkIntrusiveListHook() noexcept {
|
|
||||||
if (is_linked())
|
|
||||||
unlink();
|
|
||||||
}
|
|
||||||
|
|
||||||
void unlink() noexcept {
|
void unlink() noexcept {
|
||||||
IntrusiveListHook::unlink();
|
IntrusiveListHook::unlink();
|
||||||
siblings.next = nullptr;
|
siblings.next = nullptr;
|
||||||
@ -90,6 +84,19 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A variant of #IntrusiveListHook which auto-unlinks itself from the
|
||||||
|
* list upon destruction. As a side effect, it has an is_linked()
|
||||||
|
* method.
|
||||||
|
*/
|
||||||
|
class AutoUnlinkIntrusiveListHook : public SafeLinkIntrusiveListHook {
|
||||||
|
public:
|
||||||
|
~AutoUnlinkIntrusiveListHook() noexcept {
|
||||||
|
if (is_linked())
|
||||||
|
unlink();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class IntrusiveList {
|
class IntrusiveList {
|
||||||
IntrusiveListNode head{&head, &head};
|
IntrusiveListNode head{&head, &head};
|
||||||
@ -140,7 +147,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
~IntrusiveList() noexcept {
|
~IntrusiveList() noexcept {
|
||||||
if constexpr (std::is_base_of<AutoUnlinkIntrusiveListHook, T>::value)
|
if constexpr (std::is_base_of<SafeLinkIntrusiveListHook, T>::value)
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,8 +158,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void clear() noexcept {
|
void clear() noexcept {
|
||||||
if constexpr (std::is_base_of<AutoUnlinkIntrusiveListHook, T>::value) {
|
if constexpr (std::is_base_of<SafeLinkIntrusiveListHook, T>::value) {
|
||||||
/* for AutoUnlinkIntrusiveListHook, we need to
|
/* for SafeLinkIntrusiveListHook, we need to
|
||||||
remove each item manually, or else its
|
remove each item manually, or else its
|
||||||
is_linked() method will not work */
|
is_linked() method will not work */
|
||||||
while (!empty())
|
while (!empty())
|
||||||
|
Loading…
Reference in New Issue
Block a user