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