1*9712c20fSFrederick Mayle // Copyright 2013 Google LLC
2*9712c20fSFrederick Mayle //
3*9712c20fSFrederick Mayle // Redistribution and use in source and binary forms, with or without
4*9712c20fSFrederick Mayle // modification, are permitted provided that the following conditions are
5*9712c20fSFrederick Mayle // met:
6*9712c20fSFrederick Mayle //
7*9712c20fSFrederick Mayle // * Redistributions of source code must retain the above copyright
8*9712c20fSFrederick Mayle // notice, this list of conditions and the following disclaimer.
9*9712c20fSFrederick Mayle // * Redistributions in binary form must reproduce the above
10*9712c20fSFrederick Mayle // copyright notice, this list of conditions and the following disclaimer
11*9712c20fSFrederick Mayle // in the documentation and/or other materials provided with the
12*9712c20fSFrederick Mayle // distribution.
13*9712c20fSFrederick Mayle // * Neither the name of Google LLC nor the names of its
14*9712c20fSFrederick Mayle // contributors may be used to endorse or promote products derived from
15*9712c20fSFrederick Mayle // this software without specific prior written permission.
16*9712c20fSFrederick Mayle //
17*9712c20fSFrederick Mayle // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*9712c20fSFrederick Mayle // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*9712c20fSFrederick Mayle // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*9712c20fSFrederick Mayle // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*9712c20fSFrederick Mayle // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*9712c20fSFrederick Mayle // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*9712c20fSFrederick Mayle // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*9712c20fSFrederick Mayle // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*9712c20fSFrederick Mayle // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*9712c20fSFrederick Mayle // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*9712c20fSFrederick Mayle // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*9712c20fSFrederick Mayle
29*9712c20fSFrederick Mayle // Scopers help you manage ownership of a pointer, helping you easily manage the
30*9712c20fSFrederick Mayle // a pointer within a scope, and automatically destroying the pointer at the
31*9712c20fSFrederick Mayle // end of a scope. There are two main classes you will use, which correspond
32*9712c20fSFrederick Mayle // to the operators new/delete and new[]/delete[].
33*9712c20fSFrederick Mayle //
34*9712c20fSFrederick Mayle // Example usage (scoped_ptr):
35*9712c20fSFrederick Mayle // {
36*9712c20fSFrederick Mayle // scoped_ptr<Foo> foo(new Foo("wee"));
37*9712c20fSFrederick Mayle // } // foo goes out of scope, releasing the pointer with it.
38*9712c20fSFrederick Mayle //
39*9712c20fSFrederick Mayle // {
40*9712c20fSFrederick Mayle // scoped_ptr<Foo> foo; // No pointer managed.
41*9712c20fSFrederick Mayle // foo.reset(new Foo("wee")); // Now a pointer is managed.
42*9712c20fSFrederick Mayle // foo.reset(new Foo("wee2")); // Foo("wee") was destroyed.
43*9712c20fSFrederick Mayle // foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed.
44*9712c20fSFrederick Mayle // foo->Method(); // Foo::Method() called.
45*9712c20fSFrederick Mayle // foo.get()->Method(); // Foo::Method() called.
46*9712c20fSFrederick Mayle // SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer
47*9712c20fSFrederick Mayle // // manages a pointer.
48*9712c20fSFrederick Mayle // foo.reset(new Foo("wee4")); // foo manages a pointer again.
49*9712c20fSFrederick Mayle // foo.reset(); // Foo("wee4") destroyed, foo no longer
50*9712c20fSFrederick Mayle // // manages a pointer.
51*9712c20fSFrederick Mayle // } // foo wasn't managing a pointer, so nothing was destroyed.
52*9712c20fSFrederick Mayle //
53*9712c20fSFrederick Mayle // Example usage (scoped_array):
54*9712c20fSFrederick Mayle // {
55*9712c20fSFrederick Mayle // scoped_array<Foo> foo(new Foo[100]);
56*9712c20fSFrederick Mayle // foo.get()->Method(); // Foo::Method on the 0th element.
57*9712c20fSFrederick Mayle // foo[10].Method(); // Foo::Method on the 10th element.
58*9712c20fSFrederick Mayle // }
59*9712c20fSFrederick Mayle
60*9712c20fSFrederick Mayle #ifndef COMMON_SCOPED_PTR_H_
61*9712c20fSFrederick Mayle #define COMMON_SCOPED_PTR_H_
62*9712c20fSFrederick Mayle
63*9712c20fSFrederick Mayle // This is an implementation designed to match the anticipated future TR2
64*9712c20fSFrederick Mayle // implementation of the scoped_ptr class, and its closely-related brethren,
65*9712c20fSFrederick Mayle // scoped_array, scoped_ptr_malloc.
66*9712c20fSFrederick Mayle
67*9712c20fSFrederick Mayle #include <assert.h>
68*9712c20fSFrederick Mayle #include <stddef.h>
69*9712c20fSFrederick Mayle #include <stdlib.h>
70*9712c20fSFrederick Mayle
71*9712c20fSFrederick Mayle namespace google_breakpad {
72*9712c20fSFrederick Mayle
73*9712c20fSFrederick Mayle // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T>
74*9712c20fSFrederick Mayle // automatically deletes the pointer it holds (if any).
75*9712c20fSFrederick Mayle // That is, scoped_ptr<T> owns the T object that it points to.
76*9712c20fSFrederick Mayle // Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object.
77*9712c20fSFrederick Mayle // Also like T*, scoped_ptr<T> is thread-compatible, and once you
78*9712c20fSFrederick Mayle // dereference it, you get the threadsafety guarantees of T.
79*9712c20fSFrederick Mayle //
80*9712c20fSFrederick Mayle // The size of a scoped_ptr is small:
81*9712c20fSFrederick Mayle // sizeof(scoped_ptr<C>) == sizeof(C*)
82*9712c20fSFrederick Mayle template <class C>
83*9712c20fSFrederick Mayle class scoped_ptr {
84*9712c20fSFrederick Mayle public:
85*9712c20fSFrederick Mayle
86*9712c20fSFrederick Mayle // The element type
87*9712c20fSFrederick Mayle typedef C element_type;
88*9712c20fSFrederick Mayle
89*9712c20fSFrederick Mayle // Constructor. Defaults to initializing with NULL.
90*9712c20fSFrederick Mayle // There is no way to create an uninitialized scoped_ptr.
91*9712c20fSFrederick Mayle // The input parameter must be allocated with new.
ptr_(p)92*9712c20fSFrederick Mayle explicit scoped_ptr(C* p = NULL) : ptr_(p) { }
93*9712c20fSFrederick Mayle
94*9712c20fSFrederick Mayle // Destructor. If there is a C object, delete it.
95*9712c20fSFrederick Mayle // We don't need to test ptr_ == NULL because C++ does that for us.
~scoped_ptr()96*9712c20fSFrederick Mayle ~scoped_ptr() {
97*9712c20fSFrederick Mayle enum { type_must_be_complete = sizeof(C) };
98*9712c20fSFrederick Mayle delete ptr_;
99*9712c20fSFrederick Mayle }
100*9712c20fSFrederick Mayle
101*9712c20fSFrederick Mayle // Reset. Deletes the current owned object, if any.
102*9712c20fSFrederick Mayle // Then takes ownership of a new object, if given.
103*9712c20fSFrederick Mayle // this->reset(this->get()) works.
104*9712c20fSFrederick Mayle void reset(C* p = NULL) {
105*9712c20fSFrederick Mayle if (p != ptr_) {
106*9712c20fSFrederick Mayle enum { type_must_be_complete = sizeof(C) };
107*9712c20fSFrederick Mayle delete ptr_;
108*9712c20fSFrederick Mayle ptr_ = p;
109*9712c20fSFrederick Mayle }
110*9712c20fSFrederick Mayle }
111*9712c20fSFrederick Mayle
112*9712c20fSFrederick Mayle // Accessors to get the owned object.
113*9712c20fSFrederick Mayle // operator* and operator-> will assert() if there is no current object.
114*9712c20fSFrederick Mayle C& operator*() const {
115*9712c20fSFrederick Mayle assert(ptr_ != NULL);
116*9712c20fSFrederick Mayle return *ptr_;
117*9712c20fSFrederick Mayle }
118*9712c20fSFrederick Mayle C* operator->() const {
119*9712c20fSFrederick Mayle assert(ptr_ != NULL);
120*9712c20fSFrederick Mayle return ptr_;
121*9712c20fSFrederick Mayle }
get()122*9712c20fSFrederick Mayle C* get() const { return ptr_; }
123*9712c20fSFrederick Mayle
124*9712c20fSFrederick Mayle // Comparison operators.
125*9712c20fSFrederick Mayle // These return whether two scoped_ptr refer to the same object, not just to
126*9712c20fSFrederick Mayle // two different but equal objects.
127*9712c20fSFrederick Mayle bool operator==(C* p) const { return ptr_ == p; }
128*9712c20fSFrederick Mayle bool operator!=(C* p) const { return ptr_ != p; }
129*9712c20fSFrederick Mayle
130*9712c20fSFrederick Mayle // Swap two scoped pointers.
swap(scoped_ptr & p2)131*9712c20fSFrederick Mayle void swap(scoped_ptr& p2) {
132*9712c20fSFrederick Mayle C* tmp = ptr_;
133*9712c20fSFrederick Mayle ptr_ = p2.ptr_;
134*9712c20fSFrederick Mayle p2.ptr_ = tmp;
135*9712c20fSFrederick Mayle }
136*9712c20fSFrederick Mayle
137*9712c20fSFrederick Mayle // Release a pointer.
138*9712c20fSFrederick Mayle // The return value is the current pointer held by this object.
139*9712c20fSFrederick Mayle // If this object holds a NULL pointer, the return value is NULL.
140*9712c20fSFrederick Mayle // After this operation, this object will hold a NULL pointer,
141*9712c20fSFrederick Mayle // and will not own the object any more.
release()142*9712c20fSFrederick Mayle C* release() {
143*9712c20fSFrederick Mayle C* retVal = ptr_;
144*9712c20fSFrederick Mayle ptr_ = NULL;
145*9712c20fSFrederick Mayle return retVal;
146*9712c20fSFrederick Mayle }
147*9712c20fSFrederick Mayle
148*9712c20fSFrederick Mayle private:
149*9712c20fSFrederick Mayle C* ptr_;
150*9712c20fSFrederick Mayle
151*9712c20fSFrederick Mayle // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't
152*9712c20fSFrederick Mayle // make sense, and if C2 == C, it still doesn't make sense because you should
153*9712c20fSFrederick Mayle // never have the same object owned by two different scoped_ptrs.
154*9712c20fSFrederick Mayle template <class C2> bool operator==(scoped_ptr<C2> const& p2) const;
155*9712c20fSFrederick Mayle template <class C2> bool operator!=(scoped_ptr<C2> const& p2) const;
156*9712c20fSFrederick Mayle
157*9712c20fSFrederick Mayle // Disallow evil constructors
158*9712c20fSFrederick Mayle scoped_ptr(const scoped_ptr&);
159*9712c20fSFrederick Mayle void operator=(const scoped_ptr&);
160*9712c20fSFrederick Mayle };
161*9712c20fSFrederick Mayle
162*9712c20fSFrederick Mayle // Free functions
163*9712c20fSFrederick Mayle template <class C>
swap(scoped_ptr<C> & p1,scoped_ptr<C> & p2)164*9712c20fSFrederick Mayle void swap(scoped_ptr<C>& p1, scoped_ptr<C>& p2) {
165*9712c20fSFrederick Mayle p1.swap(p2);
166*9712c20fSFrederick Mayle }
167*9712c20fSFrederick Mayle
168*9712c20fSFrederick Mayle template <class C>
169*9712c20fSFrederick Mayle bool operator==(C* p1, const scoped_ptr<C>& p2) {
170*9712c20fSFrederick Mayle return p1 == p2.get();
171*9712c20fSFrederick Mayle }
172*9712c20fSFrederick Mayle
173*9712c20fSFrederick Mayle template <class C>
174*9712c20fSFrederick Mayle bool operator!=(C* p1, const scoped_ptr<C>& p2) {
175*9712c20fSFrederick Mayle return p1 != p2.get();
176*9712c20fSFrederick Mayle }
177*9712c20fSFrederick Mayle
178*9712c20fSFrederick Mayle // scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate
179*9712c20fSFrederick Mayle // with new [] and the destructor deletes objects with delete [].
180*9712c20fSFrederick Mayle //
181*9712c20fSFrederick Mayle // As with scoped_ptr<C>, a scoped_array<C> either points to an object
182*9712c20fSFrederick Mayle // or is NULL. A scoped_array<C> owns the object that it points to.
183*9712c20fSFrederick Mayle // scoped_array<T> is thread-compatible, and once you index into it,
184*9712c20fSFrederick Mayle // the returned objects have only the threadsafety guarantees of T.
185*9712c20fSFrederick Mayle //
186*9712c20fSFrederick Mayle // Size: sizeof(scoped_array<C>) == sizeof(C*)
187*9712c20fSFrederick Mayle template <class C>
188*9712c20fSFrederick Mayle class scoped_array {
189*9712c20fSFrederick Mayle public:
190*9712c20fSFrederick Mayle
191*9712c20fSFrederick Mayle // The element type
192*9712c20fSFrederick Mayle typedef C element_type;
193*9712c20fSFrederick Mayle
194*9712c20fSFrederick Mayle // Constructor. Defaults to intializing with NULL.
195*9712c20fSFrederick Mayle // There is no way to create an uninitialized scoped_array.
196*9712c20fSFrederick Mayle // The input parameter must be allocated with new [].
array_(p)197*9712c20fSFrederick Mayle explicit scoped_array(C* p = NULL) : array_(p) { }
198*9712c20fSFrederick Mayle
199*9712c20fSFrederick Mayle // Destructor. If there is a C object, delete it.
200*9712c20fSFrederick Mayle // We don't need to test ptr_ == NULL because C++ does that for us.
~scoped_array()201*9712c20fSFrederick Mayle ~scoped_array() {
202*9712c20fSFrederick Mayle enum { type_must_be_complete = sizeof(C) };
203*9712c20fSFrederick Mayle delete[] array_;
204*9712c20fSFrederick Mayle }
205*9712c20fSFrederick Mayle
206*9712c20fSFrederick Mayle // Reset. Deletes the current owned object, if any.
207*9712c20fSFrederick Mayle // Then takes ownership of a new object, if given.
208*9712c20fSFrederick Mayle // this->reset(this->get()) works.
209*9712c20fSFrederick Mayle void reset(C* p = NULL) {
210*9712c20fSFrederick Mayle if (p != array_) {
211*9712c20fSFrederick Mayle enum { type_must_be_complete = sizeof(C) };
212*9712c20fSFrederick Mayle delete[] array_;
213*9712c20fSFrederick Mayle array_ = p;
214*9712c20fSFrederick Mayle }
215*9712c20fSFrederick Mayle }
216*9712c20fSFrederick Mayle
217*9712c20fSFrederick Mayle // Get one element of the current object.
218*9712c20fSFrederick Mayle // Will assert() if there is no current object, or index i is negative.
219*9712c20fSFrederick Mayle C& operator[](ptrdiff_t i) const {
220*9712c20fSFrederick Mayle assert(i >= 0);
221*9712c20fSFrederick Mayle assert(array_ != NULL);
222*9712c20fSFrederick Mayle return array_[i];
223*9712c20fSFrederick Mayle }
224*9712c20fSFrederick Mayle
225*9712c20fSFrederick Mayle // Get a pointer to the zeroth element of the current object.
226*9712c20fSFrederick Mayle // If there is no current object, return NULL.
get()227*9712c20fSFrederick Mayle C* get() const {
228*9712c20fSFrederick Mayle return array_;
229*9712c20fSFrederick Mayle }
230*9712c20fSFrederick Mayle
231*9712c20fSFrederick Mayle // Comparison operators.
232*9712c20fSFrederick Mayle // These return whether two scoped_array refer to the same object, not just to
233*9712c20fSFrederick Mayle // two different but equal objects.
234*9712c20fSFrederick Mayle bool operator==(C* p) const { return array_ == p; }
235*9712c20fSFrederick Mayle bool operator!=(C* p) const { return array_ != p; }
236*9712c20fSFrederick Mayle
237*9712c20fSFrederick Mayle // Swap two scoped arrays.
swap(scoped_array & p2)238*9712c20fSFrederick Mayle void swap(scoped_array& p2) {
239*9712c20fSFrederick Mayle C* tmp = array_;
240*9712c20fSFrederick Mayle array_ = p2.array_;
241*9712c20fSFrederick Mayle p2.array_ = tmp;
242*9712c20fSFrederick Mayle }
243*9712c20fSFrederick Mayle
244*9712c20fSFrederick Mayle // Release an array.
245*9712c20fSFrederick Mayle // The return value is the current pointer held by this object.
246*9712c20fSFrederick Mayle // If this object holds a NULL pointer, the return value is NULL.
247*9712c20fSFrederick Mayle // After this operation, this object will hold a NULL pointer,
248*9712c20fSFrederick Mayle // and will not own the object any more.
release()249*9712c20fSFrederick Mayle C* release() {
250*9712c20fSFrederick Mayle C* retVal = array_;
251*9712c20fSFrederick Mayle array_ = NULL;
252*9712c20fSFrederick Mayle return retVal;
253*9712c20fSFrederick Mayle }
254*9712c20fSFrederick Mayle
255*9712c20fSFrederick Mayle private:
256*9712c20fSFrederick Mayle C* array_;
257*9712c20fSFrederick Mayle
258*9712c20fSFrederick Mayle // Forbid comparison of different scoped_array types.
259*9712c20fSFrederick Mayle template <class C2> bool operator==(scoped_array<C2> const& p2) const;
260*9712c20fSFrederick Mayle template <class C2> bool operator!=(scoped_array<C2> const& p2) const;
261*9712c20fSFrederick Mayle
262*9712c20fSFrederick Mayle // Disallow evil constructors
263*9712c20fSFrederick Mayle scoped_array(const scoped_array&);
264*9712c20fSFrederick Mayle void operator=(const scoped_array&);
265*9712c20fSFrederick Mayle };
266*9712c20fSFrederick Mayle
267*9712c20fSFrederick Mayle // Free functions
268*9712c20fSFrederick Mayle template <class C>
swap(scoped_array<C> & p1,scoped_array<C> & p2)269*9712c20fSFrederick Mayle void swap(scoped_array<C>& p1, scoped_array<C>& p2) {
270*9712c20fSFrederick Mayle p1.swap(p2);
271*9712c20fSFrederick Mayle }
272*9712c20fSFrederick Mayle
273*9712c20fSFrederick Mayle template <class C>
274*9712c20fSFrederick Mayle bool operator==(C* p1, const scoped_array<C>& p2) {
275*9712c20fSFrederick Mayle return p1 == p2.get();
276*9712c20fSFrederick Mayle }
277*9712c20fSFrederick Mayle
278*9712c20fSFrederick Mayle template <class C>
279*9712c20fSFrederick Mayle bool operator!=(C* p1, const scoped_array<C>& p2) {
280*9712c20fSFrederick Mayle return p1 != p2.get();
281*9712c20fSFrederick Mayle }
282*9712c20fSFrederick Mayle
283*9712c20fSFrederick Mayle // This class wraps the c library function free() in a class that can be
284*9712c20fSFrederick Mayle // passed as a template argument to scoped_ptr_malloc below.
285*9712c20fSFrederick Mayle class ScopedPtrMallocFree {
286*9712c20fSFrederick Mayle public:
operator()287*9712c20fSFrederick Mayle inline void operator()(void* x) const {
288*9712c20fSFrederick Mayle free(x);
289*9712c20fSFrederick Mayle }
290*9712c20fSFrederick Mayle };
291*9712c20fSFrederick Mayle
292*9712c20fSFrederick Mayle // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
293*9712c20fSFrederick Mayle // second template argument, the functor used to free the object.
294*9712c20fSFrederick Mayle
295*9712c20fSFrederick Mayle template<class C, class FreeProc = ScopedPtrMallocFree>
296*9712c20fSFrederick Mayle class scoped_ptr_malloc {
297*9712c20fSFrederick Mayle public:
298*9712c20fSFrederick Mayle
299*9712c20fSFrederick Mayle // The element type
300*9712c20fSFrederick Mayle typedef C element_type;
301*9712c20fSFrederick Mayle
302*9712c20fSFrederick Mayle // Constructor. Defaults to initializing with NULL.
303*9712c20fSFrederick Mayle // There is no way to create an uninitialized scoped_ptr.
304*9712c20fSFrederick Mayle // The input parameter must be allocated with an allocator that matches the
305*9712c20fSFrederick Mayle // Free functor. For the default Free functor, this is malloc, calloc, or
306*9712c20fSFrederick Mayle // realloc.
ptr_(p)307*9712c20fSFrederick Mayle explicit scoped_ptr_malloc(C* p = NULL): ptr_(p) {}
308*9712c20fSFrederick Mayle
309*9712c20fSFrederick Mayle // Destructor. If there is a C object, call the Free functor.
~scoped_ptr_malloc()310*9712c20fSFrederick Mayle ~scoped_ptr_malloc() {
311*9712c20fSFrederick Mayle reset();
312*9712c20fSFrederick Mayle }
313*9712c20fSFrederick Mayle
314*9712c20fSFrederick Mayle // Reset. Calls the Free functor on the current owned object, if any.
315*9712c20fSFrederick Mayle // Then takes ownership of a new object, if given.
316*9712c20fSFrederick Mayle // this->reset(this->get()) works.
317*9712c20fSFrederick Mayle void reset(C* p = NULL) {
318*9712c20fSFrederick Mayle if (ptr_ != p) {
319*9712c20fSFrederick Mayle FreeProc free_proc;
320*9712c20fSFrederick Mayle free_proc(ptr_);
321*9712c20fSFrederick Mayle ptr_ = p;
322*9712c20fSFrederick Mayle }
323*9712c20fSFrederick Mayle }
324*9712c20fSFrederick Mayle
325*9712c20fSFrederick Mayle // Get the current object.
326*9712c20fSFrederick Mayle // operator* and operator-> will cause an assert() failure if there is
327*9712c20fSFrederick Mayle // no current object.
328*9712c20fSFrederick Mayle C& operator*() const {
329*9712c20fSFrederick Mayle assert(ptr_ != NULL);
330*9712c20fSFrederick Mayle return *ptr_;
331*9712c20fSFrederick Mayle }
332*9712c20fSFrederick Mayle
333*9712c20fSFrederick Mayle C* operator->() const {
334*9712c20fSFrederick Mayle assert(ptr_ != NULL);
335*9712c20fSFrederick Mayle return ptr_;
336*9712c20fSFrederick Mayle }
337*9712c20fSFrederick Mayle
get()338*9712c20fSFrederick Mayle C* get() const {
339*9712c20fSFrederick Mayle return ptr_;
340*9712c20fSFrederick Mayle }
341*9712c20fSFrederick Mayle
342*9712c20fSFrederick Mayle // Comparison operators.
343*9712c20fSFrederick Mayle // These return whether a scoped_ptr_malloc and a plain pointer refer
344*9712c20fSFrederick Mayle // to the same object, not just to two different but equal objects.
345*9712c20fSFrederick Mayle // For compatibility with the boost-derived implementation, these
346*9712c20fSFrederick Mayle // take non-const arguments.
347*9712c20fSFrederick Mayle bool operator==(C* p) const {
348*9712c20fSFrederick Mayle return ptr_ == p;
349*9712c20fSFrederick Mayle }
350*9712c20fSFrederick Mayle
351*9712c20fSFrederick Mayle bool operator!=(C* p) const {
352*9712c20fSFrederick Mayle return ptr_ != p;
353*9712c20fSFrederick Mayle }
354*9712c20fSFrederick Mayle
355*9712c20fSFrederick Mayle // Swap two scoped pointers.
swap(scoped_ptr_malloc & b)356*9712c20fSFrederick Mayle void swap(scoped_ptr_malloc & b) {
357*9712c20fSFrederick Mayle C* tmp = b.ptr_;
358*9712c20fSFrederick Mayle b.ptr_ = ptr_;
359*9712c20fSFrederick Mayle ptr_ = tmp;
360*9712c20fSFrederick Mayle }
361*9712c20fSFrederick Mayle
362*9712c20fSFrederick Mayle // Release a pointer.
363*9712c20fSFrederick Mayle // The return value is the current pointer held by this object.
364*9712c20fSFrederick Mayle // If this object holds a NULL pointer, the return value is NULL.
365*9712c20fSFrederick Mayle // After this operation, this object will hold a NULL pointer,
366*9712c20fSFrederick Mayle // and will not own the object any more.
release()367*9712c20fSFrederick Mayle C* release() {
368*9712c20fSFrederick Mayle C* tmp = ptr_;
369*9712c20fSFrederick Mayle ptr_ = NULL;
370*9712c20fSFrederick Mayle return tmp;
371*9712c20fSFrederick Mayle }
372*9712c20fSFrederick Mayle
373*9712c20fSFrederick Mayle private:
374*9712c20fSFrederick Mayle C* ptr_;
375*9712c20fSFrederick Mayle
376*9712c20fSFrederick Mayle // no reason to use these: each scoped_ptr_malloc should have its own object
377*9712c20fSFrederick Mayle template <class C2, class GP>
378*9712c20fSFrederick Mayle bool operator==(scoped_ptr_malloc<C2, GP> const& p) const;
379*9712c20fSFrederick Mayle template <class C2, class GP>
380*9712c20fSFrederick Mayle bool operator!=(scoped_ptr_malloc<C2, GP> const& p) const;
381*9712c20fSFrederick Mayle
382*9712c20fSFrederick Mayle // Disallow evil constructors
383*9712c20fSFrederick Mayle scoped_ptr_malloc(const scoped_ptr_malloc&);
384*9712c20fSFrederick Mayle void operator=(const scoped_ptr_malloc&);
385*9712c20fSFrederick Mayle };
386*9712c20fSFrederick Mayle
387*9712c20fSFrederick Mayle template<class C, class FP> inline
swap(scoped_ptr_malloc<C,FP> & a,scoped_ptr_malloc<C,FP> & b)388*9712c20fSFrederick Mayle void swap(scoped_ptr_malloc<C, FP>& a, scoped_ptr_malloc<C, FP>& b) {
389*9712c20fSFrederick Mayle a.swap(b);
390*9712c20fSFrederick Mayle }
391*9712c20fSFrederick Mayle
392*9712c20fSFrederick Mayle template<class C, class FP> inline
393*9712c20fSFrederick Mayle bool operator==(C* p, const scoped_ptr_malloc<C, FP>& b) {
394*9712c20fSFrederick Mayle return p == b.get();
395*9712c20fSFrederick Mayle }
396*9712c20fSFrederick Mayle
397*9712c20fSFrederick Mayle template<class C, class FP> inline
398*9712c20fSFrederick Mayle bool operator!=(C* p, const scoped_ptr_malloc<C, FP>& b) {
399*9712c20fSFrederick Mayle return p != b.get();
400*9712c20fSFrederick Mayle }
401*9712c20fSFrederick Mayle
402*9712c20fSFrederick Mayle } // namespace google_breakpad
403*9712c20fSFrederick Mayle
404*9712c20fSFrederick Mayle #endif // COMMON_SCOPED_PTR_H_
405