File: auto_handle.hpp

package info (click to toggle)
videolink 1.0-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 368 kB
  • ctags: 502
  • sloc: cpp: 3,210; ansic: 880; makefile: 121
file content (83 lines) | stat: -rw-r--r-- 2,054 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#ifndef INC_AUTO_HANDLE_H
#define INC_AUTO_HANDLE_H

// 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(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 // !INC_AUTO_HANDLE_H