home *** CD-ROM | disk | FTP | other *** search
/ PC Media 7 / PC MEDIA CD07.iso / share / prog / cm / cmarray.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-06  |  6.9 KB  |  294 lines

  1. // CmArray.cpp
  2. // -----------------------------------------------------------------
  3. // Compendium - C++ Container Class Library
  4. // Copyright (C) 1992-1994, Glenn M. Poorman, All rights reserved
  5. // -----------------------------------------------------------------
  6. // Array implementation.
  7. // -----------------------------------------------------------------
  8.  
  9. #include <stdlib.h>
  10. #include <cm/include/cmarray.h>
  11.  
  12.  
  13. // "CmArray" is the default array constructor.
  14. //
  15. CmArray::CmArray(unsigned sz, unsigned dt)
  16. {
  17.   _delta   = dt;
  18.   _total   = 0;
  19.   _entries = (sz > 0) ? new CmObject*[sz] : NULL;
  20.   _size    = (_entries != NULL) ? sz : 0;
  21. }
  22.  
  23.  
  24. // "CmArray" is the array copy constructor.
  25. //
  26. CmArray::CmArray(const CmArray& A)
  27. {
  28.   _delta   = A._delta;
  29.   _total   = 0;
  30.   _entries = (A._size > 0) ? new CmObject*[A._size] : NULL;
  31.   _size    = (_entries != NULL) ? A._size : 0;
  32.   copy(A);
  33. }
  34.  
  35.  
  36. // "~CmArray" is the array destructor.
  37. //
  38. CmArray::~CmArray()
  39. {
  40.   removeAll();
  41.   delete[] _entries;
  42. }
  43.  
  44.  
  45. // "=" assignement operator copies the contents of the specified
  46. // array into this array.
  47. //
  48. CmArray& CmArray::operator=(const CmArray& A)
  49. {
  50.   if (&A != this)
  51.   {
  52.     removeAll();
  53.     delete[] _entries;
  54.     _delta   = A._delta;
  55.     _total   = 0;
  56.     _entries = (A._size > 0) ? new CmObject*[A._size] : NULL;
  57.     _size    = (_entries != NULL) ? A._size : 0;
  58.     copy(A);
  59.   }
  60.   return *this;
  61. }
  62.  
  63.  
  64. // "add" appends the specified object to the array.
  65. //
  66. Bool CmArray::add(CmObject* pObj)
  67. {
  68.   if (!pObj) return FALSE;
  69.   if (_total >= _size)
  70.     if (_delta == 0 || !resize(_size+_delta))
  71.       return FALSE;
  72.   _entries[_total++] = pObj;
  73.   return TRUE;
  74. }
  75.  
  76.  
  77. // "insertAt" inserts the specified object at the given index moving
  78. // the other objects to make room.
  79. //
  80. Bool CmArray::insertAt(int idx, CmObject* pObj)
  81. {
  82.   if (!pObj || idx < 0 || idx >= _total) return FALSE;
  83.   if (_total >= _size)
  84.     if (_delta == 0 || !resize(_size+_delta))
  85.       return FALSE;
  86.  
  87.   size_t sz = (_total - idx) * sizeof(CmObject*);
  88.   memmove(&(_entries[idx+1]), &(_entries[idx]), sz);
  89.   _entries[idx] = pObj;
  90.   _total++;
  91.   return TRUE;
  92. }
  93.  
  94.  
  95. // "replaceAt" replaces the object at the specified index with the
  96. // specified object.
  97. //
  98. Bool CmArray::replaceAt(int idx, CmObject* pObj)
  99. {
  100.   if (!pObj || idx < 0 || idx >= _total) return FALSE;
  101.   if (ownsObjects()) delete _entries[idx];
  102.   _entries[idx] = pObj;
  103.   return TRUE;
  104. }
  105.  
  106.  
  107. // "remove" removes the first occurrence of an object that isEqual to
  108. // the specified object from the array.
  109. //
  110. Bool CmArray::remove(CmObject* pObj)
  111. {
  112.   if (_total == 0 || !pObj) return FALSE;
  113.   int  ii    = 0;
  114.   Bool found = FALSE;
  115.   while (ii < _total && !found)
  116.     if (_entries[ii++]->isEqual(pObj)) found = TRUE;
  117.   return (found) ? removeAt(ii-1) : FALSE;
  118. }
  119.  
  120.  
  121. // "removeAt" removes the object at the specified index.
  122. //
  123. Bool CmArray::removeAt(int idx)
  124. {
  125.   if (idx < 0 || idx >= _total) return FALSE;
  126.  
  127.   if (ownsObjects()) delete _entries[idx];
  128.   size_t sz = (_total - idx + 1) * sizeof(CmObject*);
  129.   memmove(&(_entries[idx]), &(_entries[idx+1]), sz);
  130.   _entries[_total-1] = NULL;
  131.   _total--;
  132.   return TRUE;
  133. }
  134.  
  135.  
  136. // "index" returns the index of the first occurrence of an object
  137. // that isEqual to the specified object.
  138. //
  139. int CmArray::index(CmObject* pObj) const
  140. {
  141.   if (_total == 0 || !pObj) return FALSE;
  142.   int  ii  = 0;
  143.   int  idx = -1;
  144.   while (ii < _total && idx == -1)
  145.     if (_entries[ii++]->isEqual(pObj)) idx = ii-1;
  146.   return idx;
  147. }
  148.  
  149.  
  150. // "lookup" returns the first occurrence of an object that isEqual
  151. // to the specified object.
  152. //
  153. CmObject* CmArray::lookup(CmObject* pObj) const
  154. {
  155.   int idx = index(pObj);
  156.   return (idx > -1) ? _entries[idx] : NULL;
  157. }
  158.  
  159.  
  160. // "occurrences" returns the number of objects in the array
  161. // isEqual to the specified object.
  162. //
  163. unsigned CmArray::occurrences(CmObject* pObj) const
  164. {
  165.   if (_total == 0 || !pObj) return 0;
  166.  
  167.   int      ii  = 0;
  168.   unsigned num = 0;
  169.   while (ii < _total)
  170.     if (_entries[ii++]->isEqual(pObj)) num++;
  171.   return num;
  172. }
  173.  
  174.  
  175. // "removeAll" removes all objects from the array.
  176. //
  177. void CmArray::removeAll()
  178. {
  179.   for (int ii = 0; ii < _total; ii++)
  180.   {
  181.     if (ownsObjects()) delete _entries[ii];
  182.     _entries[ii] = NULL;
  183.   }
  184.   _total = 0;
  185. }
  186.  
  187.  
  188. // "resize" resizes the storage allocated for this array.
  189. //
  190. Bool CmArray::resize(unsigned newSize)
  191. {
  192.   if (newSize == 0)
  193.   {
  194.     removeAll();
  195.     delete[] _entries;
  196.     _entries = NULL;
  197.     _size    = 0;
  198.     return TRUE;
  199.   }
  200.  
  201.   CmObject **newEntries = new CmObject*[newSize];
  202.   if (!newEntries) return FALSE;
  203.  
  204.   if (newSize < _total)
  205.   {
  206.     for (int ii = newSize; ii < _total; ii++)
  207.       if (ownsObjects()) delete _entries[ii];
  208.     _total = newSize;
  209.   }
  210.  
  211.   memmove(newEntries, _entries, _total * sizeof(CmObject*));
  212.  
  213.   delete[] _entries;
  214.   _entries = newEntries;
  215.   _size    = newSize;
  216.   return TRUE;
  217. }
  218.  
  219.  
  220. // "isEmpty" checks if the array is empty or not.
  221. //
  222. Bool CmArray::isEmpty() const
  223. {
  224.   return (_total == 0);
  225. }
  226.  
  227.  
  228. // "quickSort" uses the standard library to perform a quick sort
  229. // on this array.
  230. //
  231. void CmArray::quickSort()
  232. {
  233.   qsort(_entries, _total, sizeof(CmObject*), &CmArray::cmpObjs);
  234. }
  235.  
  236.  
  237. // "newIterator" creates and returns an array iterator.
  238. //
  239. CmIterator* CmArray::newIterator() const
  240. {
  241.   return new CmArrayIterator(*this);
  242. }
  243.  
  244.  
  245. // "write" writes the array objects to the specified reserve file.
  246. //
  247. Bool CmArray::write(CmReserveFile& file) const
  248. {
  249.   if (!writeBase(file))    return FALSE;          // Write base container.
  250.   if (!file.write(_delta)) return FALSE;          // Write delta value.
  251.   if (!file.write(_total)) return FALSE;          // Write number of objects.
  252.  
  253.   Bool success = TRUE;
  254.   int  ii      = 0;
  255.   while (ii < _total && success)                  // For each object,
  256.     success = _entries[ii++]->writeObject(file);  // Write the object.
  257.   return success;
  258. }
  259.  
  260.  
  261. // "read" reads the array objects from the specified reserve file.
  262. //
  263. Bool CmArray::read(CmReserveFile& file)
  264. {
  265.   unsigned size = readBase(file);                 // Read base container.
  266.  
  267.   unsigned total;
  268.   if (!file.read(_delta)) return FALSE;           // Read delta value.
  269.   if (!file.read(total))  return FALSE;           // Read number of objects.
  270.   if (!resize(size))      return FALSE;           // Resize the array.
  271.  
  272.   removeAll();
  273.  
  274.   Bool success = TRUE;
  275.   int  ii      = 0;
  276.   while (ii < total && success)                   // For each object,
  277.   {
  278.     CmObject *pObj = CmObject::readObject(file);  // Read object.
  279.     if (pObj) success = add(pObj); ii++;          // Add to array.
  280.   }
  281.   return success;
  282. }
  283.  
  284.  
  285. // "cmpObjs" is called by the standard library qsort function for
  286. // sorting the array into ascending order.
  287. //
  288. int CmArray::cmpObjs(const void* obj1, const void* obj2)
  289. {
  290.   CmObject *pObj1 = *((CmObject**)obj1);
  291.   CmObject *pObj2 = *((CmObject**)obj2);
  292.   return pObj1->compare(pObj2);
  293. }
  294.