# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

object_vector.h

Go to the documentation of this file.
00001 
00007 /* Copyright, 2001 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #ifndef NL_OBJECT_VECTOR_H
00027 #define NL_OBJECT_VECTOR_H
00028 
00029 #include "nel/misc/types_nl.h"
00030 #include "nel/misc/common.h"
00031 #include "nel/misc/stream.h"
00032 #include "nel/misc/debug.h"
00033 
00034 
00035 namespace NLMISC {
00036 
00037 
00038 // ***************************************************************************
00042 struct  EReallocationFailed : public Exception
00043 {
00044         EReallocationFailed() : Exception( "Can't reallocate memory" ) {}
00045 };
00046 
00047 
00048 // ***************************************************************************
00071 template<class T, bool EnableObjectBehavior=true>       class CObjectVector
00072 {
00073 public:
00074 
00076         // @{
00077         CObjectVector()
00078         {
00079                 _Ptr= NULL;
00080                 _Size= 0;
00081         }
00082         ~CObjectVector()
00083         {
00084                 clear();
00085         }
00089         CObjectVector(const CObjectVector &vec)
00090         {
00091                 _Ptr= NULL;
00092                 _Size= 0;
00093                 operator=(vec);
00094         }
00098         CObjectVector   &operator=(const CObjectVector &vec)
00099         {
00100                 // *this=*this mgt.
00101                 if(this==&vec)
00102                         return *this;
00103                 // resize to the same size as vec.
00104                 resize(vec._Size);
00105                 // copy All the array.
00106                 copy(0, _Size, vec._Ptr);
00107 
00108                 return *this;
00109         }
00110         // @}
00111 
00112 
00114         // @{
00115 
00118         void            clear()
00119         {
00120                 destruct(0, _Size);
00121                 free(_Ptr);
00122                 _Ptr= NULL;
00123                 _Size= 0;
00124         }
00125 
00131         void            resize(uint32 size)
00132         {
00133                 // if same size, no-op.
00134                 if(size==_Size)
00135                         return;
00136 
00137                 // if empty, just clear.
00138                 if(size==0)
00139                         clear();
00140                 // crop the array?
00141                 else if(size<_Size)
00142                 {
00143                         // destruct the objects to be freed
00144                         destruct(size, _Size);
00145                         // realloc
00146                         myRealloc(size);
00147                         _Size= size;
00148                 }
00149                 // else, enlarge the array
00150                 else
00151                 {
00152                         // realloc first
00153                         myRealloc(size);
00154                         // For all new elements, construct them.
00155                         construct(_Size, size);
00156                         // change size.
00157                         _Size= size;
00158                 }
00159         }
00160 
00161         // @}
00162 
00163 
00165         // @{
00166 
00169         uint32          size() const {return _Size;}
00170 
00173         T                       &operator[](uint index) const
00174         {
00175                 return _Ptr[index];
00176         }
00177 
00180         T                       *getPtr() const {return _Ptr;}
00181 
00182         // @}
00183 
00184 
00186         // @{
00187 
00191         void            copy(uint32 dstFirst, uint32 dstLast, const T *srcPtr)
00192         {
00193                 // test if something to copy.
00194                 if(dstFirst>=dstLast)
00195                         return;
00196                 nlassert(dstLast<=_Size);
00197                 // if not object elements
00198                 if(!EnableObjectBehavior)
00199                 {
00200                         // just memcpy
00201                         memcpy(_Ptr+dstFirst, srcPtr, (dstLast-dstFirst)*sizeof(T));
00202                 }
00203                 else
00204                 {
00205                         // call ope= for all elements.
00206                         for(uint i=dstFirst; i<dstLast; i++, srcPtr++)
00207                         {
00208                                 _Ptr[i]= *srcPtr;
00209                         }
00210                 }
00211         }
00212 
00213 
00216         void            fill(uint32 dstFirst, uint32 dstLast, const T &value)
00217         {
00218                 // test if something to copy.
00219                 if(dstFirst>=dstLast)
00220                         return;
00221                 nlassert(dstLast<=_Size);
00222                 // call ope= for all elements.
00223                 for(uint i=dstFirst; i<dstLast; i++)
00224                 {
00225                         _Ptr[i]= value;
00226                 }
00227         }
00228 
00231         void            fill(const T &value)
00232         {
00233                 // call ope= for all elements.
00234                 for(uint i=0; i<_Size; i++)
00235                 {
00236                         _Ptr[i]= value;
00237                 }
00238         }
00239 
00240 
00241 
00245         void            serial(NLMISC::IStream &f)
00246         {
00247                 // Open a node header
00248                 f.xmlPushBegin ("VECTOR");
00249 
00250                 // Attrib size
00251                 f.xmlSetAttrib ("size");
00252 
00253                 sint32  len=0;
00254                 if(f.isReading())
00255                 {
00256                         f.serial(len);
00257 
00258                         // Open a node header
00259                         f.xmlPushEnd ();
00260 
00261                         // special version for vector: adjut good size.
00262                         contReset(*this);
00263                         resize (len);
00264 
00265                         // Read the vector
00266                         for(sint i=0;i<len;i++)
00267                         {
00268                                 f.xmlPush ("ELM");
00269 
00270                                 f.serial(_Ptr[i]);
00271 
00272                                 f.xmlPop ();
00273                         }
00274                 }
00275                 else
00276                 {
00277                         len= size();
00278                         f.serial(len);
00279 
00280                         // Close the node header
00281                         f.xmlPushEnd ();
00282 
00283                         // Write the vector
00284                         for(sint i=0;i<len;i++)
00285                         {
00286                                 f.xmlPush ("ELM");
00287 
00288                                 f.serial(_Ptr[i]);
00289 
00290                                 f.xmlPop ();
00291                         }
00292                 }
00293 
00294                 // Close the node
00295                 f.xmlPop ();
00296         }
00297 
00298         // @}
00299 
00300 
00301 
00302 // *******************
00303 private:
00304 
00306         T                               *_Ptr;
00308         uint32                  _Size;
00309 
00310 
00311 private:
00312         // realloc, and manage allocation failure. Don't modify _Size.
00313         void    myRealloc(uint32 size)
00314         {
00315                 // try to realloc the array.
00316                 T       *newPtr= (T*)realloc(_Ptr, size*sizeof(T));
00317                 // if realloc failure
00318                 if(newPtr==NULL)
00319                 {
00320                         // leave the array in a clean state.
00321                         clear();
00322                         // exception.
00323                         throw EReallocationFailed();
00324                 }
00325                 else
00326                 {
00327                         _Ptr= newPtr;
00328                 }
00329         }
00330 
00331         // For all elements in the range, destruct.
00332         void    destruct(uint32 i0, uint32 i1)
00333         {
00334                 // don't do it if elements don't need it.
00335                 if(!EnableObjectBehavior)
00336                         return;
00337                 // for all elements
00338                 for(uint i=i0;i<i1;i++)
00339                 {
00340                         // call dtor.
00341                         _Ptr[i].~T();
00342                 }
00343         }
00344 
00345         // For all elements in the range, construct.
00346         void    construct(uint32 i0, uint32 i1)
00347         {
00348                 // don't do it if elements don't need it.
00349                 if(!EnableObjectBehavior)
00350                         return;
00351                 // for all elements
00352                 for(uint i=i0;i<i1;i++)
00353                 {
00354 // Must do a placement new
00355 #undef new
00356                         // call ctor.
00357                         new (_Ptr+i) T;
00358 // Must do a placement new
00359 #define new NL_NEW
00360                 }
00361         }
00362 
00363 };
00364 
00365 
00366 } // NLMISC
00367 
00368 
00369 #endif // NL_OBJECT_VECTOR_H
00370 
00371 /* End of object_vector.h */