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:
parent
36a53ca896
commit
30b3c736af
1 changed files with 86 additions and 61 deletions
|
@ -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_
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue