1 /* 2 * Copyright (C) 2005, 2006, 2007 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 45 JSRetainPtr(AdoptTag, T ptr) : m_ptr(ptr) { } 46 47 JSRetainPtr(const JSRetainPtr& o) : m_ptr(o.m_ptr) { if (T ptr = m_ptr) JSRetain(ptr); } 48 49 ~JSRetainPtr() { if (T ptr = m_ptr) JSRelease(ptr); } 50 51 template <typename U> JSRetainPtr(const JSRetainPtr<U>& o) : m_ptr(o.get()) { if (T ptr = m_ptr) JSRetain(ptr); } 52 53 T get() const { return m_ptr; } 54 55 T releaseRef() { T tmp = m_ptr; m_ptr = 0; return tmp; } 56 57 T operator->() const { return m_ptr; } 58 59 bool operator!() const { return !m_ptr; } 60 61 // This conversion operator allows implicit conversion to bool but not to other integer types. 62 typedef T JSRetainPtr::*UnspecifiedBoolType; 63 operator UnspecifiedBoolType() const { return m_ptr ? &JSRetainPtr::m_ptr : 0; } 64 65 JSRetainPtr& operator=(const JSRetainPtr&); 66 template <typename U> JSRetainPtr& operator=(const JSRetainPtr<U>&); 67 JSRetainPtr& operator=(T); 68 template <typename U> JSRetainPtr& operator=(U*); 69 70 void adopt(T); 71 72 void swap(JSRetainPtr&); 73 74 private: 75 T m_ptr; 76 }; 77 78 template <typename T> inline JSRetainPtr<T>& JSRetainPtr<T>::operator=(const JSRetainPtr<T>& o) 79 { 80 T optr = o.get(); 81 if (optr) 82 JSRetain(optr); 83 T ptr = m_ptr; 84 m_ptr = optr; 85 if (ptr) 86 JSRelease(ptr); 87 return *this; 88 } 89 90 template <typename T> template <typename U> inline JSRetainPtr<T>& JSRetainPtr<T>::operator=(const JSRetainPtr<U>& o) 91 { 92 T optr = o.get(); 93 if (optr) 94 JSRetain(optr); 95 T ptr = m_ptr; 96 m_ptr = optr; 97 if (ptr) 98 JSRelease(ptr); 99 return *this; 100 } 101 102 template <typename T> inline JSRetainPtr<T>& JSRetainPtr<T>::operator=(T optr) 103 { 104 if (optr) 105 JSRetain(optr); 106 T ptr = m_ptr; 107 m_ptr = optr; 108 if (ptr) 109 JSRelease(ptr); 110 return *this; 111 } 112 113 template <typename T> inline void JSRetainPtr<T>::adopt(T optr) 114 { 115 T ptr = m_ptr; 116 m_ptr = optr; 117 if (ptr) 118 JSRelease(ptr); 119 } 120 121 template <typename T> template <typename U> inline JSRetainPtr<T>& JSRetainPtr<T>::operator=(U* optr) 122 { 123 if (optr) 124 JSRetain(optr); 125 T ptr = m_ptr; 126 m_ptr = optr; 127 if (ptr) 128 JSRelease(ptr); 129 return *this; 130 } 131 132 template <class T> inline void JSRetainPtr<T>::swap(JSRetainPtr<T>& o) 133 { 134 std::swap(m_ptr, o.m_ptr); 135 } 136 137 template <class T> inline void swap(JSRetainPtr<T>& a, JSRetainPtr<T>& b) 138 { 139 a.swap(b); 140 } 141 142 template <typename T, typename U> inline bool operator==(const JSRetainPtr<T>& a, const JSRetainPtr<U>& b) 143 { 144 return a.get() == b.get(); 145 } 146 147 template <typename T, typename U> inline bool operator==(const JSRetainPtr<T>& a, U* b) 148 { 149 return a.get() == b; 150 } 151 152 template <typename T, typename U> inline bool operator==(T* a, const JSRetainPtr<U>& b) 153 { 154 return a == b.get(); 155 } 156 157 template <typename T, typename U> inline bool operator!=(const JSRetainPtr<T>& a, const JSRetainPtr<U>& b) 158 { 159 return a.get() != b.get(); 160 } 161 162 template <typename T, typename U> inline bool operator!=(const JSRetainPtr<T>& a, U* b) 163 { 164 return a.get() != b; 165 } 166 167 template <typename T, typename U> inline bool operator!=(T* a, const JSRetainPtr<U>& b) 168 { 169 return a != b.get(); 170 } 171 172 173 #endif // JSRetainPtr_h 174