xref: /aosp_15_r20/external/google-breakpad/src/common/scoped_ptr.h (revision 9712c20fc9bbfbac4935993a2ca0b3958c5adad2)
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