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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_MEMORY_SCOPED_GENERIC_OBJ_H_
#define BASE_MEMORY_SCOPED_GENERIC_OBJ_H_
#include "base/basictypes.h"
#include "base/compiler_specific.h"
// ScopedGenericObj<> is patterned after scoped_ptr_malloc<>, except
// that it assumes the template argument is typedef'ed to a pointer
// type. It does not support retain/release semantics. It takes as its
// second template argument a functor which frees the object.
//
// Example (Mac-specific):
//
// class ScopedDestroyRendererInfo {
// public:
// void operator()(CGLRendererInfoObj x) const {
// CGLDestroyRendererInfo(x);
// }
// };
//
// ...
//
// CGLRendererInfoObj renderer_info = NULL;
// ...
// ScopedGenericObj<CGLRendererInfoObj, ScopedDestroyRendererInfo>
// scoper(renderer_info);
template<class C, class FreeProc>
class ScopedGenericObj {
public:
// The element type
typedef C element_type;
// Constructor. Defaults to initializing with NULL.
// There is no way to create an uninitialized ScopedGenericObj.
// The input parameter must be allocated with an allocator that matches the
// Free functor.
explicit ScopedGenericObj(C p = C()): obj_(p) {}
// Destructor. If there is a C object, call the Free functor.
~ScopedGenericObj() {
reset();
}
// Reset. Calls the Free functor on the current owned object, if any.
// Then takes ownership of a new object, if given.
// this->reset(this->get()) works.
void reset(C p = C()) {
if (obj_ != p) {
FreeProc free_proc;
free_proc(obj_);
obj_ = p;
}
}
operator C() const {
return obj_;
}
C get() const {
return obj_;
}
// Comparison operators.
// These return whether a ScopedGenericObj and a plain pointer refer
// to the same object, not just to two different but equal objects.
// For compatibility with the boost-derived implementation, these
// take non-const arguments.
bool operator==(C p) const {
return obj_ == p;
}
bool operator!=(C p) const {
return obj_ != p;
}
// Swap two ScopedGenericObjs.
void swap(ScopedGenericObj& b) {
C tmp = b.obj_;
b.obj_ = obj_;
obj_ = tmp;
}
// Release a pointer.
// The return value is the current pointer held by this object.
// If this object holds a NULL pointer, the return value is NULL.
// After this operation, this object will hold a NULL pointer,
// and will not own the object any more.
C release() WARN_UNUSED_RESULT {
C tmp = obj_;
obj_ = NULL;
return tmp;
}
private:
C obj_;
// no reason to use these: each ScopedGenericObj should have its own object.
template <class C2, class GP>
bool operator==(ScopedGenericObj<C2, GP> const& p) const;
template <class C2, class GP>
bool operator!=(ScopedGenericObj<C2, GP> const& p) const;
// Disallow evil constructors.
ScopedGenericObj(const ScopedGenericObj&);
void operator=(const ScopedGenericObj&);
};
template<class C, class FP> inline
void swap(ScopedGenericObj<C, FP>& a, ScopedGenericObj<C, FP>& b) {
a.swap(b);
}
template<class C, class FP> inline
bool operator==(C* p, const ScopedGenericObj<C, FP>& b) {
return p == b.get();
}
template<class C, class FP> inline
bool operator!=(C* p, const ScopedGenericObj<C, FP>& b) {
return p != b.get();
}
#endif // BASE_MEMORY_SCOPED_GENERIC_OBJ_H_
|