Home | History | Annotate | Download | only in gtk
      1 /*
      2  *  Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
      3  *  Copyright (C) 2008 Collabora Ltd.
      4  *  Copyright (C) 2009 Martin Robinson
      5  *
      6  *  This library is free software; you can redistribute it and/or
      7  *  modify it under the terms of the GNU Library General Public
      8  *  License as published by the Free Software Foundation; either
      9  *  version 2 of the License, or (at your option) any later version.
     10  *
     11  *  This library is distributed in the hope that it will be useful,
     12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14  *  Library General Public License for more details.
     15  *
     16  *  You should have received a copy of the GNU Library General Public License
     17  *  along with this library; see the file COPYING.LIB.  If not, write to
     18  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     19  *  Boston, MA 02110-1301, USA.
     20  *
     21  */
     22 
     23 #ifndef WTF_GRefPtr_h
     24 #define WTF_GRefPtr_h
     25 
     26 #include "AlwaysInline.h"
     27 #include <algorithm>
     28 
     29 typedef struct _GHashTable GHashTable;
     30 
     31 namespace WTF {
     32 
     33 enum GRefPtrAdoptType { GRefPtrAdopt };
     34 template <typename T> inline T* refGPtr(T*);
     35 template <typename T> inline void derefGPtr(T*);
     36 template <typename T> class GRefPtr;
     37 template <typename T> GRefPtr<T> adoptGRef(T*);
     38 template <> GHashTable* refGPtr(GHashTable* ptr);
     39 template <> void derefGPtr(GHashTable* ptr);
     40 
     41 template <typename T> class GRefPtr {
     42 public:
     43     GRefPtr() : m_ptr(0) { }
     44     GRefPtr(T* ptr) : m_ptr(ptr) { if (ptr) refGPtr(ptr); }
     45     GRefPtr(const GRefPtr& o) : m_ptr(o.m_ptr) { if (T* ptr = m_ptr) refGPtr(ptr); }
     46     template <typename U> GRefPtr(const GRefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) refGPtr(ptr); }
     47 
     48     ~GRefPtr() { if (T* ptr = m_ptr) derefGPtr(ptr); }
     49 
     50     void clear()
     51     {
     52         if (T* ptr = m_ptr)
     53             derefGPtr(ptr);
     54         m_ptr = 0;
     55     }
     56 
     57     T* get() const { return m_ptr; }
     58     T& operator*() const { return *m_ptr; }
     59     ALWAYS_INLINE T* operator->() const { return m_ptr; }
     60 
     61     bool operator!() const { return !m_ptr; }
     62 
     63     // This conversion operator allows implicit conversion to bool but not to other integer types.
     64     typedef T* GRefPtr::*UnspecifiedBoolType;
     65     operator UnspecifiedBoolType() const { return m_ptr ? &GRefPtr::m_ptr : 0; }
     66 
     67     GRefPtr& operator=(const GRefPtr&);
     68     GRefPtr& operator=(T*);
     69     template <typename U> GRefPtr& operator=(const GRefPtr<U>&);
     70 
     71     void swap(GRefPtr&);
     72     friend GRefPtr adoptGRef<T>(T*);
     73 
     74 private:
     75     static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
     76     // Adopting constructor.
     77     GRefPtr(T* ptr, GRefPtrAdoptType) : m_ptr(ptr) {}
     78 
     79     T* m_ptr;
     80 };
     81 
     82 template <typename T> inline GRefPtr<T>& GRefPtr<T>::operator=(const GRefPtr<T>& o)
     83 {
     84     T* optr = o.get();
     85     if (optr)
     86         refGPtr(optr);
     87     T* ptr = m_ptr;
     88     m_ptr = optr;
     89     if (ptr)
     90         derefGPtr(ptr);
     91     return *this;
     92 }
     93 
     94 template <typename T> inline GRefPtr<T>& GRefPtr<T>::operator=(T* optr)
     95 {
     96     T* ptr = m_ptr;
     97     if (optr)
     98         refGPtr(optr);
     99     m_ptr = optr;
    100     if (ptr)
    101         derefGPtr(ptr);
    102     return *this;
    103 }
    104 
    105 template <class T> inline void GRefPtr<T>::swap(GRefPtr<T>& o)
    106 {
    107     std::swap(m_ptr, o.m_ptr);
    108 }
    109 
    110 template <class T> inline void swap(GRefPtr<T>& a, GRefPtr<T>& b)
    111 {
    112     a.swap(b);
    113 }
    114 
    115 template <typename T, typename U> inline bool operator==(const GRefPtr<T>& a, const GRefPtr<U>& b)
    116 {
    117     return a.get() == b.get();
    118 }
    119 
    120 template <typename T, typename U> inline bool operator==(const GRefPtr<T>& a, U* b)
    121 {
    122     return a.get() == b;
    123 }
    124 
    125 template <typename T, typename U> inline bool operator==(T* a, const GRefPtr<U>& b)
    126 {
    127     return a == b.get();
    128 }
    129 
    130 template <typename T, typename U> inline bool operator!=(const GRefPtr<T>& a, const GRefPtr<U>& b)
    131 {
    132     return a.get() != b.get();
    133 }
    134 
    135 template <typename T, typename U> inline bool operator!=(const GRefPtr<T>& a, U* b)
    136 {
    137     return a.get() != b;
    138 }
    139 
    140 template <typename T, typename U> inline bool operator!=(T* a, const GRefPtr<U>& b)
    141 {
    142     return a != b.get();
    143 }
    144 
    145 template <typename T, typename U> inline GRefPtr<T> static_pointer_cast(const GRefPtr<U>& p)
    146 {
    147     return GRefPtr<T>(static_cast<T*>(p.get()));
    148 }
    149 
    150 template <typename T, typename U> inline GRefPtr<T> const_pointer_cast(const GRefPtr<U>& p)
    151 {
    152     return GRefPtr<T>(const_cast<T*>(p.get()));
    153 }
    154 
    155 template <typename T> inline T* getPtr(const GRefPtr<T>& p)
    156 {
    157     return p.get();
    158 }
    159 
    160 template <typename T> GRefPtr<T> adoptGRef(T* p)
    161 {
    162     return GRefPtr<T>(p, GRefPtrAdopt);
    163 }
    164 
    165 template <typename T> inline T* refGPtr(T* ptr)
    166 {
    167     if (ptr)
    168         g_object_ref_sink(ptr);
    169     return ptr;
    170 }
    171 
    172 template <typename T> inline void derefGPtr(T* ptr)
    173 {
    174     if (ptr)
    175         g_object_unref(ptr);
    176 }
    177 
    178 } // namespace WTF
    179 
    180 using WTF::GRefPtr;
    181 using WTF::refGPtr;
    182 using WTF::derefGPtr;
    183 using WTF::adoptGRef;
    184 using WTF::static_pointer_cast;
    185 using WTF::const_pointer_cast;
    186 
    187 #endif // WTF_GRefPtr_h
    188