1 /* 2 * Copyright (C) 2005, 2006, 2007, 2010 Apple 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 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef JSRetainPtr_h 30 #define JSRetainPtr_h 31 32 #include <JavaScriptCore/JSStringRef.h> 33 #include <algorithm> 34 35 inline void JSRetain(JSStringRef string) { JSStringRetain(string); } 36 inline void JSRelease(JSStringRef string) { JSStringRelease(string); } 37 38 enum AdoptTag { Adopt }; 39 40 template<typename T> class JSRetainPtr { 41 public: 42 JSRetainPtr() : m_ptr(0) { } 43 JSRetainPtr(T ptr) : m_ptr(ptr) { if (ptr) JSRetain(ptr); } 44 JSRetainPtr(AdoptTag, T ptr) : m_ptr(ptr) { } 45 JSRetainPtr(const JSRetainPtr&); 46 template<typename U> JSRetainPtr(const JSRetainPtr<U>&); 47 ~JSRetainPtr(); 48 49 T get() const { return m_ptr; } 50 51 void clear(); 52 T leakRef(); 53 54 T operator->() const { return m_ptr; } 55 56 bool operator!() const { return !m_ptr; } 57 58 // This conversion operator allows implicit conversion to bool but not to other integer types. 59 typedef T JSRetainPtr::*UnspecifiedBoolType; 60 operator UnspecifiedBoolType() const { return m_ptr ? &JSRetainPtr::m_ptr : 0; } 61 62 JSRetainPtr& operator=(const JSRetainPtr&); 63 template<typename U> JSRetainPtr& operator=(const JSRetainPtr<U>&); 64 JSRetainPtr& operator=(T); 65 template<typename U> JSRetainPtr& operator=(U*); 66 67 void adopt(T); 68 69 void swap(JSRetainPtr&); 70 71 // FIXME: Remove releaseRef once we change all callers to call leakRef instead. 72 T releaseRef() { return leakRef(); } 73 74 private: 75 T m_ptr; 76 }; 77 78 template<typename T> inline JSRetainPtr<T>::JSRetainPtr(const JSRetainPtr& o) 79 : m_ptr(o.m_ptr) 80 { 81 if (m_ptr) 82 JSRetain(m_ptr); 83 } 84 85 template<typename T> template<typename U> inline JSRetainPtr<T>::JSRetainPtr(const JSRetainPtr<U>& o) 86 : m_ptr(o.get()) 87 { 88 if (m_ptr) 89 JSRetain(m_ptr); 90 } 91 92 template<typename T> inline JSRetainPtr<T>::~JSRetainPtr() 93 { 94 if (m_ptr) 95 JSRelease(m_ptr); 96 } 97 98 template<typename T> inline void JSRetainPtr<T>::clear() 99 { 100 if (T ptr = m_ptr) { 101 m_ptr = 0; 102 JSRelease(ptr); 103 } 104 } 105 106 template<typename T> inline T JSRetainPtr<T>::leakRef() 107 { 108 T ptr = m_ptr; 109 m_ptr = 0; 110 return ptr; 111 } 112 113 template<typename T> inline JSRetainPtr<T>& JSRetainPtr<T>::operator=(const JSRetainPtr<T>& o) 114 { 115 T optr = o.get(); 116 if (optr) 117 JSRetain(optr); 118 T ptr = m_ptr; 119 m_ptr = optr; 120 if (ptr) 121 JSRelease(ptr); 122 return *this; 123 } 124 125 template<typename T> template<typename U> inline JSRetainPtr<T>& JSRetainPtr<T>::operator=(const JSRetainPtr<U>& o) 126 { 127 T optr = o.get(); 128 if (optr) 129 JSRetain(optr); 130 T ptr = m_ptr; 131 m_ptr = optr; 132 if (ptr) 133 JSRelease(ptr); 134 return *this; 135 } 136 137 template<typename T> inline JSRetainPtr<T>& JSRetainPtr<T>::operator=(T optr) 138 { 139 if (optr) 140 JSRetain(optr); 141 T ptr = m_ptr; 142 m_ptr = optr; 143 if (ptr) 144 JSRelease(ptr); 145 return *this; 146 } 147 148 template<typename T> inline void JSRetainPtr<T>::adopt(T optr) 149 { 150 T ptr = m_ptr; 151 m_ptr = optr; 152 if (ptr) 153 JSRelease(ptr); 154 } 155 156 template<typename T> template<typename U> inline JSRetainPtr<T>& JSRetainPtr<T>::operator=(U* optr) 157 { 158 if (optr) 159 JSRetain(optr); 160 T ptr = m_ptr; 161 m_ptr = optr; 162 if (ptr) 163 JSRelease(ptr); 164 return *this; 165 } 166 167 template<typename T> inline void JSRetainPtr<T>::swap(JSRetainPtr<T>& o) 168 { 169 std::swap(m_ptr, o.m_ptr); 170 } 171 172 template<typename T> inline void swap(JSRetainPtr<T>& a, JSRetainPtr<T>& b) 173 { 174 a.swap(b); 175 } 176 177 template<typename T, typename U> inline bool operator==(const JSRetainPtr<T>& a, const JSRetainPtr<U>& b) 178 { 179 return a.get() == b.get(); 180 } 181 182 template<typename T, typename U> inline bool operator==(const JSRetainPtr<T>& a, U* b) 183 { 184 return a.get() == b; 185 } 186 187 template<typename T, typename U> inline bool operator==(T* a, const JSRetainPtr<U>& b) 188 { 189 return a == b.get(); 190 } 191 192 template<typename T, typename U> inline bool operator!=(const JSRetainPtr<T>& a, const JSRetainPtr<U>& b) 193 { 194 return a.get() != b.get(); 195 } 196 197 template<typename T, typename U> inline bool operator!=(const JSRetainPtr<T>& a, U* b) 198 { 199 return a.get() != b; 200 } 201 202 template<typename T, typename U> inline bool operator!=(T* a, const JSRetainPtr<U>& b) 203 { 204 return a != b.get(); 205 } 206 207 208 #endif // JSRetainPtr_h 209