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 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 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 74private: 75 T m_ptr; 76}; 77 78template <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 90template <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 102template <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 113template <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 121template <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 132template <class T> inline void JSRetainPtr<T>::swap(JSRetainPtr<T>& o) 133{ 134 std::swap(m_ptr, o.m_ptr); 135} 136 137template <class T> inline void swap(JSRetainPtr<T>& a, JSRetainPtr<T>& b) 138{ 139 a.swap(b); 140} 141 142template <typename T, typename U> inline bool operator==(const JSRetainPtr<T>& a, const JSRetainPtr<U>& b) 143{ 144 return a.get() == b.get(); 145} 146 147template <typename T, typename U> inline bool operator==(const JSRetainPtr<T>& a, U* b) 148{ 149 return a.get() == b; 150} 151 152template <typename T, typename U> inline bool operator==(T* a, const JSRetainPtr<U>& b) 153{ 154 return a == b.get(); 155} 156 157template <typename T, typename U> inline bool operator!=(const JSRetainPtr<T>& a, const JSRetainPtr<U>& b) 158{ 159 return a.get() != b.get(); 160} 161 162template <typename T, typename U> inline bool operator!=(const JSRetainPtr<T>& a, U* b) 163{ 164 return a.get() != b; 165} 166 167template <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