18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
25af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke *  Copyright (C) 2006, 2010 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is free software; you can redistribute it and/or
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  modify it under the terms of the GNU Library General Public
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  License as published by the Free Software Foundation; either
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  version 2 of the License, or (at your option) any later version.
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is distributed in the hope that it will be useful,
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  but WITHOUT ANY WARRANTY; without even the implied warranty of
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Library General Public License for more details.
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  You should have received a copy of the GNU Library General Public License
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  along with this library; see the file COPYING.LIB.  If not, write to
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Boston, MA 02110-1301, USA.
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef WTF_OwnArrayPtr_h
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define WTF_OwnArrayPtr_h
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
245ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "Assertions.h"
255ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "Noncopyable.h"
26a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "NullPtr.h"
272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "PassOwnArrayPtr.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <algorithm>
295ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WTF {
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
325ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsentemplate<typename T> class PassOwnArrayPtr;
335ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsentemplate<typename T> PassOwnArrayPtr<T> adoptArrayPtr(T*);
345ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
35ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochtemplate <typename T> class OwnArrayPtr {
365ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenpublic:
375ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    typedef T* PtrType;
385ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
395ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    OwnArrayPtr() : m_ptr(0) { }
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
415ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // See comment in PassOwnArrayPtr.h for why this takes a const reference.
425ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    template<typename U> OwnArrayPtr(const PassOwnArrayPtr<U>& o);
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
445ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // This copy constructor is used implicitly by gcc when it generates
455ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // transients for assigning a PassOwnArrayPtr<T> object to a stack-allocated
465ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // OwnArrayPtr<T> object. It should never be called explicitly and gcc
475ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // should optimize away the constructor when generating code.
485ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    OwnArrayPtr(const OwnArrayPtr<T>&);
495af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
505ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    ~OwnArrayPtr() { deleteOwnedArrayPtr(m_ptr); }
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
525ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    PtrType get() const { return m_ptr; }
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
545ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    void clear();
555ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    PassOwnArrayPtr<T> release();
565ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    PtrType leakPtr() WARN_UNUSED_RETURN;
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
585ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    T& operator*() const { ASSERT(m_ptr); return *m_ptr; }
595ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    PtrType operator->() const { ASSERT(m_ptr); return m_ptr; }
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
615ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    T& operator[](std::ptrdiff_t i) const { ASSERT(m_ptr); ASSERT(i >= 0); return m_ptr[i]; }
625ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
635ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    bool operator!() const { return !m_ptr; }
645ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
655ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // This conversion operator allows implicit conversion to bool but not to other integer types.
660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if COMPILER(WINSCW)
675ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    operator bool() const { return m_ptr; }
680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else
695ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    typedef T* OwnArrayPtr::*UnspecifiedBoolType;
705ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    operator UnspecifiedBoolType() const { return m_ptr ? &OwnArrayPtr::m_ptr : 0; }
715ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#endif
725ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
735ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    OwnArrayPtr& operator=(const PassOwnArrayPtr<T>&);
74a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    OwnArrayPtr& operator=(std::nullptr_t) { clear(); return *this; }
755ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    template<typename U> OwnArrayPtr& operator=(const PassOwnArrayPtr<U>&);
765ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
775ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    void swap(OwnArrayPtr& o) { std::swap(m_ptr, o.m_ptr); }
785ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
795ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#ifdef LOOSE_OWN_ARRAY_PTR
805ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    explicit OwnArrayPtr(PtrType ptr) : m_ptr(ptr) { }
815ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    void set(PtrType);
825ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#endif
835ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
845ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenprivate:
855ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    PtrType m_ptr;
865ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen};
875ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
885ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsentemplate<typename T> template<typename U> inline OwnArrayPtr<T>::OwnArrayPtr(const PassOwnArrayPtr<U>& o)
895ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    : m_ptr(o.leakPtr())
905ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
915ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
925ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
935ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsentemplate<typename T> inline void OwnArrayPtr<T>::clear()
945ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
955ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    PtrType ptr = m_ptr;
965ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_ptr = 0;
975ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    deleteOwnedArrayPtr(ptr);
985ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
995ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1005ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsentemplate<typename T> inline PassOwnArrayPtr<T> OwnArrayPtr<T>::release()
1015ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
1025ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    PtrType ptr = m_ptr;
1035ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_ptr = 0;
1045ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return adoptArrayPtr(ptr);
1055ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1065ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1075ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsentemplate<typename T> inline typename OwnArrayPtr<T>::PtrType OwnArrayPtr<T>::leakPtr()
1085ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
1095ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    PtrType ptr = m_ptr;
1105ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_ptr = 0;
1115ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return ptr;
1125ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1135ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
11481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#ifdef LOOSE_OWN_ARRAY_PTR
11581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochtemplate<typename T> inline void OwnArrayPtr<T>::set(PtrType ptr)
11681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
11781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(!ptr || m_ptr != ptr);
11881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    PtrType oldPtr = m_ptr;
11981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_ptr = ptr;
12081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    deleteOwnedArrayPtr(oldPtr);
12181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
12281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#endif
12381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
1245ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsentemplate<typename T> inline OwnArrayPtr<T>& OwnArrayPtr<T>::operator=(const PassOwnArrayPtr<T>& o)
1255ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
1265ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    PtrType ptr = m_ptr;
1275ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_ptr = o.leakPtr();
1285ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    ASSERT(!ptr || m_ptr != ptr);
1295ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    deleteOwnedArrayPtr(ptr);
1305ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return *this;
1315ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1325ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1335ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsentemplate<typename T> template<typename U> inline OwnArrayPtr<T>& OwnArrayPtr<T>::operator=(const PassOwnArrayPtr<U>& o)
1345ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
1355ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    PtrType ptr = m_ptr;
1365ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_ptr = o.leakPtr();
1375ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    ASSERT(!ptr || m_ptr != ptr);
1385ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    deleteOwnedArrayPtr(ptr);
1395ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return *this;
1405ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1415ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1425ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsentemplate <typename T> inline void swap(OwnArrayPtr<T>& a, OwnArrayPtr<T>& b)
1435ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
1445ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    a.swap(b);
1455ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1465ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1475ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsentemplate<typename T, typename U> inline bool operator==(const OwnArrayPtr<T>& a, U* b)
1485ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
1495ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return a.get() == b;
1505ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1515ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1525ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsentemplate<typename T, typename U> inline bool operator==(T* a, const OwnArrayPtr<U>& b)
1535ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
1545ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return a == b.get();
1555ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1565ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1575ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsentemplate<typename T, typename U> inline bool operator!=(const OwnArrayPtr<T>& a, U* b)
1585ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
1595ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return a.get() != b;
1605ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1615ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1625ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsentemplate<typename T, typename U> inline bool operator!=(T* a, const OwnArrayPtr<U>& b)
1635ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
1645ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return a != b.get();
1655ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1665ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1675ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsentemplate <typename T> inline T* getPtr(const OwnArrayPtr<T>& p)
1685ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
1695ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return p.get();
1705ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WTF
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing WTF::OwnArrayPtr;
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif // WTF_OwnArrayPtr_h
177