00001
00150 #ifndef INC_MI32_DOUBLEAR_H
00151 #define INC_MI32_DOUBLEAR_H
00152
00153 #ifndef INC_MI32_MIDBLARY_H
00154 #include <mi32/midblary.h>
00155 #endif
00156
00157 #ifndef INC_MI32_MEMBUF_H
00158 #include <mi32/membuf.h>
00159 #endif
00160
00161 #ifndef INC_MEMORY_H
00162 #include <memory.h>
00163 #define INC_MEMORY_H
00164 #endif
00165
00181
00182 template <class _CT> class DOUBLE_ARRAY {
00183
00184 public:
00185
00187 DOUBLE_ARRAY (
00188 ):
00189 m_data(0),
00190 m_numitems(0),
00191 m_RefCount(1)
00192 { }
00193
00195 DOUBLE_ARRAY (
00196 const DOUBLE_ARRAY<_CT>& rhs
00197 ) :
00198 m_items(rhs.m_items),
00199 m_numitems(rhs.m_numitems),
00200 m_RefCount(1)
00201 {
00202 m_data = reinterpret_cast<_CT*>(m_items.GetPointer());
00203 }
00204
00205 ~DOUBLE_ARRAY (
00206 ) {}
00207
00209 DOUBLE_ARRAY<_CT>& operator= (
00210 const DOUBLE_ARRAY<_CT>& rhs
00211 ) {
00212 if (this != &rhs) {
00213 m_items = rhs.m_items;
00214 m_numitems = rhs.m_numitems;
00215 m_data = reinterpret_cast<_CT*>(m_items.GetPointer());
00216 }
00217 return (*this);
00218 }
00219
00221 bool operator== (
00222 const DOUBLE_ARRAY<_CT>& rhs
00223 ) const {
00224 if (m_numitems != rhs.m_numitems) return (false);
00225 if (m_numitems == 0) return (true);
00226 return (memcmp(m_data,m_data,m_numitems*sizeof(_CT)) == 0);
00227 }
00228
00230 bool operator!= (
00231 const DOUBLE_ARRAY<_CT>& rhs
00232 ) const {
00233 return (!operator==(rhs));
00234 }
00235
00237 operator const _CT*(
00238 ) const {
00239 return (m_data);
00240 }
00241
00243 operator _CT*(
00244 ) {
00245 return (m_data);
00246 }
00247
00251 template <typename _IDXTYPE> const _CT& operator[] (
00252 _IDXTYPE index
00253 ) const {
00254 return (m_data[index]);
00255 }
00256
00260 template <typename _IDXTYPE> _CT& operator[] (
00261 _IDXTYPE index
00262 ) {
00263 return (m_data[index]);
00264 }
00265
00267 void AddRef (
00268 ) { ++m_RefCount; }
00269
00271 ERRVALUE Append (
00272 const _CT& item
00273 ) {
00274 if (m_numitems >= GetMaxItems()) {
00275 int err;
00276 if ((err = m_items.Reserve(MAX(16,(2*m_numitems*sizeof(_CT) + sizeof(double) - 1) / sizeof(double)), true)) < 0) return (err);
00277 m_data = reinterpret_cast<_CT*>(m_items.GetPointer());
00278 }
00279 m_data[m_numitems++] = item;
00280 return (0);
00281 }
00282
00284 ERRVALUE Append (
00285 const _CT *items,
00286 unsigned numitems
00287 ) {
00288 ERRVALUE err;
00289 if ((err = Reserve(m_numitems+numitems)) < 0) return (err);
00290 memcpy(m_data+m_numitems,items,numitems*sizeof(_CT));
00291 m_numitems += numitems;
00292 return (0);
00293 }
00294
00297 ERRVALUE Assign (
00298 const _CT *items,
00299 int numitems
00300 ) {
00301 ERRVALUE err;
00302 if ((err = Reserve(numitems,true)) < 0) return (err);
00303 memcpy(m_data,items,numitems*sizeof(_CT));
00304 m_numitems = numitems;
00305 return (0);
00306 }
00307
00318 void Attach (
00319 MIDOUBLEARRAY& items,
00320 int numitems
00321 ) {
00322 m_items.Attach(items);
00323 m_numitems = numitems;
00324 m_data = reinterpret_cast<_CT*>(m_items.GetPointer());
00325 }
00326
00328 void Clear (
00329 ) { m_numitems = 0; }
00330
00332 void ClearItems (
00333 int start = 0,
00334 int end = -1
00335 ) {
00336 if (end < start) end = m_numitems - 1;
00337 memset(m_data + start, 0, (end - start + 1) * sizeof(_CT));
00338 }
00339
00342 ERRVALUE Copy (
00343 const DOUBLE_ARRAY<_CT>& rhs
00344 ) {
00345 if (this != &rhs) {
00346 return (SetItems(0, rhs, rhs.m_numitems));
00347 }
00348 return (0);
00349 }
00350
00353 void DeleteItem (
00354 int index
00355 ) {
00356 if (index >= 0 && index < m_numitems) {
00357 --m_numitems;
00358 if (index < m_numitems) {
00359 memmove(m_data+index,m_data+index+1,(m_numitems-index)*sizeof(_CT));
00360 }
00361 }
00362 }
00363
00373 void Detach (
00374 MIDOUBLEARRAY& items
00375 ) {
00376 items.Attach(m_items);
00377 m_numitems = 0;
00378 m_data = 0;
00379 }
00380
00381
00382
00384 void Free (
00385 ) {
00386 m_items.Free();
00387 m_numitems = 0;
00388 m_data = 0;
00389 }
00390
00392 void GetItems (
00393 _CT *items,
00394 int numitems,
00395 int firstitem = 0
00396 ) const {
00397 memcpy(items,m_data+firstitem,MIN(m_numitems-firstitem, numitems)*sizeof(_CT));
00398 }
00399
00402 const _CT& GetLast (
00403 ) const { return (m_data[m_numitems-1]); }
00404
00406 int GetMaxItems (
00407 ) const {
00408 return (m_items.GetNumReserved() * sizeof(double) / sizeof(_CT));
00409 }
00410
00412 int GetNumItems (
00413 ) const { return (m_numitems); }
00414
00416 UINT32 GetRefCount (
00417 ) const { return (m_RefCount); }
00418
00420 int GetSizeInBytes (
00421 ) const { return (m_numitems*sizeof(_CT)); }
00422
00424 bool IsEmpty (
00425 ) const { return (m_numitems == 0); }
00426
00428 void Release (
00429 ) { if (--m_RefCount == 0) delete this; }
00430
00433 void RemoveItem (
00434 INT32 item
00435 ) {
00436 if (item < m_numitems && item >= 0) {
00437 --m_numitems;
00438 if (item < m_numitems) { memmove(&m_data[item], &m_data[item+1], (m_numitems - item) * sizeof(_CT)); }
00439 }
00440 }
00441
00443 ERRVALUE Reserve (
00444 int newmaxitems,
00445 bool clear = false
00446 ) {
00447 if (clear) m_numitems = 0;
00448 if (newmaxitems > GetMaxItems()) {
00449 ERRVALUE err;
00450 if ((err = m_items.Reserve((newmaxitems * sizeof(_CT) + sizeof(double) - 1) / sizeof(double), true)) < 0) return (err);
00451 m_data = reinterpret_cast<_CT*>(m_items.GetPointer());
00452 }
00453 return (0);
00454 }
00455
00457 void ReserveExc (
00458 int newmaxitems,
00459 bool clear = false
00460 ) {
00461 if (clear) m_numitems = 0;
00462 if (newmaxitems > GetMaxItems()) {
00463 m_items.ReserveExc((newmaxitems * sizeof(_CT) + sizeof(double) - 1) / sizeof(double), true);
00464 m_data = reinterpret_cast<_CT*>(m_items.GetPointer());
00465 }
00466 }
00467
00471 ERRVALUE Resize (
00472 int numitems,
00473 bool keepold = true,
00474 bool clear = false
00475 ) {
00476 int err;
00477 if ((err = Reserve(numitems,!keepold)) < 0) return (err);
00478 if (clear && numitems > m_numitems) memset(m_data+m_numitems,0,(numitems-m_numitems)*sizeof(_CT));
00479 m_numitems = numitems;
00480 return (0);
00481 }
00482
00486 void ResizeExc (
00487 int numitems,
00488 bool keepold = true,
00489 bool clear = false
00490 ) {
00491 ReserveExc(numitems,!keepold);
00492 if (clear && numitems > m_numitems) memset(m_data+m_numitems,0,(numitems-m_numitems)*sizeof(_CT));
00493 m_numitems = numitems;
00494 }
00495
00497 void Reverse (
00498 ) {
00499 for (int i = 0; (i < m_numitems/2); ++i) {
00500 _CT temp(m_data[i]);
00501 m_data[i] = m_data[m_numitems-i-1];
00502 m_data[m_numitems-i-1] = temp;
00503 }
00504 }
00505
00508 ERRVALUE SetItems (
00509 int firstitem,
00510 const _CT *items,
00511 int numitems
00512 ) {
00513 ERRVALUE err;
00514 if ((err = Reserve(firstitem+numitems)) < 0) return (err);
00515 memcpy(m_data+firstitem,items,numitems*sizeof(_CT));
00516 if (m_numitems < firstitem + numitems) m_numitems = firstitem + numitems;
00517 return (0);
00518 }
00519
00523 void Sort (
00524 int (*CompFunc)(_CT*, _CT*, void*),
00525 void *data = 0
00526 ) {
00527 heapsort(m_data, m_numitems, sizeof(_CT), reinterpret_cast<int (*)(void*, void*, void*)>(CompFunc), data);
00528 }
00529
00531 void Swap (
00532 DOUBLE_ARRAY<_CT>& rhs
00533 ) {
00534 m_items.Swap(rhs.m_items);
00535 _CT *t_data = m_data;
00536 m_data = rhs.m_data;
00537 rhs.m_data = t_data;
00538 int t_numitems = m_numitems;
00539 m_numitems = rhs.m_numitems;
00540 rhs.m_numitems = t_numitems;
00541 }
00542
00544 void SwapBytes (
00545 ) { for (int i = 0;(i < m_numitems);++i) ::SwapBytes(m_data[i]); }
00546
00548 void TransferOwnerFrom (
00549 DOUBLE_ARRAY<_CT>& rhs
00550 ) {
00551 MIDOUBLEARRAY temp;
00552 int numitems = rhs.GetNumItems();
00553 rhs.Detach(temp);
00554 Attach(temp, numitems);
00555 return;
00556 }
00557
00559 template <class _T2> void TransferOwnerFromExt (
00560 DOUBLE_ARRAY<_T2>& rhs
00561 ) {
00562 MIDOUBLEARRAY temp;
00563 UINT32 numbytes = rhs.GetNumItems() * sizeof(_T2);
00564 rhs.Detach(temp);
00565 int numitems = static_cast<int>(numbytes / sizeof(_CT));
00566 Attach(temp, numitems);
00567 }
00568
00569 private:
00570 #ifndef GENERATING_DOXYGEN_OUTPUT
00571
00572 MIDOUBLEARRAY m_items;
00573 _CT* m_data;
00574 int m_numitems;
00575 UINT32 m_RefCount;
00576 #endif // GENERATING_DOXYGEN_OUTPUT
00577 };
00578
00579 #endif // INC_MI32_DOUBLEAR_H