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
{
friend class TimerWheel;
friend class IntrusiveList<CoarseTimerEvent>;
friend struct IntrusiveListBaseHookTraits<CoarseTimerEvent>;
EventLoop &loop;

View File

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

View File

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

View File

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