Home | History | Annotate | Download | only in API
      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