karrayul.h

Go to the documentation of this file.
00001 
00004 #ifndef FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KARRAYUL_H
00005 #define FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KARRAYUL_H
00006 
00007 /**************************************************************************************
00008 
00009  Copyright (C) 2001 - 2010 Autodesk, Inc. and/or its licensors.
00010  All Rights Reserved.
00011 
00012  The coded instructions, statements, computer programs, and/or related material 
00013  (collectively the "Data") in these files contain unpublished information 
00014  proprietary to Autodesk, Inc. and/or its licensors, which is protected by 
00015  Canada and United States of America federal copyright law and by international 
00016  treaties. 
00017  
00018  The Data may not be disclosed or distributed to third parties, in whole or in
00019  part, without the prior written consent of Autodesk, Inc. ("Autodesk").
00020 
00021  THE DATA IS PROVIDED "AS IS" AND WITHOUT WARRANTY.
00022  ALL WARRANTIES ARE EXPRESSLY EXCLUDED AND DISCLAIMED. AUTODESK MAKES NO
00023  WARRANTY OF ANY KIND WITH RESPECT TO THE DATA, EXPRESS, IMPLIED OR ARISING
00024  BY CUSTOM OR TRADE USAGE, AND DISCLAIMS ANY IMPLIED WARRANTIES OF TITLE, 
00025  NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR USE. 
00026  WITHOUT LIMITING THE FOREGOING, AUTODESK DOES NOT WARRANT THAT THE OPERATION
00027  OF THE DATA WILL BE UNINTERRUPTED OR ERROR FREE. 
00028  
00029  IN NO EVENT SHALL AUTODESK, ITS AFFILIATES, PARENT COMPANIES, LICENSORS
00030  OR SUPPLIERS ("AUTODESK GROUP") BE LIABLE FOR ANY LOSSES, DAMAGES OR EXPENSES
00031  OF ANY KIND (INCLUDING WITHOUT LIMITATION PUNITIVE OR MULTIPLE DAMAGES OR OTHER
00032  SPECIAL, DIRECT, INDIRECT, EXEMPLARY, INCIDENTAL, LOSS OF PROFITS, REVENUE
00033  OR DATA, COST OF COVER OR CONSEQUENTIAL LOSSES OR DAMAGES OF ANY KIND),
00034  HOWEVER CAUSED, AND REGARDLESS OF THE THEORY OF LIABILITY, WHETHER DERIVED
00035  FROM CONTRACT, TORT (INCLUDING, BUT NOT LIMITED TO, NEGLIGENCE), OR OTHERWISE,
00036  ARISING OUT OF OR RELATING TO THE DATA OR ITS USE OR ANY OTHER PERFORMANCE,
00037  WHETHER OR NOT AUTODESK HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSS
00038  OR DAMAGE. 
00039 
00040 **************************************************************************************/
00041 #include <fbxfilesdk/fbxfilesdk_def.h>
00042 
00043 #include <fbxfilesdk/components/kbaselib/klib/kdebug.h>
00044 
00045 #define KFBX_ARRAYUL_BLOCKSIZE 4
00046 
00047 #include <fbxfilesdk/fbxfilesdk_nsbegin.h> // namespace
00048 
00049     /***********************************************************************
00050         CLASS KStaticArray
00051     ************************************************************************/
00052     template< class Type > class KBaseStaticArray
00053     {
00054         protected:
00055         int  mCount;
00056         Type *mArrayBuf;
00057 
00058         public:
00059         inline int GetCount() { return mCount; }
00060 
00062         inline Type &operator[](int pIndex)
00063         {
00064         #ifdef KFBX_PRIVATE
00065             K_ASSERT_MSG( pIndex >= 0   , "Buffer underflow");
00066             K_ASSERT_MSG( pIndex < mCount,"Buffer overflow.");
00067         #endif
00068             return mArrayBuf[pIndex];
00069         }
00070     };
00071 
00072     // Static Array
00073     template< class Type, int Count > class KStaticArray : public KBaseStaticArray<Type>
00074     {
00075         public:
00076         Type mArray[Count];
00077             inline KStaticArray(){ this->mArrayBuf = mArray; this->mCount = Count;}
00078     };
00079 
00080     template< class Type, int Count1, int Count2 > class KStaticArray2d
00081     {
00082         public:
00083 #if defined(KARCH_DEV_MSC) && (_MSC_VER <= 1200)// VC6
00084         KStaticArray<Type,Count2> *mArray;
00085 
00086         KStaticArray2d() { mArray = FbxSdkNew< KStaticArray<Type,Count2> >(Count1); }
00087         ~KStaticArray2d() { FbxSdkDeleteArray(mArray); }
00088 #else
00089         KStaticArray<Type,Count2> mArray[Count1];
00090 #endif
00091 
00092         // Access pointer at given index.
00093         inline KStaticArray< Type, Count2 > &operator[](int pIndex)
00094         {
00095         #ifdef KFBX_PRIVATE
00096             K_ASSERT_MSG( pIndex >= 0   , "Buffer underflow.");
00097             K_ASSERT_MSG( pIndex < Count1,"Buffer overflow.");
00098         #endif
00099             return mArray[pIndex];
00100         }
00101     };
00102 
00103     /***********************************************************************
00104         CLASS KArrayTemplate
00105     ************************************************************************/
00106     class  KBaseArraySize {
00107         public:
00108             KBaseArraySize( int pItemSize)
00109                 : mItemSize(pItemSize)
00110             {
00111             }
00112             inline int GetTypeSize() const { return mItemSize; }
00113         private:
00114             int mItemSize;
00115     };
00116 
00117     template <class T> class  KBaseArraySizeType
00118     {
00119         public:
00120             inline int GetTypeSize() const { return sizeof(T); }
00121     };
00122 
00123     // Helpers
00124     KFBX_DLL void KBaseArrayFree(char*);
00125     KFBX_DLL char* KBaseArrayRealloc(char*, size_t);
00126     
00128     //
00129     //  WARNING!
00130     //
00131     //  Anything beyond these lines may not be documented accurately and is
00132     //  subject to change without notice.
00133     //
00135     #ifndef DOXYGEN_SHOULD_SKIP_THIS
00136         KFBX_DLL void* KBaseArrayGetAlloc();
00137     #endif
00138 
00139     template <class TypeSize> class  KBaseArray
00140     {
00141         protected:
00142             struct KHeader {
00143                 int mArrayCount;
00144                 int mBlockCount;
00145             };
00146 
00147 
00148         protected:
00152             inline KBaseArray(TypeSize pTypeSize)
00153                 : mTypeSize(pTypeSize)
00154             {
00155                 mBaseArray  = NULL;
00156             }
00157 
00158 
00160             inline ~KBaseArray(){
00161                 Clear ();
00162             }
00163 
00171             inline int      InsertAt(int pIndex, void *pItem)
00172             {
00173               int lArrayCount = GetArrayCount();
00174               int lBlockCount = GetBlockCount();
00175 
00176                 #ifdef KFBX_PRIVATE
00177                     K_ASSERT( pIndex >= 0 );
00178                 #endif
00179 
00180                 if (pIndex>lArrayCount) {
00181                     pIndex = GetArrayCount();
00182                 }
00183 
00184                 if (lArrayCount>= lBlockCount*KFBX_ARRAYUL_BLOCKSIZE)
00185                 {
00186                     // must Alloc.Realloc some new space
00187 
00188                     // double the number of blocks.
00189                     lBlockCount = ( 0 == lBlockCount ) ? 1 : lBlockCount * 2;
00190                     char* lBaseArray = KBaseArrayRealloc(mBaseArray, (size_t) (lBlockCount*KFBX_ARRAYUL_BLOCKSIZE*GetTypeSize()) + GetHeaderOffset() );
00191                     if(!lBaseArray)
00192                         return -1;
00193                     mBaseArray = lBaseArray;
00194                 }
00195 
00196                 if (pIndex<lArrayCount)
00197                 {
00198                     // This is an insert
00199                     memmove (&(mBaseArray[(pIndex+1)*GetTypeSize()+ GetHeaderOffset() ]), &(mBaseArray[(pIndex)*GetTypeSize()+ GetHeaderOffset()] ), GetTypeSize()*(lArrayCount-pIndex));
00200                 }
00201 
00202                 memmove (&(mBaseArray[(pIndex)*GetTypeSize()+ GetHeaderOffset() ]), pItem, GetTypeSize());
00203 
00204                 SetArrayCount(lArrayCount+1);
00205                 SetBlockCount(lBlockCount);
00206 
00207                 return pIndex;
00208             }
00209 
00210 
00217             inline void*    GetAt(int pIndex)                           { return &(mBaseArray[(pIndex)*GetTypeSize()+ GetHeaderOffset() ]); }
00218 
00225             inline void RemoveAt(int pIndex)
00226             {
00227 
00228             #if defined(_DEBUG) && !defined(KARCH_ENV_MACOSX)
00229                 if (!ValidateIndex( pIndex ))
00230                 {
00231                     return;
00232                 }
00233             #endif
00234                 int lArrayCount = GetArrayCount();
00235                 if (pIndex+1<lArrayCount)
00236                 {
00237                     memmove (&(mBaseArray[(pIndex)*GetTypeSize()+ GetHeaderOffset() ]), &(mBaseArray[(pIndex+1)*GetTypeSize()+ GetHeaderOffset() ]), GetTypeSize()*(lArrayCount-pIndex-1));
00238                 }
00239 
00240                 SetArrayCount( lArrayCount-1 );
00241 
00242             #ifdef _DEBUG
00243                 memset( &(mBaseArray[(GetArrayCount())*GetTypeSize()+ GetHeaderOffset() ]),0,GetTypeSize());
00244             #endif
00245             }
00246 
00247 
00253             inline bool ValidateIndex( int pIndex ) const
00254             {
00255                 int lArrayCount = GetArrayCount();
00256                 if (pIndex>=0 && pIndex<lArrayCount)
00257                 {
00258                     return true;
00259                 } else
00260                 {
00261                     #ifdef KFBX_PRIVATE
00262                         K_ASSERT_MSG_NOW(_T("ArrayTemplate : Index out of range"));
00263                     #endif
00264                     return false;
00265                 }
00266             }
00267 
00268 
00269         public:
00273             inline int GetCount() const { return GetArrayCount(); }
00274 
00276             inline void Clear()
00277             {
00278                 if (mBaseArray!=NULL)
00279                 {
00280                     KBaseArrayFree(mBaseArray);
00281                     mBaseArray = NULL;
00282                 }
00283             }
00284 
00285 
00287             inline void Empty()
00288             {
00289                 #ifdef KFBX_PRIVATE
00290                 #ifdef _DEBUG
00291                     memset( mBaseArray+ GetHeaderOffset() ,0,GetArrayCount()*GetTypeSize());
00292                 #endif
00293             #endif
00294                 SetArrayCount(0);
00295             }
00296 
00297 
00303             inline int      Reserve(int pCapacity)
00304             {
00305                 #ifdef KFBX_PRIVATE
00306                     K_ASSERT( pCapacity > 0 );
00307                 #endif
00308 
00309                 if( pCapacity )
00310                 {
00311                     const kUInt lTempNewBlockCount = ( (kUInt) (pCapacity + KFBX_ARRAYUL_BLOCKSIZE - 1 ) / KFBX_ARRAYUL_BLOCKSIZE );
00312                     const kUInt lNewBlockCount = (lTempNewBlockCount > 1 ? lTempNewBlockCount : 1);
00313 
00314                     int         lArrayCount   = GetArrayCount();
00315                     int         lBlockCount   = GetBlockCount();
00316 
00317                     const kUInt lOldArraySize = lArrayCount*GetTypeSize();
00318                     const kUInt lNewArraySize = lNewBlockCount*KFBX_ARRAYUL_BLOCKSIZE*GetTypeSize();
00319 
00320                     if (lNewBlockCount != (kUInt) lBlockCount)
00321                     {
00322                         char* lBaseArray = KBaseArrayRealloc(mBaseArray, (size_t) lNewArraySize+ GetHeaderOffset()  );
00323                         if (!lBaseArray)
00324                             return GetBlockCount()*KFBX_ARRAYUL_BLOCKSIZE;
00325                         mBaseArray = lBaseArray;
00326                     }
00327 
00328                     if( lNewBlockCount > (kUInt) lBlockCount ) {
00329                         memset( ((char*)mBaseArray+ GetHeaderOffset() ) + lOldArraySize, 0, (size_t) (lNewArraySize-lOldArraySize) );
00330                         SetArrayCount(lArrayCount);
00331                     } else if (pCapacity < lArrayCount)
00332                     {
00333                         memset( ((char*)mBaseArray+ GetHeaderOffset() ) + pCapacity*GetTypeSize(), 0, (size_t) (lNewArraySize-pCapacity*GetTypeSize()) );
00334                         SetArrayCount(pCapacity);
00335                     }
00336 
00337                     SetBlockCount(lNewBlockCount);
00338                 }
00339 
00340                 return GetBlockCount()*KFBX_ARRAYUL_BLOCKSIZE;
00341             }
00342 
00343 
00345             //  Differ from SetCount because array capacity can be lowered.
00346 
00352             inline void     SetCount (int pCount)
00353             {
00354             #ifdef KFBX_PRIVATE
00355             #ifdef _DEBUG
00356                 if (pCount<0)
00357                 {
00358                     K_ASSERT_MSG_NOW (_T("ArrayUL : Item count can't be negative"));
00359                     return ;
00360                 }
00361             #endif
00362             #endif
00363                 int lArrayCount = GetArrayCount();
00364                 if (pCount > lArrayCount)
00365                 {
00366                     AddMultiple( pCount-lArrayCount);
00367                 } else
00368                 {
00369                     SetArrayCount(pCount);
00370                 }
00371             }
00372 
00373             inline void     Resize(int pItemCount)
00374             {
00375                 #ifdef KFBX_PRIVATE
00376                     K_ASSERT( pItemCount >= 0 );
00377                 #endif
00378 
00379                 const kUInt lTempNewBlockCount = ( (kUInt) (pItemCount + KFBX_ARRAYUL_BLOCKSIZE - 1 ) / KFBX_ARRAYUL_BLOCKSIZE );
00380                 const kUInt lNewBlockCount = (lTempNewBlockCount > 1 ? lTempNewBlockCount : 1);
00381 
00382                 int         lArrayCount     = GetArrayCount();
00383                 int         lBlockCount   = GetBlockCount();
00384 
00385                 const kUInt lOldArraySize   = lArrayCount*GetTypeSize();
00386                 const kUInt lNewArraySize   = lNewBlockCount*KFBX_ARRAYUL_BLOCKSIZE*GetTypeSize();
00387 
00388                 if (lNewBlockCount != (kUInt) lBlockCount)
00389                 {
00390                     char* lBaseArray = KBaseArrayRealloc(mBaseArray, (size_t) lNewArraySize+ GetHeaderOffset()  );
00391                     if (!lBaseArray)
00392                         return;
00393                     mBaseArray = lBaseArray;
00394                 }
00395 
00396                 if( lNewBlockCount > (kUInt) lBlockCount )
00397                     memset( ((char*)mBaseArray+ GetHeaderOffset() ) + lOldArraySize, 0, (size_t) (lNewArraySize-lOldArraySize) );
00398                 else if (pItemCount < lArrayCount)
00399                     memset( ((char*)mBaseArray+ GetHeaderOffset() ) + pItemCount*GetTypeSize(), 0, (size_t) (lNewArraySize-pItemCount*GetTypeSize()) );
00400 
00401                 SetBlockCount(lNewBlockCount);
00402                 SetArrayCount(pItemCount);
00403             }
00404 
00405             inline void     AddMultiple(int pItemCount)
00406             {
00407                 #ifdef KFBX_PRIVATE
00408                     K_ASSERT( pItemCount > 0 );
00409                 #endif
00410 
00411                 if( pItemCount )
00412                 {
00413                     int         lArrayCount = GetArrayCount();
00414                     int         lBlockCount = GetBlockCount();
00415                     const kUInt lTempNewBlockCount = ( (kUInt) (lArrayCount+pItemCount + KFBX_ARRAYUL_BLOCKSIZE - 1 ) / KFBX_ARRAYUL_BLOCKSIZE );
00416                     const kUInt lNewBlockCount = (lTempNewBlockCount > 1 ? lTempNewBlockCount : 1);
00417 
00418                     const kUInt lOldArraySize = lArrayCount*GetTypeSize();
00419                     const kUInt lNewArraySize = lNewBlockCount*KFBX_ARRAYUL_BLOCKSIZE*GetTypeSize();
00420 
00421                     #ifdef KFBX_PRIVATE
00422                         K_ASSERT( lOldArraySize < lNewArraySize );
00423                     #endif
00424 
00425                     if( lNewBlockCount > (kUInt) lBlockCount )
00426                     {
00427                         char* lBaseArray = KBaseArrayRealloc(mBaseArray, (size_t) lNewArraySize+ GetHeaderOffset()  );
00428                         if (!lBaseArray)
00429                             return;
00430                         mBaseArray = lBaseArray;
00431                         lBlockCount = lNewBlockCount;
00432                     }
00433 
00434                     memset( ((char*)mBaseArray+ GetHeaderOffset() ) + lOldArraySize, 0, (size_t) (lNewArraySize-lOldArraySize) );
00435                     SetArrayCount ( lArrayCount + pItemCount );
00436                     SetBlockCount (lBlockCount);
00437                 }
00438             }
00439 
00440 
00441             inline int  GetTypeSize() const { return mTypeSize.GetTypeSize(); }
00442 
00444         //
00445         //  WARNING!
00446         //
00447         //  Anything beyond these lines may not be documented accurately and is
00448         //  subject to change without notice.
00449         //
00451         #ifndef DOXYGEN_SHOULD_SKIP_THIS
00452 
00453         protected:
00454             inline KHeader* const   GetHeader() const
00455             {
00456                 return (KHeader*    const   )mBaseArray;
00457             }
00458             inline KHeader*     GetHeader()
00459             {
00460                 return (KHeader*)mBaseArray;
00461             }
00462             inline int GetHeaderOffset() const
00463             {
00464                 return sizeof(KHeader);
00465             }
00466             inline int GetArrayCount() const
00467             {
00468                 return GetHeader() ? GetHeader()->mArrayCount : 0;
00469             }
00470             inline void SetArrayCount(int pArrayCount)
00471             {
00472                 if (GetHeader()) GetHeader()->mArrayCount=pArrayCount;
00473             }
00474             inline int GetBlockCount() const
00475             {
00476                 return GetHeader() ? GetHeader()->mBlockCount : 0;
00477             }
00478             inline void SetBlockCount(int pArrayCount)
00479             {
00480                 if (GetHeader()) GetHeader()->mBlockCount=pArrayCount;
00481             }
00482 
00483         protected:
00484             char*           mBaseArray;
00485             TypeSize        mTypeSize;
00486 
00487         #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
00488 
00489     };
00490 
00492     template < class Type > class  KArrayTemplate : public KBaseArray< KBaseArraySizeType<Type> >
00493     {
00494         typedef KBaseArray< KBaseArraySizeType<Type> > ParentClass;
00495 
00496 #ifdef _MSC_VER
00497         // Previously class KArrayTemplate is for pointers. Somehow, it's used to store other types.
00498         // Here's a compile-time checking for known incompatible classes.
00499         // If it happens you find new incompatible ones, declare them with macro KFBX_INCOMPATIBLE_WITH_KARRAYTEMPLATE
00500         // Also see file string.h
00501         K_STATIC_ASSERT(
00502             KFBX_IS_SIMPLE_TYPE(Type)
00503             || __is_enum(Type)
00504             || (__has_trivial_constructor(Type)&&__has_trivial_destructor(Type))
00505             || !KFBX_IS_INCOMPATIBLE_WITH_KARRAYTEMPLATE(Type)
00506         );
00507 #endif
00508 
00509     public:
00512         inline KArrayTemplate()
00513             : ParentClass (KBaseArraySizeType<Type>())
00514         {
00515         }
00516 
00518         inline KArrayTemplate(const KArrayTemplate& pArrayTemplate)
00519             : ParentClass (KBaseArraySizeType<Type>())
00520         {
00521             *this = pArrayTemplate;
00522         }
00523 
00524         inline ~KArrayTemplate() {}
00525 
00532         inline int InsertAt(int pIndex, Type pItem)
00533         {
00534             return ParentClass::InsertAt( pIndex,&pItem );
00535         }
00536 
00541         inline Type RemoveAt(int pIndex)
00542         {
00543             Type tmpItem = GetAt(pIndex);
00544             ParentClass::RemoveAt( pIndex );
00545             return tmpItem;
00546         }
00547 
00551         inline Type RemoveLast()
00552         {
00553             return RemoveAt(ParentClass::GetArrayCount()-1);
00554         }
00555 
00560         inline bool RemoveIt(Type pItem)
00561         {
00562             int Index = Find (pItem);
00563             if (Index>=0)
00564             {
00565                 RemoveAt (Index);
00566                 return true;
00567             }
00568             return false;
00569         }
00570 
00572         inline Type &operator[](int pIndex) const
00573         {
00574         #if defined(_DEBUG) && !defined(KARCH_ENV_MACOSX)
00575             if (!ParentClass::ValidateIndex( pIndex ))
00576             {
00577                 return (Type &)(ParentClass::mBaseArray[(0)*sizeof(Type)+ ParentClass::GetHeaderOffset() ]);
00578             }
00579         #endif
00580             return (Type &)(ParentClass::mBaseArray[(pIndex)*sizeof(Type)+ ParentClass::GetHeaderOffset() ]);
00581         }
00582 
00584         inline void SetAt(int pIndex, Type pItem)
00585         {
00586         #if defined(_DEBUG) && !defined(KARCH_ENV_MACOSX)
00587             if (!ParentClass::ValidateIndex( pIndex ))
00588             {
00589                 return;
00590             }
00591         #endif
00592             GetArray()[pIndex] = pItem;
00593         }
00594 
00596         inline void SetLast(Type pItem)
00597         {
00598             SetAt (ParentClass::GetArrayCount()-1, pItem);
00599         }
00600 
00602         inline Type GetAt(int pIndex) const
00603         {
00604         #if defined(_DEBUG) && !defined(KARCH_ENV_MACOSX)
00605             if (!ParentClass::ValidateIndex( pIndex ))
00606             {
00607                 return (Type &)(ParentClass::mBaseArray[(0)*sizeof(Type)+ ParentClass::GetHeaderOffset() ]);
00608             }
00609         #endif
00610             return (Type &)(ParentClass::mBaseArray[(pIndex)*sizeof(Type)+ ParentClass::GetHeaderOffset() ]);
00611         }
00612 
00616         inline Type GetFirst() const
00617         {
00618         #ifdef KFBX_PRIVATE
00619             K_ASSERT( ParentClass::GetArrayCount() >= 1 );
00620         #endif
00621             return GetAt(0);
00622         }
00623 
00627         inline Type GetLast() const
00628         {
00629         #ifdef KFBX_PRIVATE
00630             K_ASSERT( ParentClass::GetArrayCount() >= 1 );
00631         #endif
00632             return GetAt(ParentClass::GetArrayCount()-1);
00633         }
00634 
00639         inline int Find(Type pItem) const
00640         {
00641             return FindAfter( -1, pItem );
00642         }
00643 
00649         inline int FindAfter(int pAfterIndex, Type pItem) const
00650         {
00651         #ifdef KFBX_PRIVATE
00652         #ifdef _DEBUG
00653             if ( pAfterIndex > ParentClass::GetArrayCount() || pAfterIndex < -1 )
00654             {
00655                 K_ASSERT_MSG_NOW (_T("ArrayUL : Search Begin Index out of range"));
00656                 return -1;
00657             }
00658         #endif
00659         #endif
00660             int Count;
00661             for ( Count=pAfterIndex+1; Count<ParentClass::GetArrayCount(); Count++)
00662             {
00663                 if (GetAt(Count)==pItem)
00664                 {
00665                     return Count;
00666                 }
00667             }
00668             return -1;
00669         }
00670 
00676         inline int FindBefore(int pBeforeIndex, Type pItem) const
00677         {
00678         #ifdef KFBX_PRIVATE
00679         #ifdef _DEBUG
00680             if ( pBeforeIndex > ParentClass::GetArrayCount() || pBeforeIndex <= 0 )
00681             {
00682                 K_ASSERT_MSG_NOW (_T("ArrayUL : Search Begin Index out of range"));
00683                 return -1;
00684             }
00685         #endif
00686         #endif
00687             int Count;
00688             for ( Count=pBeforeIndex-1; Count>=0; Count--)
00689             {
00690                 if (GetAt(Count)==pItem)
00691                 {
00692                     return Count;
00693                 }
00694             }
00695             return -1;
00696         }
00697 
00701         inline int Add(Type pItem)
00702         {
00703             return InsertAt(ParentClass::GetArrayCount(), pItem);
00704         }
00705 
00709         inline int AddUnique(Type pItem)
00710         {
00711             int lReturnIndex = Find(pItem);
00712             if (lReturnIndex == -1)
00713             {
00714                 lReturnIndex = Add(pItem);
00715             }
00716             return lReturnIndex;
00717         }
00718 
00722         inline void AddMultiple( kUInt pItemCount )
00723         {
00724             ParentClass::AddMultiple( pItemCount );
00725         }
00726 
00727         inline void AddArray(KArrayTemplate<Type> &pArray)
00728         {
00729             int lSourceIndex, lCount = pArray.GetCount();
00730             if( lCount == 0 ) return;
00731             int lDestinationIndex = ParentClass::GetCount();
00732             AddMultiple(lCount);
00733             for( lSourceIndex = 0; lSourceIndex < lCount; lSourceIndex++)
00734             {
00735                 SetAt(lDestinationIndex++, pArray[lSourceIndex]);
00736             }
00737         }
00738 
00739         inline void AddArrayNoDuplicate(KArrayTemplate<Type> &pArray)
00740         {
00741             int i, lCount = pArray.GetCount();
00742             for( i = 0; i < lCount; i++)
00743             {
00744                 Type lItem = pArray[i];
00745                 if (Find(lItem) == -1)
00746                 {
00747                     Add(lItem);
00748                 }
00749             }
00750         }
00751         inline void RemoveArray(KArrayTemplate<Type> &pArray)
00752         {
00753             int lRemoveIndex, lRemoveCount = pArray.GetCount();
00754             for( lRemoveIndex = 0; lRemoveIndex < lRemoveCount; lRemoveIndex++)
00755             {
00756                 RemoveIt(pArray[lRemoveIndex]);
00757             }
00758         }
00759 
00761         inline Type* GetArray() const
00762         {
00763             if (ParentClass::mBaseArray == NULL)
00764                 return NULL;
00765 
00766             return (Type*)(ParentClass::mBaseArray+ ParentClass::GetHeaderOffset()) ;
00767         }
00768 
00770         inline KArrayTemplate<Type>& operator=(const KArrayTemplate<Type>& pArrayTemplate)
00771         {
00772             if ( this != &pArrayTemplate )
00773             {
00774                 ParentClass::Clear();
00775 
00776                 int i, lCount = pArrayTemplate.GetCount();
00777 
00778                 for (i = 0; i < lCount; i++)
00779                 {
00780                     Add(pArrayTemplate[i]);
00781                 }
00782             }
00783 
00784             return (*this);
00785         }
00786 
00788             inline operator Type* ()
00789             {
00790                 return GetArray();
00791             }
00792     };
00793 
00795     //
00796     //  WARNING!
00797     //
00798     //  Anything beyond these lines may not be documented accurately and is
00799     //  subject to change without notice.
00800     //
00802 
00803     #ifndef DOXYGEN_SHOULD_SKIP_THIS
00804     template <class Type> inline void FbxSdkDeleteAndClear(KArrayTemplate<Type>& Array)
00805     {
00806         kUInt lItemCount = Array.GetCount();
00807         while( lItemCount )
00808         {
00809             lItemCount--;
00810             Type& Item = (Array.operator[](lItemCount));
00811             FbxSdkDelete(Item);
00812             Item = NULL;
00813         }
00814         Array.Clear();
00815     }
00816 
00817     template <class Type> inline void DeleteAndClear(KArrayTemplate<Type>& Array)
00818     {
00819         kUInt lItemCount = Array.GetCount();
00820         while( lItemCount )
00821         {
00822             lItemCount--;
00823             Type& Item = (Array.operator[](lItemCount));
00824             delete Item;
00825             Item = NULL;
00826         }
00827         Array.Clear();
00828     }
00829 /*    template <class Type> inline void DeleteAndClear(KArrayTemplate<Type>& Array)
00830     {
00831         kUInt lItemCount = Array.GetCount();
00832         while( lItemCount )
00833         {
00834             lItemCount--;
00835             Type& Item = (Array.operator[](lItemCount));
00836             delete Item;
00837             Item = NULL;
00838         }
00839         Array.Clear();
00840     }
00841 */
00842     typedef class KFBX_DLL KArrayTemplate<int *>    KArrayHkInt;
00843     typedef class KFBX_DLL KArrayTemplate<kUInt *>  KArrayHkUInt;
00844     typedef class KFBX_DLL KArrayTemplate<double *> KArrayHkDouble;
00845     typedef class KFBX_DLL KArrayTemplate<float *>  KArrayHkFloat;
00846     typedef class KFBX_DLL KArrayTemplate<void *>   KArrayVoid;
00847     typedef class KFBX_DLL KArrayTemplate<char *>   KArrayChar;
00848     typedef class KFBX_DLL KArrayTemplate<int>      KIntArray;
00849     typedef class KFBX_DLL KArrayTemplate<kUInt>    KUIntArray;
00850     typedef class KFBX_DLL KArrayTemplate<float>    KFloatArray;
00851     typedef class KFBX_DLL KArrayTemplate<double>   KDoubleArray;
00852 
00853     typedef class KFBX_DLL KArrayTemplate<kReference>   KArrayUL;
00854 
00855     #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
00856 
00857 #include <fbxfilesdk/fbxfilesdk_nsend.h>
00858 
00859 #endif // FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KARRAYUL_H
00860