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