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