Home | History | Annotate | Download | only in cpp
      1 /*
      2  * Copyright (C) 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  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
     14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
     17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     23  * THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #ifndef WKRetainPtr_h
     27 #define WKRetainPtr_h
     28 
     29 #include <WebKit2/WKType.h>
     30 #include <algorithm>
     31 
     32 namespace WebKit {
     33 
     34 enum WKAdoptTag { AdoptWK };
     35 
     36 template<typename T> class WKRetainPtr {
     37 public:
     38     typedef T PtrType;
     39 
     40     WKRetainPtr()
     41         : m_ptr(0)
     42     {
     43     }
     44 
     45     WKRetainPtr(PtrType ptr)
     46         : m_ptr(ptr)
     47     {
     48         if (ptr)
     49             WKRetain(ptr);
     50     }
     51 
     52     WKRetainPtr(WKAdoptTag, PtrType ptr)
     53         : m_ptr(ptr)
     54     {
     55     }
     56 
     57     template<typename U> WKRetainPtr(const WKRetainPtr<U>& o)
     58         : m_ptr(o.get())
     59     {
     60         if (PtrType ptr = m_ptr)
     61             WKRetain(ptr);
     62     }
     63 
     64     WKRetainPtr(const WKRetainPtr& o)
     65         : m_ptr(o.m_ptr)
     66     {
     67         if (PtrType ptr = m_ptr)
     68             WKRetain(ptr);
     69     }
     70 
     71     ~WKRetainPtr()
     72     {
     73         if (PtrType ptr = m_ptr)
     74             WKRelease(ptr);
     75     }
     76 
     77     PtrType get() const { return m_ptr; }
     78 
     79     void clear()
     80     {
     81         PtrType ptr = m_ptr;
     82         m_ptr = 0;
     83         if (ptr)
     84             WKRelease(ptr);
     85     }
     86 
     87     PtrType leakRef()
     88     {
     89         PtrType ptr = m_ptr;
     90         m_ptr = 0;
     91         return ptr;
     92     }
     93 
     94     PtrType operator->() const { return m_ptr; }
     95     bool operator!() const { return !m_ptr; }
     96 
     97     // This conversion operator allows implicit conversion to bool but not to other integer types.
     98     typedef PtrType WKRetainPtr::*UnspecifiedBoolType;
     99     operator UnspecifiedBoolType() const { return m_ptr ? &WKRetainPtr::m_ptr : 0; }
    100 
    101     WKRetainPtr& operator=(const WKRetainPtr&);
    102     template<typename U> WKRetainPtr& operator=(const WKRetainPtr<U>&);
    103     WKRetainPtr& operator=(PtrType);
    104     template<typename U> WKRetainPtr& operator=(U*);
    105 
    106     void adopt(PtrType);
    107     void swap(WKRetainPtr&);
    108 
    109 private:
    110     PtrType m_ptr;
    111 };
    112 
    113 template<typename T> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(const WKRetainPtr<T>& o)
    114 {
    115     PtrType optr = o.get();
    116     if (optr)
    117         WKRetain(optr);
    118     PtrType ptr = m_ptr;
    119     m_ptr = optr;
    120     if (ptr)
    121         WKRelease(ptr);
    122     return *this;
    123 }
    124 
    125 template<typename T> template<typename U> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(const WKRetainPtr<U>& o)
    126 {
    127     PtrType optr = o.get();
    128     if (optr)
    129         WKRetain(optr);
    130     PtrType ptr = m_ptr;
    131     m_ptr = optr;
    132     if (ptr)
    133         WKRelease(ptr);
    134     return *this;
    135 }
    136 
    137 template<typename T> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(PtrType optr)
    138 {
    139     if (optr)
    140         WKRetain(optr);
    141     PtrType ptr = m_ptr;
    142     m_ptr = optr;
    143     if (ptr)
    144         WKRelease(ptr);
    145     return *this;
    146 }
    147 
    148 template<typename T> inline void WKRetainPtr<T>::adopt(PtrType optr)
    149 {
    150     PtrType ptr = m_ptr;
    151     m_ptr = optr;
    152     if (ptr)
    153         WKRelease(ptr);
    154 }
    155 
    156 template<typename T> template<typename U> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(U* optr)
    157 {
    158     if (optr)
    159         WKRetain(optr);
    160     PtrType ptr = m_ptr;
    161     m_ptr = optr;
    162     if (ptr)
    163         WKRelease(ptr);
    164     return *this;
    165 }
    166 
    167 template<typename T> inline void WKRetainPtr<T>::swap(WKRetainPtr<T>& o)
    168 {
    169     std::swap(m_ptr, o.m_ptr);
    170 }
    171 
    172 template<typename T> inline void swap(WKRetainPtr<T>& a, WKRetainPtr<T>& b)
    173 {
    174     a.swap(b);
    175 }
    176 
    177 template<typename T, typename U> inline bool operator==(const WKRetainPtr<T>& a, const WKRetainPtr<U>& b)
    178 {
    179     return a.get() == b.get();
    180 }
    181 
    182 template<typename T, typename U> inline bool operator==(const WKRetainPtr<T>& a, U* b)
    183 {
    184     return a.get() == b;
    185 }
    186 
    187 template<typename T, typename U> inline bool operator==(T* a, const WKRetainPtr<U>& b)
    188 {
    189     return a == b.get();
    190 }
    191 
    192 template<typename T, typename U> inline bool operator!=(const WKRetainPtr<T>& a, const WKRetainPtr<U>& b)
    193 {
    194     return a.get() != b.get();
    195 }
    196 
    197 template<typename T, typename U> inline bool operator!=(const WKRetainPtr<T>& a, U* b)
    198 {
    199     return a.get() != b;
    200 }
    201 
    202 template<typename T, typename U> inline bool operator!=(T* a, const WKRetainPtr<U>& b)
    203 {
    204     return a != b.get();
    205 }
    206 
    207 template<typename T> inline WKRetainPtr<T> adoptWK(T o)
    208 {
    209     return WKRetainPtr<T>(AdoptWK, o);
    210 }
    211 
    212 } // namespace WebKit
    213 
    214 using WebKit::WKRetainPtr;
    215 using WebKit::AdoptWK;
    216 using WebKit::adoptWK;
    217 
    218 #endif // WKRetainPtr_h
    219