Listing 1: The full auto_handle implementation

 
// A template class for returning 
// auto_handles by value
template<class H> 
struct auto_handle_ref
{
    explicit auto_handle_ref(H h) 
        : handle_(h) {}    
    H handle_;
};


// auto_handle
template<class H, 
    class T = handle_traits<H>,
    class B = base_handle<H, T> > 
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<some_class> h = func()
    // where func returns auto_handle by
    // value
    auto_handle(
        const auto_handle_ref<H>& r) throw()
        : handle_(r.handle_) 
    {}
    operator auto_handle_ref<H>() 
    { return auto_handle_ref<H>(release()); }

    // other operators
    auto_handle& operator=(
        const auto_handle_ref<H>& r) 
    {
        auto_handle tmp(r);
        
        std::swap(handle_, tmp.handle_);
        return *this;
    }

    auto_handle& operator=(
        auto_handle& rhs)
    {
        auto_handle tmp(rhs);

        std::swap(handle_, tmp.handle_);
        return *this;
    }
    
    bool operator !() const
    { return handle_ == T::null_value(); }

private:
    H handle_;
};
— End of Listing —