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/Noncopyable.h"
     26 #include "wtf/NullPtr.h"
     27 #include "wtf/OwnPtrCommon.h"
     28 #include <algorithm>
     29 
     30 namespace WTF {
     31 
     32     template<typename T> class PassOwnPtr;
     33 
     34     template<typename T> class OwnPtr {
     35 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
     36         // If rvalue references are not supported, the copy constructor is
     37         // public so OwnPtr cannot be marked noncopyable. See note below.
     38         WTF_MAKE_NONCOPYABLE(OwnPtr);
     39 #endif
     40         WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(OwnPtr);
     41     public:
     42         typedef typename RemoveExtent<T>::Type ValueType;
     43         typedef ValueType* PtrType;
     44 
     45         OwnPtr() : m_ptr(0) { }
     46         OwnPtr(std::nullptr_t) : m_ptr(0) { }
     47 
     48         // See comment in PassOwnPtr.h for why this takes a const reference.
     49         OwnPtr(const PassOwnPtr<T>&);
     50         template<typename U> OwnPtr(const PassOwnPtr<U>&, EnsurePtrConvertibleArgDecl(U, T));
     51 
     52 #if !COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
     53         // This copy constructor is used implicitly by gcc when it generates
     54         // transients for assigning a PassOwnPtr<T> object to a stack-allocated
     55         // OwnPtr<T> object. It should never be called explicitly and gcc
     56         // should optimize away the constructor when generating code.
     57         OwnPtr(const OwnPtr&);
     58 #endif
     59 
     60         ~OwnPtr()
     61         {
     62             OwnedPtrDeleter<T>::deletePtr(m_ptr);
     63             m_ptr = 0;
     64         }
     65 
     66         PtrType get() const { return m_ptr; }
     67 
     68         void clear();
     69         PassOwnPtr<T> release();
     70         PtrType leakPtr() WARN_UNUSED_RETURN;
     71 
     72         ValueType& operator*() const { ASSERT(m_ptr); return *m_ptr; }
     73         PtrType operator->() const { ASSERT(m_ptr); return m_ptr; }
     74 
     75         ValueType& operator[](std::ptrdiff_t i) const;
     76 
     77         bool operator!() const { return !m_ptr; }
     78 
     79         // This conversion operator allows implicit conversion to bool but not to other integer types.
     80         typedef PtrType OwnPtr::*UnspecifiedBoolType;
     81         operator UnspecifiedBoolType() const { return m_ptr ? &OwnPtr::m_ptr : 0; }
     82 
     83         OwnPtr& operator=(const PassOwnPtr<T>&);
     84         OwnPtr& operator=(std::nullptr_t) { clear(); return *this; }
     85         template<typename U> OwnPtr& operator=(const PassOwnPtr<U>&);
     86 
     87 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
     88         OwnPtr(OwnPtr&&);
     89         template<typename U> OwnPtr(OwnPtr<U>&&);
     90 
     91         OwnPtr& operator=(OwnPtr&&);
     92         template<typename U> OwnPtr& operator=(OwnPtr<U>&&);
     93 #endif
     94 
     95         void swap(OwnPtr& o) { std::swap(m_ptr, o.m_ptr); }
     96 
     97     private:
     98 #if !COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
     99         // If rvalue references are supported, noncopyable takes care of this.
    100         OwnPtr& operator=(const OwnPtr&);
    101 #endif
    102 
    103         // We should never have two OwnPtrs for the same underlying object (otherwise we'll get
    104         // double-destruction), so these equality operators should never be needed.
    105         template<typename U> bool operator==(const OwnPtr<U>&) const { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; }
    106         template<typename U> bool operator!=(const OwnPtr<U>&) const { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; }
    107         template<typename U> bool operator==(const PassOwnPtr<U>&) const { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; }
    108         template<typename U> bool operator!=(const PassOwnPtr<U>&) const { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; }
    109 
    110         PtrType m_ptr;
    111     };
    112 
    113     template<typename T> inline OwnPtr<T>::OwnPtr(const PassOwnPtr<T>& o)
    114         : m_ptr(o.leakPtr())
    115     {
    116     }
    117 
    118     template<typename T> template<typename U> inline OwnPtr<T>::OwnPtr(const PassOwnPtr<U>& o, EnsurePtrConvertibleArgDefn(U, T))
    119         : m_ptr(o.leakPtr())
    120     {
    121         COMPILE_ASSERT(!IsArray<T>::value, Pointers_to_array_must_never_be_converted);
    122     }
    123 
    124     template<typename T> inline void OwnPtr<T>::clear()
    125     {
    126         PtrType ptr = m_ptr;
    127         m_ptr = 0;
    128         OwnedPtrDeleter<T>::deletePtr(ptr);
    129     }
    130 
    131     template<typename T> inline PassOwnPtr<T> OwnPtr<T>::release()
    132     {
    133         PtrType ptr = m_ptr;
    134         m_ptr = 0;
    135         return PassOwnPtr<T>(ptr);
    136     }
    137 
    138     template<typename T> inline typename OwnPtr<T>::PtrType OwnPtr<T>::leakPtr()
    139     {
    140         PtrType ptr = m_ptr;
    141         m_ptr = 0;
    142         return ptr;
    143     }
    144 
    145     template<typename T> inline typename OwnPtr<T>::ValueType& OwnPtr<T>::operator[](std::ptrdiff_t i) const
    146     {
    147         COMPILE_ASSERT(IsArray<T>::value, Elements_access_is_possible_for_arrays_only);
    148         ASSERT(m_ptr);
    149         ASSERT(i >= 0);
    150         return m_ptr[i];
    151     }
    152 
    153     template<typename T> inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<T>& o)
    154     {
    155         PtrType ptr = m_ptr;
    156         m_ptr = o.leakPtr();
    157         ASSERT(!ptr || m_ptr != ptr);
    158         OwnedPtrDeleter<T>::deletePtr(ptr);
    159         return *this;
    160     }
    161 
    162     template<typename T> template<typename U> inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<U>& o)
    163     {
    164         COMPILE_ASSERT(!IsArray<T>::value, Pointers_to_array_must_never_be_converted);
    165         PtrType ptr = m_ptr;
    166         m_ptr = o.leakPtr();
    167         ASSERT(!ptr || m_ptr != ptr);
    168         OwnedPtrDeleter<T>::deletePtr(ptr);
    169         return *this;
    170     }
    171 
    172 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
    173     template<typename T> inline OwnPtr<T>::OwnPtr(OwnPtr<T>&& o)
    174         : m_ptr(o.leakPtr())
    175     {
    176     }
    177 
    178     template<typename T> template<typename U> inline OwnPtr<T>::OwnPtr(OwnPtr<U>&& o)
    179         : m_ptr(o.leakPtr())
    180     {
    181         COMPILE_ASSERT(!IsArray<T>::value, Pointers_to_array_must_never_be_converted);
    182     }
    183 
    184     template<typename T> inline OwnPtr<T>& OwnPtr<T>::operator=(OwnPtr<T>&& o)
    185     {
    186         PtrType ptr = m_ptr;
    187         m_ptr = o.leakPtr();
    188         ASSERT(!ptr || m_ptr != ptr);
    189         OwnedPtrDeleter<T>::deletePtr(ptr);
    190 
    191         return *this;
    192     }
    193 
    194     template<typename T> template<typename U> inline OwnPtr<T>& OwnPtr<T>::operator=(OwnPtr<U>&& o)
    195     {
    196         COMPILE_ASSERT(!IsArray<T>::value, Pointers_to_array_must_never_be_converted);
    197         PtrType ptr = m_ptr;
    198         m_ptr = o.leakPtr();
    199         ASSERT(!ptr || m_ptr != ptr);
    200         OwnedPtrDeleter<T>::deletePtr(ptr);
    201 
    202         return *this;
    203     }
    204 #endif
    205 
    206     template<typename T> inline void swap(OwnPtr<T>& a, OwnPtr<T>& b)
    207     {
    208         a.swap(b);
    209     }
    210 
    211     template<typename T, typename U> inline bool operator==(const OwnPtr<T>& a, U* b)
    212     {
    213         return a.get() == b;
    214     }
    215 
    216     template<typename T, typename U> inline bool operator==(T* a, const OwnPtr<U>& b)
    217     {
    218         return a == b.get();
    219     }
    220 
    221     template<typename T, typename U> inline bool operator!=(const OwnPtr<T>& a, U* b)
    222     {
    223         return a.get() != b;
    224     }
    225 
    226     template<typename T, typename U> inline bool operator!=(T* a, const OwnPtr<U>& b)
    227     {
    228         return a != b.get();
    229     }
    230 
    231     template<typename T> inline typename OwnPtr<T>::PtrType getPtr(const OwnPtr<T>& p)
    232     {
    233         return p.get();
    234     }
    235 
    236 } // namespace WTF
    237 
    238 using WTF::OwnPtr;
    239 
    240 #endif // WTF_OwnPtr_h
    241