1589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#ifndef V8_SMART_ARRAY_POINTER_H_
29589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#define V8_SMART_ARRAY_POINTER_H_
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A 'scoped array pointer' that calls DeleteArray on its pointer when the
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// destructor is called.
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate<typename T>
38589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochclass SmartArrayPointer {
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
40589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Default constructor. Constructs an empty scoped pointer.
41589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  inline SmartArrayPointer() : p_(NULL) {}
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
43589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Constructs a scoped pointer from a plain one.
44589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  explicit inline SmartArrayPointer(T* ptr) : p_(ptr) {}
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Copy constructor removes the pointer from the original to avoid double
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // freeing.
48589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  inline SmartArrayPointer(const SmartArrayPointer<T>& rhs) : p_(rhs.p_) {
49589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    const_cast<SmartArrayPointer<T>&>(rhs).p_ = NULL;
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // When the destructor of the scoped pointer is executed the plain pointer
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is deleted using DeleteArray.  This implies that you must allocate with
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // NewArray.
55589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  inline ~SmartArrayPointer() { if (p_) DeleteArray(p_); }
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
57589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  inline T* operator->() const { return p_; }
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // You can get the underlying pointer out with the * operator.
60589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  inline T* operator*() { return p_; }
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // You can use [n] to index as if it was a plain pointer
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline T& operator[](size_t i) {
64589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return p_[i];
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // We don't have implicit conversion to a T* since that hinders migration:
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // You would not be able to change a method from returning a T* to
69589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // returning an SmartArrayPointer<T> and then get errors wherever it is used.
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If you want to take out the plain pointer and don't want it automatically
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // deleted then call Detach().  Afterwards, the smart pointer is empty
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // (NULL).
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline T* Detach() {
76589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    T* temp = p_;
77589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    p_ = NULL;
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return temp;
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
81589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Assignment requires an empty (NULL) SmartArrayPointer as the receiver. Like
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the copy constructor it removes the pointer in the original to avoid
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // double freeing.
84589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  inline SmartArrayPointer& operator=(const SmartArrayPointer<T>& rhs) {
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(is_empty());
86589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    T* tmp = rhs.p_;  // swap to handle self-assignment
87589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    const_cast<SmartArrayPointer<T>&>(rhs).p_ = NULL;
88589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    p_ = tmp;
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return *this;
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
92589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  inline bool is_empty() { return p_ == NULL; }
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
95589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  T* p_;
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
100589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#endif  // V8_SMART_ARRAY_POINTER_H_
101