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
|
||||
* list upon destruction. As a side effect, it has an is_linked()
|
||||
* method.
|
||||
* A variant of #IntrusiveListHook which keeps track of whether it is
|
||||
* currently in a list.
|
||||
*/
|
||||
class AutoUnlinkIntrusiveListHook : public IntrusiveListHook {
|
||||
class SafeLinkIntrusiveListHook : public IntrusiveListHook {
|
||||
public:
|
||||
AutoUnlinkIntrusiveListHook() noexcept {
|
||||
SafeLinkIntrusiveListHook() noexcept {
|
||||
siblings.next = nullptr;
|
||||
}
|
||||
|
||||
~AutoUnlinkIntrusiveListHook() noexcept {
|
||||
if (is_linked())
|
||||
unlink();
|
||||
}
|
||||
|
||||
void unlink() noexcept {
|
||||
IntrusiveListHook::unlink();
|
||||
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>
|
||||
class IntrusiveList {
|
||||
IntrusiveListNode head{&head, &head};
|
||||
@ -140,7 +147,7 @@ public:
|
||||
}
|
||||
|
||||
~IntrusiveList() noexcept {
|
||||
if constexpr (std::is_base_of<AutoUnlinkIntrusiveListHook, T>::value)
|
||||
if constexpr (std::is_base_of<SafeLinkIntrusiveListHook, T>::value)
|
||||
clear();
|
||||
}
|
||||
|
||||
@ -151,8 +158,8 @@ public:
|
||||
}
|
||||
|
||||
void clear() noexcept {
|
||||
if constexpr (std::is_base_of<AutoUnlinkIntrusiveListHook, T>::value) {
|
||||
/* for AutoUnlinkIntrusiveListHook, we need to
|
||||
if constexpr (std::is_base_of<SafeLinkIntrusiveListHook, T>::value) {
|
||||
/* for SafeLinkIntrusiveListHook, we need to
|
||||
remove each item manually, or else its
|
||||
is_linked() method will not work */
|
||||
while (!empty())
|
||||
|
Loading…
Reference in New Issue
Block a user