wxMaxima
|
A weak non-owning pointer that becomes null whenever the observed object is destroyed. More...
#include <CellPtr.h>
Public Types | |
using | value_type = T |
using | pointer = T * |
using | const_pointer = const T * |
using | reference = T & |
Public Member Functions | |
pointer | get () const noexcept |
reference | operator* () const noexcept |
pointer | operator-> () const noexcept |
operator pointer () const noexcept | |
template<typename PtrT , typename std::enable_if< std::is_pointer< PtrT >::value, bool >::type = true> | |
PtrT | CastAs () const noexcept |
CellPtr (int)=delete | |
CellPtr (void *)=delete | |
void | reset () noexcept |
CellPtr (decltype(nullptr)) noexcept | |
CellPtr & | operator= (decltype(nullptr)) noexcept |
bool | operator== (decltype(nullptr)) const noexcept |
bool | operator!= (decltype(nullptr)) const noexcept |
template<typename U , typename std::enable_if< is_pointer< U >(), bool >::type = true> | |
CellPtr (U obj) noexcept | |
template<typename U , typename std::enable_if< is_pointer< U >(), bool >::type = true> | |
CellPtr & | operator= (U obj) noexcept |
template<typename U , typename std::enable_if< is_pointer< U >(), bool >::type = true> | |
void | reset (U obj) noexcept |
CellPtr (CellPtr &o) noexcept | |
CellPtr (CellPtr &&o) noexcept | |
CellPtr & | operator= (const CellPtr &o) noexcept |
CellPtr & | operator= (CellPtr &&o) noexcept |
template<typename U , typename std::enable_if< std::is_convertible< typename std::add_pointer< U >::type, pointer >::value, bool >::type = true> | |
CellPtr (CellPtr< U > &&o) noexcept | |
template<typename U , typename std::enable_if< std::is_convertible< typename std::add_pointer< U >::type, pointer >::value, bool >::type = true> | |
CellPtr (const CellPtr< U > &o) noexcept | |
template<typename U , typename std::enable_if< std::is_convertible< typename std::add_pointer< U >::type, pointer >::value, bool >::type = true> | |
CellPtr & | operator= (CellPtr< U > &&o) noexcept |
template<typename U , typename std::enable_if< std::is_convertible< typename std::add_pointer< U >::type, pointer >::value, bool >::type = true> | |
CellPtr & | operator= (const CellPtr< U > &o) noexcept |
template<typename U , typename Del > | |
CellPtr (std::unique_ptr< U, Del > &&)=delete | |
template<typename U , typename Del , typename std::enable_if< std::is_convertible< typename std::add_pointer< U >::type, pointer >::value, bool >::type = true> | |
CellPtr (const std::unique_ptr< U, Del > &ptr) noexcept | |
template<typename U , typename Del > | |
CellPtr & | operator= (std::unique_ptr< U, Del > &&)=delete |
template<typename U , typename Del , typename std::enable_if< std::is_convertible< typename std::add_pointer< U >::type, pointer >::value, bool >::type = true> | |
CellPtr & | operator= (const std::unique_ptr< U, Del > &o) noexcept |
operator bool () const noexcept | |
auto | cmpPointers (const CellPtrBase &o) const noexcept |
This is exactly like the spaceship operator in C++20. | |
auto | cmpObjects (const CellPtrBase &o) const noexcept |
This is the spaceship operator acting on pointed-to objects. | |
auto | cmpObjects (const Observed *o) const noexcept |
This is the spaceship operator acting on pointed-to objects. | |
bool | IsNull () const |
bool | HasOneObserved () const |
bool | HasControlBlock () const |
Static Public Member Functions | |
static size_t | GetLiveInstanceCount () noexcept |
Protected Member Functions | |
Observed * | base_get () const noexcept |
void | base_reset (Observed *obj=nullptr) noexcept |
A weak non-owning pointer that becomes null whenever the observed object is destroyed.
The use of this pointer type has performance implications. It is not a "free" abstraction!
Warning: To maintain performance, most cells should have at most one CellPtr pointing at them. Currently, this is the m_nextToDraw - it uses up our "CellPtr budget". The remaining CellPtrs are in CellPointers, and there is very few cells at any given time that are pointed-to by those pointers, and thus the performance impact is minimal.
In the common case of being null, or of being the only CellPtr to a given cell, the performance is similar to a raw pointer: it stores the cell pointer directly. The pointed-to cell points back to this sole pointer, so that it can reset it to null when it gets destroyed. A CellPtr is exactly the size of an Observed *
.
When the second CellPtr is made to point to a cell, a shared control block is allocated on behalf of the cell, and both the CellPtr and the cell point to it. The control block is greedily dereferenced whenever the CellPtr notices that the cell it pointed to has vanished. But, once a cell has a ControlBlock, it doesn't get rid of it until no pointers point to it. So, if there are two+ pointers pointing to a cell, then only one is left, there still is a control block, and the pointers still "pointer chase" through that control block. Getting rid of the control block in this case is a low-priority TODO at the moment, since there's no performance impact seen from this.
The observed type must be derived from Observed, and this fact is checked at the point of instantiation. The pointer's instance can be declared with forward-defined classes.
|
protectednoexceptinherited |
Different objects must have control blocks that are either null or non-null but different.