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