Home | History | Annotate | Download | only in testing
      1 /*
      2  * Copyright (C) 2013 Google 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 are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #ifndef WebScopedPtr_h
     32 #define WebScopedPtr_h
     33 
     34 #include <stddef.h>
     35 
     36 namespace WebTestRunner {
     37 
     38 template<typename Deallocator, typename T>
     39 class WebScopedPtrBase {
     40 public:
     41     // Default constructor. Constructs an empty scoped pointer.
     42     inline WebScopedPtrBase() : m_ptr(0) { }
     43 
     44     // Constructs a scoped pointer from a plain one.
     45     explicit inline WebScopedPtrBase(T* ptr) : m_ptr(ptr) { }
     46 
     47     // Copy constructor removes the pointer from the original to avoid double
     48     // freeing.
     49     inline WebScopedPtrBase(const WebScopedPtrBase<Deallocator, T>& rhs)
     50         : m_ptr(rhs.m_ptr)
     51     {
     52         const_cast<WebScopedPtrBase<Deallocator, T>&>(rhs).m_ptr = 0;
     53     }
     54 
     55     // When the destructor of the scoped pointer is executed the plain pointer
     56     // is deleted using DeleteArray. This implies that you must allocate with
     57     // NewArray.
     58     inline ~WebScopedPtrBase()
     59     {
     60         if (m_ptr)
     61             Deallocator::Delete(m_ptr);
     62     }
     63 
     64     inline T* operator->() const { return m_ptr; }
     65 
     66     // You can get the underlying pointer out with the * operator.
     67     inline T* operator*() { return m_ptr; }
     68 
     69     // You can use [n] to index as if it was a plain pointer.
     70     inline T& operator[](size_t i)
     71     {
     72         return m_ptr[i];
     73     }
     74 
     75     // You can use [n] to index as if it was a plain pointer.
     76     const inline T& operator[](size_t i) const
     77     {
     78         return m_ptr[i];
     79     }
     80 
     81     // We don't have implicit conversion to a T* since that hinders migration:
     82     // You would not be able to change a method from returning a T* to
     83     // returning an WebScopedArrayPtr<T> and then get errors wherever it is used.
     84     inline T* get() const { return m_ptr; }
     85 
     86     inline void reset(T* newValue = 0)
     87     {
     88         if (m_ptr)
     89             Deallocator::Delete(m_ptr);
     90         m_ptr = newValue;
     91     }
     92 
     93     // Assignment requires an empty (0) WebScopedArrayPtr as the receiver. Like
     94     // the copy constructor it removes the pointer in the original to avoid
     95     // double freeing.
     96     inline WebScopedPtrBase<Deallocator, T>& operator=(const WebScopedPtrBase<Deallocator, T>& rhs)
     97     {
     98         reset(rhs.m_ptr);
     99         const_cast<WebScopedPtrBase<Deallocator, T>&>(rhs).m_ptr = 0;
    100         return *this;
    101     }
    102 
    103     inline bool isEmpty() { return !m_ptr; }
    104 
    105 private:
    106     T* m_ptr;
    107 };
    108 
    109 // A 'scoped array pointer' that calls DeleteArray on its pointer when the
    110 // destructor is called.
    111 template<typename T>
    112 struct ArrayDeallocator {
    113     static void Delete(T* array)
    114     {
    115         DeleteArray(array);
    116     }
    117 };
    118 
    119 template<typename T>
    120 class WebScopedArrayPtr: public WebScopedPtrBase<ArrayDeallocator<T>, T> {
    121 public:
    122     inline WebScopedArrayPtr() { }
    123     explicit inline WebScopedArrayPtr(T* ptr)
    124         : WebScopedPtrBase<ArrayDeallocator<T>, T>(ptr) { }
    125     inline WebScopedArrayPtr(const WebScopedArrayPtr<T>& rhs)
    126         : WebScopedPtrBase<ArrayDeallocator<T>, T>(rhs) { }
    127 };
    128 
    129 template<typename T>
    130 struct ObjectDeallocator {
    131     static void Delete(T* object)
    132     {
    133         delete object;
    134     }
    135 };
    136 
    137 template<typename T>
    138 class WebScopedPtr: public WebScopedPtrBase<ObjectDeallocator<T>, T> {
    139 public:
    140     inline WebScopedPtr() { }
    141     explicit inline WebScopedPtr(T* ptr)
    142         : WebScopedPtrBase<ObjectDeallocator<T>, T>(ptr) { }
    143     inline WebScopedPtr(const WebScopedPtr<T>& rhs)
    144         : WebScopedPtrBase<ObjectDeallocator<T>, T>(rhs) { }
    145 };
    146 
    147 } // namespace WebTestRunner
    148 
    149 #endif // WebScopedPtr_h
    150