Array.h

Go to the documentation of this file.
00001 /*------------------------------------------------------------------------------
00002 
00003    Octree Component, version 2.1
00004    Copyright (c) 2004-2007,  Harrison Ainsworth / HXA7241.
00005 
00006    http://www.hxa7241.org/
00007 
00008 ------------------------------------------------------------------------------*/
00009 
00010 /*------------------------------------------------------------------------------
00011 
00012 Copyright (c) 2004-2007, Harrison Ainsworth / HXA7241.
00013 
00014 Redistribution and use in source and binary forms, with or without modification,
00015 are permitted provided that the following conditions are met:
00016 
00017 * Redistributions of source code must retain the above copyright notice, this
00018   list of conditions and the following disclaimer.
00019 * Redistributions in binary form must reproduce the above copyright notice, this
00020   list of conditions and the following disclaimer in the documentation and/or
00021   other materials provided with the distribution.
00022 * The name of the author may not be used to endorse or promote products derived
00023   from this software without specific prior written permission.
00024 
00025 THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
00026 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00027 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
00028 SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00029 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00030 OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00031 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00032 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00033 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00034 OF SUCH DAMAGE.
00035 
00036 ------------------------------------------------------------------------------*/
00037 
00038 
00039 #ifndef Array_h
00040 #define Array_h
00041 
00042 
00043 #include "Primitives.h"
00044 
00045 
00046 
00047 
00048 namespace hxa7241_general
00049 {
00050    using namespace hxa7241;
00051 
00052 
00062 template<class TYPE>
00063 class Array
00064 {
00066 public:
00067                   Array();
00068    explicit       Array( dword length );                               // throws
00069 
00070                  ~Array();
00071                   Array( const Array& );                               // throws
00072            Array& operator=( const Array& );                           // throws
00073 
00074 
00076            void   setLength( dword length );                           // throws
00077 
00078            void   swap( Array& );
00079            void   append( const TYPE& );                               // throws
00080            void   remove( int index );                                 // throws
00081 
00082            void   zeroStorage();
00083 
00084            TYPE*  getStorage();
00085            TYPE&  operator[]( int index );
00086 
00087 
00089            dword  getLength()                                             const;
00090            bool   isEmpty()                                               const;
00091    static  dword  getMaxLength();
00092 
00093            const TYPE*  getStorage()                                      const;
00094            const TYPE&  operator[]( int index )                           const;
00095 
00096 
00098 protected:
00099            void   assign( const Array<TYPE>& );
00100 
00101            void   acquireStorage( dword length,
00102                                   bool  isCopied );
00103 
00104    static  void   copyObjects( TYPE*       lValStart,
00105                                const TYPE* rValStart,
00106                                dword       length );
00107 
00108 
00110 private:
00111    TYPE* pStorage_m;
00112    dword length_m;
00113 };
00114 
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00123 template<class TYPE>
00124 Array<TYPE>::Array()
00125  : pStorage_m( 0 )
00126  , length_m  ( 0 )
00127 {
00128 }
00129 
00130 
00131 template<class TYPE>
00132 Array<TYPE>::Array
00133 (
00134    const dword length
00135 )
00136  : pStorage_m( 0 )
00137  , length_m  ( 0 )
00138 {
00139    Array<TYPE>::setLength( length );
00140 }
00141 
00142 
00143 template<class TYPE>
00144 Array<TYPE>::~Array()
00145 {
00146    delete[] pStorage_m;
00147 }
00148 
00149 
00150 template<class TYPE>
00151 Array<TYPE>::Array
00152 (
00153    const Array<TYPE>& other
00154 )
00155  : pStorage_m( 0 )
00156  , length_m  ( 0 )
00157 {
00158    Array<TYPE>::assign( other );
00159 }
00160 
00161 
00162 template<class TYPE>
00163 Array<TYPE>& Array<TYPE>::operator=
00164 (
00165    const Array<TYPE>& other
00166 )
00167 {
00168    assign( other );
00169 
00170    return *this;
00171 }
00172 
00173 
00174 
00175 
00177 template<class TYPE>
00178 void Array<TYPE>::setLength
00179 (
00180    const dword length
00181 )
00182 {
00183    acquireStorage( length, false );
00184 }
00185 
00186 
00187 template<class TYPE>
00188 void Array<TYPE>::swap
00189 (
00190    Array<TYPE>& other
00191 )
00192 {
00193    TYPE*const tmpM  = pStorage_m;
00194    pStorage_m       = other.pStorage_m;
00195    other.pStorage_m = tmpM;
00196 
00197    const dword tmpL = length_m;
00198    length_m         = other.length_m;
00199    other.length_m   = tmpL;
00200 }
00201 
00202 
00203 template<class TYPE>
00204 void Array<TYPE>::append
00205 (
00206    const TYPE& element
00207 )
00208 {
00209    // expand storage, duplicating elements
00210    acquireStorage( length_m + 1, true );
00211 
00212    // write new element into last position
00213    *(pStorage_m + length_m - 1) = element;
00214 
00215 
00216 // // make larger storage
00217 // Array<TYPE> newArray( length_m + 1 );
00218 //
00219 // // duplicate elements, and append new element
00220 // copyObjects( newArray.pStorage_m, pStorage_m, length_m );
00221 // *(newArray.pStorage_m + length_m) = element;
00222 //
00223 // // swap new storage with this
00224 // swap( newArray );
00225 }
00226 
00227 
00228 template<class TYPE>
00229 void Array<TYPE>::remove
00230 (
00231    const int index
00232 )
00233 {
00234    // check index is within range
00235    if( (index >= 0) & (index < length_m)  )
00236    {
00237       // make smaller storage
00238       Array<TYPE> newArray( length_m - 1 );
00239 
00240       // copy elements, skipping element at index
00241       {
00242                TYPE* pDestination = newArray.pStorage_m;
00243                TYPE* pEnd         = pDestination + newArray.length_m;
00244          const TYPE* pSource      = pStorage_m;
00245          const TYPE* pIndex       = pSource + index;
00246          while( pDestination < pEnd )
00247          {
00248             pSource += static_cast<dword>(pSource == pIndex);
00249             *(pDestination++) = *(pSource++);
00250          }
00251       }
00252 
00253       // swap new storage with this
00254       swap( newArray );
00255    }
00256 }
00257 
00258 
00259 template<class TYPE>
00260 void Array<TYPE>::zeroStorage()
00261 {
00262    for( dword i = length_m;  i-- > 0; )
00263    {
00264       pStorage_m[ i ] = TYPE();
00265    }
00266 }
00267 
00268 
00269 template<class TYPE>
00270 inline
00271 TYPE* Array<TYPE>::getStorage()
00272 {
00273    return pStorage_m;
00274 }
00275 
00276 
00277 template<class TYPE>
00278 inline
00279 TYPE& Array<TYPE>::operator[]
00280 (
00281    const int index
00282 )
00283 {
00284    return pStorage_m[ index ];
00285 }
00286 
00287 
00288 
00289 
00291 template<class TYPE>
00292 inline
00293 dword Array<TYPE>::getLength() const
00294 {
00295    return length_m;
00296 }
00297 
00298 
00299 template<class TYPE>
00300 inline
00301 bool Array<TYPE>::isEmpty() const
00302 {
00303    return 0 == length_m;
00304 }
00305 
00306 
00307 template<class TYPE>
00308 inline
00309 dword Array<TYPE>::getMaxLength()
00310 {
00311    return DWORD_MAX;
00312 }
00313 
00314 
00315 template<class TYPE>
00316 inline
00317 const TYPE* Array<TYPE>::getStorage() const
00318 {
00319    return pStorage_m;
00320 }
00321 
00322 
00323 template<class TYPE>
00324 inline
00325 const TYPE& Array<TYPE>::operator[]
00326 (
00327    const int index
00328 ) const
00329 {
00330    return pStorage_m[ index ];
00331 }
00332 
00333 
00334 
00335 
00337 template<class TYPE>
00338 void Array<TYPE>::assign
00339 (
00340    const Array<TYPE>& other
00341 )
00342 {
00343    if( &other != this )
00344    {
00345       acquireStorage( other.getLength(), false );
00346 
00347       copyObjects( getStorage(), other.getStorage(), other.getLength() );
00348    }
00349 }
00350 
00351 
00352 template<class TYPE>
00353 void Array<TYPE>::acquireStorage
00354 (
00355    dword      newLength,
00356    const bool isCopied
00357 )
00358 {
00359    // clamp to 0 min
00360    newLength = (newLength >= 0) ? newLength : 0;
00361 
00362    // only allocate if different length
00363    if( newLength != length_m )
00364    {
00365       // allocate new storage
00366       TYPE* pNewStorage = new TYPE[ newLength ];
00367 
00368       // copy elements to new storage
00369       if( isCopied )
00370       {
00371          copyObjects( pNewStorage, pStorage_m,
00372             (length_m <= newLength ? length_m : newLength) );
00373       }
00374 
00375       // delete old storage and set the members
00376       delete[] pStorage_m;
00377       pStorage_m = pNewStorage;
00378       length_m   = newLength;
00379    }
00380 }
00381 
00382 
00383 template<class TYPE>
00384 void Array<TYPE>::copyObjects
00385 (
00386    TYPE*const       pDestination,
00387    const TYPE*const pSource,
00388    const dword      length
00389 )
00390 {
00391    if( length >= 0 )
00392    {
00393             TYPE* pDestinationCursor = pDestination + length;
00394       const TYPE* pSourceCursor      = pSource      + length;
00395 
00396       while( pDestinationCursor > pDestination )
00397       {
00398          *(--pDestinationCursor) = *(--pSourceCursor);
00399       }
00400    }
00401 }
00402 
00403 
00404 }//namespace
00405 
00406 
00407 
00408 
00409 #endif//Array_h

Generated on Fri Feb 13 13:58:10 2009 for meshmorph by  doxygen 1.5.1