cesium-native  0.41.0
ReferenceCounted.h
1 #pragma once
2 
3 #include <CesiumUtility/Assert.h>
4 
5 #include <atomic>
6 #include <cstdint>
7 
8 #ifndef NDEBUG
9 #include <thread>
10 #endif
11 
12 namespace CesiumUtility {
13 
14 #ifndef NDEBUG
15 template <bool isThreadSafe> class ThreadIdHolder;
16 
17 template <> class ThreadIdHolder<false> {
18  ThreadIdHolder() : _threadID(std::this_thread::get_id()) {}
19 
20  std::thread::id _threadID;
21 
22  template <typename T, bool isThreadSafe> friend class ReferenceCounted;
23 };
24 
25 template <> class ThreadIdHolder<true> {};
26 #endif
27 
47 template <typename T, bool isThreadSafe = true>
49 #ifndef NDEBUG
50  : public ThreadIdHolder<isThreadSafe>
51 #endif
52 {
53 public:
54  ReferenceCounted() noexcept {}
55  ~ReferenceCounted() noexcept { CESIUM_ASSERT(this->_referenceCount == 0); }
56 
62  void addReference() const /*noexcept*/ {
63 #ifndef NDEBUG
64  if constexpr (!isThreadSafe) {
65  CESIUM_ASSERT(std::this_thread::get_id() == this->_threadID);
66  }
67 #endif
68 
69  ++this->_referenceCount;
70  }
71 
78  void releaseReference() const /*noexcept*/ {
79 #ifndef NDEBUG
80  if constexpr (!isThreadSafe) {
81  CESIUM_ASSERT(std::this_thread::get_id() == this->_threadID);
82  }
83 #endif
84 
85  CESIUM_ASSERT(this->_referenceCount > 0);
86  const int32_t references = --this->_referenceCount;
87  if (references == 0) {
88  delete static_cast<const T*>(this);
89  }
90  }
91 
95  std::int32_t getReferenceCount() const noexcept {
96  return this->_referenceCount;
97  }
98 
99 private:
100  using ThreadSafeCounter = std::atomic<std::int32_t>;
101  using NonThreadSafeCounter = std::int32_t;
102  using CounterType =
103  std::conditional_t<isThreadSafe, ThreadSafeCounter, NonThreadSafeCounter>;
104 
105  mutable CounterType _referenceCount{0};
106 };
107 
118 template <typename T>
120 
131 template <typename T>
133 
134 } // namespace CesiumUtility
A reference-counted base class, meant to be used with IntrusivePointer.
std::int32_t getReferenceCount() const noexcept
Returns the current reference count of this instance.
void releaseReference() const
Removes a counted reference from this object. When the last reference is removed, this method will de...
void addReference() const
Adds a counted reference to this object. Use CesiumUtility::IntrusivePointer instead of calling this ...
Utility classes for Cesium.