util/IntrusiveList: move various static functions to struct IntrusiveListBaseHook

This commit is contained in:
Max Kellermann 2022-06-08 10:31:09 +02:00 committed by Max Kellermann
parent e8e33d5fc4
commit 5348a446a7
4 changed files with 33 additions and 7 deletions

View File

@ -54,7 +54,7 @@ class EventLoop;
class CoarseTimerEvent final : AutoUnlinkIntrusiveListHook class CoarseTimerEvent final : AutoUnlinkIntrusiveListHook
{ {
friend class TimerWheel; friend class TimerWheel;
friend class IntrusiveList<CoarseTimerEvent>; friend struct IntrusiveListBaseHookTraits<CoarseTimerEvent>;
EventLoop &loop; EventLoop &loop;

View File

@ -36,7 +36,7 @@ class EventLoop;
class DeferEvent final : AutoUnlinkIntrusiveListHook class DeferEvent final : AutoUnlinkIntrusiveListHook
{ {
friend class EventLoop; friend class EventLoop;
friend class IntrusiveList<DeferEvent>; friend struct IntrusiveListBaseHookTraits<DeferEvent>;
EventLoop &loop; EventLoop &loop;

View File

@ -46,7 +46,7 @@ class EventLoop;
class SocketEvent final : IntrusiveListHook, public EventPollBackendEvents class SocketEvent final : IntrusiveListHook, public EventPollBackendEvents
{ {
friend class EventLoop; friend class EventLoop;
friend class IntrusiveList<SocketEvent>; friend struct IntrusiveListBaseHookTraits<SocketEvent>;
EventLoop &loop; EventLoop &loop;

View File

@ -43,7 +43,8 @@ struct IntrusiveListNode {
}; };
class IntrusiveListHook { class IntrusiveListHook {
template<typename T> friend class IntrusiveList; template<typename T> friend struct IntrusiveListBaseHookTraits;
template<typename T, typename HookTraits> friend class IntrusiveList;
protected: protected:
IntrusiveListNode siblings; IntrusiveListNode siblings;
@ -117,13 +118,14 @@ struct IntrusiveListHookDetection {
IntrusiveListHook>; IntrusiveListHook>;
}; };
/**
* For classes which embed #IntrusiveListHook as base class.
*/
template<typename T> template<typename T>
class IntrusiveList { struct IntrusiveListBaseHookTraits {
template<typename U> template<typename U>
using Hook = typename IntrusiveListHookDetection<U>::type; using Hook = typename IntrusiveListHookDetection<U>::type;
IntrusiveListNode head{&head, &head};
static constexpr T *Cast(IntrusiveListNode *node) noexcept { static constexpr T *Cast(IntrusiveListNode *node) noexcept {
auto *hook = &Hook<T>::Cast(*node); auto *hook = &Hook<T>::Cast(*node);
return static_cast<T *>(hook); return static_cast<T *>(hook);
@ -141,6 +143,30 @@ class IntrusiveList {
static constexpr const auto &ToHook(const T &t) noexcept { static constexpr const auto &ToHook(const T &t) noexcept {
return static_cast<const Hook<T> &>(t); return static_cast<const Hook<T> &>(t);
} }
};
template<typename T, typename HookTraits=IntrusiveListBaseHookTraits<T>>
class IntrusiveList {
template<typename U>
using Hook = typename IntrusiveListHookDetection<U>::type;
IntrusiveListNode head{&head, &head};
static constexpr T *Cast(IntrusiveListNode *node) noexcept {
return HookTraits::Cast(node);
}
static constexpr const T *Cast(const IntrusiveListNode *node) noexcept {
return HookTraits::Cast(node);
}
static constexpr auto &ToHook(T &t) noexcept {
return HookTraits::ToHook(t);
}
static constexpr const auto &ToHook(const T &t) noexcept {
return HookTraits::ToHook(t);
}
static constexpr IntrusiveListNode &ToNode(T &t) noexcept { static constexpr IntrusiveListNode &ToNode(T &t) noexcept {
return ToHook(t).siblings; return ToHook(t).siblings;