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