home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cset21v1.zip / IBMCPP / IBMCLASS / IBAGKS.IF < prev    next >
Text File  |  1993-09-22  |  18KB  |  528 lines

  1. /*******************************************************************************
  2. *                                                                              *
  3. * COPYRIGHT:                                                                   *
  4. *   IBM C/C++ Tools Version 2.01 - Collection Class Library                    *
  5. *   Licensed Materials - Property of IBM                                       *
  6. *   (C) Copyright IBM Corporation 1992, 1993                                   *
  7. *   All Rights Reserved                                                        *
  8. *   US Government Users Restricted Rights - Use, duplication, or disclosure    *
  9. *   restricted by GSA ADP Schedule Contract with IBM Corp.                     *
  10. *                                                                              *
  11. *******************************************************************************/
  12. #include <ibexcept.h>
  13.  
  14. template < class Element, class ElementOps, class Base >
  15. inline void IWBagOnKeySet < Element, ElementOps, Base >::
  16. checkCursorIsForThis (ICursor const& cursor) const
  17. {
  18. #ifndef INO_CHECKS
  19.   ICHECK (((Cursor const&)cursor).isFor (*this),
  20.           ICursorInvalidException, ICursorNotForThisText)
  21. #endif
  22. }
  23.  
  24. template < class Element, class ElementOps, class Base >
  25. inline void IWBagOnKeySet < Element, ElementOps, Base >::
  26. checkCursor (ICursor const& cursor) const
  27. {
  28. #ifndef INO_CHECKS
  29.   ICHECK (((Cursor const&)cursor).isFor (*this),
  30.           ICursorInvalidException, ICursorNotForThisText)
  31.   ICHECK (cursor.isValid (), ICursorInvalidException, IInvalidCursorText)
  32. #endif
  33. }
  34.  
  35. template < class Element, class ElementOps, class Base >
  36. inline IWBagOnKeySet < Element, ElementOps, Base >::
  37. IWBagOnKeySet (INumber n)
  38. : ivBase (n)
  39. , ivNumberOfElements (0)
  40. {
  41. }
  42.  
  43. template < class Element, class ElementOps, class Base >
  44. inline IWBagOnKeySet < Element, ElementOps, Base >::
  45. IWBagOnKeySet (IWBagOnKeySet < Element, ElementOps, Base > const& collection)
  46. : ivBase (collection.ivBase)
  47. , ivNumberOfElements (collection.ivNumberOfElements)
  48. {
  49. }
  50.  
  51. template < class Element, class ElementOps, class Base >
  52. inline IWBagOnKeySet < Element, ElementOps, Base >& IWBagOnKeySet < Element, ElementOps, Base >::
  53. operator= (IWBagOnKeySet < Element, ElementOps, Base > const& collection)
  54. { ivBase.operator= (collection.ivBase);
  55.   ivNumberOfElements = collection.ivNumberOfElements;
  56.   return *this;
  57. }
  58.  
  59. template < class Element, class ElementOps, class Base >
  60. inline IWBagOnKeySet < Element, ElementOps, Base >::
  61. ~IWBagOnKeySet ()
  62. {
  63. }
  64.  
  65. template < class Element, class ElementOps, class Base >
  66. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  67. add (Element const& element)
  68. { Cursor dummy (*this);
  69.   return add (element, dummy);
  70. }
  71.  
  72. template < class Element, class ElementOps, class Base >
  73. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  74. add (Element const& element, ICursor &cursor)
  75. { ((Cursor&) cursor).occurrence = 1;
  76.   IBKeyElm < Element > e (element);
  77.   if (ivBase.locateOrAddElementWithKey (e, cursor))
  78.     ivBase.elementAt (cursor).occurrences++;
  79.   ivNumberOfElements++;
  80.   return True;
  81. }
  82.  
  83. template < class Element, class ElementOps, class Base >
  84. inline void IWBagOnKeySet < Element, ElementOps, Base >::
  85. addAllFrom (IWBagOnKeySet < Element, ElementOps, Base > const& collection)
  86. {
  87. #ifndef INO_CHECKS
  88.   ICHECK (this != &collection,
  89.           IIdenticalCollectionException, IIdenticalCollectionText)
  90. #endif
  91.   Base::Cursor thisCursor (ivBase), collectionCursor (collection.ivBase);
  92.   forCursor (collectionCursor) {
  93.     if (ivBase.locateOrAddElementWithKey
  94.                  (collectionCursor.element(), thisCursor))
  95.       ivBase.elementAt (thisCursor).occurrences +=
  96.         collectionCursor.element().occurrences;
  97.     ivNumberOfElements +=
  98.       collectionCursor.element().occurrences;
  99.   }
  100. }
  101.  
  102. template < class Element, class ElementOps, class Base >
  103. inline Element const& IWBagOnKeySet < Element, ElementOps, Base >::
  104. elementAt (ICursor const& cursor) const
  105. { return ivBase.elementAt (cursor).elem;
  106. }
  107.  
  108. template < class Element, class ElementOps, class Base >
  109. inline Element& IWBagOnKeySet < Element, ElementOps, Base >::
  110. elementAt (ICursor const& cursor)
  111. { return ivBase.elementAt (cursor).elem;
  112. }
  113.  
  114. template < class Element, class ElementOps, class Base >
  115. inline Element const& IWBagOnKeySet < Element, ElementOps, Base >::
  116. anyElement () const
  117. { return ivBase.anyElement ().elem;
  118. }
  119.  
  120. template < class Element, class ElementOps, class Base >
  121. inline void IWBagOnKeySet < Element, ElementOps, Base >::
  122. removeAt (ICursor const& cursor)
  123. { if (--ivBase.elementAt (cursor).occurrences == 0)
  124.     ivBase.removeAt (cursor);
  125.   ivNumberOfElements--;
  126. }
  127.  
  128. template < class Element, class ElementOps, class Base >
  129. inline INumber IWBagOnKeySet < Element, ElementOps, Base >::
  130. removeAll (IBoolean (*predicate) (Element const&, void*), void* env)
  131. { RemoveEnv re;
  132.   re.predicate = predicate;
  133.   re.removeCount = 0;
  134.   re.env = env;
  135.   ivBase.removeAll (removePredicate, &re);
  136.   ivNumberOfElements -= re.removeCount;
  137.   return re.removeCount;
  138. }
  139.  
  140. template < class Element, class ElementOps, class Base >
  141. inline void IWBagOnKeySet < Element, ElementOps, Base >::
  142. replaceAt (ICursor const& cursor, Element const& element)
  143. {
  144. #ifndef INO_CHECKS
  145.   ICHECK (elementOps().equal (ivBase.elementAt (cursor).elem, element),
  146.           IInvalidReplacementException, IInvalidReplacementText)
  147. #endif
  148.   elementOps().assign (ivBase.elementAt (cursor).elem, element);
  149. }
  150.  
  151. template < class Element, class ElementOps, class Base >
  152. inline void IWBagOnKeySet < Element, ElementOps, Base >::
  153. removeAll ()
  154. { ivBase.removeAll ();
  155.   ivNumberOfElements = 0;
  156. }
  157.  
  158. template < class Element, class ElementOps, class Base >
  159. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  160. isBounded () const
  161. { return ivBase.isBounded ();
  162. }
  163.  
  164. template < class Element, class ElementOps, class Base >
  165. inline INumber IWBagOnKeySet < Element, ElementOps, Base >::
  166. maxNumberOfElements () const
  167. { return ivBase.maxNumberOfElements ();
  168. }
  169.  
  170. template < class Element, class ElementOps, class Base >
  171. inline INumber IWBagOnKeySet < Element, ElementOps, Base >::
  172. numberOfElements () const
  173. { return ivNumberOfElements;
  174. }
  175.  
  176. template < class Element, class ElementOps, class Base >
  177. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  178. isEmpty () const
  179. { return ivBase.isEmpty ();
  180. }
  181.  
  182. template < class Element, class ElementOps, class Base >
  183. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  184. isFull () const
  185. { return ivBase.isBounded () &&
  186.   ivNumberOfElements == ivBase.maxNumberOfElements ();
  187. }
  188.  
  189. template < class Element, class ElementOps, class Base >
  190. inline ICursor* IWBagOnKeySet < Element, ElementOps, Base >::
  191. newCursor () const
  192. { ICursor* result = new Cursor (*this);
  193.   ICHECK (result != 0, IOutOfMemory, IOutOfMemoryText)
  194.   return result;
  195. }
  196.  
  197. template < class Element, class ElementOps, class Base >
  198. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  199. setToFirst (ICursor &cursor) const
  200. { checkCursorIsForThis (cursor);
  201.   return ((Cursor&) cursor).Cursor::setToFirst ();
  202. }
  203.  
  204. template < class Element, class ElementOps, class Base >
  205. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  206. setToNext (ICursor &cursor) const
  207. { checkCursor (cursor);
  208.   return ((Cursor&) cursor).Cursor::setToNext ();
  209. }
  210.  
  211. template < class Element, class ElementOps, class Base >
  212. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  213. allElementsDo (IBoolean (*iterationFunction) (Element &, void*),
  214.                void* environment)
  215. { Cursor cursor (*this);
  216.   forCursor (cursor)
  217.     if (! (*iterationFunction) (ivBase.elementAt (cursor).elem, environment))
  218.       return False;
  219.   return True;
  220. }
  221.  
  222. template < class Element, class ElementOps, class Base >
  223. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  224. allElementsDo (IIterator <Element>& iterator)
  225. { Cursor cursor (*this);
  226.   forCursor (cursor)
  227.     if (! iterator.applyTo (ivBase.elementAt (cursor).elem))
  228.       return False;
  229.   return True;
  230. }
  231.  
  232. template < class Element, class ElementOps, class Base >
  233. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  234. allElementsDo (IBoolean (*iterationFunction) (Element const&, void*),
  235.                void* environment) const
  236. { Cursor cursor (*this);
  237.   forCursor (cursor)
  238.     if (! (*iterationFunction) (ivBase.elementAt (cursor).elem, environment))
  239.       return False;
  240.   return True;
  241. }
  242.  
  243. template < class Element, class ElementOps, class Base >
  244. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  245. allElementsDo (IConstantIterator <Element>& iterator) const
  246. { Cursor cursor (*this);
  247.   forCursor (cursor)
  248.     if (! iterator.applyTo (ivBase.elementAt (cursor).elem))
  249.       return False;
  250.   return True;
  251. }
  252.  
  253. template < class Element, class ElementOps, class Base >
  254. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  255. isConsistent () const
  256. { return ivBase.isConsistent ();
  257. }
  258.  
  259. template < class Element, class ElementOps, class Base >
  260. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  261. contains (Element const& element) const
  262. { return ivBase.containsElementWithKey (element);
  263. }
  264.  
  265. template < class Element, class ElementOps, class Base >
  266. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  267. containsAllFrom (IWBagOnKeySet < Element, ElementOps, Base > const& collection) const
  268. { return ivBase.containsAllKeysFrom (collection.ivBase);
  269. }
  270.  
  271. template < class Element, class ElementOps, class Base >
  272. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  273. locate (Element const& element, ICursor &cursor) const
  274. { ((Cursor&)cursor).occurrence = 1;
  275.   return ivBase.locateElementWithKey (element, cursor);
  276. }
  277.  
  278. template < class Element, class ElementOps, class Base >
  279. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  280. locateOrAdd (Element const& element)
  281. { Cursor dummy (*this);
  282.   return locateOrAdd (element, dummy);
  283. }
  284.  
  285. template < class Element, class ElementOps, class Base >
  286. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  287. locateOrAdd (Element const& element, ICursor &cursor)
  288. { ((Cursor&)cursor).occurrence = 1;
  289.   IBKeyElm < Element > e (element);
  290.   IBoolean result = ivBase.locateOrAddElementWithKey (e, cursor);
  291.   if (! result)
  292.     ivNumberOfElements++;
  293.   return result;
  294. }
  295.  
  296. template < class Element, class ElementOps, class Base >
  297. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  298. remove (Element const& element)
  299. { Cursor cursor (*this);
  300.   if (locate (element, cursor)) {
  301.     removeAt (cursor);
  302.     return True;
  303.   }
  304.   else
  305.     return False;
  306. }
  307.  
  308. template < class Element, class ElementOps, class Base >
  309. inline INumber IWBagOnKeySet < Element, ElementOps, Base >::
  310. numberOfOccurrences (Element const& element) const
  311. { Cursor cursor (*this);
  312.   if (locate (element, cursor))
  313.     return ivBase.elementAt (cursor).occurrences;
  314.   else
  315.     return 0;
  316. }
  317.  
  318. template < class Element, class ElementOps, class Base >
  319. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  320. locateNext (Element const& element, ICursor& cursor) const
  321. { if (elementOps().equal (element, elementAt (cursor))) {
  322.     if (ivBase.elementAt (cursor).occurrences ==
  323.         ((Cursor&) cursor).occurrence) {
  324.       cursor.invalidate ();
  325.       return False;
  326.     } else {
  327.       ((Cursor&) cursor).occurrence++;
  328.       return True;
  329.     }
  330.   }
  331.   else {
  332.     ((Cursor&) cursor).occurrence = 1;
  333.     return ivBase.locateElementWithKey (element, cursor);
  334.   }
  335. }
  336.  
  337. template < class Element, class ElementOps, class Base >
  338. inline INumber IWBagOnKeySet < Element, ElementOps, Base >::
  339. removeAllOccurrences (Element const& element)
  340. { Cursor cursor (*this);
  341.   if (! ivBase.locateElementWithKey (element, cursor))
  342.     return 0;
  343.   INumber result = ivBase.elementAt (cursor).occurrences;
  344.   ivNumberOfElements -= result;
  345.   ivBase.removeAt (cursor);
  346.   return result;
  347. }
  348.  
  349. template < class Element, class ElementOps, class Base >
  350. inline INumber IWBagOnKeySet < Element, ElementOps, Base >::
  351. numberOfDifferentElements () const
  352. { return ivBase.numberOfElements ();
  353. }
  354.  
  355. template < class Element, class ElementOps, class Base >
  356. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  357. setToNextDifferentElement (ICursor& cursor) const
  358. { ((Cursor&)cursor).occurrence = 1;
  359.   return ivBase.setToNext (cursor);
  360. }
  361.  
  362. template < class Element, class ElementOps, class Base >
  363. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  364. operator== (IWBagOnKeySet < Element, ElementOps, Base > const& collection) const
  365. { if (ivNumberOfElements != collection.ivNumberOfElements)
  366.     return False;
  367.   Base::Cursor cursor (ivBase);
  368.   forCursor (cursor) {
  369.     if (collection.numberOfOccurrences (cursor.element().elem) !=
  370.         ivBase.elementAt (cursor).occurrences)
  371.       return False;
  372.   }
  373.   return True;
  374. }
  375.  
  376. template < class Element, class ElementOps, class Base >
  377. inline IBoolean IWBagOnKeySet < Element, ElementOps, Base >::
  378. operator!= (IWBagOnKeySet < Element, ElementOps, Base > const& collection) const
  379. { return ! operator== (collection);
  380. }
  381.  
  382. template < class Element, class ElementOps, class Base >
  383. inline void IWBagOnKeySet < Element, ElementOps, Base >::
  384. unionWith (IWBagOnKeySet < Element, ElementOps, Base > const& collection)
  385. { if (this != &collection)
  386.     addAllFrom (collection);
  387.   else
  388.   { Base::Cursor cursor (ivBase);
  389.     forCursor (cursor) {
  390.       ivBase.elementAt (cursor).occurrences *= 2;
  391.     }
  392.     ivNumberOfElements *= 2;
  393.   }
  394. }
  395.  
  396. template < class Element, class ElementOps, class Base >
  397. inline void IWBagOnKeySet < Element, ElementOps, Base >::
  398. intersectionWith (IWBagOnKeySet < Element, ElementOps, Base > const& collection)
  399. { if (this != &collection)
  400.   { Base::Cursor cursor (ivBase);
  401.     forCursor (cursor) {
  402.       INumber occ = collection.numberOfOccurrences (cursor.element().elem);
  403.       INumber& thisOcc = ivBase.elementAt (cursor).occurrences;
  404.       if (occ < thisOcc) {
  405.         ivNumberOfElements -= thisOcc - occ;
  406.         thisOcc = occ;
  407.       }
  408.     }
  409.     ivBase.removeAll (cleanupPredicate);
  410.   }
  411. }
  412.  
  413. template < class Element, class ElementOps, class Base >
  414. inline void IWBagOnKeySet < Element, ElementOps, Base >::
  415. differenceWith (IWBagOnKeySet < Element, ElementOps, Base > const& collection)
  416. { if (this == &collection)
  417.     removeAll ();
  418.   else
  419.   { Base::Cursor cursor (ivBase);
  420.     forCursor (cursor) {
  421.       INumber occ = collection.numberOfOccurrences (cursor.element ().elem);
  422.       INumber& thisOcc = ivBase.elementAt (cursor).occurrences;
  423.       INumber n = (thisOcc < occ ? thisOcc : occ);
  424.       thisOcc -= n;
  425.       ivNumberOfElements -= n;
  426.     }
  427.     ivBase.removeAll (cleanupPredicate);
  428.   }
  429. }
  430.  
  431. template < class Element, class ElementOps, class Base >
  432. inline void IWBagOnKeySet < Element, ElementOps, Base >::
  433. addUnion (IWBagOnKeySet < Element, ElementOps, Base > const& collection1,
  434.           IWBagOnKeySet < Element, ElementOps, Base > const& collection2)
  435. { if (this == &collection1) {
  436.     if (this == &collection2) {
  437.       Base::Cursor cursor (ivBase);
  438.       forCursor (cursor) {
  439.         ivBase.elementAt (cursor).occurrences *= 3;
  440.       }
  441.       ivNumberOfElements *= 3;
  442.     }
  443.     else {
  444.       unionWith (collection1);
  445.       unionWith (collection2);
  446.     }
  447.   }
  448.   else {
  449.     unionWith (collection2);
  450.     unionWith (collection1);
  451.   }
  452. }
  453.  
  454. template < class Element, class ElementOps, class Base >
  455. inline void IWBagOnKeySet < Element, ElementOps, Base >::
  456. addIntersection (IWBagOnKeySet < Element, ElementOps, Base > const& collection1,
  457.                  IWBagOnKeySet < Element, ElementOps, Base > const& collection2)
  458. { if (this == &collection1) {
  459.     if (this == &collection2)
  460.       unionWith (*this);
  461.     else
  462.       addIntersection (collection2, collection1);
  463.   }
  464.   else {
  465.     Base::Cursor cursor2 (collection2.ivBase);
  466.     forCursor (cursor2) {
  467.       Element const& e = cursor2.element ().elem;
  468.       INumber n1, n2;
  469.       n1 = collection1.numberOfOccurrences (e);
  470.       n2 = cursor2.element ().occurrences;
  471.       INumber n = (n1 < n2 ? n1 : n2);
  472.       if (n > 0) {
  473.         Base::Cursor cursor (ivBase);
  474.         if (ivBase.locateOrAddElementWithKey (e, cursor))
  475.           ivBase.elementAt (cursor).occurrences += n;
  476.         else
  477.           ivBase.elementAt (cursor).occurrences = n;
  478.         ivNumberOfElements += n;
  479.       }
  480.     }
  481.   }
  482. }
  483.  
  484. template < class Element, class ElementOps, class Base >
  485. inline void IWBagOnKeySet < Element, ElementOps, Base >::
  486. addDifference (IWBagOnKeySet < Element, ElementOps, Base > const& collection1,
  487.                IWBagOnKeySet < Element, ElementOps, Base > const& collection2)
  488. { if (this == &collection1) {
  489.     if (this == &collection2)
  490.       return;
  491.     else {
  492.       unionWith (*this);
  493.       Base::Cursor cursor2 (collection2.ivBase);
  494.       forCursor (cursor2) {
  495.         Element const& e = cursor2.element ().elem;
  496.         INumber n1, n2;
  497.         n1 = numberOfOccurrences (e) / 2;
  498.         n2 = cursor2.element ().occurrences;
  499.         INumber n = (n1 < n2 ? n1 : n2);
  500.         if (n > 0) {
  501.           Base::Cursor cursor (ivBase);
  502.           ivBase.locateElementWithKey (e, cursor);
  503.           ivBase.elementAt (cursor).occurrences -= n;
  504.           ivNumberOfElements -= n;
  505.         }
  506.       }
  507.     }
  508.   }
  509.   else {
  510.     Base::Cursor cursor1 (collection1.ivBase);
  511.     forCursor (cursor1) {
  512.       Element const& e = cursor1.element ().elem;
  513.       INumber n1, n2;
  514.       n1 = cursor1.element ().occurrences;
  515.       n2 = collection2.numberOfOccurrences (e);
  516.       INumber n = (n1 < n2 ? 0 : n1 - n2);
  517.       if (n > 0) {
  518.         Base::Cursor cursor (ivBase);
  519.         if (ivBase.locateOrAddElementWithKey (e, cursor))
  520.           ivBase.elementAt (cursor).occurrences += n;
  521.         else
  522.           ivBase.elementAt (cursor).occurrences = n;
  523.         ivNumberOfElements += n;
  524.       }
  525.     }
  526.   }
  527. }
  528.