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

Generated on Wed May 31 15:27:07 2006 for TNTsdk by  doxygen 1.3.8-20040913