1 // Copyright (C) 2014 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 #ifndef EMUGL_SMART_PTR_H 15 #define EMUGL_SMART_PTR_H 16 17 #include <stddef.h> 18 19 namespace emugl { 20 21 // Hidden atomic ref-counting implementation. 22 class RefCount; 23 24 // Base class for all templated SmartPtr<> instances. Reduces 25 // template expansion and code. Consider this to be an implementation 26 // detail of SmartPtr<>, so don't rely on anything here. 27 class SmartPtrBase { 28 public: 29 // Defrault constructor. SmartPtrBase()30 SmartPtrBase() : mPtr(NULL), mRefCount(NULL) {} 31 32 // Normal constructor. This takes ownership of |ptr|, though only 33 // template instances are capable of destroying the object. 34 explicit SmartPtrBase(void* ptr); 35 36 // Copy-constructor, this increments the reference count. 37 SmartPtrBase(const SmartPtrBase& other); 38 39 // Assignment operator, also increments the reference count. 40 SmartPtrBase& operator=(const SmartPtrBase& other); 41 42 // Nothing happens in this destructor, the real work must be performed 43 // in subclasses. ~SmartPtrBase()44 ~SmartPtrBase() {} 45 46 47 // Used to enable 'if (smart_ptr) { ... }' properly. 48 operator void*() const { 49 return mPtr; 50 } 51 52 // Return internal reference count value, only use for unit testing. 53 int getRefCount() const; 54 55 protected: 56 // Used internally to increment the reference count. 57 void addRef(); 58 59 // Copy the |other| into this instance, returns the old pointer value 60 // if it needs to be destroyed by the caller, or NULL otherwise. 61 void* copyFrom(const SmartPtrBase& other); 62 63 // Used internally to decrement the reference count, if it reaches 0, 64 // returns the pointer to be destroyed, NULL otherwise. 65 void* release(); 66 67 void* mPtr; 68 RefCount* mRefCount; 69 }; 70 71 72 // The real template class to be used for smart pointers. 73 // Typical uses: 74 // 75 // SmartPtr<Foo> ptr(new Foo()); // takes ownership. 76 // SmartPtr<Foo> ptr2; // empty pointer. 77 // ptr2 = ptr; // copies pointer + increment reference count. 78 // Foo* obj = ptr.Ptr(); // access pointed object. 79 // ptr->DoStuff(); // operate directly on pointed object. 80 // (*ptr)->DoStuff(); // same here. 81 // 82 // On scope exit, the internal reference count is decremented and the 83 // object is deleted automatically when it reaches 0, indicating that 84 // there are no more owners. 85 // 86 // IMPORTANT: You need to be sure that only one 'chain' of smart pointers 87 // own a given object. I.e. the following is incorrect: 88 // 89 // Foo* foo = new Foo(); // create new instance. 90 // SmartPtr<Foo> ptr(foo); // |ptr| takes ownership of |foo|. 91 // SmartPtr<Foo> ptr2(foo); // |ptr2| takes also ownership of |foo|. 92 // 93 // The problem is that |ptr| and |ptr2| don't know anything about each 94 // other, and will not share the same reference count. Once a smart pointer 95 // owns an object, only use other smart pointers that are copy-constructed 96 // or assigned with the initial one to keep everything consistent. 97 template <class T> 98 class SmartPtr : public emugl::SmartPtrBase { 99 public: 100 // Default constructor. The instance holds a NULL pointer. SmartPtr()101 SmartPtr() : SmartPtrBase() {} 102 103 // Regular constructor, takes ownership of |ptr|. SmartPtr(T * ptr)104 explicit SmartPtr(T* ptr) : SmartPtrBase(ptr) {} 105 106 // Copy-constructor, |this| and |other| will share the same internal 107 // reference count, which is incremented by 1. SmartPtr(const SmartPtr & other)108 SmartPtr(const SmartPtr& other) 109 : SmartPtrBase(reinterpret_cast<const SmartPtrBase&>(other)) {} 110 111 // Assignment operator, same semantics as copy-constructor. 112 SmartPtr& operator=(const SmartPtr& other) { 113 void* old_ptr = copyFrom(static_cast<const SmartPtrBase&>(other)); 114 if (old_ptr) 115 delete reinterpret_cast<T*>(old_ptr); 116 return *this; 117 } 118 119 // Destructor, decrements reference count and destroys the object 120 // if it reaches 0 (indicating this was the last owning smart pointer). ~SmartPtr()121 ~SmartPtr() { 122 void* ptr = release(); 123 if (ptr) 124 delete reinterpret_cast<T*>(ptr); 125 } 126 127 // Return owned object instance, or NULL. Ptr()128 T* Ptr() const { 129 return reinterpret_cast<T*>(mPtr); 130 } 131 132 // Return owned object instance, or NULL constPtr()133 const T* constPtr() const { 134 return reinterpret_cast<const T*>(mPtr); 135 } 136 137 // Operate directly on owned object. 138 T* operator->() const { 139 return Ptr(); 140 } 141 142 // Return reference to owned object. 143 T& operator*() const { 144 return *Ptr(); 145 } 146 }; 147 148 } // namespace emugl 149 150 #endif // EMUGL_SMART_PTR_H 151