COROIO: coroio/actors/intrusive_list.hpp Source File
COROIO
Loading...
Searching...
No Matches
intrusive_list.hpp
1#pragma once
2
3#include <memory>
4
5namespace NNet {
6namespace NActors {
7
8template<typename T>
10 std::unique_ptr<T> Next = nullptr;
11 TIntrusiveListNode<T>* Prev = nullptr;
12 int Tag = 0;
13};
14
15template<typename T>
16class TIntrusiveList {
17public:
18 TIntrusiveList(int tag = 0)
19 : Root_{nullptr, nullptr, tag}
20 , Tail_(&Root_)
21 , Tag_(tag)
22 { }
23
24 TIntrusiveList(const TIntrusiveList&) = delete;
25 TIntrusiveList& operator=(const TIntrusiveList&) = delete;
26
27 size_t Size() const {
28 return Size_;
29 }
30
31 bool Empty() const {
32 return Size_ == 0;
33 }
34
35 void PushBack(std::unique_ptr<T>&& node) {
36 node->Prev = Tail_;
37 node->Next = nullptr;
38 node->Tag = Tag_;
39
40 Tail_->Next = std::move(node);
41 Tail_ = Tail_->Next.get();
42
43 Size_++;
44 }
45
46 std::unique_ptr<T> Erase(T* node) {
47 assert(node);
48 assert(node != &Root_);
49
50 if (node->Tag != Tag_) {
51 return nullptr;
52 }
53
54 std::unique_ptr<T>& owner = node->Prev->Next;
55 std::unique_ptr<T> result = std::move(owner);
56 owner = std::move(node->Next);
57
58 if (owner) {
59 owner->Prev = node->Prev;
60 } else {
61 Tail_ = node->Prev;
62 }
63
64 result->Next = nullptr;
65 result->Prev = nullptr;
66 result->Tag = 0;
67
68 assert(Size_ > 0);
69 Size_--;
70 return result;
71 }
72
73 T* Front() {
74 return Root_.Next.get();
75 }
76
77 std::unique_ptr<T> PopFront() noexcept {
78 auto result = std::move(Root_.Next);
79 Root_.Next = std::move(result->Next);
80
81 if (Root_.Next) {
82 Root_.Next->Prev = &Root_;
83 } else {
84 Tail_ = &Root_;
85 }
86
87 result->Next = nullptr;
88 result->Prev = nullptr;
89 result->Tag = 0;
90 Size_--;
91 return result;
92 }
93
94private:
97 size_t Size_ = 0;
98 int Tag_;
99};
100
101} // namespace NActors
102} // namespace NNet
Definition intrusive_list.hpp:9