/*
* $Header: /home/dscott/nasty/memory/autohndl.h,v 1.1 2001/11/06 21:48:50 dscott Exp $
* $NoKeywords: $
*/
#ifndef AUTOHANDLE_H_
#define AUTOHANDLE_H_ 1
template
struct handle_traits
{
static H null_value()
{ return 0; }
static void dispose(H) throw();
static H clone(const H& h);
};
// default auto_handle base class:
// copy ctor is disabled
template
class base_handle
{
public:
base_handle() {}
static void dispose(H h) throw()
{ T::dispose(h); }
static H copy(H h) throw()
{ return h; }
// place-holder
static void swap(base_handle&) throw()
{}
private:
base_handle(base_handle&);
base_handle& operator=(
base_handle&);
};
// helper for returning
// auto_handles by value
template
struct auto_handle_ref
{
explicit auto_handle_ref(H h)
: handle_(h)
{}
H handle_;
};
// auto_handle
template,
class B = base_handle >
class auto_handle : private B
{
public:
// 20.4.5.1 construct/copy/destroy
explicit auto_handle(
const H& h = T::null_value()) throw()
: handle_(h)
{}
auto_handle(auto_handle& that) throw()
: B(that),
handle_(B::copy(that.handle_))
{}
~auto_handle() throw()
{
B::dispose(handle_);
}
// 20.4.5.2 members
H get() const throw()
{ return handle_; }
// release ownership
H release() throw()
{
H h(handle_);
handle_ = T::null_value();
return h;
}
void reset(const H& handle) throw()
{
if (handle_ != handle)
{
T::dispose(handle_);
handle_ = handle;
}
}
// 20.4.5.3 conversions
// implicit ctor, clients may write
// auto_handle h = func()
// where func returns auto_handle by
// value
auto_handle(
const auto_handle_ref& r) throw()
: handle_(r.handle_)
{}
// other operators
auto_handle& operator=(
const auto_handle_ref& r)
{
auto_handle tmp(r);
swap(tmp);
return *this;
}
auto_handle& operator=(
auto_handle& rhs)
{
auto_handle tmp(rhs);
swap(tmp);
return *this;
}
operator auto_handle_ref()
{ return auto_handle_ref(release()); }
bool operator !() const
{ return handle_ == T::null_value(); }
void swap(auto_handle& that) throw()
{
B::swap(that);
std::swap(handle_, that.handle_);
}
private:
H handle_;
}; // auto_handle
template >
class cloner
{
public:
cloner() {}
cloner(const cloner&) {}
static void dispose(H h) throw()
{ T::dispose(h); }
static H copy(H h)
{ return T::clone(h); }
};
#endif // AUTOHANDLE_H_