1*b0d29bc4SBrooks Davis// Copyright 2010 The Kyua Authors. 2*b0d29bc4SBrooks Davis// All rights reserved. 3*b0d29bc4SBrooks Davis// 4*b0d29bc4SBrooks Davis// Redistribution and use in source and binary forms, with or without 5*b0d29bc4SBrooks Davis// modification, are permitted provided that the following conditions are 6*b0d29bc4SBrooks Davis// met: 7*b0d29bc4SBrooks Davis// 8*b0d29bc4SBrooks Davis// * Redistributions of source code must retain the above copyright 9*b0d29bc4SBrooks Davis// notice, this list of conditions and the following disclaimer. 10*b0d29bc4SBrooks Davis// * Redistributions in binary form must reproduce the above copyright 11*b0d29bc4SBrooks Davis// notice, this list of conditions and the following disclaimer in the 12*b0d29bc4SBrooks Davis// documentation and/or other materials provided with the distribution. 13*b0d29bc4SBrooks Davis// * Neither the name of Google Inc. nor the names of its contributors 14*b0d29bc4SBrooks Davis// may be used to endorse or promote products derived from this software 15*b0d29bc4SBrooks Davis// without specific prior written permission. 16*b0d29bc4SBrooks Davis// 17*b0d29bc4SBrooks Davis// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18*b0d29bc4SBrooks Davis// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19*b0d29bc4SBrooks Davis// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20*b0d29bc4SBrooks Davis// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21*b0d29bc4SBrooks Davis// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22*b0d29bc4SBrooks Davis// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23*b0d29bc4SBrooks Davis// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24*b0d29bc4SBrooks Davis// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25*b0d29bc4SBrooks Davis// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26*b0d29bc4SBrooks Davis// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27*b0d29bc4SBrooks Davis// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28*b0d29bc4SBrooks Davis 29*b0d29bc4SBrooks Davis#if !defined(UTILS_AUTO_ARRAY_IPP) 30*b0d29bc4SBrooks Davis#define UTILS_AUTO_ARRAY_IPP 31*b0d29bc4SBrooks Davis 32*b0d29bc4SBrooks Davis#include "utils/auto_array.hpp" 33*b0d29bc4SBrooks Davis 34*b0d29bc4SBrooks Davisnamespace utils { 35*b0d29bc4SBrooks Davis 36*b0d29bc4SBrooks Davis 37*b0d29bc4SBrooks Davisnamespace detail { 38*b0d29bc4SBrooks Davis 39*b0d29bc4SBrooks Davis 40*b0d29bc4SBrooks Davis/// Constructs a new auto_array_ref from a pointer. 41*b0d29bc4SBrooks Davis/// 42*b0d29bc4SBrooks Davis/// \param ptr The pointer to wrap. 43*b0d29bc4SBrooks Davistemplate< class T > inline 44*b0d29bc4SBrooks Davisauto_array_ref< T >::auto_array_ref(T* ptr) : 45*b0d29bc4SBrooks Davis _ptr(ptr) 46*b0d29bc4SBrooks Davis{ 47*b0d29bc4SBrooks Davis} 48*b0d29bc4SBrooks Davis 49*b0d29bc4SBrooks Davis 50*b0d29bc4SBrooks Davis} // namespace detail 51*b0d29bc4SBrooks Davis 52*b0d29bc4SBrooks Davis 53*b0d29bc4SBrooks Davis/// Constructs a new auto_array from a given pointer. 54*b0d29bc4SBrooks Davis/// 55*b0d29bc4SBrooks Davis/// This grabs ownership of the pointer unless it is NULL. 56*b0d29bc4SBrooks Davis/// 57*b0d29bc4SBrooks Davis/// \param ptr The pointer to wrap. If not NULL, the memory pointed to must 58*b0d29bc4SBrooks Davis/// have been allocated with operator new[]. 59*b0d29bc4SBrooks Davistemplate< class T > inline 60*b0d29bc4SBrooks Davisauto_array< T >::auto_array(T* ptr) throw() : 61*b0d29bc4SBrooks Davis _ptr(ptr) 62*b0d29bc4SBrooks Davis{ 63*b0d29bc4SBrooks Davis} 64*b0d29bc4SBrooks Davis 65*b0d29bc4SBrooks Davis 66*b0d29bc4SBrooks Davis/// Constructs a copy of an auto_array. 67*b0d29bc4SBrooks Davis/// 68*b0d29bc4SBrooks Davis/// \param ptr The pointer to copy from. This pointer is invalidated and the 69*b0d29bc4SBrooks Davis/// new copy grabs ownership of the object pointed to. 70*b0d29bc4SBrooks Davistemplate< class T > inline 71*b0d29bc4SBrooks Davisauto_array< T >::auto_array(auto_array< T >& ptr) throw() : 72*b0d29bc4SBrooks Davis _ptr(ptr.release()) 73*b0d29bc4SBrooks Davis{ 74*b0d29bc4SBrooks Davis} 75*b0d29bc4SBrooks Davis 76*b0d29bc4SBrooks Davis 77*b0d29bc4SBrooks Davis/// Constructs a new auto_array form a reference. 78*b0d29bc4SBrooks Davis/// 79*b0d29bc4SBrooks Davis/// Internal function used to construct a new auto_array from an object 80*b0d29bc4SBrooks Davis/// returned, for example, from a function. 81*b0d29bc4SBrooks Davis/// 82*b0d29bc4SBrooks Davis/// \param ref The reference. 83*b0d29bc4SBrooks Davistemplate< class T > inline 84*b0d29bc4SBrooks Davisauto_array< T >::auto_array(detail::auto_array_ref< T > ref) throw() : 85*b0d29bc4SBrooks Davis _ptr(ref._ptr) 86*b0d29bc4SBrooks Davis{ 87*b0d29bc4SBrooks Davis} 88*b0d29bc4SBrooks Davis 89*b0d29bc4SBrooks Davis 90*b0d29bc4SBrooks Davis/// Destructor for auto_array objects. 91*b0d29bc4SBrooks Davistemplate< class T > inline 92*b0d29bc4SBrooks Davisauto_array< T >::~auto_array(void) throw() 93*b0d29bc4SBrooks Davis{ 94*b0d29bc4SBrooks Davis if (_ptr != NULL) 95*b0d29bc4SBrooks Davis delete [] _ptr; 96*b0d29bc4SBrooks Davis} 97*b0d29bc4SBrooks Davis 98*b0d29bc4SBrooks Davis 99*b0d29bc4SBrooks Davis/// Gets the value of the wrapped pointer without releasing ownership. 100*b0d29bc4SBrooks Davis/// 101*b0d29bc4SBrooks Davis/// \return The raw mutable pointer. 102*b0d29bc4SBrooks Davistemplate< class T > inline 103*b0d29bc4SBrooks DavisT* 104*b0d29bc4SBrooks Davisauto_array< T >::get(void) throw() 105*b0d29bc4SBrooks Davis{ 106*b0d29bc4SBrooks Davis return _ptr; 107*b0d29bc4SBrooks Davis} 108*b0d29bc4SBrooks Davis 109*b0d29bc4SBrooks Davis 110*b0d29bc4SBrooks Davis/// Gets the value of the wrapped pointer without releasing ownership. 111*b0d29bc4SBrooks Davis/// 112*b0d29bc4SBrooks Davis/// \return The raw immutable pointer. 113*b0d29bc4SBrooks Davistemplate< class T > inline 114*b0d29bc4SBrooks Davisconst T* 115*b0d29bc4SBrooks Davisauto_array< T >::get(void) const throw() 116*b0d29bc4SBrooks Davis{ 117*b0d29bc4SBrooks Davis return _ptr; 118*b0d29bc4SBrooks Davis} 119*b0d29bc4SBrooks Davis 120*b0d29bc4SBrooks Davis 121*b0d29bc4SBrooks Davis/// Gets the value of the wrapped pointer and releases ownership. 122*b0d29bc4SBrooks Davis/// 123*b0d29bc4SBrooks Davis/// \return The raw mutable pointer. 124*b0d29bc4SBrooks Davistemplate< class T > inline 125*b0d29bc4SBrooks DavisT* 126*b0d29bc4SBrooks Davisauto_array< T >::release(void) throw() 127*b0d29bc4SBrooks Davis{ 128*b0d29bc4SBrooks Davis T* ptr = _ptr; 129*b0d29bc4SBrooks Davis _ptr = NULL; 130*b0d29bc4SBrooks Davis return ptr; 131*b0d29bc4SBrooks Davis} 132*b0d29bc4SBrooks Davis 133*b0d29bc4SBrooks Davis 134*b0d29bc4SBrooks Davis/// Changes the value of the wrapped pointer. 135*b0d29bc4SBrooks Davis/// 136*b0d29bc4SBrooks Davis/// If the auto_array was pointing to an array, such array is released and the 137*b0d29bc4SBrooks Davis/// wrapped pointer is replaced with the new pointer provided. 138*b0d29bc4SBrooks Davis/// 139*b0d29bc4SBrooks Davis/// \param ptr The pointer to use as a replacement; may be NULL. 140*b0d29bc4SBrooks Davistemplate< class T > inline 141*b0d29bc4SBrooks Davisvoid 142*b0d29bc4SBrooks Davisauto_array< T >::reset(T* ptr) throw() 143*b0d29bc4SBrooks Davis{ 144*b0d29bc4SBrooks Davis if (_ptr != NULL) 145*b0d29bc4SBrooks Davis delete [] _ptr; 146*b0d29bc4SBrooks Davis _ptr = ptr; 147*b0d29bc4SBrooks Davis} 148*b0d29bc4SBrooks Davis 149*b0d29bc4SBrooks Davis 150*b0d29bc4SBrooks Davis/// Assignment operator. 151*b0d29bc4SBrooks Davis/// 152*b0d29bc4SBrooks Davis/// \param ptr The object to copy from. This is invalidated after the copy. 153*b0d29bc4SBrooks Davis/// \return A reference to the auto_array object itself. 154*b0d29bc4SBrooks Davistemplate< class T > inline 155*b0d29bc4SBrooks Davisauto_array< T >& 156*b0d29bc4SBrooks Davisauto_array< T >::operator=(auto_array< T >& ptr) throw() 157*b0d29bc4SBrooks Davis{ 158*b0d29bc4SBrooks Davis reset(ptr.release()); 159*b0d29bc4SBrooks Davis return *this; 160*b0d29bc4SBrooks Davis} 161*b0d29bc4SBrooks Davis 162*b0d29bc4SBrooks Davis 163*b0d29bc4SBrooks Davis/// Internal assignment operator for function returns. 164*b0d29bc4SBrooks Davis/// 165*b0d29bc4SBrooks Davis/// \param ref The reference object to copy from. 166*b0d29bc4SBrooks Davis/// \return A reference to the auto_array object itself. 167*b0d29bc4SBrooks Davistemplate< class T > inline 168*b0d29bc4SBrooks Davisauto_array< T >& 169*b0d29bc4SBrooks Davisauto_array< T >::operator=(detail::auto_array_ref< T > ref) throw() 170*b0d29bc4SBrooks Davis{ 171*b0d29bc4SBrooks Davis if (_ptr != ref._ptr) { 172*b0d29bc4SBrooks Davis delete [] _ptr; 173*b0d29bc4SBrooks Davis _ptr = ref._ptr; 174*b0d29bc4SBrooks Davis } 175*b0d29bc4SBrooks Davis return *this; 176*b0d29bc4SBrooks Davis} 177*b0d29bc4SBrooks Davis 178*b0d29bc4SBrooks Davis 179*b0d29bc4SBrooks Davis/// Subscript operator to access the array by position. 180*b0d29bc4SBrooks Davis/// 181*b0d29bc4SBrooks Davis/// This does not perform any bounds checking, in particular because auto_array 182*b0d29bc4SBrooks Davis/// does not know the size of the arrays pointed to by it. 183*b0d29bc4SBrooks Davis/// 184*b0d29bc4SBrooks Davis/// \param pos The position to access, indexed from zero. 185*b0d29bc4SBrooks Davis/// 186*b0d29bc4SBrooks Davis/// \return A mutable reference to the element at the specified position. 187*b0d29bc4SBrooks Davistemplate< class T > inline 188*b0d29bc4SBrooks DavisT& 189*b0d29bc4SBrooks Davisauto_array< T >::operator[](int pos) throw() 190*b0d29bc4SBrooks Davis{ 191*b0d29bc4SBrooks Davis return _ptr[pos]; 192*b0d29bc4SBrooks Davis} 193*b0d29bc4SBrooks Davis 194*b0d29bc4SBrooks Davis 195*b0d29bc4SBrooks Davis/// Subscript operator to access the array by position. 196*b0d29bc4SBrooks Davis/// 197*b0d29bc4SBrooks Davis/// This does not perform any bounds checking, in particular because auto_array 198*b0d29bc4SBrooks Davis/// does not know the size of the arrays pointed to by it. 199*b0d29bc4SBrooks Davis/// 200*b0d29bc4SBrooks Davis/// \param pos The position to access, indexed from zero. 201*b0d29bc4SBrooks Davis/// 202*b0d29bc4SBrooks Davis/// \return An immutable reference to the element at the specified position. 203*b0d29bc4SBrooks Davistemplate< class T > inline 204*b0d29bc4SBrooks Davisconst T& 205*b0d29bc4SBrooks Davisauto_array< T >::operator[](int pos) const throw() 206*b0d29bc4SBrooks Davis{ 207*b0d29bc4SBrooks Davis return _ptr[pos]; 208*b0d29bc4SBrooks Davis} 209*b0d29bc4SBrooks Davis 210*b0d29bc4SBrooks Davis 211*b0d29bc4SBrooks Davis/// Internal conversion to a reference wrapper. 212*b0d29bc4SBrooks Davis/// 213*b0d29bc4SBrooks Davis/// This is used internally to support returning auto_array objects from 214*b0d29bc4SBrooks Davis/// functions. The auto_array is invalidated when used. 215*b0d29bc4SBrooks Davis/// 216*b0d29bc4SBrooks Davis/// \return A new detail::auto_array_ref object holding the pointer. 217*b0d29bc4SBrooks Davistemplate< class T > inline 218*b0d29bc4SBrooks Davisauto_array< T >::operator detail::auto_array_ref< T >(void) throw() 219*b0d29bc4SBrooks Davis{ 220*b0d29bc4SBrooks Davis return detail::auto_array_ref< T >(release()); 221*b0d29bc4SBrooks Davis} 222*b0d29bc4SBrooks Davis 223*b0d29bc4SBrooks Davis 224*b0d29bc4SBrooks Davis} // namespace utils 225*b0d29bc4SBrooks Davis 226*b0d29bc4SBrooks Davis 227*b0d29bc4SBrooks Davis#endif // !defined(UTILS_AUTO_ARRAY_IPP) 228