// Copyright 2013 Google LLC // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google LLC nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Scopers help you manage ownership of a pointer, helping you easily manage the // a pointer within a scope, and automatically destroying the pointer at the // end of a scope. There are two main classes you will use, which correspond // to the operators new/delete and new[]/delete[]. // // Example usage (scoped_ptr): // { // scoped_ptr<Foo> foo(new Foo("wee")); // } // foo goes out of scope, releasing the pointer with it. // // { // scoped_ptr<Foo> foo; // No pointer managed. // foo.reset(new Foo("wee")); // Now a pointer is managed. // foo.reset(new Foo("wee2")); // Foo("wee") was destroyed. // foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed. // foo->Method(); // Foo::Method() called. // foo.get()->Method(); // Foo::Method() called. // SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer // // manages a pointer. // foo.reset(new Foo("wee4")); // foo manages a pointer again. // foo.reset(); // Foo("wee4") destroyed, foo no longer // // manages a pointer. // } // foo wasn't managing a pointer, so nothing was destroyed. // // Example usage (scoped_array): // { // scoped_array<Foo> foo(new Foo[100]); // foo.get()->Method(); // Foo::Method on the 0th element. // foo[10].Method(); // Foo::Method on the 10th element. // } #ifndef COMMON_SCOPED_PTR_H_ #define COMMON_SCOPED_PTR_H_ // This is an implementation designed to match the anticipated future TR2 // implementation of the scoped_ptr class, and its closely-related brethren, // scoped_array, scoped_ptr_malloc. #include <assert.h> #include <stddef.h> #include <stdlib.h> namespace google_breakpad { // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T> // automatically deletes the pointer it holds (if any). // That is, scoped_ptr<T> owns the T object that it points to. // Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object. // Also like T*, scoped_ptr<T> is thread-compatible, and once you // dereference it, you get the threadsafety guarantees of T. // // The size of a scoped_ptr is small: // sizeof(scoped_ptr<C>) == sizeof(C*) template <class C> class scoped_ptr { … }; // Free functions template <class C> void swap(scoped_ptr<C>& p1, scoped_ptr<C>& p2) { … } template <class C> bool operator==(C* p1, const scoped_ptr<C>& p2) { … } template <class C> bool operator!=(C* p1, const scoped_ptr<C>& p2) { … } // scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate // with new [] and the destructor deletes objects with delete []. // // As with scoped_ptr<C>, a scoped_array<C> either points to an object // or is NULL. A scoped_array<C> owns the object that it points to. // scoped_array<T> is thread-compatible, and once you index into it, // the returned objects have only the threadsafety guarantees of T. // // Size: sizeof(scoped_array<C>) == sizeof(C*) template <class C> class scoped_array { … }; // Free functions template <class C> void swap(scoped_array<C>& p1, scoped_array<C>& p2) { … } template <class C> bool operator==(C* p1, const scoped_array<C>& p2) { … } template <class C> bool operator!=(C* p1, const scoped_array<C>& p2) { … } // This class wraps the c library function free() in a class that can be // passed as a template argument to scoped_ptr_malloc below. class ScopedPtrMallocFree { … }; // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a // second template argument, the functor used to free the object. template<class C, class FreeProc = ScopedPtrMallocFree> class scoped_ptr_malloc { … }; template<class C, class FP> inline void swap(scoped_ptr_malloc<C, FP>& a, scoped_ptr_malloc<C, FP>& b) { … } template<class C, class FP> inline bool operator==(C* p, const scoped_ptr_malloc<C, FP>& b) { … } template<class C, class FP> inline bool operator!=(C* p, const scoped_ptr_malloc<C, FP>& b) { … } } // namespace google_breakpad #endif // COMMON_SCOPED_PTR_H_