44#define PROMEKI_SHARED(BASE) \
46 RefCount _promeki_refct; \
47 virtual BASE *_promeki_clone() const { return new BASE(*this); }
67#define PROMEKI_SHARED_DERIVED(BASE, DERIVED) \
69 virtual BASE *_promeki_clone() const override { return new DERIVED(*this); }
88#define PROMEKI_SHARED_FINAL(TYPE) \
90 RefCount _promeki_refct; \
91 TYPE *_promeki_clone() const { return new TYPE(*this); }
122 if(v.load(std::memory_order_relaxed) >=
Immortal)
return;
123 v.fetch_add(1, std::memory_order_relaxed);
134 if(v.load(std::memory_order_relaxed) >=
Immortal)
return false;
135 return v.fetch_sub(1, std::memory_order_acq_rel) == 1;
140 return v.load(std::memory_order_relaxed);
145 return v.load(std::memory_order_relaxed) >=
Immortal;
150 v.store(
Immortal, std::memory_order_relaxed);
180 T *_promeki_clone()
const {
183 assert(
typeid(*_object) ==
typeid(
T));
184 return new T(*_object);
186 T *object()
const {
return _object; }
188 T *_object =
nullptr;
267 template<
typename...
Args>
270 sp.setData(
new T(std::forward<Args>(
args)...));
281 if(&
sp ==
this)
return *
this;
289 if(&
sp ==
this)
return *
this;
297 std::swap(_data,
other._data);
308 if(_data ==
nullptr || _data->_promeki_refct.value() < 2)
return;
309 T *copy = _data->_promeki_clone();
316 bool isNull()
const {
317 return _data ==
nullptr;
320 bool isValid()
const {
321 return _data !=
nullptr;
324 explicit operator bool()
const {
325 return _data !=
nullptr;
329 return _data ==
other._data;
333 return _data !=
other._data;
336 bool operator==(std::nullptr_t)
const {
337 return _data ==
nullptr;
340 bool operator!=(std::nullptr_t)
const {
341 return _data !=
nullptr;
344 int referenceCount()
const {
345 return _data ==
nullptr ? 0 : _data->_promeki_refct.value();
348 const T *ptr()
const {
353 return _data->object();
363 return _data->object();
367 const T *operator->()
const {
371 const T &operator*()
const {
380 if(_data ==
nullptr)
return;
381 _data->_promeki_refct.inc();
389 if(_data ==
nullptr)
return;
390 if(_data->_promeki_refct.dec())
delete _data;
394 constexpr void setData(
T *
obj) {
Dynamic array container wrapping std::vector.
Definition list.h:40
An atomic reference count object.
Definition sharedptr.h:101
void inc()
Atomically increments the reference count.
Definition sharedptr.h:121
bool dec()
Atomically decrements the reference count.
Definition sharedptr.h:133
RefCount()
Constructs a reference count initialized to 1.
Definition sharedptr.h:107
RefCount & operator=(const RefCount &)
Copy assignment resets the reference count to 1.
Definition sharedptr.h:113
void setImmortal()
Marks this refcount as immortal. inc/dec become no-ops.
Definition sharedptr.h:149
RefCount(const RefCount &o)
Copy constructor resets the reference count to 1 for the new object.
Definition sharedptr.h:110
bool isImmortal() const
Returns true if this refcount is immortal (will never reach zero).
Definition sharedptr.h:144
int value() const
Returns the current reference count value.
Definition sharedptr.h:139
static constexpr int Immortal
Threshold at or above which the refcount is considered immortal.
Definition sharedptr.h:104
A proxy class for managing reference counting of objects that do not natively support it.
Definition sharedptr.h:174
A smart pointer class with reference counting and optional copy-on-write semantics.
Definition sharedptr.h:252
#define PROMEKI_NAMESPACE_BEGIN
Starts a promeki namespace block.
Definition namespace.h:14
#define PROMEKI_NAMESPACE_END
Ends a promeki namespace block.
Definition namespace.h:19
Definition sharedptr.h:191