From 1048f23680ece42be173d8e42c4cb80738a9c411 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 24 Feb 2021 20:28:47 +0100 Subject: [PATCH] util/IntrusiveList: add hook class SafeLinkIntrusiveListHook Similar to boost::intrusive::safe_link. --- src/util/IntrusiveList.hxx | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/util/IntrusiveList.hxx b/src/util/IntrusiveList.hxx index 4f88ac626..19b9a5b11 100644 --- a/src/util/IntrusiveList.hxx +++ b/src/util/IntrusiveList.hxx @@ -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 class IntrusiveList { IntrusiveListNode head{&head, &head}; @@ -140,7 +147,7 @@ public: } ~IntrusiveList() noexcept { - if constexpr (std::is_base_of::value) + if constexpr (std::is_base_of::value) clear(); } @@ -151,8 +158,8 @@ public: } void clear() noexcept { - if constexpr (std::is_base_of::value) { - /* for AutoUnlinkIntrusiveListHook, we need to + if constexpr (std::is_base_of::value) { + /* for SafeLinkIntrusiveListHook, we need to remove each item manually, or else its is_linked() method will not work */ while (!empty())