00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00169 #ifndef cxx_template_INCLUDED
00170 #define cxx_template_INCLUDED "cxx_template.h"
00171 #ifdef _KEEP_RCS_ID
00172 static char *cxx_templatercs_id = cxx_template_INCLUDED"$Revision: 1.2 $";
00173 #endif
00174
00175 #include "mempool.h"
00176 #include "erglob.h"
00177 #include "errors.h"
00178
00179 template <class T>
00180 class DYN_ARRAY {
00181 private:
00182 MEM_POOL *_mpool;
00183 mUINT32 _size;
00184 mINT32 _lastidx;
00185 T *_array;
00186
00187 DYN_ARRAY(const DYN_ARRAY&);
00188 public:
00189
00190 DYN_ARRAY(void);
00191 DYN_ARRAY(MEM_POOL *pool);
00192 ~DYN_ARRAY(void);
00193
00194 MEM_POOL* Get_Mem_Pool() { return _mpool; }
00195 void Set_Mem_Pool(MEM_POOL* mpool) { _mpool = mpool; }
00196
00197 void Alloc_array(mUINT32 arr_size);
00198 void Force_Alloc_array(mUINT32 arr_size);
00199 void Realloc_array(mUINT32 new_size);
00200 void Free_array(void);
00201 void Bzero_array(void);
00202
00203 DYN_ARRAY<T>& operator = (const DYN_ARRAY<T>& a);
00204 T& Get(mUINT32 idx) const;
00205 void Set(mUINT32 idx, const T& val);
00206 T& operator[] (mUINT32 idx) const
00207 { Is_True(idx <= _lastidx, ("DYN_ARRAY::[]:Subscript out of range"));
00208 return (_array[idx]); }
00209 T& operator[] (mUINT32 idx)
00210 { Is_True(idx <= _lastidx, ("DYN_ARRAY::[]:Subscript out of range"));
00211 return (_array[idx]); }
00212
00213 void AddElement (const T& val)
00214 {
00215 #ifdef KEY
00216 mUINT32 idx = Newidx();
00217 _array[idx] = val;
00218 #else
00219 _array[Newidx()] = val;
00220 #endif
00221 }
00222 mUINT32 Elements () const { return (_lastidx+1); }
00223
00224 mUINT32 Newidx(void);
00225 void Decidx(void) { _lastidx--; }
00226 void Initidx(UINT32 idx);
00227 void Setidx(UINT32 idx);
00228 void Resetidx(void) { _lastidx = -1; }
00229 mUINT32 Sizeof(void) const { return _size; }
00230 mINT32 Lastidx(void) const { return _lastidx; }
00231 mUINT32 Idx(T *t) const { return t - _array; }
00232 };
00233
00297 template <class T>
00298 class STACK {
00299 private:
00300 DYN_ARRAY<T> _stack;
00301
00302 STACK(const STACK&);
00303 STACK& operator = (const STACK&);
00304
00305 public:
00306 STACK(MEM_POOL *pool):_stack(pool) {}
00307 ~STACK(void) {}
00308 void Push(const T& val) { _stack[_stack.Newidx()]=val;}
00309 void Settop(const T& val);
00310 INT32 Topidx(void) { return _stack.Lastidx(); }
00311 T Pop(void) {
00312 T t;
00313 INT32 idx = _stack.Lastidx();
00314 FmtAssert(idx >= 0, ("STACK::pop(): Stack Empty"));
00315 t = _stack[idx];
00316 _stack.Decidx();
00317 return t;
00318 }
00319
00320 T& Top_nth(const INT32 n) const;
00321 T& Bottom_nth(const INT32 n) const;
00322 T& Top(void) const;
00323 BOOL Is_Empty(void) const;
00324 void Clear(void) { _stack.Resetidx(); }
00325 void Free() { _stack.Free_array(); }
00326 void Alloc(const INT32 n) { _stack.Alloc_array(n); }
00327 mINT32 Elements() const { return(_stack.Lastidx() +1);}
00328 };
00329
00330
00345 template <class CONTAINER, class PREDICATE>
00346 void Remove_if(CONTAINER& container, PREDICATE pred);
00347
00348
00349
00350
00351
00352
00353 #define MIN_ARRAY_SIZE 16
00354
00355 template <class T >
00356 DYN_ARRAY<T>::DYN_ARRAY(void)
00357 {
00358 _lastidx = -1;
00359 _size = 0;
00360 _array = NULL;
00361 _mpool = NULL;
00362 }
00363
00364 template <class T >
00365 DYN_ARRAY<T>::DYN_ARRAY(MEM_POOL *pool)
00366 {
00367 _lastidx = -1;
00368 _size = 0;
00369 _array = NULL;
00370 _mpool = pool;
00371 }
00372
00373 template <class T >
00374 DYN_ARRAY<T>::~DYN_ARRAY()
00375 {
00376 Free_array();
00377 }
00378
00379
00380 template <class T>
00381 void
00382 DYN_ARRAY<T>::Alloc_array(mUINT32 arr_size)
00383 {
00384 _size = arr_size > MIN_ARRAY_SIZE ? arr_size : MIN_ARRAY_SIZE;
00385 _array = (T*)MEM_POOL_Alloc(_mpool, _size * sizeof(T));
00386 if ( _array == NULL ) ErrMsg ( EC_No_Mem, "DYN_ARRAY::Alloc_array" );
00387 }
00388
00389
00390 template <class T>
00391 void
00392 DYN_ARRAY<T>::Force_Alloc_array (mUINT32 arr_size)
00393 {
00394 _size = arr_size > 1 ? arr_size : 1;
00395 _array = (T*)MEM_POOL_Alloc(_mpool, _size * sizeof(T));
00396 if ( _array == NULL ) ErrMsg ( EC_No_Mem, "DYN_ARRAY::Alloc_array" );
00397 }
00398
00399 template <class T>
00400 void
00401 DYN_ARRAY<T>::Realloc_array(mUINT32 new_size)
00402 {
00403 _array = (T*)MEM_POOL_Realloc(_mpool,
00404 _array,
00405 sizeof(T) * _size,
00406 sizeof(T) * new_size);
00407 if ( _array == NULL ) ErrMsg ( EC_No_Mem, "DYN_ARRAY::Realloc_array" );
00408 _size = new_size;
00409 }
00410
00411 template <class T>
00412 void
00413 DYN_ARRAY<T>::Free_array()
00414 {
00415 if (_array != NULL) {
00416 MEM_POOL_FREE(_mpool,_array);
00417 _array = NULL;
00418 _size = 0;
00419 }
00420 }
00421
00422 template <class T>
00423 void
00424 DYN_ARRAY<T>::Bzero_array()
00425 {
00426 if (_array != NULL) BZERO(_array,sizeof(T) * _size);
00427 }
00428
00429 template <class T>
00430 DYN_ARRAY<T>&
00431 DYN_ARRAY<T>::operator = (const DYN_ARRAY<T>& a)
00432 {
00433 if (_size != a._size) Realloc_array(a._size);
00434 _lastidx = a._lastidx;
00435 memcpy (_array, a._array, a._size * sizeof(T));
00436 return *this;
00437 }
00438
00439 template <class T >
00440 mUINT32
00441 DYN_ARRAY<T>::Newidx()
00442 {
00443 _lastidx++;
00444 if (_lastidx >= _size) {
00445
00446 if (_array == NULL) {
00447 Alloc_array (MIN_ARRAY_SIZE);
00448 } else {
00449 Realloc_array (_size * 2);
00450 }
00451 }
00452 return _lastidx;
00453 }
00454
00455 template <class T >
00456 void
00457 DYN_ARRAY<T>::Initidx(UINT32 idx)
00458 {
00459 _lastidx=idx;
00460 if (_lastidx >= _size) {
00461
00462 if (_array != NULL) {
00463 Free_array();
00464 }
00465 Alloc_array(_lastidx + 1);
00466 }
00467 }
00468
00469 template <class T >
00470 void
00471 DYN_ARRAY<T>::Setidx(UINT32 idx)
00472 {
00473 _lastidx=idx;
00474 if (_lastidx >= _size) {
00475
00476 if (_array == 0)
00477 Alloc_array(_lastidx + 1);
00478 else {
00479 INT32 new_size = _size * 2;
00480 while (new_size < _lastidx + 1) new_size *= 2;
00481 Realloc_array(new_size);
00482 }
00483 }
00484 }
00485
00486 template <class T>
00487 void STACK<T>::Settop(const T& val)
00488 {
00489 INT32 idx = _stack.Lastidx();
00490
00491 Is_True(idx >= 0, ("STACK::Settop(): Stack Empty"));
00492 _stack[idx] = val;
00493 }
00494
00495
00496 template <class T>
00497 T& STACK<T>::Top_nth(const INT32 n) const
00498 {
00499 INT32 idx = _stack.Lastidx();
00500
00501 Is_True(idx >= n, ("STACK::Top_nth(): Access beyond stack bottom"));
00502 return _stack[idx - n];
00503 }
00504
00505
00506 template <class T>
00507 T& STACK<T>::Bottom_nth(const INT32 n) const
00508 {
00509 INT32 idx = _stack.Lastidx();
00510
00511 Is_True(n <= idx, ("STACK::Bottom_nth(): Access beyond stack top"));
00512 return _stack[n];
00513 }
00514
00515
00516 template <class T>
00517 T& STACK<T>::Top(void) const
00518 {
00519 INT32 idx = _stack.Lastidx();
00520
00521 Is_True(idx >= 0, ("STACK::Top(): Stack Empty"));
00522 return _stack[idx];
00523 }
00524
00525 template <class T>
00526 BOOL STACK<T>::Is_Empty(void) const
00527 {
00528 return _stack.Lastidx() < 0;
00529 }
00530
00531
00532 template <class CONTAINER, class PREDICATE>
00533 void Remove_if(CONTAINER& container, PREDICATE predicate)
00534 {
00535 typename CONTAINER::CONTAINER_NODE *prev = NULL, *curr, *next;
00536 for (curr = container.Head(); curr != NULL; curr = next) {
00537 next = curr->Next();
00538 if (predicate(curr)) {
00539 if (prev == NULL)
00540 container.Set_Head(next);
00541 else
00542 prev->Set_Next(next);
00543 } else {
00544 prev = curr;
00545 }
00546 }
00547 if (prev == NULL)
00548 container.Set_Tail(container.Head());
00549 else
00550 container.Set_Tail(prev);
00551 }
00552
00553 #endif // cxx_template_INCLUDED