11#ifndef TLX_COUNTING_PTR_HEADER
12#define TLX_COUNTING_PTR_HEADER
27 template <
typename Type>
37 template <
typename Type>
64template <
typename Type,
typename Deleter = CountingPtrDefaultDeleter>
77 {
if (o) o->inc_reference(); }
87 template <
typename Other,
typename OtherDeleter>
112 template <
typename Subclass,
113 typename =
typename std::enable_if<
114 std::is_convertible<Subclass*, Type*>::value,
void>::type>
122 { other.ptr_ =
nullptr; }
125 template <
typename Subclass,
126 typename =
typename std::enable_if<
127 std::is_convertible<Subclass*, Type*>::value,
void>::type>
130 { other.ptr_ =
nullptr; }
135 if (
ptr_ == other.ptr_)
145 template <
typename Subclass,
146 typename =
typename std::enable_if<
147 std::is_convertible<Subclass*, Type*>::value,
void>::type>
150 if (
ptr_ == other.ptr_)
160 if (
ptr_ == other.ptr_)
164 other.ptr_ =
nullptr;
169 template <
typename Subclass,
170 typename =
typename std::enable_if<
171 std::is_convertible<Subclass*, Type*>::value,
void>::type>
173 if (
ptr_ == other.ptr_)
177 other.ptr_ =
nullptr;
206 {
return (
ptr_ !=
nullptr); }
209 operator bool () const noexcept
214 {
return (
ptr_ ==
nullptr); }
223 {
return ptr_->reference_count(); }
239 { std::swap(
ptr_, b.ptr_); }
254 {
return ptr_ == other.ptr_; }
258 {
return ptr_ != other.ptr_; }
262 {
return ptr_ == other; }
266 {
return ptr_ != other; }
270 {
return ptr_ < other.ptr_; }
274 {
return ptr_ <= other.ptr_; }
278 {
return ptr_ > other.ptr_; }
282 {
return ptr_ >= other.ptr_; }
286 {
return ptr_ < other; }
290 {
return ptr_ <= other; }
294 {
return ptr_ > other; }
298 {
return ptr_ >= other; }
304template <
typename Type>
308template <
typename Type>
312template <
typename Type,
typename... Args>
319template <
typename A,
typename D>
325template <
typename A,
typename D>
327 return os << c.
get();
default deleter for CountingPtr
void operator()(Type *ptr) const noexcept
dummy deleter for CountingPtr
void operator()(Type *) const noexcept
High-performance smart pointer used as a wrapping reference counting pointer.
void inc_reference(Type *o) noexcept
increment reference count of object.
bool unique() const noexcept
if the object is referred by this CountingPtr only
void unify()
make and refer a copy if the original object was shared.
bool empty() const noexcept
test for a nullptr pointer
CountingPtr(Type *ptr) noexcept
constructor from pointer: initializes new reference to ptr.
Type * get() const noexcept
return the enclosed pointer.
CountingPtr(const CountingPtr &other) noexcept
copy-constructor: also initializes new reference to ptr.
~CountingPtr()
destructor: decrements reference count in ptr.
void swap(CountingPtr &b) noexcept
swap enclosed object with another counting pointer (no reference counts need change)
friend class CountingPtr
all CountingPtr are friends such that they may steal pointers.
Type * operator->() const noexcept
return the enclosed pointer.
bool operator==(const CountingPtr &other) const noexcept
test equality of only the pointer values.
bool operator<=(const CountingPtr &other) const noexcept
compare the pointer values.
CountingPtr(std::nullptr_t) noexcept
implicit conversion from nullptr_t: contains a nullptr pointer.
CountingPtr & operator=(const CountingPtr &other) noexcept
copy-assignment operator: acquire reference on new one and dereference current object.
void dec_reference() noexcept
decrement reference count of current object and maybe delete it.
Type & operator*() const noexcept
return the enclosed object as reference.
bool valid() const noexcept
test for a non-nullptr pointer
bool operator>(const CountingPtr &other) const noexcept
compare the pointer values.
Type * ptr_
the pointer to the currently referenced object.
Type element_type
contained type.
bool operator!=(const CountingPtr &other) const noexcept
test inequality of only the pointer values.
CountingPtr(CountingPtr &&other) noexcept
move-constructor: just moves pointer, does not change reference counts.
void reset()
release contained pointer, frees object if this is the last reference.
CountingPtr(const CountingPtr< Subclass, Deleter > &other) noexcept
copy-constructor: also initializes new reference to ptr.
CountingPtr(CountingPtr< Subclass, Deleter > &&other) noexcept
move-constructor: just moves pointer, does not change reference counts.
bool operator<(const CountingPtr &other) const noexcept
compare the pointer values.
CountingPtr() noexcept
default constructor: contains a nullptr pointer.
size_t use_count() const noexcept
Returns the number of different shared_ptr instances managing the current object.
bool operator>=(const CountingPtr &other) const noexcept
compare the pointer values.
Provides reference counting abilities for use with CountingPtr.
size_t reference_count() const noexcept
Return the number of references to this object (for debugging)
bool unique() const noexcept
Test if the ReferenceCounter is referenced by only one CountingPtr.
std::atomic< size_t > reference_count_
the reference count is kept mutable for CountingPtr<const Type> to change the reference count.
ReferenceCounter() noexcept
new objects have zero reference count
bool dec_reference() const noexcept
Call whenever resetting (i.e.
void inc_reference() const noexcept
Call whenever setting a pointer to the object.
ReferenceCounter(const ReferenceCounter &) noexcept
coping still creates a new object with zero reference count
ReferenceCounter & operator=(const ReferenceCounter &) noexcept
assignment operator, leaves pointers unchanged
void swap(CountingPtr< A, D > &a1, CountingPtr< A, D > &a2) noexcept
swap enclosed object with another counting pointer (no reference counts need change)
CountingPtr< Type > make_counting(Args &&... args)
method analogous to std::make_shared and std::make_unique.
std::ostream & operator<<(std::ostream &os, const CountingPtr< A, D > &c)
print pointer