/*
* Copyright (C) 2003 Momchil Velikov
*
* See file COPYING for license.
*/
#ifndef nonstd__smart_ptr_h
#define nonstd__smart_ptr_h 1
#include
namespace nonstd
{
/* Storage policies */
template
class default_storage_policy
{
public:
typedef T *stored_type;
typedef T *pointer_type;
typedef T &reference_type;
default_storage_policy ()
: ptr_ (0)
{}
default_storage_policy (const stored_type &p)
: ptr_ (p)
{}
default_storage_policy (const default_storage_policy &)
{}
template
default_storage_policy (const default_storage_policy &)
{}
pointer_type
get_ptr () const
{
return ptr_;
}
reference_type
get_ref () const
{
return *ptr_;
}
stored_type &
get_impl_ref ()
{
return ptr_;
}
const stored_type &
get_impl_ref () const
{
return ptr_;
}
void
destroy ()
{
delete ptr_;
}
void
swap (default_storage_policy &sp)
{
std::swap (ptr_, sp.ptr_);
}
private:
stored_type ptr_;
};
/* Ownership policies. */
/* Non-intrusive reference count. */
template
class ref_count
{
public:
ref_count () : count_ (new unsigned int (1)) {}
template friend class ref_count;
template
ref_count (const ref_count &rc)
: count_ (rc.count_)
{}
Ptr
duplicate (const Ptr &ptr)
{
++*count_;
return ptr;
}
bool
release (const Ptr &)
{
if (--*count_)
return false;
delete count_;
return true;
}
void
swap (ref_count &rc)
{
std::swap (count_, rc.count_);
}
private:
unsigned int *count_;
};
/* Intrusive reference count. */
template
class intrusive_ref_count
{
public:
intrusive_ref_count () {}
template
intrusive_ref_count (const intrusive_ref_count &)
{}
static Ptr
duplicate (const Ptr &ptr)
{
return ptr->duplicate ();
}
static bool
release (const Ptr &ptr)
{
if (ptr)
return ptr->release ();
else
return false;
}
static void
swap (intrusive_ref_count &)
{}
};
template class StoragePolicy = default_storage_policy,
template class OwnershipPolicy = ref_count>
class smart_ptr
: public StoragePolicy,
public OwnershipPolicy::pointer_type>
{
protected:
typedef StoragePolicy SP;
typedef OwnershipPolicy OP;
public:
smart_ptr () {}
smart_ptr (const typename SP::stored_type &p)
: SP (p)
{}
smart_ptr (const smart_ptr &sp)
: SP (sp), OP (sp)
{
SP::get_impl_ref () = OP::duplicate (sp.get_impl_ref ());
}
template class SP1,
template class OP1>
smart_ptr (const smart_ptr &sp)
: SP (sp), OP (sp)
{
SP::get_impl_ref () = duplicate (sp.get_impl_ref ());
}
~smart_ptr ()
{
if (OP::release (SP::get_impl_ref ()))
SP::destroy ();
}
smart_ptr &
operator= (const smart_ptr &sp)
{
smart_ptr tmp (sp);
tmp.swap (*this);
return *this;
}
template class SP1,
template class OP1>
smart_ptr &
operator= (const smart_ptr &sp)
{
smart_ptr tmp (sp);
tmp.swap (*this);
return *this;
}
typename SP::pointer_type
operator-> () const
{
return SP::get_ptr ();
}
typename SP::reference_type
operator* () const
{
return SP::get_ref ();
}
protected:
void
swap (smart_ptr &sp)
{
SP::swap (sp);
OP::swap (sp);
}
};
}
#endif /* nonstd__smart_ptr_h */
/*
* Local variables:
* mode: C++
* indent-tabs-mode: nil
* arch-tag: 92d98e78-dd24-45d8-a1a5-d3310b85faf0
* End:
*/
               (
geocities.com/siliconvalley/pines)                   (
geocities.com/siliconvalley)