simplear.h

Go to the documentation of this file.
00001 /**
00002  * \file simplear.h <mi32/simplear.h>
00003  * \brief Definitions for SIMPLE_ARRAY template
00004  *
00005  * \if NODOC
00006  * $Id: simplear.h_v 1.44 2004/04/16 21:50:03 scowan Exp $
00007  *
00008  * $Log: simplear.h_v $
00009  * Revision 1.44  2004/04/16 21:50:03  scowan
00010  * Added locate method.
00011  *
00012  * Revision 1.43  2004/04/01 21:33:44  mju
00013  * Add GetLast and RemoveLast methods.
00014  *
00015  * Revision 1.42  2003/09/22 19:09:40  dwilliss
00016  * Version of array index operator that takes long for SUN64 to avoid gcc
00017  * error
00018  *
00019  * Revision 1.41  2003/09/15 13:49:56  fileserver!dwilliss
00020  * Doxygen
00021  *
00022  * Revision 1.40  2003/07/28 13:41:45  mju
00023  * Remove deprecated methods.
00024  *
00025  * Revision 1.39  2003/07/25 20:58:42  mju
00026  * Add Assign() method, deprecate old SetItems().
00027  * Add SetItems variant which does not shrink array.
00028  *
00029  * Revision 1.38  2003/06/24 21:47:30  scowan
00030  * Compiler optimization error also in remove fast method.
00031  *
00032  * Revision 1.37  2003/06/18 14:27:26  mju
00033  * Fix compiler optimization bug in RemoveItem by decrement numitems before memmove.
00034  *
00035  * Revision 1.36  2003/06/17 21:49:27  mju
00036  * *** empty log message ***
00037  *
00038  * Revision 1.35  2003/04/09 19:12:52  dwilliss
00039  * Don't use _T in templates.  Mac's ctype defines a global _T
00040  *
00041  * Revision 1.34  2002/10/03 16:49:19  mju
00042  * Remove allocincrement stuff and deprecate method to set.
00043  *
00044  * Revision 1.33  2002/09/30 17:32:57  mju
00045  * Remove redundant swapitems methods as is equivalent to Reverse().
00046  *
00047  * Revision 1.32  2002/09/12 14:54:24  scowan
00048  * Added has item method.
00049  *
00050  * Revision 1.31  2002/07/05 21:53:53  scowan
00051  * resize memset in case _CT is an object with deprecated memset stuff.
00052  *
00053  * Revision 1.30  2002/06/20 15:51:51  scowan
00054  * Prevent ABR.
00055  *
00056  * Revision 1.29  2002/04/02 18:24:29  mju
00057  * Add IsEmpty() method.
00058  * Clarify what will be cleared when 'clear' set to true in Resize().
00059  *
00060  * Revision 1.28  2002/03/18 15:19:21  dwilliss
00061  * Need to include stdansic.h if we want to be sure memcpy has a prototype
00062  *
00063  * Revision 1.27  2001/12/18 17:40:31  scowan
00064  * Set allocincrement in constructors.
00065  *
00066  * Revision 1.26  2001/10/30 16:52:50  dwilliss
00067  * Documented what the CompFunc for Sort() is expected to return
00068  *
00069  * Revision 1.25  2001/09/07 17:15:22  scowan
00070  * Change sort compare function to return int.
00071  *
00072  * Revision 1.24  2001/05/24 20:50:34  scowan
00073  * Adjuect some method names.
00074  *
00075  * Revision 1.23  2001/05/24 18:00:09  scowan
00076  * Added multiple helper methods.
00077  *
00078  * Revision 1.22  2001/02/06 17:35:26  mju
00079  * Add ReserveExc and AppendExc methods.
00080  *
00081  * Revision 1.21  2001/01/30 15:01:10  mju
00082  * Add Get/SetItem methods as array/cast operators confused if array type is pointer.
00083  *
00084  * Revision 1.20  2000/12/04 16:31:25  mju
00085  * Fix genitor 'end ignore' tag.
00086  *
00087  * Revision 1.19  2000/10/13 16:45:07  dwilliss
00088  * Added array operater overloads taking long on Mac only to avoid stupid
00089  * ambiguous function overload error
00090  *
00091  * Revision 1.18  2000/08/23 15:53:16  scowan
00092  * Do an bouns check on Clear Items().
00093  *
00094  * Revision 1.17  2000/08/18 14:41:03  scowan
00095  * Removed additional array operators because the other platforms went Huh!?!?
00096  * Stupid VC6.0.
00097  *
00098  * Revision 1.16  2000/08/17 16:01:00  scowan
00099  * Added unsigned int versions of array operator methods, was causeing a
00100  * strange error to occur if an unsigned int was used to access a simple array
00101  * entry.
00102  *
00103  * Revision 1.15  2000/08/09 13:46:54  mju
00104  * Add Append() methods using C-style array and SIMPLE_ARRAY.
00105  *
00106  * Revision 1.14  2000/08/02 21:43:38  mju
00107  * Change Resize() to only clear new entries if keepold 'true'.
00108  *
00109  * Revision 1.13  2000/08/01 14:04:54  dwilliss
00110  * Added a Copy() method.
00111  * Fixed error in methods taking/returning SIMPLE_ARRAY.  Needs to specify
00112  *   the template type.
00113  *
00114  * Revision 1.12  2000/07/27 17:18:14  mju
00115  * Retire SetNumItems().
00116  *
00117  * Revision 1.11  2000/07/27 15:40:36  dwilliss
00118  * Wrote Attach()/Detach() methods
00119  *
00120  * Revision 1.10  2000/07/26 16:08:36  dwilliss
00121  * Fixed compile error in Free()
00122  *
00123  * Revision 1.9  2000/07/21 22:25:36  scowan
00124  * Added Free() method
00125  *
00126  * Revision 1.8  2000/07/18 20:56:57  mju
00127  * Add Resize() and deprecate SetNumItems().
00128  *
00129  * Revision 1.7  2000/06/22 14:52:55  mju
00130  * Fix ClearItems to not clear past ending item.
00131  *
00132  * Revision 1.5  2000/06/21 16:39:24  scowan
00133  * Set items must return a value error fix.
00134  *
00135  * Revision 1.3  2000/06/21 15:23:31  scowan
00136  * Added swap bytes method.
00137  *
00138  * Revision 1.2  2000/05/11 20:33:22  mju
00139  * Change GetSizeInBytes to return required size, not allocated size.
00140  * Add Swap() method.
00141  *
00142  * Revision 1.1  2000/05/10 13:26:15  mju
00143  * Initial revision
00144  *
00145  * \endif
00146 **/
00147 
00148 #ifndef  INC_MI32_SIMPLEAR_H
00149 #define  INC_MI32_SIMPLEAR_H
00150 
00151 #ifndef  INC_MI32_MIODEFNS_H
00152 #include <mi32/miodefns.h>    //! For MmAlloc/Realloc/Free defns
00153 #endif
00154 
00155 #ifndef  INC_MI32_STDANSIC_H
00156 #include <mi32/stdansic.h>    //! memcpy()
00157 #endif
00158 
00159 #ifndef  INC_MI32_MEMBUF_H
00160 #include <mi32/membuf.h>      //! For SwapBytes() defn
00161 #endif
00162 
00163 //! Simple array template.
00164 //!
00165 //! This template is designed to contain an array of items which can be allocated
00166 //! using MmAlloc/MmRealloc.  The primary purpose of this template is to replace
00167 //! allocated arrays where direct access to both array elements and the ability
00168 //! to access a pointer to the first element (as for a C array) is required.
00169 //! Do not use this template with classes which require constructors or have
00170 //! virtual methods or which do not have compiler-generated assignment operators.
00171 //!
00172 //! For maximum efficiency, only minimal validation of access to array elements is performed.
00173 //! No initialization of array items is performed by the template.
00174 //!
00175 //! For doubles and objects based on doubles, use DOUBLE_ARRAY<> in mi32/doublear.h
00176 //!
00177 //! Instances of this class are passed to DLLs, so do not add or remove members.
00178 
00179 template <class _CT> class SIMPLE_ARRAY {
00180    public:
00181 
00182       //! Default constructor, creates empty array.
00183       SIMPLE_ARRAY (
00184          ):
00185          m_items(0),
00186          m_numitems(0),
00187          m_numalloc(0),
00188          m_spare(0)
00189          { }
00190 
00191       //! Copy constructor.
00192       SIMPLE_ARRAY (
00193          const SIMPLE_ARRAY<_CT>& rhs
00194          ) {
00195          MmAllocExc((void**)&m_items,rhs.m_numalloc*sizeof(_CT));
00196          m_numalloc = rhs.m_numalloc;
00197          memcpy(m_items,rhs.m_items,rhs.m_numitems*sizeof(_CT));
00198          m_numitems = rhs.m_numitems;
00199          m_spare = rhs.m_spare;
00200          }
00201 
00202       //! Destructor.
00203       ~SIMPLE_ARRAY (
00204          ) {
00205          if (m_items != 0) free(m_items);
00206          }
00207 
00208       //! Assignment.
00209       SIMPLE_ARRAY<_CT>& operator= (
00210          const SIMPLE_ARRAY<_CT>& rhs
00211          ) {
00212          if (this != &rhs) {
00213             if (m_numalloc < rhs.m_numalloc) {
00214                //! Free the old array instead of using realloc to avoid expensive copy.
00215                MmFree(m_items);
00216                MmAllocExc((void**)&m_items,rhs.m_numalloc*sizeof(_CT));
00217                m_numalloc = rhs.m_numalloc;
00218                }
00219             memcpy(m_items,rhs.m_items,rhs.m_numitems*sizeof(_CT));
00220             m_numitems = rhs.m_numitems;
00221             }
00222          return (*this);
00223          }
00224 
00225       //! Equality operator.
00226       bool operator== (
00227          const SIMPLE_ARRAY<_CT>& rhs
00228          ) const {
00229          if (m_numitems != rhs.m_numitems) return (false);
00230          if (m_numitems == 0) return (true);
00231          return (memcmp(m_items,rhs.m_items,m_numitems*sizeof(_CT)) == 0);
00232          }
00233 
00234       //! Inequality operator.
00235       bool operator!= (
00236          const SIMPLE_ARRAY<_CT>& rhs
00237          ) const {
00238          return (!operator==(rhs));
00239          }
00240 
00241       //! Cast to const array of template type.
00242       operator const _CT*(
00243          ) const {
00244          return (m_items);
00245          }
00246 
00247       //! Cast to array of template type.
00248       operator _CT*(
00249          ) {
00250          return (m_items);
00251          }
00252 
00253       //! Read (const) access to array element.
00254       //!
00255       //! @note Does not verify that index is within valid range.
00256       const _CT& operator[] (
00257          int index
00258          ) const {
00259          return (m_items[index]);
00260          }
00261 
00262       //! Write (non-const) access to array element.
00263       //!
00264       //! @note Does not verify that index is within valid range.
00265       _CT& operator[] (
00266          int index
00267          ) {
00268          return (m_items[index]);
00269          }
00270 
00271       #ifndef GENERATING_DOXYGEN_OUTPUT
00272    #if defined(MAC_NATIVE) || defined(SUN64)
00273       // Fixes ambiguity error on Macintosh.
00274       
00275       // Read (const) access to array element.
00276       //
00277       // @note Does not verify that index is within valid range.
00278       const _CT& operator[] (
00279          long index
00280          ) const {
00281          return (m_items[index]);
00282          }
00283 
00284       // Write (non-const) access to array element.
00285       //
00286       // @note Does not verify that index is within valid range.
00287       _CT& operator[] (
00288          long index
00289          ) {
00290          return (m_items[index]);
00291          }
00292    #endif
00293       #endif //!< GENERATING_DOXYGEN_OUTPUT
00294 
00295       //! Append item to end of array, extending if necessary.
00296       ERRVALUE Append (
00297          const _CT& item
00298          ) {
00299          if (m_numitems >= m_numalloc) {
00300             int err;
00301             if ((err = Reserve(MAX(16,2*m_numitems))) < 0) return (err);
00302             }
00303          m_items[m_numitems++] = item;
00304          return (0);
00305          }
00306 
00307       //! Append items from C array, reserving space if needed.
00308       ERRVALUE Append (
00309          const _CT *items,                //!< Items to append
00310          int numitems                     //!< Number of items to append
00311          ) {
00312          int err;
00313          if ((err = Reserve(m_numitems+numitems)) < 0) return (err);
00314          memcpy(m_items+m_numitems,items,numitems*sizeof(_CT));
00315          m_numitems += numitems;
00316          return (0);
00317          }
00318 
00319       //! Append items from SIMPLE_ARRAY reserving space if needed.
00320       ERRVALUE Append (
00321          const SIMPLE_ARRAY<_CT>& rhs
00322          ) {
00323          int err;
00324          if ((err = Reserve(m_numitems+rhs.m_numitems)) < 0) return (err);
00325          memcpy(m_items+m_numitems,rhs.m_items,rhs.m_numitems*sizeof(_CT));
00326          m_numitems += rhs.m_numitems;
00327          return (0);
00328          }
00329 
00330       //! Append item to end of array, extending if necessary.
00331       //! Throws exception if out of memory.
00332       void AppendExc (
00333          const _CT& item
00334          ) {
00335          if (m_numitems >= m_numalloc) {
00336             ReserveExc(MAX(16,2*m_numitems));
00337             }
00338          m_items[m_numitems++] = item;
00339          return;
00340          }
00341 
00342       //! Append items from C array, reserving space if needed.
00343       //! Throws exception if out of memory.
00344       void AppendExc (
00345          const _CT *items,                //!< Items to append
00346          int numitems                     //!< Number of items to append
00347          ) {
00348          ReserveExc(m_numitems+numitems);
00349          memcpy(m_items+m_numitems,items,numitems*sizeof(_CT));
00350          m_numitems += numitems;
00351          return;
00352          }
00353 
00354       //! Append items from SIMPLE_ARRAY reserving space if needed.
00355       //! Throws exception if out of memory.
00356       void AppendExc (
00357          const SIMPLE_ARRAY<_CT>& rhs
00358          ) {
00359          ReserveExc(m_numitems+rhs.m_numitems);
00360          memcpy(m_items+m_numitems,rhs.m_items,rhs.m_numitems*sizeof(_CT));
00361          m_numitems += rhs.m_numitems;
00362          return;
00363          }
00364 
00365       //! Append item to end of array if unique, extending if necessary.
00366       ERRVALUE AppendUnique (
00367          const _CT& item
00368          ) {
00369          INT32 j;
00370          for (j = 0;(j < m_numitems);++j) {
00371             if (m_items[j] == item) break;
00372             }
00373          return ((j == m_numitems) ? Append(item) : 0);
00374          }
00375 
00376       //! Append item to end of array if unique, extending if necessary.
00377       //! Throws exception if out of memory.
00378       void AppendUniqueExc (
00379          const _CT& item
00380          ) {
00381          INT32 j;
00382          for (j = 0;(j < m_numitems);++j) {
00383             if (m_items[j] == item) break;
00384             }
00385          if (j == m_numitems) AppendExc(item);
00386          return;
00387          }
00388 
00389       //! Assign from C array, reserving space if needed.
00390       //! Resizes the array to the specified number of items.
00391       ERRVALUE Assign (
00392          const _CT *items,                //!< Items to copy to array
00393          int numitems                     //!< Number of items to copy
00394          ) {
00395          int err;
00396          if ((err = Reserve(numitems)) < 0) return (err);
00397          memcpy(m_items,items,numitems*sizeof(_CT));
00398          m_numitems = numitems;
00399          return (0);
00400          }
00401 
00402       //! Attach a buffer to the SIMPLE_ARRAY.
00403       //! After passing a buffer to Attach(), the SIMPLE_ARRAY "<b>owns</b>" the
00404       //! buffer and will free it in its destructor.  
00405       //! @param items Reference to a pointer to the templated data type.
00406       //! The reason it's a reference is that after recording the pointer,
00407       //! Attach() will set <i>your</i> pointer to 0.  This will prevent you
00408       //! from accidently freeing a pointer you no longer own.  If you want
00409       //! it back, call the Detach() method
00410       void Attach (
00411          _CT *& items,                 
00412          int numitems               //!< Number of items in array
00413          ) {
00414          Free();
00415          m_items = items;
00416          m_numitems = m_numalloc = numitems;
00417          items = 0;
00418          return;
00419          }
00420 
00421 
00422       //! Clear the array, does not free resources.
00423       void Clear (
00424          ) {
00425          m_numitems = 0;
00426          return;
00427          }
00428 
00429       //! Clear items in the array
00430       void ClearItems (
00431          int start = 0,
00432          int end = -1                  //!< Default -1, use number of items
00433          ) {
00434          if (end < start) end = m_numitems - 1;
00435          if (end >= start) {     //! Start might be larger than end
00436             memset(m_items + start, 0, (end - start + 1) * sizeof(_CT));
00437             }
00438          return;
00439          }
00440 
00441 
00442       //! Copy the contents of another SIMPLE_ARRAY.
00443       //! Same as assignment, but returns an error code instead of throwing an exception.
00444       ERRVALUE Copy (
00445          const SIMPLE_ARRAY<_CT>& rhs
00446          ) {
00447          if (this != &rhs) {
00448             if (m_numalloc < rhs.m_numalloc) {
00449                //! Free the old array instead of using realloc to avoid expensive copy.
00450                MmFree(m_items);
00451                ERRVALUE err = MmAlloc((void**)&m_items,rhs.m_numalloc*sizeof(_CT));
00452                if (err < 0) return (err);
00453                m_numalloc = rhs.m_numalloc;
00454                }
00455             memcpy(m_items,rhs.m_items,rhs.m_numitems*sizeof(_CT));
00456             m_numitems = rhs.m_numitems;
00457             }
00458          return (0);
00459          }
00460 
00461       //! Detach the buffer from the SIMPLE_ARRAY.
00462       //!
00463       //! This turns ownership of the buffer over to the caller, who is then
00464       //! responsibile for seeing that it gets disposed of.
00465       //! After calling Detach(), the SIMPLE_ARRAY will behave as if it had
00466       //! just been constructed.  In other words, it will be a NULL pointer
00467       //! pointing to 0 items.
00468       //! This means that if you want to know how many items are in the
00469       //! array returned, you'd better find out @{before} you call Detach()!
00470       _CT* Detach (
00471          ) {
00472          _CT* ret = m_items;
00473          m_numalloc = m_numitems = 0;
00474          m_items = 0;
00475          return (ret);
00476          }
00477 
00478       //! Free the array.
00479       void Free (
00480          ) {
00481          m_numalloc = m_numitems = 0;
00482          MmFree(m_items);
00483          return;
00484          }
00485 
00486       //! Get array item, does not verify index range.
00487       const _CT& GetItem (
00488          int index
00489          ) const { return (m_items[index]); }
00490 
00491       //! Get last item in array.
00492       //! Does not verify that array is non-empty.
00493       const _CT& GetLast (
00494          ) const { return (m_items[m_numitems-1]); }
00495 
00496       //! Get maximum number of items in array.
00497       int GetMaxItems (
00498          ) const { return (m_numalloc); }
00499 
00500       //! Get number of items in array.
00501       int GetNumItems (
00502          ) const { return (m_numitems); }
00503 
00504       //! Get size of array required to hold current number of items in bytes.
00505       int GetSizeInBytes (
00506          ) const { return (m_numitems*sizeof(_CT)); }
00507 
00508       //! Determine if an item exists in the array.
00509       //! Item must have a valid operator==()
00510       //! @return 'True' if item found
00511       bool HasItem (
00512          const _CT& item
00513          ) const {
00514          for (INT32 i = 0;(i < m_numitems);++i) {
00515             if (m_items[i] == item) return (true);
00516             }
00517          return (false);
00518          }
00519 
00520       //! Insert multiple items into the array
00521       void InsertItems (
00522          int start,
00523          int num = 1
00524          ) {
00525          ReserveExc(m_numitems+num);
00526          memmove(&m_items[start + num], &m_items[start], (m_numitems - start) * sizeof(_CT));
00527          m_numitems += num;
00528          return;
00529          }
00530 
00531       //! Determine if array is empty.
00532       bool IsEmpty (
00533          ) const { return (GetNumItems() == 0); }
00534 
00535       //! Binary search for an entry or the place where the entry should be
00536       //! _Pr is a functor that returns -1 if 1st item < 2nd, 1 if 1st > 2nd, 0 if 1st == 2nd
00537       //! 'item' is the first parameter passed to the _Pr functor
00538       //! @return Position that is equal or immediately less than 'item', or GetNumItems() if item > all list items
00539       template<class _Pr1>
00540       INT32 Locate (
00541          const _CT& item,
00542          _Pr1 _Pr
00543          ) const {
00544          if (m_numitems == 0) return (0);
00545          INT32 l = 0, r = m_numitems-1, q;
00546          do {
00547             q = (l+r)/2;
00548             int test = _Pr(item, m_items[q]);
00549             if (test == 0) return (q);
00550             if (test < 0) {
00551                r = q - 1;
00552                q = r;
00553                }
00554             else {
00555                l = q + 1;
00556                q = l;
00557                }
00558             } while (l <= r);
00559          return (q);
00560          }
00561 
00562       //! Remove duplicate entries in the list, assume not sorted    
00563       void RemoveDuplicates (
00564          ) {
00565          for (INT32 i = 0;(i < m_numitems);++i) {
00566             for (INT32 k = i+1;(k < m_numitems);++k) {
00567                if (m_items[i] == m_items[k]) {
00568                   m_items[k] = m_items[m_numitems-1];
00569                   m_numitems --;
00570                   k --;
00571                   }
00572                }
00573             }
00574          return;
00575          }     
00576 
00577       //! Remove an item by placing the end item in its place.
00578       void RemoveFast (
00579          INT32 item
00580          ) {
00581          if (item >= 0 && item < m_numitems) {
00582             m_numitems --;
00583             m_items[item] = m_items[m_numitems];
00584             }
00585          return;
00586          }
00587 
00588       //! Remove item at specified index, maintaining order.
00589       //! Note that this is inefficient for large arrays.
00590       void RemoveItem (
00591          INT32 item
00592          ) {
00593          if (item < m_numitems && item >= 0) {
00594             --m_numitems;
00595             if (item < m_numitems) { memmove(&m_items[item], &m_items[item+1], (m_numitems - item) * sizeof(_CT)); }
00596             }
00597          return;
00598          }
00599 
00600       //! Remove last item(s) from array.
00601       void RemoveLast (
00602          INT32 count = 1                           //!< Number of items to remove
00603          ) {
00604          if (count > m_numitems)
00605             m_numitems = 0;
00606          else
00607             m_numitems -= count;
00608          return;
00609          }
00610 
00611       //! Remove items matching the item passed in.  _CT must have a operator==() defined
00612       //! Maintains item order
00613       //! @return 'True' if one or more items was removed
00614       bool RemoveMatchingItems (
00615          const _CT& item
00616          ) {
00617          INT32 i, num;
00618          for (num = i = 0;(i < m_numitems); ++i) {
00619             if (m_items[i] != item) {
00620                if (num < i) m_items[num] = m_items[i];      // Avoid expensive copy if not needed
00621                num ++;
00622                }
00623             }
00624          bool retval = (m_numitems != num);
00625          m_numitems = num;
00626          return (retval);
00627          }
00628 
00629       //! Reserve space in array for up to specified number of items.
00630       ERRVALUE Reserve (
00631          int newmaxitems,                 //!< New maximum number of items
00632          bool clear = false               //!< Clear the array by resetting number of items to 0
00633          ) {
00634          if (clear) m_numitems = 0;
00635          if (newmaxitems > m_numalloc) {
00636             int err;
00637             if (m_numitems == 0) {
00638                //! Free the old array to avoid expensive copy in reallocation
00639                MmFree(m_items);
00640                }
00641             if ((err = MmRealloc((void**)&m_items,newmaxitems*sizeof(_CT))) < 0) return (err);
00642             m_numalloc = newmaxitems;
00643             }
00644          return (0);
00645          }
00646 
00647       //! Reserve space in array for up to specified number of items.
00648       //! Throws exception if out of memory.
00649       void ReserveExc (
00650          int newmaxitems,                 //!< New maximum number of items
00651          bool clear = false               //!< Clear the array by resetting number of items to 0
00652          ) {
00653          if (clear) m_numitems = 0;
00654          if (newmaxitems > m_numalloc) {
00655             if (m_numitems == 0) {
00656                //! Free the old array to avoid expensive copy in reallocation
00657                MmFree(m_items);
00658                }
00659             MmReallocExc((void**)&m_items,newmaxitems*sizeof(_CT));
00660             m_numalloc = newmaxitems;
00661             }
00662          return;
00663          }
00664 
00665       //! Resize array to specified number of items.
00666       //! If the new size is larger than the previous size and the array is
00667       //! not cleared the new array entries will have indeterminant values.
00668       ERRVALUE Resize (
00669          int numitems,                    //!< New number of items desired
00670          bool keepold = true,             //!< Keep old array entries
00671          bool clear = false               //!< Clear new array items to zeros
00672          ) {
00673          int err;
00674          if ((err = Reserve(numitems,!keepold)) < 0) return (err);
00675          if (clear && numitems > m_numitems) memset(static_cast<void*>(m_items+m_numitems),0,(numitems-m_numitems)*sizeof(_CT));
00676          m_numitems = numitems;
00677          return (0);
00678          }
00679 
00680       //! Reverse order of items in array.
00681       void Reverse (
00682          ) {
00683          for (int i = 0; (i < m_numitems/2); ++i) {
00684             _CT temp(m_items[i]);
00685             m_items[i] = m_items[m_numitems-i-1];
00686             m_items[m_numitems-i-1] = temp;
00687             }
00688          return;
00689          }
00690 
00691       //! Set single item, does not verify index range.
00692       void SetItem (
00693          int index,                       //!< Item index, must be in range from 0 to NumItems-1
00694          const _CT& item                     //!< Item value to set
00695          ) {
00696          m_items[index] = item;
00697          }
00698 
00699       //! Set array items from C array, expanding if needed.
00700       //! Will not reduce the number of items in the array.
00701       ERRVALUE SetItems (
00702          int firstitem,                   //!< First array item to replace
00703          const _CT *items,                //!< Items to copy to array
00704          int numitems                     //!< Number of items to copy
00705          ) {
00706          int err;
00707          if ((err = Reserve(firstitem+numitems)) < 0) return (err);
00708          memcpy(m_items+firstitem,items,numitems*sizeof(_CT));
00709          if (m_numitems < firstitem + numitems) m_numitems = firstitem + numitems;
00710          return (0);
00711          }
00712 
00713       //! Sort the items in the array.
00714       //! CompFunc should return 1 if the first item < the 2nd item
00715       //! Otherwise, return 0.
00716       void Sort (
00717          int (*CompFunc)(_CT*, _CT*, void*),
00718          void *data = 0
00719          ) {
00720          //! Compare function cannot return 'bool', must be 'int'.
00721          heapsort(m_items, m_numitems, sizeof(_CT), reinterpret_cast<int (*)(void*, void*, void*)>(CompFunc), data);
00722          }
00723          
00724       //! Swap (exchange) two SIMPLE_ARRAYs.
00725       //! This exchanges the internal buffers so minimal copying is performed for efficiency.
00726       void Swap (
00727          SIMPLE_ARRAY<_CT>& rhs
00728          ) {
00729          _CT *t_items = m_items;
00730          m_items = rhs.m_items;
00731          rhs.m_items = t_items;
00732          int t_numitems = m_numitems;
00733          m_numitems = rhs.m_numitems;
00734          rhs.m_numitems = t_numitems;
00735          int t_numalloc = m_numalloc;
00736          m_numalloc = rhs.m_numalloc;
00737          rhs.m_numalloc = t_numalloc;
00738          }
00739 
00740       //! Swap bytes in a SIMPLE_ARRAY, assume that there is an overload to swap a _CT
00741       void SwapBytes (
00742          ) {
00743          for (int i = 0;(i < m_numitems);++i) ::SwapBytes(m_items[i]);
00744          }
00745 
00746    private:
00747       #ifndef GENERATING_DOXYGEN_OUTPUT
00748       _CT *m_items;                       //!< The actual array
00749       int m_numitems;                     //!< Number of valid items
00750       int m_numalloc;                     //!< Number of items allocated
00751       int m_spare;
00752       #endif // GENERATING_DOXYGEN_OUTPUT
00753 
00754    };
00755 
00756 #endif   //!< INC_MI32_SIMPLEAR_H

Generated on Tue Dec 14 13:18:36 2004 for TNTsdk by  doxygen 1.3.8-20040913