5 #ifndef TCPSPSUITE_INTRUSIVE_SHARED_PTR_HPP
6 #define TCPSPSUITE_INTRUSIVE_SHARED_PTR_HPP
10 template <
class T,
class Accessor,
bool safe_mode = false>
11 class IntrusiveSharedPtr {
13 using own_type = IntrusiveSharedPtr<T, Accessor, safe_mode>;
15 IntrusiveSharedPtr(
const own_type & other) noexcept : content(other.content)
17 if (this->content !=
nullptr) {
18 Accessor::increment(this->content);
22 IntrusiveSharedPtr(own_type && other) noexcept : content(other.content)
24 other.content =
nullptr;
27 IntrusiveSharedPtr(T * content_new) noexcept : content(content_new)
30 if (content_new !=
nullptr) {
31 Accessor::set_count(this->content, 1);
35 IntrusiveSharedPtr() noexcept { this->content =
nullptr; };
39 if (this->content ==
nullptr)
43 Accessor::decrement(this->content);
44 if (Accessor::get_count(this->content) == 0) {
45 Accessor::deallocate(this->content);
50 reset(T * content_new) noexcept
52 if (this->content !=
nullptr) {
54 Accessor::decrement(this->content);
55 if (Accessor::get_count(this->content) == 0) {
56 Accessor::deallocate(this->content);
60 this->content = content_new;
62 if (this->content !=
nullptr) {
63 Accessor::set_count(content_new, 1);
67 T & operator*() const noexcept {
return *(this->content); };
68 T * operator->() const noexcept {
return this->content; };
77 operator=(
const own_type & other)
79 this->content = other.content;
80 if (this->content !=
nullptr) {
81 Accessor::increment(this->content);
88 operator=(own_type && other)
90 this->content = other.content;
91 other.content =
nullptr;
101 class SharedPtrPool {
103 class ContainerAccessor;
106 using PointerT = IntrusiveSharedPtr<T, ContainerAccessor>;
108 class Container :
public T {
110 Container(SharedPtrPool<T> * pool_new) : T(), pool(pool_new), count(0) {}
111 Container() =
delete;
114 SharedPtrPool<T> * pool;
117 friend class ContainerAccessor;
118 friend class SharedPtrPool<T>;
121 IntrusiveSharedPtr<T, ContainerAccessor>
124 if (this->free.empty()) {
125 this->store.push_back(
126 std::vector<Container>(this->chunk_size, Container(
this)));
127 for (Container & c : this->store.back()) {
128 this->free.push_back(&c);
132 Container * c = this->free.back();
133 this->free.pop_back();
134 return IntrusiveSharedPtr<T, ContainerAccessor>((T *)c);
137 SharedPtrPool() : chunk_size(10000) {}
138 SharedPtrPool(
size_t chunk_size_new) : chunk_size(chunk_size_new) {}
141 class ContainerAccessor {
144 get_count(
const T * c) noexcept
146 return ((
const Container *)c)->Container::count;
149 set_count(T * c,
size_t count) noexcept
151 ((Container *)c)->Container::count = count;
154 increment(T * c) noexcept
156 ((Container *)c)->Container::count++;
159 decrement(T * c) noexcept
161 ((Container *)c)->Container::count--;
164 deallocate(T * c) noexcept
166 ((Container *)c)->Container::pool->free.push_back((Container *)c);
171 std::list<std::vector<Container>> store;
172 std::vector<Container *> free;
177 #endif // TCPSPSUITE_INTRUSIVE_SHARED_PTR_HPP