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

  1. // CmCont.cpp
  2. // -----------------------------------------------------------------
  3. // Compendium - C++ Container Class Library
  4. // Copyright (C) 1992-1994, Glenn M. Poorman, All rights reserved
  5. // -----------------------------------------------------------------
  6. // Abstract container implementation.
  7. // -----------------------------------------------------------------
  8.  
  9. #include <cm/include/cmcont.h>
  10. #include <cm/include/cmlist.h>
  11.  
  12.  
  13. // "[]" indexing operator allows objects to be retrieved by index.
  14. // This operator cannot be used as an lvalue.
  15. //
  16. CmObject* CmContainer::operator[](int idx) const
  17. {
  18.   if (idx < 0 || idx >= size()) return NULL;
  19.   CmIterator *iterator = newIterator();
  20.   CmObject   *out      = NULL;
  21.   int         ii       = 0;
  22.   while (!iterator->done() && ii <= idx)
  23.   {
  24.     if (ii++ == idx) out = iterator->current();
  25.     iterator->next();
  26.   }
  27.   delete iterator;
  28.   return out;
  29. }
  30.  
  31.  
  32. // "lookupAll" allocates and returns a container with pointers to
  33. // all objects in this container equal to the specified object.
  34. //
  35. CmContainer* CmContainer::lookupAll(CmObject* pObj) const
  36. {
  37.   CmLinkedList *pList    = new CmLinkedList;
  38.   CmIterator   *iterator = newIterator();
  39.  
  40.   pList->ownsObjects(FALSE);
  41.   while (!iterator->done())
  42.   {
  43.     CmObject* temp = iterator->next();
  44.     if (temp->isEqual(pObj)) pList->add(temp);
  45.   }
  46.  
  47.   delete iterator;
  48.   return pList;
  49. }
  50.  
  51.  
  52. // "addAllFrom" adds all the objects from the specified container
  53. // to this container.
  54. //
  55. Bool CmContainer::addAllFrom(CmContainer* container)
  56. {
  57.   CmIterator *iterator = container->newIterator();
  58.   Bool        success  = TRUE;
  59.   while (!iterator->done() && success)
  60.   {
  61.     if (ownsObjects()) success = add(iterator->next()->newCopy());
  62.     else               success = add(iterator->next());
  63.   }
  64.   delete iterator;
  65.   return success;
  66. }
  67.  
  68.  
  69. // "printOn" prints the type of container and the container contents
  70. // on the specified output stream.
  71. //
  72. void CmContainer::printOn(ostream& os) const
  73. {
  74.   os << "Type " << isA() << " contains -" << endl;
  75.   CmIterator *iterator = newIterator();
  76.   while (!iterator->done())
  77.     os << *(iterator->next()) << endl;
  78.   delete iterator;
  79. }
  80.  
  81.  
  82. // "write" writes the container contents to the specified file.
  83. //
  84. Bool CmContainer::write(CmReserveFile& file) const
  85. {
  86.   if (!writeBase(file)) return FALSE;              // Write base container.
  87.  
  88.   Bool        success  = TRUE;
  89.   CmIterator *iterator = newIterator();
  90.   while (!iterator->done() && success)             // Cycle through objects.
  91.     success = iterator->next()->writeObject(file); // Write the object.
  92.   delete iterator;
  93.   return success;
  94. }
  95.  
  96.  
  97. // "read" reads objects from the specified file into this container.
  98. //
  99. Bool CmContainer::read(CmReserveFile& file)
  100. {
  101.   unsigned size = readBase(file);                 // Read base container.
  102.  
  103.   removeAll();                                    // Empty the container.
  104.  
  105.   int  ii      = 0;
  106.   Bool success = TRUE;
  107.   while (ii < size && success)                    // For each object.
  108.   {
  109.     CmObject *pObj = CmObject::readObject(file);  // Read object.
  110.     if (pObj) success = add(pObj); ii++;          // Add to container.
  111.   }
  112.   return success;
  113. }
  114.  
  115.  
  116. // "forEach" iterates through all the objects in the container calling
  117. // the specified function for each object until there are no more objects
  118. // or the function returns FALSE.
  119. //
  120. void CmContainer::forEach(CmQueryFunc pFunc, void* pData)
  121. {
  122.   Bool        cont     = TRUE;
  123.   CmIterator* iterator = newIterator();
  124.   while (!iterator->done() && cont)
  125.     cont = (*pFunc)(iterator->next(), pData);
  126.   delete iterator;
  127. }
  128.  
  129.  
  130. // "forEach" iterates through all the objects in the container calling
  131. // the specified object member function for each object until there are
  132. // no more objects or the function returns FALSE.
  133. //
  134. void CmContainer::forEach(CmQueryMemFunc pFunc, void* pData)
  135. {
  136.   Bool        cont     = TRUE;
  137.   CmIterator* iterator = newIterator();
  138.   while (!iterator->done() && cont)
  139.   {
  140.     CmObject *pObj = iterator->next();
  141.     cont = (pObj->*pFunc)(pData);
  142.   }
  143.   delete iterator;
  144. }
  145.  
  146.  
  147. // "firstThat" returns the first object in the container that is
  148. // passed into the specified function and returns TRUE.
  149. //
  150. CmObject* CmContainer::firstThat(CmQueryFunc pFunc, void* pData)
  151. {
  152.   CmObject   *outObj   = NULL;
  153.   CmIterator *iterator = newIterator();
  154.   while (!iterator->done() && !outObj)
  155.   {
  156.     CmObject *pObj = iterator->next();
  157.     if ((*pFunc)(pObj, pData)) outObj = pObj;
  158.   }
  159.   return outObj;
  160. }
  161.  
  162.  
  163. // "firstThat" returns the first object in the container who's specified
  164. // member function returns TRUE.
  165. //
  166. CmObject* CmContainer::firstThat(CmQueryMemFunc pFunc, void* pData)
  167. {
  168.   CmObject   *outObj   = NULL;
  169.   CmIterator *iterator = newIterator();
  170.   while (!iterator->done() && !outObj)
  171.   {
  172.     CmObject *pObj = iterator->next();
  173.     if ((pObj->*pFunc)(pData)) outObj = pObj;
  174.   }
  175.   return outObj;
  176. }
  177.  
  178.  
  179. // "query" cycles through all the objects in the container calling the
  180. // specified function for each.  Every object in which the function returns
  181. // returns TRUE gets added to a subset container which is then returned
  182. // from the function.
  183. //
  184. CmContainer* CmContainer::query(CmQueryFunc pFunc, void* pData)
  185. {
  186.   CmLinkedList *pList    = new CmLinkedList;
  187.   CmIterator   *iterator = newIterator();
  188.  
  189.   pList->ownsObjects(FALSE);
  190.   while (!iterator->done())
  191.   {
  192.     CmObject* pObj = iterator->next();
  193.     if ((*pFunc)(pObj, pData)) pList->add(pObj);
  194.   }
  195.  
  196.   delete iterator;
  197.   return pList;
  198. }
  199.  
  200.  
  201. // "query" cycles through all the objects in the container calling the
  202. // specified object member function for each.  Every object in which the
  203. // function returns returns TRUE gets added to a subset container which
  204. // is then returned from the function.
  205. //
  206. CmContainer* CmContainer::query(CmQueryMemFunc pFunc, void* pData)
  207. {
  208.   CmLinkedList *pList    = new CmLinkedList;
  209.   CmIterator   *iterator = newIterator();
  210.  
  211.   pList->ownsObjects(FALSE);
  212.   while (!iterator->done())
  213.   {
  214.     CmObject* pObj = iterator->next();
  215.     if ((pObj->*pFunc)(pData)) pList->add(pObj);
  216.   }
  217.  
  218.   delete iterator;
  219.   return pList;
  220. }
  221.  
  222.  
  223. // "copy" copies the contents from the specified container into this
  224. // container.
  225. //
  226. void CmContainer::copy(const CmContainer& C)
  227. {
  228.   _ownsObjects = C._ownsObjects;
  229.   CmIterator *iterator = C.newIterator();
  230.   while (!iterator->done())
  231.   {
  232.     if (ownsObjects()) add(iterator->next()->newCopy());
  233.     else               add(iterator->next());
  234.   }
  235.   delete iterator;
  236. }
  237.  
  238.  
  239. // "writeBase" writes the base container members to the specified file.
  240. //
  241. Bool CmContainer::writeBase(CmReserveFile& file) const
  242. {
  243.   Bool success = file.write(_ownsObjects);
  244.   if (success) success = file.write(_size);
  245.   return success;
  246. }
  247.  
  248.  
  249. // "readBase" reads the base container members from the specified file
  250. // and returns the container size (the _size member is not set here).
  251. //
  252. unsigned CmContainer::readBase(CmReserveFile& file)
  253. {
  254.   unsigned size;
  255.   Bool success = file.read(_ownsObjects);
  256.   if (success) success = file.read(size);
  257.   return (success) ? size : (unsigned) 0;
  258. }
  259.