11 #ifndef TLX_COUNTING_PTR_HEADER 12 #define TLX_COUNTING_PTR_HEADER 18 #include <type_traits> 27 template <
typename Type>
37 template <
typename Type>
64 template <
typename Type,
typename Deleter = CountingPtrDefaultDeleter>
77 {
if (o) o->inc_reference(); }
81 if (ptr_ && ptr_->dec_reference())
87 template <
typename Other,
typename OtherDeleter>
104 { inc_reference(ptr_); }
109 { inc_reference(ptr_); }
112 template <
typename Subclass,
113 typename =
typename std::enable_if<
114 std::is_convertible<Subclass*, Type*>::value,
void>::type>
117 { inc_reference(ptr_); }
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_)
137 inc_reference(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_)
152 inc_reference(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;
190 Type& operator * () const noexcept {
196 Type* operator -> () const noexcept {
202 Type *
get()
const noexcept {
return ptr_; }
206 {
return (ptr_ !=
nullptr); }
209 operator bool () const noexcept
214 {
return (ptr_ ==
nullptr); }
218 {
return ptr_ && ptr_->unique(); }
223 {
return ptr_->reference_count(); }
243 if (ptr_ && !ptr_->unique())
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; }
304 template <
typename Type>
308 template <
typename Type>
312 template <
typename Type,
typename... Args>
319 template <
typename A,
typename D>
325 template <
typename A,
typename D>
326 std::ostream& operator << (std::ostream& os, const CountingPtr<A, D>& c) {
327 return os << c.get();
347 : reference_count_(0) { }
351 : reference_count_(0) { }
360 { assert(reference_count_ == 0); }
365 { ++reference_count_; }
375 assert(reference_count_ > 0);
376 return (--reference_count_ == 0);
381 {
return (reference_count_ == 1); }
385 {
return reference_count_; }
438 #endif // !TLX_COUNTING_PTR_HEADER size_t use_count() const noexcept
Returns the number of different shared_ptr instances managing the current object. ...
void unify()
make and refer a copy if the original object was shared.
CountingPtr< Type > make_counting(Args &&...args)
method analogous to std::make_shared and std::make_unique.
Type element_type
contained type.
CountingPtr(Type *ptr) noexcept
constructor from pointer: initializes new reference to ptr.
bool unique() const noexcept
Test if the ReferenceCounter is referenced by only one CountingPtr.
dummy deleter for CountingPtr
static bool operator!=(const StringView &a, const std::string &b) noexcept
inequality operator to compare a StringView with a std::string
void operator()(Type *ptr) const noexcept
CountingPtr(const CountingPtr< Subclass, Deleter > &other) noexcept
copy-constructor: also initializes new reference to ptr.
static bool operator>(const StringView &x, const std::string &y) noexcept
void reset()
release contained pointer, frees object if this is the last reference.
default deleter for CountingPtr
bool valid() const noexcept
test for a non-nullptr pointer
ReferenceCounter(const ReferenceCounter &) noexcept
coping still creates a new object with zero reference count
Type * ptr_
the pointer to the currently referenced object.
CountingPtr() noexcept
default constructor: contains a nullptr pointer.
CountingPtr(CountingPtr &&other) noexcept
move-constructor: just moves pointer, does not change reference counts.
CountingPtr(const CountingPtr &other) noexcept
copy-constructor: also initializes new reference to ptr.
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.
static bool operator>=(const StringView &x, const std::string &y) noexcept
static bool operator<=(const StringView &x, const std::string &y) noexcept
void swap(CountingPtr< A, D > &a1, CountingPtr< A, D > &a2) noexcept
swap enclosed object with another counting pointer (no reference counts need change) ...
size_t reference_count() const noexcept
Return the number of references to this object (for debugging)
bool unique() const noexcept
if the object is referred by this CountingPtr only
void inc_reference(Type *o) noexcept
increment reference count of object.
High-performance smart pointer used as a wrapping reference counting pointer.
static bool operator==(const StringView &a, const std::string &b) noexcept
equality operator to compare a StringView with a std::string
bool empty() const noexcept
test for a nullptr pointer
~CountingPtr()
destructor: decrements reference count in ptr.
void inc_reference() const noexcept
Call whenever setting a pointer to the object.
void dec_reference() noexcept
decrement reference count of current object and maybe delete it.
CountingPtr(CountingPtr< Subclass, Deleter > &&other) noexcept
move-constructor: just moves pointer, does not change reference counts.
static bool operator<(const StringView &a, const std::string &b) noexcept
less operator to compare a StringView with a std::string lexicographically
CountingPtr(std::nullptr_t) noexcept
implicit conversion from nullptr_t: contains a nullptr pointer.
Provides reference counting abilities for use with CountingPtr.
void swap(CountingPtr &b) noexcept
swap enclosed object with another counting pointer (no reference counts need change) ...