template<typename T, typename HANDLER>
class maxon::BaseRef< T, HANDLER >
This is a general template for references of any kind. The characteristic feature of it is that special actions are triggered whenever the reference is set, cleared, changed or destructed. For example, a reference to a reference-counted object has to increase the reference count of the pointee when the pointer is set, and to decrease the count when the reference is cleared. Another example of reference is a unique reference which simply frees the pointee when it is cleared or destructed.
BaseRef delegates the specific behaviour to static members of the template parameter HANDLER. There are several implementations available to be used as HANDLER:
- StrongRefHandler is used for objects which have a reference counter (used by StrongRef).
- StrongCOWRefHandler has an additional copy-on-write semantics. I.e., if the pointee is referenced more than once, a copy is made before the pointee is modified through the BaseRef (used by StrongCOWRef).
- UniqueRefHandler uses DeleteObj to release the memory, so the object's destructor is invoked (used by UniqueRef).
- PointerHandler lets the BaseRef behave like an ordinary C++ pointer, so nothing is done when the pointer is changed (used by Pointer).
So if you want to have a reference to an object of type MyType with reference counting and copy-on-write semantics, you could use BaseRef<const MyType, StrongCOWRefHandler> which is equivalent to StrongCOWRef<MyType>.
- Template Parameters
-
T | Type of the referenced object. |
HANDLER | Base class for BaseRef. This implements the specific behaviour whenever a reference is changed to point to another object, see above. |
- Note
- BaseRef is neither atomic nor thread-safe..
- After a BaseRef is guaranteed not to change anymore multiple threads can safely read from it concurrently.
- Reading and writing on the same BaseRef from different threads will crash (the reference to an object might have been released by a writing thread before a reading thread was able to add a reference).
- Writing to the same BaseRef from different threads will also crash because this implies a read operation (a write has to read the old value to release the reference to the previous object).
- If you really have to read and write from multiple threads you could use the ThreadSafeRef class.
|
T * | GetPointer () |
|
ConstReferencedType * | GetPointer () const |
|
T * | operator-> () |
|
ConstReferencedType * | operator-> () const |
|
std::conditional< std::is_void< T >::value, DeleteReturnType01, T >::type & | operator* () |
|
std::conditional< std::is_void< ConstReferencedType >::value, DeleteReturnType01, T >::type & | operator* () const |
|
| operator T* () |
|
| operator ConstReferencedType * () const |
|
| operator Bool () const |
|
| operator Bool () |
|
const std::conditional< std::is_void< T >::value, DeleteReturnType01, T >::type & | operator[] (Int) const =delete |
|
ResultRef< typename std::remove_const< T >::type > | MakeWritable (Bool resetOnError=true) |
|
std::conditional< std::is_void< T >::value, DeleteReturnType01, T >::type & | GetOrNull () const |
|
| BaseRef () |
|
MAXON_IMPLICIT | BaseRef (std::nullptr_t)=delete |
|
MAXON_IMPLICIT | BaseRef (T *o) |
|
template<typename PTR > |
| BaseRef (ForwardResultPtr< PTR > o) |
|
| BaseRef (ResultPtr< T > o, Int) |
|
| BaseRef (const BaseRef &src) |
|
template<typename REF , typename = typename std::enable_if<!STD_IS_REPLACEMENT(base_of, BaseRef, REF) && maxon::HasErasedBase<typename REF::ReferencedType, ReferencedType>::value>::type> |
MAXON_IMPLICIT | BaseRef (const REF &src) |
|
template<typename REF , typename = typename std::enable_if<!STD_IS_REPLACEMENT(base_of, BaseRef, REF) && maxon::HasErasedBase<typename REF::ReferencedType, ReferencedType>::value>::type> |
MAXON_IMPLICIT | BaseRef (REF &src) |
|
BaseRef & | operator= (T *src) |
|
BaseRef & | operator= (std::nullptr_t src) |
|
BaseRef & | operator= (const BaseRef &src) |
|
template<typename REF , typename = typename std::enable_if<!STD_IS_REPLACEMENT(base_of, BaseRef, REF) && maxon::HasErasedBase<typename REF::ReferencedType, ReferencedType>::value>::type> |
BaseRef & | operator= (const REF &src) |
|
template<typename REF , typename = typename std::enable_if<!STD_IS_REPLACEMENT(base_of, BaseRef, REF) && maxon::HasErasedBase<typename REF::ReferencedType, ReferencedType>::value>::type> |
BaseRef & | operator= (REF &src) |
|
| BaseRef (BaseRef &&src) |
|
template<typename REF , typename = typename std::enable_if<!STD_IS_REPLACEMENT(const, REF) && !STD_IS_REPLACEMENT(base_of, BaseRef, REF) && maxon::HasErasedBase<typename REF::ReferencedType, ReferencedType>::value>::type> |
MAXON_IMPLICIT | BaseRef (REF &&src) |
|
BaseRef & | operator= (BaseRef &&src) |
|
template<typename REF , typename = typename std::enable_if<!STD_IS_REPLACEMENT(const, REF) && !STD_IS_REPLACEMENT(base_of, BaseRef, REF) && maxon::HasErasedBase<typename REF::ReferencedType, ReferencedType>::value>::type> |
BaseRef & | operator= (REF &&src) |
|
| ~BaseRef () |
|
Bool | operator== (const BaseRef &b) const |
|
Bool | operator!= (const BaseRef &b) const |
|
Bool | operator< (const BaseRef &b) const |
|
| MAXON_OPERATOR_INEQUALITY (BaseRef) |
|
Bool | operator== (const T *b) const |
|
Bool | operator!= (const T *b) const |
|
Bool | operator== (typename std::remove_const< T >::type *b) const |
|
Bool | operator!= (typename std::remove_const< T >::type *b) const |
|
Bool | operator== (std::nullptr_t) const |
|
Bool | operator!= (std::nullptr_t) const |
|
HashInt | GetHashCode () const |
|
UniqueHash | GetUniqueHashCode () const |
|
T * | Disconnect () |
|
void | PrivateSetTarget (ResultPtr< T > src) |
|
void | PrivateSetPointer (T *ptr) |
|
Sets the internal pointer to nullptr and returns its previous value. This moves the ownership of the object from this BaseRef to the invoking code, so you have to take care of proper deallocation once the object isn't needed any longer.
If this BaseRef is a strong reference, the reference count must be exactly 1 before the call, otherwise a nullptr will be returned.
- Returns
- The pointer to the previously referenced object.