Added support for policy based explicit/implicit constructor

git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@131 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
rani_sharoni 2003-08-21 12:55:14 +00:00
parent 36a53ca896
commit 30b3c736af

View file

@ -73,11 +73,11 @@ namespace Loki
friend inline PointerType GetImpl(const DefaultSPStorage& sp) friend inline PointerType GetImpl(const DefaultSPStorage& sp)
{ return sp.pointee_; } { return sp.pointee_; }
friend inline const StoredType& GetImplRef(const DefaultSPStorage& sp) friend inline const StoredType& GetImplRef(const DefaultSPStorage& sp)
{ return sp.pointee_; } { return sp.pointee_; }
friend inline StoredType& GetImplRef(DefaultSPStorage& sp) friend inline StoredType& GetImplRef(DefaultSPStorage& sp)
{ return sp.pointee_; } { return sp.pointee_; }
protected: protected:
// Destroys the data stored // Destroys the data stored
@ -779,13 +779,30 @@ namespace Loki
SmartPtr, const SmartPtr>::Result SmartPtr, const SmartPtr>::Result
CopyArg; CopyArg;
private:
struct NeverMatched;
#ifdef LOKI_SMARTPTR_CONVERSION_CONSTRUCTOR_POLICY
typedef typename Select< CP::allow, const StoredType&, NeverMatched>::Result ImplicitArg;
typedef typename Select<!CP::allow, const StoredType&, NeverMatched>::Result ExplicitArg;
#else
typedef const StoredType& ImplicitArg;
typedef typename Select<false, const StoredType&, NeverMatched>::Result ExplicitArg;
#endif
public:
SmartPtr() SmartPtr()
{ KP::OnDefault(GetImpl(*this)); } { KP::OnDefault(GetImpl(*this)); }
SmartPtr(const StoredType& p) : SP(p) explicit
SmartPtr(ExplicitArg p) : SP(p)
{ KP::OnInit(GetImpl(*this)); } { KP::OnInit(GetImpl(*this)); }
SmartPtr(CopyArg& rhs) SmartPtr(ImplicitArg p) : SP(p)
{ KP::OnInit(GetImpl(*this)); }
SmartPtr(CopyArg& rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs) : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
{ GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); } { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
@ -797,9 +814,9 @@ namespace Loki
template <class> class KP1, template <class> class KP1,
template <class> class SP1 template <class> class SP1
> >
SmartPtr(const SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs) SmartPtr(const SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs) : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
{ GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); } { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
template template
< <
@ -809,23 +826,23 @@ namespace Loki
template <class> class KP1, template <class> class KP1,
template <class> class SP1 template <class> class SP1
> >
SmartPtr(SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs) SmartPtr(SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs) : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
{ GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); } { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
SmartPtr(ByRef<SmartPtr> rhs) SmartPtr(ByRef<SmartPtr> rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs) : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
{} {}
operator ByRef<SmartPtr>() operator ByRef<SmartPtr>()
{ return ByRef<SmartPtr>(*this); } { return ByRef<SmartPtr>(*this); }
SmartPtr& operator=(CopyArg& rhs) SmartPtr& operator=(CopyArg& rhs)
{ {
SmartPtr temp(rhs); SmartPtr temp(rhs);
temp.Swap(*this); temp.Swap(*this);
return *this; return *this;
} }
template template
< <
@ -835,12 +852,12 @@ namespace Loki
template <class> class KP1, template <class> class KP1,
template <class> class SP1 template <class> class SP1
> >
SmartPtr& operator=(const SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs) SmartPtr& operator=(const SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs)
{ {
SmartPtr temp(rhs); SmartPtr temp(rhs);
temp.Swap(*this); temp.Swap(*this);
return *this; return *this;
} }
template template
< <
@ -850,37 +867,37 @@ namespace Loki
template <class> class KP1, template <class> class KP1,
template <class> class SP1 template <class> class SP1
> >
SmartPtr& operator=(SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs) SmartPtr& operator=(SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs)
{ {
SmartPtr temp(rhs); SmartPtr temp(rhs);
temp.Swap(*this); temp.Swap(*this);
return *this; return *this;
} }
void Swap(SmartPtr& rhs) void Swap(SmartPtr& rhs)
{ {
OP::Swap(rhs); OP::Swap(rhs);
CP::Swap(rhs); CP::Swap(rhs);
KP::Swap(rhs); KP::Swap(rhs);
SP::Swap(rhs); SP::Swap(rhs);
} }
~SmartPtr() ~SmartPtr()
{ {
if (OP::Release(GetImpl(*static_cast<SP*>(this)))) if (OP::Release(GetImpl(*static_cast<SP*>(this))))
{ {
SP::Destroy(); SP::Destroy();
} }
} }
friend inline void Release(SmartPtr& sp, typename SP::StoredType& p) friend inline void Release(SmartPtr& sp, typename SP::StoredType& p)
{ {
p = GetImplRef(sp); p = GetImplRef(sp);
GetImplRef(sp) = SP::Default(); GetImplRef(sp) = SP::Default();
} }
friend inline void Reset(SmartPtr& sp, typename SP::StoredType p) friend inline void Reset(SmartPtr& sp, typename SP::StoredType p)
{ SmartPtr(p).Swap(sp); } { SmartPtr(p).Swap(sp); }
PointerType operator->() PointerType operator->()
{ {
@ -1231,6 +1248,14 @@ namespace std
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// December 09, 2001: Included <cassert> // December 09, 2001: Included <cassert>
// February 2, 2003: fixed dependent names - credit due to Rani Sharoni // February 2, 2003: fixed dependent names - credit due to Rani Sharoni
// August 21, 2003: Added support for policy based explicit/implicit constructor.
// The new code will be effective if a macro named
// *** LOKI_SMARTPTR_CONVERSION_CONSTRUCTOR_POLICY ***
// is defined (due to backward computability concerns).
// In case that the macro is defined and the conversion policy allow flag is off
// (e.g. DisallowConversion) then the conversion from the "pointer" to the
// SmartPtr must be explicit.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#endif // SMARTPTR_INC_ #endif // SMARTPTR_INC_