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 35inline void JSRetain(JSStringRef string) { JSStringRetain(string); } 36inline void JSRelease(JSStringRef string) { JSStringRelease(string); } 37 38enum AdoptTag { Adopt }; 39 40template<typename T> class JSRetainPtr { 41public: 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 74private: 75 T m_ptr; 76}; 77 78template<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 85template<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 92template<typename T> inline JSRetainPtr<T>::~JSRetainPtr() 93{ 94 if (m_ptr) 95 JSRelease(m_ptr); 96} 97 98template<typename T> inline void JSRetainPtr<T>::clear() 99{ 100 if (T ptr = m_ptr) { 101 m_ptr = 0; 102 JSRelease(ptr); 103 } 104} 105 106template<typename T> inline T JSRetainPtr<T>::leakRef() 107{ 108 T ptr = m_ptr; 109 m_ptr = 0; 110 return ptr; 111} 112 113template<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 125template<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 137template<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 148template<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 156template<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 167template<typename T> inline void JSRetainPtr<T>::swap(JSRetainPtr<T>& o) 168{ 169 std::swap(m_ptr, o.m_ptr); 170} 171 172template<typename T> inline void swap(JSRetainPtr<T>& a, JSRetainPtr<T>& b) 173{ 174 a.swap(b); 175} 176 177template<typename T, typename U> inline bool operator==(const JSRetainPtr<T>& a, const JSRetainPtr<U>& b) 178{ 179 return a.get() == b.get(); 180} 181 182template<typename T, typename U> inline bool operator==(const JSRetainPtr<T>& a, U* b) 183{ 184 return a.get() == b; 185} 186 187template<typename T, typename U> inline bool operator==(T* a, const JSRetainPtr<U>& b) 188{ 189 return a == b.get(); 190} 191 192template<typename T, typename U> inline bool operator!=(const JSRetainPtr<T>& a, const JSRetainPtr<U>& b) 193{ 194 return a.get() != b.get(); 195} 196 197template<typename T, typename U> inline bool operator!=(const JSRetainPtr<T>& a, U* b) 198{ 199 return a.get() != b; 200} 201 202template<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