1 // Copyright 2005 Ben Hutchings <ben@decadent.org.uk>.
2 // See the file "COPYING" for licence details.
4 #ifndef INC_AUTO_HANDLE_HPP
5 #define INC_AUTO_HANDLE_HPP
7 // Like auto_ptr, but for arbitrary "handle" types.
9 // - handle_type: the type of the raw handle to be wrapped
10 // - closer_type: a function object type whose operator() takes a raw handle
11 // and closes it (or does nothing if it is a null handle)
12 // - factory_type: a function object type whose operator() returns a null
15 template<typename handle_type, typename closer_type, typename factory_type>
16 class auto_handle_ref;
18 template<typename handle_type, typename closer_type, typename factory_type>
20 // Use inheritance so we can benefit from the empty base optimisation
21 : private closer_type, private factory_type
23 typedef auto_handle_ref<handle_type, closer_type, factory_type> ref_type;
26 : handle_(factory_type::operator()())
28 explicit auto_handle(handle_type handle)
31 auto_handle(auto_handle & other)
32 : handle_(other.release())
34 auto_handle(ref_type other)
35 : handle_(other.release())
37 auto_handle & operator=(auto_handle & other)
39 reset(other.release());
45 handle_type get() const
51 handle_type handle(handle_);
52 handle_ = factory_type::operator()();
57 closer_type::operator()(handle_);
58 handle_ = factory_type::operator()();
60 void reset(handle_type handle)
62 closer_type::operator()(handle_);
67 return ref_type(*this);
73 template<typename handle_type, typename closer_type, typename factory_type>
76 typedef auto_handle<handle_type, closer_type, factory_type> target_type;
78 explicit auto_handle_ref(target_type & target)
83 return target_.release();
86 target_type & target_;
89 #endif // !defined(INC_AUTO_HANDLE_HPP)