github.com/ckxng/wakeup@v0.0.0-20190105202853-90356a5f5a15/include/internal/cef_ptr.h (about) 1 // Copyright (c) 2008 Marshall A. Greenblatt. Portions Copyright (c) 2 // 2006-2008 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 name Chromium Embedded 15 // Framework nor the names of its contributors may be used to endorse 16 // or promote products derived from this software without specific prior 17 // written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 32 #ifndef CEF_INCLUDE_INTERNAL_CEF_PTR_H_ 33 #define CEF_INCLUDE_INTERNAL_CEF_PTR_H_ 34 #pragma once 35 36 #include <stddef.h> 37 38 /// 39 // Smart pointer implementation borrowed from base/ref_counted.h 40 // <p> 41 // A smart pointer class for reference counted objects. Use this class instead 42 // of calling AddRef and Release manually on a reference counted object to 43 // avoid common memory leaks caused by forgetting to Release an object 44 // reference. Sample usage: 45 // <pre> 46 // class MyFoo : public CefBase { 47 // ... 48 // }; 49 // 50 // void some_function() { 51 // // The MyFoo object that |foo| represents starts with a single 52 // // reference. 53 // CefRefPtr<MyFoo> foo = new MyFoo(); 54 // foo->Method(param); 55 // // |foo| is released when this function returns 56 // } 57 // 58 // void some_other_function() { 59 // CefRefPtr<MyFoo> foo = new MyFoo(); 60 // ... 61 // foo = NULL; // explicitly releases |foo| 62 // ... 63 // if (foo) 64 // foo->Method(param); 65 // } 66 // </pre> 67 // The above examples show how CefRefPtr<T> acts like a pointer to T. 68 // Given two CefRefPtr<T> classes, it is also possible to exchange 69 // references between the two objects, like so: 70 // <pre> 71 // { 72 // CefRefPtr<MyFoo> a = new MyFoo(); 73 // CefRefPtr<MyFoo> b; 74 // 75 // b.swap(a); 76 // // now, |b| references the MyFoo object, and |a| references NULL. 77 // } 78 // </pre> 79 // To make both |a| and |b| in the above example reference the same MyFoo 80 // object, simply use the assignment operator: 81 // <pre> 82 // { 83 // CefRefPtr<MyFoo> a = new MyFoo(); 84 // CefRefPtr<MyFoo> b; 85 // 86 // b = a; 87 // // now, |a| and |b| each own a reference to the same MyFoo object. 88 // // the reference count of the underlying MyFoo object will be 2. 89 // } 90 // </pre> 91 // Reference counted objects can also be passed as function parameters and 92 // used as function return values: 93 // <pre> 94 // void some_func_with_param(CefRefPtr<MyFoo> param) { 95 // // A reference is added to the MyFoo object that |param| represents 96 // // during the scope of some_func_with_param() and released when 97 // // some_func_with_param() goes out of scope. 98 // } 99 // 100 // CefRefPtr<MyFoo> some_func_with_retval() { 101 // // The MyFoo object that |foox| represents starts with a single 102 // // reference. 103 // CefRefPtr<MyFoo> foox = new MyFoo(); 104 // 105 // // Creating the return value adds an additional reference. 106 // return foox; 107 // 108 // // When some_func_with_retval() goes out of scope the original |foox| 109 // // reference is released. 110 // } 111 // 112 // void and_another_function() { 113 // CefRefPtr<MyFoo> foo = new MyFoo(); 114 // 115 // // pass |foo| as a parameter. 116 // some_function(foo); 117 // 118 // CefRefPtr<MyFoo> foo2 = some_func_with_retval(); 119 // // Now, since we kept a reference to the some_func_with_retval() return 120 // // value, |foo2| is the only class pointing to the MyFoo object created 121 // in some_func_with_retval(), and it has a reference count of 1. 122 // 123 // some_func_with_retval(); 124 // // Now, since we didn't keep a reference to the some_func_with_retval() 125 // // return value, the MyFoo object created in some_func_with_retval() 126 // // will automatically be released. 127 // } 128 // </pre> 129 // And in standard containers: 130 // <pre> 131 // { 132 // // Create a vector that holds MyFoo objects. 133 // std::vector<CefRefPtr<MyFoo> > MyFooVec; 134 // 135 // // The MyFoo object that |foo| represents starts with a single 136 // // reference. 137 // CefRefPtr<MyFoo> foo = new MyFoo(); 138 // 139 // // When the MyFoo object is added to |MyFooVec| the reference count 140 // // is increased to 2. 141 // MyFooVec.push_back(foo); 142 // } 143 // </pre> 144 // </p> 145 /// 146 template <class T> 147 class CefRefPtr { 148 public: 149 CefRefPtr() : ptr_(NULL) { 150 } 151 152 CefRefPtr(T* p) : ptr_(p) { // NOLINT(runtime/explicit) 153 if (ptr_) 154 ptr_->AddRef(); 155 } 156 157 CefRefPtr(const CefRefPtr<T>& r) : ptr_(r.ptr_) { 158 if (ptr_) 159 ptr_->AddRef(); 160 } 161 162 ~CefRefPtr() { 163 if (ptr_) 164 ptr_->Release(); 165 } 166 167 T* get() const { return ptr_; } 168 operator T*() const { return ptr_; } 169 T* operator->() const { return ptr_; } 170 171 CefRefPtr<T>& operator=(T* p) { 172 // AddRef first so that self assignment should work 173 if (p) 174 p->AddRef(); 175 if (ptr_ ) 176 ptr_ ->Release(); 177 ptr_ = p; 178 return *this; 179 } 180 181 CefRefPtr<T>& operator=(const CefRefPtr<T>& r) { 182 return *this = r.ptr_; 183 } 184 185 void swap(T** pp) { 186 T* p = ptr_; 187 ptr_ = *pp; 188 *pp = p; 189 } 190 191 void swap(CefRefPtr<T>& r) { 192 swap(&r.ptr_); // NOLINT(build/include_what_you_use) 193 } 194 195 private: 196 T* ptr_; 197 }; 198 199 #endif // CEF_INCLUDE_INTERNAL_CEF_PTR_H_