Home | History | Annotate | Download | only in wtf
      1 /*
      2  *  Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
      3  *  Copyright (C) 2013 Intel Corporation. All rights reserved.
      4  *
      5  *  This library is free software; you can redistribute it and/or
      6  *  modify it under the terms of the GNU Library General Public
      7  *  License as published by the Free Software Foundation; either
      8  *  version 2 of the License, or (at your option) any later version.
      9  *
     10  *  This library is distributed in the hope that it will be useful,
     11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13  *  Library General Public License for more details.
     14  *
     15  *  You should have received a copy of the GNU Library General Public License
     16  *  along with this library; see the file COPYING.LIB.  If not, write to
     17  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     18  *  Boston, MA 02110-1301, USA.
     19  *
     20  */
     21 
     22 #ifndef WTF_OwnPtr_h
     23 #define WTF_OwnPtr_h
     24 
     25 #include "wtf/HashTableDeletedValueType.h"
     26 #include "wtf/Noncopyable.h"
     27 #include "wtf/NullPtr.h"
     28 #include "wtf/OwnPtrCommon.h"
     29 #include <algorithm>
     30 
     31 namespace WTF {
     32 
     33     template<typename T> class PassOwnPtr;
     34 
     35     template<typename T> class OwnPtr {
     36 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
     37         // If rvalue references are not supported, the copy constructor is
     38         // public so OwnPtr cannot be marked noncopyable. See note below.
     39         WTF_MAKE_NONCOPYABLE(OwnPtr);
     40 #endif
     41         WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(OwnPtr);
     42     public:
     43         typedef typename RemoveExtent<T>::Type ValueType;
     44         typedef ValueType* PtrType;
     45 
     46         OwnPtr() : m_ptr(0) { }
     47         OwnPtr(std::nullptr_t) : m_ptr(0) { }
     48 
     49         // See comment in PassOwnPtr.h for why this takes a const reference.
     50         OwnPtr(const PassOwnPtr<T>&);
     51         template<typename U> OwnPtr(const PassOwnPtr<U>&, EnsurePtrConvertibleArgDecl(U, T));
     52 
     53         // Hash table deleted values, which are only constructed and never copied or destroyed.
     54         OwnPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
     55         bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
     56 
     57 #if !COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
     58         // This copy constructor is used implicitly by gcc when it generates
     59         // transients for assigning a PassOwnPtr<T> object to a stack-allocated
     60         // OwnPtr<T> object. It should never be called explicitly and gcc
     61         // should optimize away the constructor when generating code.
     62         OwnPtr(const OwnPtr&);
     63 #endif
     64 
     65         ~OwnPtr()
     66         {
     67             OwnedPtrDeleter<T>::deletePtr(m_ptr);
     68             m_ptr = 0;
     69         }
     70 
     71         PtrType get() const { return m_ptr; }
     72 
     73         void clear();
     74         PassOwnPtr<T> release();
     75         PtrType leakPtr() WARN_UNUSED_RETURN;
     76 
     77         ValueType& operator*() const { ASSERT(m_ptr); return *m_ptr; }
     78         PtrType operator->() const { ASSERT(m_ptr); return m_ptr; }
     79 
     80         ValueType& operator[](std::ptrdiff_t i) const;
     81 
     82         bool operator!() const { return !m_ptr; }
     83 
     84         // This conversion operator allows implicit conversion to bool but not to other integer types.
     85         typedef PtrType OwnPtr::*UnspecifiedBoolType;
     86         operator UnspecifiedBoolType() const { return m_ptr ? &OwnPtr::m_ptr : 0; }
     87 
     88         OwnPtr& operator=(const PassOwnPtr<T>&);
     89         OwnPtr& operator=(std::nullptr_t) { clear(); return *this; }
     90         template<typename U> OwnPtr& operator=(const PassOwnPtr<U>&);
     91 
     92 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
     93         OwnPtr(OwnPtr&&);
     94         template<typename U> OwnPtr(OwnPtr<U>&&);
     95 
     96         OwnPtr& operator=(OwnPtr&&);
     97         template<typename U> OwnPtr& operator=(OwnPtr<U>&&);
     98 #endif
     99 
    100         void swap(OwnPtr& o) { std::swap(m_ptr, o.m_ptr); }
    101 
    102         static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
    103 
    104     private:
    105 #if !COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
    106         // If rvalue references are supported, noncopyable takes care of this.
    107         OwnPtr& operator=(const OwnPtr&);
    108 #endif
    109 
    110         // We should never have two OwnPtrs for the same underlying object (otherwise we'll get
    111         // double-destruction), so these equality operators should never be needed.
    112         template<typename U> bool operator==(const OwnPtr<U>&) const { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; }
    113         template<typename U> bool operator!=(const OwnPtr<U>&) const { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; }
    114         template<typename U> bool operator==(const PassOwnPtr<U>&) const { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; }
    115         template<typename U> bool operator!=(const PassOwnPtr<U>&) const { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; }
    116 
    117         PtrType m_ptr;
    118     };
    119 
    120     template<typename T> inline OwnPtr<T>::OwnPtr(const PassOwnPtr<T>& o)
    121         : m_ptr(o.leakPtr())
    122     {
    123     }
    124 
    125     template<typename T> template<typename U> inline OwnPtr<T>::OwnPtr(const PassOwnPtr<U>& o, EnsurePtrConvertibleArgDefn(U, T))
    126         : m_ptr(o.leakPtr())
    127     {
    128         COMPILE_ASSERT(!IsArray<T>::value, Pointers_to_array_must_never_be_converted);
    129     }
    130 
    131     template<typename T> inline void OwnPtr<T>::clear()
    132     {
    133         PtrType ptr = m_ptr;
    134         m_ptr = 0;
    135         OwnedPtrDeleter<T>::deletePtr(ptr);
    136     }
    137 
    138     template<typename T> inline PassOwnPtr<T> OwnPtr<T>::release()
    139     {
    140         PtrType ptr = m_ptr;
    141         m_ptr = 0;
    142         return PassOwnPtr<T>(ptr);
    143     }
    144 
    145     template<typename T> inline typename OwnPtr<T>::PtrType OwnPtr<T>::leakPtr()
    146     {
    147         PtrType ptr = m_ptr;
    148         m_ptr = 0;
    149         return ptr;
    150     }
    151 
    152     template<typename T> inline typename OwnPtr<T>::ValueType& OwnPtr<T>::operator[](std::ptrdiff_t i) const
    153     {
    154         COMPILE_ASSERT(IsArray<T>::value, Elements_access_is_possible_for_arrays_only);
    155         ASSERT(m_ptr);
    156         ASSERT(i >= 0);
    157         return m_ptr[i];
    158     }
    159 
    160     template<typename T> inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<T>& o)
    161     {
    162         PtrType ptr = m_ptr;
    163         m_ptr = o.leakPtr();
    164         ASSERT(!ptr || m_ptr != ptr);
    165         OwnedPtrDeleter<T>::deletePtr(ptr);
    166         return *this;
    167     }
    168 
    169     template<typename T> template<typename U> inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<U>& o)
    170     {
    171         COMPILE_ASSERT(!IsArray<T>::value, Pointers_to_array_must_never_be_converted);
    172         PtrType ptr = m_ptr;
    173         m_ptr = o.leakPtr();
    174         ASSERT(!ptr || m_ptr != ptr);
    175         OwnedPtrDeleter<T>::deletePtr(ptr);
    176         return *this;
    177     }
    178 
    179 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
    180     template<typename T> inline OwnPtr<T>::OwnPtr(OwnPtr<T>&& o)
    181         : m_ptr(o.leakPtr())
    182     {
    183     }
    184 
    185     template<typename T> template<typename U> inline OwnPtr<T>::OwnPtr(OwnPtr<U>&& o)
    186         : m_ptr(o.leakPtr())
    187     {
    188         COMPILE_ASSERT(!IsArray<T>::value, Pointers_to_array_must_never_be_converted);
    189     }
    190 
    191     template<typename T> inline OwnPtr<T>& OwnPtr<T>::operator=(OwnPtr<T>&& o)
    192     {
    193         PtrType ptr = m_ptr;
    194         m_ptr = o.leakPtr();
    195         ASSERT(!ptr || m_ptr != ptr);
    196         OwnedPtrDeleter<T>::deletePtr(ptr);
    197 
    198         return *this;
    199     }
    200 
    201     template<typename T> template<typename U> inline OwnPtr<T>& OwnPtr<T>::operator=(OwnPtr<U>&& o)
    202     {
    203         COMPILE_ASSERT(!IsArray<T>::value, Pointers_to_array_must_never_be_converted);
    204         PtrType ptr = m_ptr;
    205         m_ptr = o.leakPtr();
    206         ASSERT(!ptr || m_ptr != ptr);
    207         OwnedPtrDeleter<T>::deletePtr(ptr);
    208 
    209         return *this;
    210     }
    211 #endif
    212 
    213     template<typename T> inline void swap(OwnPtr<T>& a, OwnPtr<T>& b)
    214     {
    215         a.swap(b);
    216     }
    217 
    218     template<typename T, typename U> inline bool operator==(const OwnPtr<T>& a, U* b)
    219     {
    220         return a.get() == b;
    221     }
    222 
    223     template<typename T, typename U> inline bool operator==(T* a, const OwnPtr<U>& b)
    224     {
    225         return a == b.get();
    226     }
    227 
    228     template<typename T, typename U> inline bool operator!=(const OwnPtr<T>& a, U* b)
    229     {
    230         return a.get() != b;
    231     }
    232 
    233     template<typename T, typename U> inline bool operator!=(T* a, const OwnPtr<U>& b)
    234     {
    235         return a != b.get();
    236     }
    237 
    238     template<typename T> inline typename OwnPtr<T>::PtrType getPtr(const OwnPtr<T>& p)
    239     {
    240         return p.get();
    241     }
    242 
    243 } // namespace WTF
    244 
    245 using WTF::OwnPtr;
    246 
    247 #endif // WTF_OwnPtr_h
    248