Skip to content

Commit d45c2e7

Browse files
author
Damir Zainullin
committed
++
1 parent 0fa7609 commit d45c2e7

1 file changed

Lines changed: 93 additions & 0 deletions

File tree

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#pragma once
2+
3+
//#include "outputContainer.hpp"
4+
5+
#include <atomic>
6+
#include <cstddef>
7+
#include <iostream>
8+
9+
template<typename T>
10+
class ReferenceCounter {
11+
public:
12+
/*explicit ReferenceCounter(T data) noexcept
13+
: m_data(std::move(data))
14+
{
15+
}*/
16+
17+
explicit ReferenceCounter() noexcept
18+
: m_data()
19+
{
20+
}
21+
22+
ReferenceCounter& operator=(const ReferenceCounter&) = delete;
23+
ReferenceCounter(const ReferenceCounter&) = delete;
24+
25+
T& getData() noexcept { return m_data; }
26+
27+
void incrementUserCount() noexcept { m_refCount++; }
28+
29+
void decrementUserCount()
30+
{
31+
if (m_refCount == 0) {
32+
throw std::runtime_error(
33+
"ReferenceCounterHandler destructor called but user count is already zero.");
34+
}
35+
const uint8_t refCount = m_refCount--;
36+
if (refCount == 0) {
37+
m_data.~T();
38+
}
39+
}
40+
41+
bool hasUsers() const noexcept { return m_refCount.load() > 0; }
42+
43+
private:
44+
T m_data;
45+
std::atomic_uint8_t m_refCount {0};
46+
};
47+
48+
template<typename T>
49+
class Reference {
50+
public:
51+
explicit Reference(ReferenceCounter<T>& counter) noexcept
52+
: m_counter(&counter)
53+
{
54+
m_counter->incrementUserCount();
55+
}
56+
57+
auto&& getData(this auto&& self) noexcept { return self.m_counter->getData(); }
58+
59+
Reference(const Reference& other) noexcept
60+
: Reference(*other.m_counter)
61+
{
62+
}
63+
64+
/*Reference& operator=(const Reference& other) noexcept
65+
{
66+
if (this != &other) {
67+
m_counter->decrementUserCount();
68+
m_counter = other.m_counter;
69+
m_counter->incrementUserCount();
70+
}
71+
return *this;
72+
}*/
73+
74+
void assign(const Reference& other,
75+
AllocationBufferBase<ReferenceCounter<T>>& allocationBuffer) noexcept
76+
{
77+
if (this != &other) {
78+
return;
79+
}
80+
const uint8_t userCount = m_counter->decrementUserCount();
81+
if (userCount == 0) {
82+
allocationBuffer.deallocate(m_counter);
83+
}
84+
m_counter = other.m_counter;
85+
m_counter->incrementUserCount();
86+
87+
}
88+
89+
~Reference() noexcept { m_counter->decrementUserCount(); }
90+
91+
private:
92+
ReferenceCounter<T>* m_counter;
93+
};

0 commit comments

Comments
 (0)