Array.inline.h

Go to the documentation of this file.
00001 //*****************************************************************************/
00002 // Copyright (c) 1998-2006 Autodesk, Inc.
00003 // All rights reserved.
00004 // 
00005 // These coded instructions, statements, and computer programs contain
00006 // unpublished proprietary information written by Autodesk, Inc., and are
00007 // protected by Federal copyright law. They may not be disclosed to third
00008 // parties or copied or duplicated in any form, in whole or in part, without
00009 // the prior written consent of Autodesk, Inc.
00010 //*****************************************************************************/
00011 /*==============================================================================
00012 
00013   file:     Array.inline.h
00014   author:   Daniel Levesque
00015   created:  27 March 2006
00016   description:
00017     Array container.
00018 
00019 ==============================================================================*/
00020 
00021 template<class T> inline T* Array<T>::ArrayAllocate(size_t len)
00022 {
00023     DbgAssert(len < 0x40000000);  // 1G sanity check
00024     T* p = (T*) UtilAllocateMemory(len * sizeof(T));
00025     return p;
00026 }
00027 #pragma warning(push)
00028 // Disable the warnings for conditional expression is constant as a result of the compiler support for Type Traits
00029 #pragma warning(disable:4127)
00030 template <class T> inline void Array<T>::ArrayConstruct(T* arrayBegin, size_t len, const T& defaultVal)
00031 {
00032     if(!__has_trivial_constructor(T))
00033     {
00034         for(size_t i = 0; i < len; ++i)
00035         {
00036             new(&(arrayBegin[i])) T(defaultVal);
00037         }
00038     }
00039 }
00040 
00041 template <class T> inline void Array<T>::ArrayDeAllocate(T* arrayBegin)
00042 {
00043     UtilDeallocateMemory(arrayBegin);
00044 }
00045 
00046 #pragma warning(push)
00047 #pragma warning(disable:4100)
00048 template <class T> inline void Array<T>::ArrayDestruct(T* arrayBegin, size_t len)
00049 {
00050     if(!__has_trivial_destructor(T)) 
00051     {
00052         for(size_t i = 0; i < len; ++i)
00053         {
00054             arrayBegin[i].~T();
00055         }
00056     }
00057 }
00058 #pragma warning(pop) // 4100
00059 
00060 template <class T> void Array<T>::ArrayCopy(T* pCopy, const T * pSource, size_t nCount)
00061 {
00062     // Auto-detect whether it's safe to use memcpy() or whether we need
00063     // to call the copy operator. We're counting on the fact that this condition,
00064     // being resolvable at compile-time, will be removed by the optimizer.
00065     if(__has_assign(T)) {
00066         // Type has an assignment operator; use it.
00067         for(size_t i = 0; i < nCount; ++i)
00068         {
00069             pCopy[i] = (pSource[i]);
00070         }
00071     }
00072     else {
00073         // Type does not have an assignment operator; use memcpy() as it's usually faster.
00074         if (nCount > 0) 
00075         {
00076             memcpy(pCopy, pSource, nCount * sizeof(T));
00077         }
00078     }
00079 }
00080 
00081 template <class T> void Array<T>::ArrayCopyOverlap(T* pCopy, const T * pSource, size_t nCount)
00082 {
00083     // Auto-detect whether it's safe to use memcpy() or whether we need
00084     // to call the copy operator. We're counting on the fact that this condition,
00085     // being resolvable at compile-time, will be removed by the optimizer.
00086     if(__has_assign(T)) {
00087         // Type has an assignment operator; use it.
00088         for(size_t i = nCount; --i >= 0;)
00089         {
00090             pCopy[i] = (pSource[i]);
00091         }
00092     }
00093     else {
00094         // Type does not have an assignment operator; use memcpy() as it's usually faster.
00095         if (nCount > 0) 
00096         {
00097             memmove(pCopy, pSource, nCount * sizeof(T));
00098         }
00099     }
00100 }
00101 
00102 template <class T> void Array<T>::ArrayCopyConstruct(T* pCopy, const T * pSource, size_t nCount)
00103 {
00104     // Auto-detect whether it's safe to use memcpy() or whether we need
00105     // to call the copy operator. We're counting on the fact that this condition,
00106     // being resolvable at compile-time, will be removed by the optimizer.
00107     if(__has_copy(T)) {
00108         // Type has an assignment operator; use it.
00109         for(size_t i = 0; i < nCount; ++i)
00110         {
00111             new(&(pCopy[i])) T(pSource[i]);
00112         }
00113     }
00114     else {
00115         // Type does not have an assignment operator; use memcpy() as it's usually faster.
00116         if (nCount > 0) 
00117         {
00118             memcpy(pCopy, pSource, nCount * sizeof(T));
00119         }
00120     }
00121 }
00122 
00123 #pragma warning(pop) // 4127
00124 
00125 // Inline methods.
00126 template <class T> inline bool Array<T>::contains(const T& value, size_t start) const
00127 { 
00128     return this->findFrom(value, start) != -1;
00129 }
00130 
00131 template <class T> inline size_t Array<T>::length() const
00132 { 
00133     return mUsedLen;
00134 }
00135 
00136 template <class T> inline bool Array<T>::isEmpty() const
00137 { 
00138     return mUsedLen == 0; 
00139 }
00140 
00141 template <class T> inline size_t Array<T>::lengthUsed() const
00142 { 
00143     return mUsedLen; 
00144 }
00145 
00146 template <class T> inline size_t Array<T>::lengthReserved() const
00147 { 
00148     return mReservedLen; 
00149 }
00150 
00151 template <class T> inline size_t Array<T>::growLength() const
00152 { 
00153     return mGrowLen;
00154 }
00155 
00156 template <class T> inline const T* Array<T>::asArrayPtr() const
00157 { 
00158     return mpArray;
00159 }
00160 
00161 template <class T> inline T* Array<T>::asArrayPtr()
00162 { 
00163     return mpArray; 
00164 }
00165 
00166 template <class T> inline bool Array<T>::isValidIndex(size_t i) const
00167 { 
00168     return i >= 0 && i < mUsedLen; 
00169 }
00170 
00171 template <class T> inline T& Array<T>::operator [] (size_t i)
00172 {
00173     DbgAssert(this->isValidIndex(i));
00174     return mpArray[i];
00175 }
00176 
00177 template <class T> inline const T& Array<T>::operator [] (size_t i) const
00178 { 
00179     DbgAssert(this->isValidIndex(i)); 
00180     return mpArray[i];
00181 }
00182 
00183 template <class T> inline T& Array<T>::at(size_t i)
00184 { 
00185     DbgAssert(this->isValidIndex(i));
00186     return mpArray[i];
00187 }
00188 
00189 template <class T> inline const T& Array<T>::at(size_t i) const
00190 { 
00191     DbgAssert(this->isValidIndex(i)); 
00192     return mpArray[i];
00193 }
00194 
00195 template <class T> inline Array<T>& Array<T>::setAt(size_t i, const T& value)
00196 { 
00197     DbgAssert(this->isValidIndex(i)); 
00198     mpArray[i] = value;
00199     return *this;
00200 }
00201 
00202 template <class T> inline T& Array<T>::first()
00203 { 
00204     DbgAssert(!this->isEmpty()); 
00205     return mpArray[0]; 
00206 }
00207 
00208 template <class T> inline const T& Array<T>::first() const
00209 { 
00210     DbgAssert(!this->isEmpty()); 
00211     return mpArray[0];
00212 }
00213 
00214 template <class T> inline T& Array<T>::last()
00215 {
00216     DbgAssert(!this->isEmpty()); 
00217     return mpArray[mUsedLen-1];
00218 }
00219 
00220 template <class T> inline const T& Array<T>::last() const
00221 { 
00222     DbgAssert(!this->isEmpty()); 
00223     return mpArray[mUsedLen-1];
00224 }
00225 
00226 template <class T> inline size_t Array<T>::append(const T& value)
00227 { 
00228     insertAt(mUsedLen, value); 
00229     return mUsedLen-1; 
00230 }
00231 
00232 template <class T> Array<T>& Array<T>::append(const T* values, size_t count)
00233 {
00234     return insertAt(mUsedLen, values, count);
00235 }
00236 
00237 template <class T> inline Array<T>& Array<T>::removeFirst()
00238 { 
00239     DbgAssert(!isEmpty()); 
00240     return removeAt(0); 
00241 }
00242 
00243 template <class T> inline Array<T>& Array<T>::removeLast()
00244 { 
00245     DbgAssert(!isEmpty());
00246     return removeAt(mUsedLen - 1); 
00247 }
00248 
00249 template <class T> inline Array<T>& Array<T>::removeAll()
00250 { 
00251     if(mUsedLen > 0) {
00252         ArrayDestruct(mpArray, mUsedLen);
00253         mUsedLen = 0;
00254     }
00255     return *this; 
00256 }
00257 
00258 template <class T> inline Array<T>& Array<T>::setGrowLength(size_t glen)
00259 { 
00260     DbgAssert(glen > 0);
00261     if(glen > 0) {
00262         mGrowLen = glen;
00263     }
00264     else {
00265         DbgAssert(false);
00266         // Growth length needs to be at least 1.
00267         mGrowLen = 1; 
00268     }
00269     return *this; 
00270 }
00271 
00272 
00273 template <class T> inline void Array<T>::handleOutOfMemory() {
00274 
00275     DbgAssert(false);
00276     UtilOutOfMemoryException();
00277 }