Condy v1.7.0
C++ Asynchronous System Call Layer for Linux
Loading...
Searching...
No Matches
intrusive.hpp
Go to the documentation of this file.
1
5
6#pragma once
7
8#include "condy/utils.hpp"
9#include <cassert>
10#include <utility>
11
12namespace condy {
13
14struct SingleLinkEntry {
15 SingleLinkEntry *next = nullptr;
16};
17
18struct DoubleLinkEntry {
19 DoubleLinkEntry *next = nullptr;
20 DoubleLinkEntry *prev = nullptr;
21};
22
23template <typename T, SingleLinkEntry T::*Member> class IntrusiveSingleList {
24public:
25 IntrusiveSingleList() = default;
26 IntrusiveSingleList(IntrusiveSingleList &&other) noexcept
27 : head_(std::exchange(other.head_, nullptr)),
28 tail_(std::exchange(other.tail_, nullptr)) {}
29 IntrusiveSingleList &operator=(IntrusiveSingleList &&other) noexcept {
30 if (this != &other) {
31 assert(empty());
32 head_ = std::exchange(other.head_, nullptr);
33 tail_ = std::exchange(other.tail_, nullptr);
34 }
35 return *this;
36 }
37
38 CONDY_DELETE_COPY(IntrusiveSingleList);
39
40public:
41 void push_back(T *item) noexcept {
42 assert(item != nullptr);
43 SingleLinkEntry *entry = &(item->*Member);
44 assert(entry->next == nullptr);
45 entry->next = nullptr;
46 if (!head_) {
47 head_ = entry;
48 tail_ = entry;
49 } else {
50 tail_->next = entry;
51 tail_ = entry;
52 }
53 }
54
55 void push_back(IntrusiveSingleList other) noexcept {
56 if (other.empty()) {
57 return;
58 }
59 if (empty()) {
60 head_ = other.head_;
61 tail_ = other.tail_;
62 } else {
63 tail_->next = other.head_;
64 tail_ = other.tail_;
65 }
66 }
67
68 bool empty() const noexcept { return head_ == nullptr; }
69
70 T *pop_front() noexcept {
71 if (empty()) {
72 return nullptr;
73 }
74 SingleLinkEntry *entry = head_;
75 head_ = head_->next;
76 if (!head_) {
77 tail_ = nullptr;
78 }
79 entry->next = nullptr;
80 return container_of(Member, entry);
81 }
82
83private:
84 SingleLinkEntry *head_ = nullptr;
85 SingleLinkEntry *tail_ = nullptr;
86};
87
88template <typename T, DoubleLinkEntry T::*Member> class IntrusiveDoubleList {
89public:
90 IntrusiveDoubleList() = default;
91 IntrusiveDoubleList(IntrusiveDoubleList &&other) noexcept
92 : head_(std::exchange(other.head_, nullptr)),
93 tail_(std::exchange(other.tail_, nullptr)) {}
94 IntrusiveDoubleList &operator=(IntrusiveDoubleList &&other) noexcept {
95 if (this != &other) {
96 assert(empty());
97 head_ = std::exchange(other.head_, nullptr);
98 tail_ = std::exchange(other.tail_, nullptr);
99 }
100 return *this;
101 }
102
103 CONDY_DELETE_COPY(IntrusiveDoubleList);
104
105public:
106 void push_back(T *item) noexcept {
107 assert(item != nullptr);
108 DoubleLinkEntry *entry = &(item->*Member);
109 assert(entry->next == nullptr && entry->prev == nullptr);
110 entry->next = nullptr;
111 entry->prev = tail_;
112 if (!head_) {
113 head_ = entry;
114 tail_ = entry;
115 } else {
116 tail_->next = entry;
117 tail_ = entry;
118 }
119 }
120
121 bool empty() const noexcept { return head_ == nullptr; }
122
123 T *pop_front() noexcept {
124 if (empty()) {
125 return nullptr;
126 }
127 DoubleLinkEntry *entry = head_;
128 head_ = head_->next;
129 if (head_) {
130 head_->prev = nullptr;
131 } else {
132 tail_ = nullptr;
133 }
134 entry->next = nullptr;
135 entry->prev = nullptr;
136 return container_of(Member, entry);
137 }
138
139 bool remove(T *item) noexcept {
140 assert(item != nullptr);
141 DoubleLinkEntry *entry = &(item->*Member);
142 if (entry->prev == nullptr && entry->next == nullptr &&
143 head_ != entry) {
144 return false;
145 }
146 if (entry->prev) {
147 entry->prev->next = entry->next;
148 } else {
149 assert(head_ == entry);
150 head_ = entry->next;
151 }
152 if (entry->next) {
153 entry->next->prev = entry->prev;
154 } else {
155 assert(tail_ == entry);
156 tail_ = entry->prev;
157 }
158 entry->next = nullptr;
159 entry->prev = nullptr;
160 return true;
161 }
162
163private:
164 DoubleLinkEntry *head_ = nullptr;
165 DoubleLinkEntry *tail_ = nullptr;
166};
167
168} // namespace condy
The main namespace for the Condy library.
Definition condy.hpp:31
Internal utility classes and functions used by Condy.