Logo Search packages:      
Sourcecode: videolink version File versions  Download package

auto_handle.hpp

// Copyright 2005 Ben Hutchings <ben@decadent.org.uk>.
// See the file "COPYING" for licence details.

#ifndef INC_AUTO_HANDLE_HPP
#define INC_AUTO_HANDLE_HPP

// Like auto_ptr, but for arbitrary "handle" types.
// The parameters are:
// - handle_type: the type of the raw handle to be wrapped
// - closer_type: a function object type whose operator() takes a raw handle
//                and closes it (or does nothing if it is a null handle)
// - factory_type: a function object type whose operator() returns a null
//                 handle

template<typename handle_type, typename closer_type, typename factory_type>
class auto_handle_ref;

template<typename handle_type, typename closer_type, typename factory_type>
class auto_handle
    // Use inheritance so we can benefit from the empty base optimisation
    : private closer_type, private factory_type
{
    typedef auto_handle_ref<handle_type, closer_type, factory_type> ref_type;
public:
    auto_handle()
          : handle_(factory_type::operator()())
      {}
    explicit auto_handle(handle_type handle)
          : handle_(handle)
      {}
    auto_handle(auto_handle & other)
          : handle_(other.release())
      {}
    auto_handle(ref_type other)
          : handle_(other.release())
      {}
    auto_handle & operator=(auto_handle & other)
      {
          reset(other.release());
      }
    ~auto_handle()
      {
          reset();
      }
    handle_type get() const
      {
          return handle_;
      }
    handle_type release()
      {
          handle_type handle(handle_);
          handle_ = factory_type::operator()();
          return handle;
      }
    void reset()
      {
          closer_type::operator()(handle_);
          handle_ = factory_type::operator()();
      }
    void reset(handle_type handle)
      {
          closer_type::operator()(handle_);
          handle_ = handle;
      }
    operator ref_type()
      {
          return ref_type(*this);
      }
private:
    handle_type handle_;
};

template<typename handle_type, typename closer_type, typename factory_type>
class auto_handle_ref
{
    typedef auto_handle<handle_type, closer_type, factory_type> target_type;
public:
    explicit auto_handle_ref(target_type & target)
          : target_(target)
      {}
    handle_type release()
      {
          return target_.release();
      }
private:
    target_type & target_;
};

#endif // !defined(INC_AUTO_HANDLE_HPP)

Generated by  Doxygen 1.6.0   Back to index