227 lines
6.2 KiB
Objective-C
Executable File
227 lines
6.2 KiB
Objective-C
Executable File
/**
|
|
**
|
|
** @RDE_HEADER@
|
|
** Base class for reference counted objects
|
|
** $Id$
|
|
** $HeadURL$
|
|
** $Author$
|
|
**
|
|
** -----------------------------------------------------------------------------------------------
|
|
**
|
|
** Hardware-Umgebung: Intel-PC
|
|
** Software-Umgebung: Linux, Windows 7, Qt 5.4. ArcGIS 10.2.5
|
|
**
|
|
** Pgrm-Sprache ....: C++ 11
|
|
**
|
|
** HIER/SACHN ......: P: -- ---- - --- QE
|
|
**
|
|
** Version .........: $Revision$
|
|
** -----------------------------------------------------------------------------------------------
|
|
**
|
|
** Autor ...........: Nikolaus Hanekamp, SEDG, Tel. 2906
|
|
**
|
|
** -----------------------------------------------------------------------------------------------
|
|
**
|
|
** Notizen .........:
|
|
**
|
|
** 18.08.2004, NH : Urversion
|
|
** 13.05.2015, JT : Refactoring for use with Qt5, ArcGIS 10.2.5
|
|
** adding methodes according to std::share_ptr like reset
|
|
**
|
|
** -----------------------------------------------------------------------------------------------
|
|
**
|
|
** Copyright (C) 2004 Rheinmetall Defence Electronics GmbH, D-28309 BREMEN
|
|
**
|
|
** -----------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "referenced.h"
|
|
|
|
|
|
namespace SituationMap
|
|
{
|
|
|
|
/**
|
|
@class RefPointer ref_pointer.h
|
|
@brief Smart pointer for handling referenced counted objects
|
|
|
|
Simple class template to implement reference counted pointers or smart pointers. The RefPointer class controls the
|
|
reference counter of the object \c T the pointer points to. The class \c T have to be derived from class \c Referenced,
|
|
where the reference counter member variable is located. In case of this reference counter gets zero delete will be called
|
|
automatically.
|
|
|
|
@see Referenced
|
|
|
|
*/
|
|
template<class T> class RefPointer
|
|
{
|
|
|
|
public:
|
|
|
|
using ElementType = T;
|
|
|
|
/**
|
|
@name Construction and Destruction
|
|
@{
|
|
*/
|
|
RefPointer() : RefPointer(nullptr) {}
|
|
RefPointer(const RefPointer &rp) : RefPointer(rp._ptr) {}
|
|
|
|
explicit RefPointer(ElementType *t)
|
|
: _ptr(t)
|
|
{
|
|
static_assert(std::is_base_of<Referenced, T>::value
|
|
, "Class of template SituationMap::RefPointer have to be derived from class SituationMap::Referenced");
|
|
|
|
if (_ptr) _ptr->ref();
|
|
} /* RefPointer */
|
|
|
|
~RefPointer()
|
|
{
|
|
if (_ptr) _ptr->unref();
|
|
_ptr = nullptr;
|
|
} /* ~RefPointer */
|
|
|
|
/** @} */
|
|
|
|
/**
|
|
Checks if pointer is valid.
|
|
*/
|
|
explicit inline operator bool() const { return (_ptr != nullptr); }
|
|
|
|
/**
|
|
@name Casting
|
|
@{
|
|
*/
|
|
/**
|
|
To create reference pointer from a derived class directly this contructor template can be used.
|
|
How to use it is shown in the following example:
|
|
|
|
\code
|
|
|
|
RefPointer<AbstractMapObject> objPtr = getAbstractMapObject();
|
|
|
|
RefPointer<Participant> participantObj( objPtr );
|
|
if (participantObj != NULL)
|
|
{
|
|
...
|
|
}
|
|
|
|
\endcode
|
|
|
|
Alternatively it is posible to create \b participantObj from example above as follows:
|
|
|
|
\code
|
|
|
|
RefPointer<Participant> participantObj = RefPointer<Participant>(dynamic_cast<Participant*>(objPtr.get()));
|
|
|
|
\endcode
|
|
*/
|
|
|
|
template<class Y> explicit RefPointer(RefPointer<Y> assignPtr)
|
|
{
|
|
_ptr = dynamic_cast<T *>(assignPtr.get());
|
|
if (_ptr) _ptr->ref();
|
|
}
|
|
|
|
|
|
template<class Y> explicit RefPointer(Y *assignPtr)
|
|
{
|
|
_ptr = dynamic_cast<T *>(assignPtr);
|
|
if (_ptr) _ptr->ref();
|
|
}
|
|
|
|
/** @} */
|
|
|
|
|
|
inline RefPointer &operator = (const RefPointer &rp)
|
|
{
|
|
if (_ptr == rp._ptr) return *this;
|
|
T *tmp_ptr = _ptr;
|
|
_ptr = rp._ptr;
|
|
if (_ptr) _ptr->ref();
|
|
// unref second to prevent any deletion of any object which might
|
|
// be referenced by the other object. i.e rp is child of the
|
|
// original _ptr.
|
|
if (tmp_ptr) tmp_ptr->unref();
|
|
return *this;
|
|
}
|
|
|
|
inline RefPointer &operator = (ElementType *ptr)
|
|
{
|
|
if (_ptr == ptr) return *this;
|
|
T *tmp_ptr = _ptr;
|
|
_ptr = ptr;
|
|
if (_ptr) _ptr->ref();
|
|
// unref second to prevent any deletion of any object which might
|
|
// be referenced by the other object. i.e rp is child of the
|
|
// original _ptr.
|
|
if (tmp_ptr) tmp_ptr->unref();
|
|
return *this;
|
|
}
|
|
|
|
inline void reset() { *this = nullptr; }
|
|
inline void reset(T *ptr) { *this = ptr; }
|
|
|
|
/**
|
|
@name Comparison Operators
|
|
Compares the pointer element \c _ptr with other pointers.
|
|
@{
|
|
*/
|
|
inline bool operator == (const RefPointer &rp) const { return (_ptr == rp._ptr); }
|
|
inline bool operator != (const RefPointer &rp) const { return (_ptr != rp._ptr); }
|
|
inline bool operator < (const RefPointer &rp) const { return (_ptr < rp._ptr); }
|
|
inline bool operator > (const RefPointer &rp) const { return (_ptr > rp._ptr); }
|
|
|
|
inline bool operator == (const ElementType *ptr) const { return (_ptr == ptr); }
|
|
inline bool operator != (const ElementType *ptr) const { return (_ptr != ptr); }
|
|
inline bool operator < (const ElementType *ptr) const { return (_ptr < ptr); }
|
|
inline bool operator > (const ElementType *ptr) const { return (_ptr > ptr); }
|
|
/** @} */
|
|
|
|
/**
|
|
@name Access Operators
|
|
Get access to the pointer or the object it points to.
|
|
@{
|
|
*/
|
|
inline ElementType &operator*() { return *_ptr; }
|
|
inline const ElementType &operator*() const { return *_ptr; }
|
|
|
|
inline ElementType *operator->() { return _ptr; }
|
|
inline const ElementType *operator->() const { return _ptr; }
|
|
|
|
inline ElementType *get() { return _ptr; }
|
|
inline const ElementType *get() const { return _ptr; }
|
|
/** @} */
|
|
|
|
/**
|
|
@name Checks if the pointer is valid.
|
|
@{
|
|
*/
|
|
inline bool valid() const { return _ptr != nullptr; }
|
|
inline bool operator!() const { return _ptr == nullptr; }
|
|
/** @} */
|
|
|
|
/**
|
|
* @name Control Over Object Pointer
|
|
* Take control over the object pointed to by RefPointer, unreference but do not delete even if ref count goes to 0,
|
|
* return the pointer to the object.
|
|
* Note, do not use this unless you are 100% sure your code handles the deletion of the object correctly, and
|
|
* only use when absolutely required.
|
|
@{
|
|
*/
|
|
inline ElementType *take() { return release();}
|
|
inline ElementType *release() { T *tmp = _ptr; if (_ptr) _ptr->unref_nodelete(); _ptr = nullptr; return tmp;}
|
|
/** @} */
|
|
|
|
private:
|
|
|
|
ElementType *_ptr;
|
|
};
|
|
|
|
} // SituationMap
|
|
|
|
|