|
//#include "ptr_engine0.h" //No class slicing protection
//Relies on comprehensive correct use of virtual destructors
//pointers 2 to 3 times larger
//#define XNR_VIRTUAL_DESTRUCTOR_WARNINGS
namespace xnr {
class _null_ptr;
namespace eng {
class _has_ref_counts
{
private:
public:
_DGNSTC_DECLARE_RC_COUNTER
protected:
class reference_controler;/*Forward Declaration*/
_has_ref_counts() : m_pRC(NULL) {}
class reference_controler
{
public:
#ifdef XNR_MEMORY_POOL
static xnr_memory_pool<reference_controler> stm_RefControlerPool;
_DGNSTC_MEMORY_POOL_MONITOR0
void *operator new(size_t size)
{return stm_RefControlerPool.give_new_slot();}
void operator delete (void *p)
{stm_RefControlerPool.take_back_slot(p);}
#endif
protected:
LONG m_WeakCount;
LONG m_StrongCount;
public:
reference_controler() : m_WeakCount(1), m_StrongCount(1){_DGNSTC_INC_RC_COUNT}
~reference_controler(){_DGNSTC_DEC_RC_COUNT}
inline void AddWeakRef() {m_WeakCount++;}
bool ReleaseWeak()
{
if(0==--m_WeakCount)
{
delete this;
return true;
}
else
return false;
}
void AddStrongRef()
{
if(m_StrongCount<0)
m_StrongCount--;
else
m_StrongCount++;
}
inline bool IsValidObject() {return (m_StrongCount!=0); }
bool ReleaseStrong()//Decrements strong count
{ //returns true if object must be deleted
if(m_StrongCount<0)
{
if(0==++m_StrongCount)
xnr_fatal_error("Deletion while used by Fast Pointer");
return false;
}
if(0==--m_StrongCount)
{
return true;
}
else
return false;
}
bool ResetStrong() //Resets strong count
{ //returns true if object must be deleted
if(m_StrongCount<0)
#ifdef FOR_RELEASE
m_StrongCount=-1;
#else
xnr_fatal_error("Deletion while used by Fast Pointer");
#endif
else
{
m_StrongCount=0;
return true;
}
return false;
}
void QuietResetStrong() //Resets strong count
{ //Does not indicate deletion of object
if(m_StrongCount<0)
xnr_fatal_error("Deletion while used by Fast Pointer");
m_StrongCount=0;
}
reference_controler* CloneAndReset()
{
if(m_StrongCount<0)
#ifdef FOR_RELEASE
m_StrongCount=-1;
#else
xnr_fatal_error("Deletion while used by Fast Pointer");
#endif
return new reference_controler;
}
bool FastPtrLock()
{
if(m_StrongCount>0)
{
m_StrongCount=-m_StrongCount;
#ifdef FOR_RELEASE
m_StrongCount--;
#endif
return true;
}
else
return false;
}
void FastPtrUnlock()
{
if(m_StrongCount<0)
{
m_StrongCount=-m_StrongCount;
#ifdef FOR_RELEASE
m_StrongCount--;
#endif
}
}
};
template <class U> reference_controler* _assure_reference_controler(U* pT) const
{
if(NULL==m_pRC)
m_pRC=new reference_controler;
return m_pRC;
}
void _quiet_hard_reset()
{
if(m_pRC!=NULL)
{
m_pRC->QuietResetStrong();
//ReleaseWeak() deletes reference controller when weak_count==0
m_pRC->ReleaseWeak();
m_pRC=NULL;
}
}
mutable reference_controler* m_pRC;
};
template <class U> class _ptr;
template <class T> class _ptr : protected _has_ref_counts
{
friend class _has_ref_counts;
template <class U> friend class _value_with_counts;
template <class U> friend class _ptr;
private:
mutable T* m_pT;
protected:
_ptr() : m_pT(NULL) {}
inline T* get_unchecked_pointer()const {return (T*)(this->m_pT);}
inline void _throw_if_invalid() const
{
if(false==_is_valid())
xnr_exception_error("NULL reference");
}
inline void _just_throw() const
{
xnr_exception_error("NULL reference");
}
inline void _throw_if_null() const
{
if(NULL==this->m_pT)
xnr_exception_error("NULL _owner_ptr");
}
void _reset()
{
if(m_pRC!=NULL)
{
if(m_pRC->ReleaseStrong())
delete m_pT;//deletes object when strong_count==0
m_pRC->ReleaseWeak();//deletes reference controller when weak_count==0
m_pRC=NULL;
}
else if(this->m_pT)
delete this->m_pT;//no reference controler - just delete the object
this->m_pT=NULL;
}
void _quiet_reset()
{
if(m_pRC!=NULL)
{
m_pRC->ReleaseStrong();
//No delete
m_pRC->ReleaseWeak();//deletes reference controller when weak_count==0
m_pRC=NULL;
}
//No delete
this->m_pT=NULL;
}
void _hard_reset()
{
if(m_pRC!=NULL)
{
if(m_pRC->ResetStrong())
delete m_pT;
m_pRC->ReleaseWeak();//deletes reference controller when weak_count==0
m_pRC=NULL;
}
else if(this->m_pT)
delete this->m_pT;//no reference controler - just delete the object
this->m_pT=NULL;
}
void _quiet_hard_reset()
{
_has_ref_counts::_quiet_hard_reset();
this->m_pT=NULL;
}
void _release()const
{
if(m_pRC!=NULL)
{
m_pRC->ReleaseWeak();//deletes reference controller when weak_count==0
m_pRC=NULL;//and forget it
}
this->m_pT=NULL;
}
template <class U> void _point_to_ref(_ptr<U> const& r)
{
if(r._is_valid())
{
this->m_pT=r.m_pT;
m_pRC=r.m_pRC;
m_pRC->AddWeakRef();
}
}
template <class U> void _point_to_owner(_ptr<U> const& apT)
{
if(apT._is_valid())
{
this->m_pT=apT.m_pT;
m_pRC=apT._assure_reference_controler<U>(apT.m_pT);
m_pRC->AddWeakRef();
}
}
template <class U> void _point_to_p(U* const& p)
{
this->m_pT=p;
m_pRC=NULL;
}
bool _fast_ptr_lock()
{
return m_pRC->FastPtrLock();
}
void _fast_ptr_unlock()
{
if(m_pRC)
return m_pRC->FastPtrUnlock();
}
void _assign_from_raw(T*const pT)
{
this->m_pT=pT;
}
template <class U> void _assign_from_raw(U*const pU)
{
this->m_pT=pU; //_assure_reference_controler<U>(pU);
#ifdef XNR_VIRTUAL_DESTRUCTOR_WARNINGS
struct{};
//*** WARNING Base class owner; virtual destructor required **** //
//*********** See Output window for classes affected ************//
#endif
}
void _adopt(_ptr<T> const& ope)
{
if(ope._is_valid())
{
this->m_pT = ope.m_pT;
m_pRC = ope.m_pRC;
ope.m_pRC = NULL;
ope.m_pT = NULL;
}
}
template <class U> void _adopt(_ptr<U> const& ope)
{
if(ope._is_valid())
{
this->m_pT = ope.m_pT;
m_pRC =ope._assure_reference_controler<U>(ope.m_pT);//ope.m_pRC;
ope.m_pRC = NULL;
ope.m_pT = NULL;
}
#ifdef XNR_VIRTUAL_DESTRUCTOR_WARNINGS
struct{};
//*** WARNING Base class owner; virtual destructor required **** //
//*********** See Output window for classes affected ************//
#endif
}
void _steal(_ptr<T>const& apT)
{
if(apT._is_valid())
{
this->m_pT = apT.m_pT;
if(apT.m_pRC)
{
m_pRC = apT.m_pRC->CloneAndReset();
apT.m_pRC->ReleaseWeak();
apT.m_pRC=NULL;
}
apT.m_pT = NULL;
}
}
template <class U> void _steal(_ptr<U>const& apT)
{
if(apT._is_valid())
{
this->m_pT = apT.m_pT;
if(apT.m_pRC)
{
m_pRC = apT.m_pRC.CloneAndReset();
apT.m_pRC.ReleaseWeak();
apT.m_pRC=NULL;
}
else
_assure_reference_controler<U>(apT.m_pT);
apT.m_pT = NULL;
}
}
template <class U> void _share(_ptr<U> const& spT)
{
if(spT._is_valid())
{
this->m_pT=spT.m_pT;
m_pRC=spT._assure_reference_controler<U>(spT.m_pT);
m_pRC->AddWeakRef();
m_pRC->AddStrongRef();
}
}
#ifdef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
void _hold_boost_shared_ptr(boost::shared_ptr<T>const& sh)
{
m_pRC=(reference_controler*)new boost::shared_ptr<T>(sh);
m_pT=sh.get();
}
void _hold_boost_weak_ptr(boost::weak_ptr<T>const& wp)
{
m_pRC=(reference_controler*)new boost::shared_ptr<T>(wp);
m_pT=((boost::shared_ptr<T>*)m_pRC)->get();
}
void _release_boost_ptr()
{
delete (boost::shared_ptr<T>*)m_pRC;
}
#endif
public:
bool _is_valid() const
{
if(
(m_pRC!= NULL && m_pRC->IsValidObject())
||
(NULL==m_pRC && this->m_pT!=0)
)
return true;
else
_release();
return false;
}
template <class U> void _downcast_from(_ptr<U> const& apT)
{
if(apT._is_valid())
{
this->m_pT=static_cast<T*>(apT.m_pT);
m_pRC=apT._assure_reference_controler<U>(apT.m_pT);
if(m_pRC)
m_pRC->AddWeakRef();
}
}
T* get_pointer() const {if(_is_valid()) return this->m_pT; return NULL;}
//================================================================1=========//
// Public operations and prohibtions common to all pointers
//==============================================================================//
public: \
bool operator!=(_null_ptr& wpT)const {return get_pointer()!=NULL;}\
bool operator==(_null_ptr& wpT)const {return NULL==get_pointer();}\
template<class U> bool operator==(_ptr<U>const& wpT)const {return get_pointer()==static_cast<T*>(wpT.get_pointer());}\
template<class U> bool operator!=(_ptr<U>const& wpT)const {return get_pointer()!=static_cast<T*>(wpT.get_pointer());}\
operator bool() const { return _is_valid();}\
private:\
void* operator new(unsigned int s) {return NULL;}\
operator void*() const {return NULL;}\
const T** operator&() {return &(this->m_pT);}
};
template <class T> class _value_with_counts : protected _has_ref_counts
{
protected:
_value_with_counts(){}
~_value_with_counts(){_quiet_hard_reset();}
public:
void _set_ptr_to_value_with_counts(_ptr<T>& r, T* pT)
{
r.m_pRC=_has_ref_counts::_assure_reference_controler(pT);
m_pRC->AddWeakRef();
r.m_pT=pT;
}
};
#ifdef _DGNSTC
int ptr_engine_diagnostic();
#endif
}//namespace eng
template <class T> class vtor : public T
{
public:
virtual ~vtor()
{
}
};
}//namespace xnr
#define XNR_MEMORY_POOL_INSTANCE xnr_memory_pool<eng::_has_ref_counts::reference_controler> eng::_has_ref_counts::reference_controler::stm_RefControlerPool(100);
#define xnr_virtual virtual
#define PTR_ENGINE_DEFINED
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Software Author with engineering, science and mathematical background.
Many years using C++ to develop responsive visualisations of fine grained dynamic information largely in the fields of public transport and supply logistics. Currently interested in what can be done to make the use of C++ cleaner, safer, and more comfortable.