15#include "sparta/utils/Utils.hpp"
17#include "sparta/utils/SpartaSharedPointerBaseAllocator.hpp"
22 template<
class Po
interT>
23 class SpartaSharedPointerAllocator;
25 template<
class Po
interT>
26 class SpartaWeakPointer;
79 template <
class Po
interT>
83 template<
class Po
interT2>
94 RefCount(PointerT * _p,
void * mem_block) :
95 p(_p), mem_block(mem_block)
98 explicit RefCount(PointerT * _p) :
103 ~RefCount() { p =
nullptr; }
107 PointerT * p =
nullptr;
108 void * mem_block =
nullptr;
123 ref_count_(p ==
nullptr ?
nullptr : new RefCount(p))
142 template<
class Po
interT2>
146 static_assert(std::is_base_of<PointerT, PointerT2>::value ==
true,
147 "Only upcasting (derived class -> base class) of SpartaSharedPointer is supported!");
148 static_assert(std::has_virtual_destructor<PointerT>::value ==
true,
149 "Base class must have a virtual destructor defined to support upcasting!");
162 ref_count_(orig.ref_count_)
177 ref_count_(orig.ref_count_)
180 orig.ref_count_ =
nullptr;
199 ref_count_ = orig.ref_count_;
218 ref_count_ = orig.ref_count_;
219 orig.ref_count_ =
nullptr;
233 return (ref_count_ ==
nullptr) || (ref_count_->p ==
nullptr);
246 explicit operator bool()
const {
247 return (ref_count_ && (ref_count_->p ==
nullptr ?
false :
true));
255 return (ref_count_ ? ref_count_->p :
nullptr);
263 sparta_assert(ref_count_ !=
nullptr,
"This is a null SpartaSharedPointer");
264 return *(ref_count_->p);
272 return (ref_count_ ? ref_count_->p :
nullptr);
279 void reset(PointerT * p =
nullptr) {
281 ref_count_ = p ==
nullptr ? nullptr :
new RefCount(p);
290 return ref_count_->p ? ref_count_->count : 0;
311 static void releaseRefCount_(RefCount *& ref_count)
313 if(0 == ref_count->count) {
322 --(ref_count->count);
327 ++ref_count->wp_count;
329 BaseAllocator::MemBlockBase * memory_block =
330 static_cast<BaseAllocator::MemBlockBase *
>(ref_count->mem_block);
338 memory_block->alloc->releaseObject_(memory_block);
342 ref_count->p =
nullptr;
349 --ref_count->wp_count;
352 if((0 >= ref_count->count) && (0 == ref_count->wp_count))
358 BaseAllocator::MemBlockBase * memory_block =
359 static_cast<BaseAllocator::MemBlockBase *
>(ref_count->mem_block);
362 memory_block->alloc->releaseBlock_(memory_block);
377 releaseRefCount_(ref_count_);
383 explicit SpartaSharedPointer(RefCount * cnt,
const bool weak_ptr =
false) :
386 if(weak_ptr && ref_count_) { ++ref_count_->count; }
389 RefCount * ref_count_ =
nullptr;
391 friend class SpartaSharedPointerAllocator<PointerT>;
392 friend class SpartaWeakPointer<PointerT>;
394 template<
typename PtrT,
typename... Args>
395 friend SpartaSharedPointer<PtrT>
396 allocate_sparta_shared_pointer(SpartaSharedPointerAllocator<PtrT> &, Args&&...args);
406 template<
class Po
interT>
418 wp_ref_cnt_(sp.ref_count_)
421 ++(wp_ref_cnt_->wp_count);
428 --(wp_ref_cnt_->wp_count);
430 wp_ref_cnt_ =
nullptr;
439 wp_ref_cnt_(orig.wp_ref_cnt_)
442 ++(wp_ref_cnt_->wp_count);
451 wp_ref_cnt_(orig.wp_ref_cnt_)
453 orig.wp_ref_cnt_ =
nullptr;
463 --(wp_ref_cnt_->wp_count);
466 wp_ref_cnt_ = orig.wp_ref_cnt_;
469 ++(wp_ref_cnt_->wp_count);
481 --(wp_ref_cnt_->wp_count);
485 wp_ref_cnt_ = orig.wp_ref_cnt_;
486 orig.wp_ref_cnt_ =
nullptr;
496 return (wp_ref_cnt_->count <= 0 ? 0 : wp_ref_cnt_->count);
507 return wp_ref_cnt_->count <= 0;
526 template<
typename PtrT,
typename Ptr2>
527 bool operator==(
const SpartaSharedPointer<PtrT>& ptr1,
const SpartaSharedPointer<Ptr2>& ptr2)
noexcept
528 {
return ptr1.get() == ptr2.get(); }
530 template<
typename PtrT>
531 bool operator==(
const SpartaSharedPointer<PtrT>& ptr1, std::nullptr_t)
noexcept
534 template<
typename PtrT>
535 bool operator==(std::nullptr_t,
const SpartaSharedPointer<PtrT>& ptr1)
noexcept
538 template<
typename PtrT,
typename Ptr2>
539 bool operator!=(
const SpartaSharedPointer<PtrT>& ptr1,
const SpartaSharedPointer<Ptr2>& ptr2)
noexcept
540 {
return ptr1.get() != ptr2.get(); }
542 template<
typename PtrT>
543 bool operator!=(
const SpartaSharedPointer<PtrT>& ptr1, std::nullptr_t)
noexcept
544 {
return (
bool)ptr1; }
546 template<
typename PtrT>
547 bool operator!=(std::nullptr_t,
const SpartaSharedPointer<PtrT>& ptr1)
noexcept
548 {
return (
bool)ptr1; }
550 template<
typename PtrT>
551 std::ostream&
operator<<(std::ostream & os,
const SpartaSharedPointer<PtrT> & p)
560namespace MetaStruct {
564 struct is_any_pointer<
sparta::SpartaSharedPointer<T>> :
public std::true_type {};
567 struct is_any_pointer<
sparta::SpartaSharedPointer<T> const> :
public std::true_type {};
570 struct is_any_pointer<
sparta::SpartaSharedPointer<T> &> :
public std::true_type {};
573 struct is_any_pointer<
sparta::SpartaSharedPointer<T> const &> :
public std::true_type {};
576 struct remove_any_pointer<
sparta::SpartaSharedPointer<T>> {
using type = T; };
579 struct remove_any_pointer<
sparta::SpartaSharedPointer<T> const> {
using type = T; };
582 struct remove_any_pointer<
sparta::SpartaSharedPointer<T> &> {
using type = T; };
585 struct remove_any_pointer<
sparta::SpartaSharedPointer<T> const &> {
using type = T; };
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
#define SPARTA_EXPECT_TRUE(x)
A macro for hinting to the compiler a particular condition should be considered most likely true.
Used for garbage collection, will delete the object it points to when all objects are finished using ...
SpartaSharedPointer(SpartaSharedPointer &&orig)
Take ownership of a reference pointer.
SpartaSharedPointer(PointerT *p=nullptr) noexcept
Construct a Reference Pointer with the given memory object.
PointerT & operator*() const
Dereference the RefPointer (const)
PointerT * operator->() const
Dereference the RefPointer (const)
SpartaSharedPointer(const SpartaSharedPointer< PointerT2 > &orig) noexcept
Construct a reference pointer given another implicitly convertable reference pointer.
bool operator!() const
The not ! operator.
SpartaSharedPointer & operator=(SpartaSharedPointer &&orig)
Assignment move operator.
~SpartaSharedPointer()
Detach this shared pointer; if last, delete underlying object.
PointerT element_type
Expected typedef for the resource type.
uint32_t use_count() const
Get the current reference count.
PointerT * get() const
Get the underlying pointer.
constexpr SpartaSharedPointer(std::nullptr_t) noexcept
Constructor for SpartaSharedPointer<T> ptr = nullptr;.
SpartaSharedPointer & operator=(const SpartaSharedPointer &orig)
Assignment operator.
SpartaSharedPointer(const SpartaSharedPointer &orig)
Construct a reference pointer given another reference pointer.
void reset(PointerT *p=nullptr)
Reset this shared pointer.
Like in STL, create a weak pointer to a SpartaSharedPointer.
SpartaWeakPointer & operator=(SpartaWeakPointer &&orig)
Move assign a SpartaWeakPointer from another.
SpartaSharedPointer< PointerT > lock() const noexcept
Lock and return a SpartaSharedPointer this SpartaWeakPointer points to.
constexpr SpartaWeakPointer() noexcept=default
Create an empty, expired weakpointer.
bool expired() const noexcept
Has the SpartaSharedPointer that this weak pointer points to expired?
SpartaWeakPointer(const SpartaWeakPointer &orig)
Create a copy of the SpartaWeakPointer.
~SpartaWeakPointer()
Destroy (and detach) from a SpartaSharedPointer.
long use_count() const noexcept
The use count of the SpartaSharedPointer. Will be 0 if none left.
SpartaWeakPointer & operator=(const SpartaWeakPointer &orig)
Assign a SpartaWeakPointer from another.
SpartaWeakPointer(SpartaWeakPointer &&orig)
Move a SpartaWeakPointer.
Macros for handling exponential backoff.
std::ostream & operator<<(std::ostream &o, const SimulationInfo &info)
ostream insertion operator for SimulationInfo