1 /* 2 * Copyright (C) 2013 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef WebScopedPtr_h 32 #define WebScopedPtr_h 33 34 #include <stddef.h> 35 36 namespace WebTestRunner { 37 38 template<typename Deallocator, typename T> 39 class WebScopedPtrBase { 40 public: 41 // Default constructor. Constructs an empty scoped pointer. 42 inline WebScopedPtrBase() : m_ptr(0) { } 43 44 // Constructs a scoped pointer from a plain one. 45 explicit inline WebScopedPtrBase(T* ptr) : m_ptr(ptr) { } 46 47 // Copy constructor removes the pointer from the original to avoid double 48 // freeing. 49 inline WebScopedPtrBase(const WebScopedPtrBase<Deallocator, T>& rhs) 50 : m_ptr(rhs.m_ptr) 51 { 52 const_cast<WebScopedPtrBase<Deallocator, T>&>(rhs).m_ptr = 0; 53 } 54 55 // When the destructor of the scoped pointer is executed the plain pointer 56 // is deleted using DeleteArray. This implies that you must allocate with 57 // NewArray. 58 inline ~WebScopedPtrBase() 59 { 60 if (m_ptr) 61 Deallocator::Delete(m_ptr); 62 } 63 64 inline T* operator->() const { return m_ptr; } 65 66 // You can get the underlying pointer out with the * operator. 67 inline T* operator*() { return m_ptr; } 68 69 // You can use [n] to index as if it was a plain pointer. 70 inline T& operator[](size_t i) 71 { 72 return m_ptr[i]; 73 } 74 75 // You can use [n] to index as if it was a plain pointer. 76 const inline T& operator[](size_t i) const 77 { 78 return m_ptr[i]; 79 } 80 81 // We don't have implicit conversion to a T* since that hinders migration: 82 // You would not be able to change a method from returning a T* to 83 // returning an WebScopedArrayPtr<T> and then get errors wherever it is used. 84 inline T* get() const { return m_ptr; } 85 86 inline void reset(T* newValue = 0) 87 { 88 if (m_ptr) 89 Deallocator::Delete(m_ptr); 90 m_ptr = newValue; 91 } 92 93 // Assignment requires an empty (0) WebScopedArrayPtr as the receiver. Like 94 // the copy constructor it removes the pointer in the original to avoid 95 // double freeing. 96 inline WebScopedPtrBase<Deallocator, T>& operator=(const WebScopedPtrBase<Deallocator, T>& rhs) 97 { 98 reset(rhs.m_ptr); 99 const_cast<WebScopedPtrBase<Deallocator, T>&>(rhs).m_ptr = 0; 100 return *this; 101 } 102 103 inline bool isEmpty() { return !m_ptr; } 104 105 private: 106 T* m_ptr; 107 }; 108 109 // A 'scoped array pointer' that calls DeleteArray on its pointer when the 110 // destructor is called. 111 template<typename T> 112 struct ArrayDeallocator { 113 static void Delete(T* array) 114 { 115 DeleteArray(array); 116 } 117 }; 118 119 template<typename T> 120 class WebScopedArrayPtr: public WebScopedPtrBase<ArrayDeallocator<T>, T> { 121 public: 122 inline WebScopedArrayPtr() { } 123 explicit inline WebScopedArrayPtr(T* ptr) 124 : WebScopedPtrBase<ArrayDeallocator<T>, T>(ptr) { } 125 inline WebScopedArrayPtr(const WebScopedArrayPtr<T>& rhs) 126 : WebScopedPtrBase<ArrayDeallocator<T>, T>(rhs) { } 127 }; 128 129 template<typename T> 130 struct ObjectDeallocator { 131 static void Delete(T* object) 132 { 133 delete object; 134 } 135 }; 136 137 template<typename T> 138 class WebScopedPtr: public WebScopedPtrBase<ObjectDeallocator<T>, T> { 139 public: 140 inline WebScopedPtr() { } 141 explicit inline WebScopedPtr(T* ptr) 142 : WebScopedPtrBase<ObjectDeallocator<T>, T>(ptr) { } 143 inline WebScopedPtr(const WebScopedPtr<T>& rhs) 144 : WebScopedPtrBase<ObjectDeallocator<T>, T>(rhs) { } 145 }; 146 147 } // namespace WebTestRunner 148 149 #endif // WebScopedPtr_h 150