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>
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
67 assert(Size_ > 0);
68 Size_--;
69 return result;
70 }
71
72 T* Front() {
73 return Root_.Next.get();
74 }
75
76 std::unique_ptr<T> PopFront() noexcept {
77 auto result = std::move(Root_.Next);
78 Root_.Next = std::move(result->Next);
79
80 if (Root_.Next) {
81 Root_.Next->Prev = &Root_;
82 } else {
83 Tail_ = &Root_;
84 }
85
86 result->Next = nullptr;
87 result->Prev = nullptr;
88 Size_--;
89 return result;
90 }
91
92private:
95 size_t Size_ = 0;
96 int Tag_;
97};
98
99} // namespace NActors
100} // namespace NNet
Definition intrusive_list.hpp:16
Definition intrusive_list.hpp:9