home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cset21v1.zip / IBMCPP / IBMCLASS / ISBKSS.IF < prev    next >
Text File  |  1993-09-22  |  23KB  |  673 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 IWSrtBagOnKSSet < Element, ElementOps, Base >::
  16. checkNotEmpty () const
  17. {
  18. #ifndef INO_CHECKS
  19.   ICHECK (!isEmpty (), IEmptyException, ICollectionIsEmptyText)
  20. #endif
  21. }
  22.  
  23. template < class Element, class ElementOps, class Base >
  24. inline void IWSrtBagOnKSSet < Element, ElementOps, Base >::
  25. checkCursorIsValid (ICursor const& cursor) const
  26. {
  27. #ifndef INO_CHECKS
  28.   ICHECK (cursor.isValid (),
  29.           ICursorInvalidException, IInvalidCursorText)
  30. #endif
  31. }
  32.  
  33. template < class Element, class ElementOps, class Base >
  34. inline void IWSrtBagOnKSSet < Element, ElementOps, Base >::
  35. checkPositionExists (IPosition position) const
  36. {
  37. #ifndef INO_CHECKS
  38.   ICHECK (1 <= position && position <= numberOfElements(),
  39.           IPositionInvalidException, IInvalidPositionText)
  40. #endif
  41. }
  42.  
  43. template < class Element, class ElementOps, class Base >
  44. inline IWSrtBagOnKSSet < Element, ElementOps, Base >::
  45. IWSrtBagOnKSSet (INumber n)
  46. : ivBase (n)
  47. , ivNumberOfElements (0)
  48. {
  49. }
  50.  
  51. template < class Element, class ElementOps, class Base >
  52. inline IWSrtBagOnKSSet < Element, ElementOps, Base >::
  53. IWSrtBagOnKSSet (IWSrtBagOnKSSet < Element, ElementOps, Base > const& collection)
  54. : ivBase (collection.ivBase)
  55. , ivNumberOfElements (collection.ivNumberOfElements)
  56. {
  57. }
  58.  
  59. template < class Element, class ElementOps, class Base >
  60. inline IWSrtBagOnKSSet < Element, ElementOps, Base >& IWSrtBagOnKSSet < Element, ElementOps, Base >::
  61. operator= (IWSrtBagOnKSSet < Element, ElementOps, Base > const& collection)
  62. { ivBase.operator= (collection.ivBase);
  63.   ivNumberOfElements = collection.ivNumberOfElements;
  64.   return *this;
  65. }
  66.  
  67. template < class Element, class ElementOps, class Base >
  68. inline IWSrtBagOnKSSet < Element, ElementOps, Base >::
  69. ~IWSrtBagOnKSSet ()
  70. {
  71. }
  72.  
  73. template < class Element, class ElementOps, class Base >
  74. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  75. add (Element const& element)
  76. { Cursor dummy (*this);
  77.   return add (element, dummy);
  78. }
  79.  
  80. template < class Element, class ElementOps, class Base >
  81. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  82. add (Element const& element, ICursor &cursor)
  83. { ((Cursor&) cursor).occurrence = 1;
  84.   ISBKSElm < Element > e (element);
  85.   if (ivBase.locateOrAddElementWithKey (e, cursor))
  86.     ivBase.elementAt (cursor).occurrences++;
  87.   ivNumberOfElements++;
  88.   return True;
  89. }
  90.  
  91. template < class Element, class ElementOps, class Base >
  92. inline void IWSrtBagOnKSSet < Element, ElementOps, Base >::
  93. addAllFrom (IWSrtBagOnKSSet < Element, ElementOps, Base > const& collection)
  94. {
  95. #ifndef INO_CHECKS
  96.   ICHECK (this != &collection,
  97.           IIdenticalCollectionException, IIdenticalCollectionText)
  98. #endif
  99.   Base::Cursor thisCursor (ivBase), collectionCursor (collection.ivBase);
  100.   forCursor (collectionCursor) {
  101.     if (ivBase.locateOrAddElementWithKey
  102.                  (collectionCursor.element(), thisCursor))
  103.       ivBase.elementAt (thisCursor).occurrences +=
  104.         collectionCursor.element().occurrences;
  105.     ivNumberOfElements +=
  106.       collectionCursor.element().occurrences;
  107.   }
  108. }
  109.  
  110. template < class Element, class ElementOps, class Base >
  111. inline Element const& IWSrtBagOnKSSet < Element, ElementOps, Base >::
  112. elementAt (ICursor const& cursor) const
  113. { return ivBase.elementAt (cursor).elem;
  114. }
  115.  
  116. template < class Element, class ElementOps, class Base >
  117. inline Element& IWSrtBagOnKSSet < Element, ElementOps, Base >::
  118. elementAt (ICursor const& cursor)
  119. { return ivBase.elementAt (cursor).elem;
  120. }
  121.  
  122. template < class Element, class ElementOps, class Base >
  123. inline Element const& IWSrtBagOnKSSet < Element, ElementOps, Base >::
  124. anyElement () const
  125. { return ivBase.anyElement ().elem;
  126. }
  127.  
  128. template < class Element, class ElementOps, class Base >
  129. inline void IWSrtBagOnKSSet < Element, ElementOps, Base >::
  130. removeAt (ICursor const& cursor)
  131. { if (--ivBase.elementAt (cursor).occurrences == 0)
  132.     ivBase.removeAt (cursor);
  133.   ivNumberOfElements--;
  134. }
  135.  
  136. template < class Element, class ElementOps, class Base >
  137. inline INumber IWSrtBagOnKSSet < Element, ElementOps, Base >::
  138. removeAll (IBoolean (*predicate) (Element const&, void*), void* env)
  139. { RemoveEnv re;
  140.   re.predicate = predicate;
  141.   re.removeCount = 0;
  142.   re.env = env;
  143.   ivBase.removeAll (removePredicate, &re);
  144.   ivNumberOfElements -= re.removeCount;
  145.   return re.removeCount;
  146. }
  147.  
  148. template < class Element, class ElementOps, class Base >
  149. inline void IWSrtBagOnKSSet < Element, ElementOps, Base >::
  150. replaceAt (ICursor const& cursor, Element const& element)
  151. {
  152. #ifndef INO_CHECKS
  153.   ICHECK (elementOps().equal (ivBase.elementAt (cursor).elem, element),
  154.           IInvalidReplacementException, IInvalidReplacementText)
  155. #endif
  156.   elementOps().assign (ivBase.elementAt (cursor).elem, element);
  157. }
  158.  
  159. template < class Element, class ElementOps, class Base >
  160. inline void IWSrtBagOnKSSet < Element, ElementOps, Base >::
  161. removeAll ()
  162. { ivBase.removeAll ();
  163.   ivNumberOfElements = 0;
  164. }
  165.  
  166. template < class Element, class ElementOps, class Base >
  167. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  168. isBounded () const
  169. { return ivBase.isBounded ();
  170. }
  171.  
  172. template < class Element, class ElementOps, class Base >
  173. inline INumber IWSrtBagOnKSSet < Element, ElementOps, Base >::
  174. maxNumberOfElements () const
  175. { return ivBase.maxNumberOfElements ();
  176. }
  177.  
  178. template < class Element, class ElementOps, class Base >
  179. inline INumber IWSrtBagOnKSSet < Element, ElementOps, Base >::
  180. numberOfElements () const
  181. { return ivNumberOfElements;
  182. }
  183.  
  184. template < class Element, class ElementOps, class Base >
  185. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  186. isEmpty () const
  187. { return ivBase.isEmpty ();
  188. }
  189.  
  190. template < class Element, class ElementOps, class Base >
  191. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  192. isFull () const
  193. { return ivBase.isBounded () &&
  194.   ivNumberOfElements == ivBase.maxNumberOfElements ();
  195. }
  196.  
  197. template < class Element, class ElementOps, class Base >
  198. inline ICursor* IWSrtBagOnKSSet < Element, ElementOps, Base >::
  199. newCursor () const
  200. { ICursor* result = new Cursor (*this);
  201.   ICHECK (result != 0, IOutOfMemory, IOutOfMemoryText)
  202.   return result;
  203. }
  204.  
  205. template < class Element, class ElementOps, class Base >
  206. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  207. setToFirst (ICursor &cursor) const
  208. { IBoolean result = ivBase.setToFirst (cursor);
  209.   if (result)
  210.     ((Cursor&)cursor).occurrence = 1;
  211.   return result;
  212. }
  213.  
  214. template < class Element, class ElementOps, class Base >
  215. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  216. setToNext (ICursor &cursor) const
  217. { checkCursorIsValid (cursor);
  218.   if (((Cursor&)cursor).occurrence ==
  219.         ivBase.elementAt (cursor).occurrences) {
  220.     ((Cursor&)cursor).occurrence = 1;
  221.     return ivBase.setToNext (cursor);
  222.   }
  223.   else {
  224.     ((Cursor&)cursor).occurrence++;
  225.     return True;
  226.   }
  227. }
  228.  
  229. template < class Element, class ElementOps, class Base >
  230. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  231. allElementsDo (IBoolean (*iterationFunction) (Element &, void*),
  232.                void* environment)
  233. { Cursor cursor (*this);
  234.   forCursor (cursor)
  235.     if (! (*iterationFunction) (ivBase.elementAt (cursor).elem, environment))
  236.       return False;
  237.   return True;
  238. }
  239.  
  240. template < class Element, class ElementOps, class Base >
  241. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  242. allElementsDo (IIterator <Element>& iterator)
  243. { Cursor cursor (*this);
  244.   forCursor (cursor)
  245.     if (! iterator.applyTo (ivBase.elementAt (cursor).elem))
  246.       return False;
  247.   return True;
  248. }
  249.  
  250. template < class Element, class ElementOps, class Base >
  251. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  252. allElementsDo (IBoolean (*iterationFunction) (Element const&, void*),
  253.                void* environment) const
  254. { Cursor cursor (*this);
  255.   forCursor (cursor)
  256.     if (! (*iterationFunction) (ivBase.elementAt (cursor).elem, environment))
  257.       return False;
  258.   return True;
  259. }
  260.  
  261. template < class Element, class ElementOps, class Base >
  262. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  263. allElementsDo (IConstantIterator <Element>& iterator) const
  264. { Cursor cursor (*this);
  265.   forCursor (cursor)
  266.     if (! iterator.applyTo (ivBase.elementAt (cursor).elem))
  267.       return False;
  268.   return True;
  269. }
  270.  
  271. template < class Element, class ElementOps, class Base >
  272. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  273. isConsistent () const
  274. { return ivBase.isConsistent ();
  275. }
  276.  
  277. template < class Element, class ElementOps, class Base >
  278. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  279. contains (Element const& element) const
  280. { return ivBase.containsElementWithKey (element);
  281. }
  282.  
  283. template < class Element, class ElementOps, class Base >
  284. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  285. containsAllFrom (IWSrtBagOnKSSet < Element, ElementOps, Base > const& collection) const
  286. { return ivBase.containsAllKeysFrom (collection.ivBase);
  287. }
  288.  
  289. template < class Element, class ElementOps, class Base >
  290. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  291. locate (Element const& element, ICursor &cursor) const
  292. { ((Cursor&)cursor).occurrence = 1;
  293.   return ivBase.locateElementWithKey (element, cursor);
  294. }
  295.  
  296. template < class Element, class ElementOps, class Base >
  297. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  298. locateOrAdd (Element const& element)
  299. { Cursor dummy (*this);
  300.   return locateOrAdd (element, dummy);
  301. }
  302.  
  303. template < class Element, class ElementOps, class Base >
  304. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  305. locateOrAdd (Element const& element, ICursor &cursor)
  306. { ((Cursor&)cursor).occurrence = 1;
  307.   ISBKSElm < Element > e (element);
  308.   IBoolean result = ivBase.locateOrAddElementWithKey (e, cursor);
  309.   if (! result)
  310.     ivNumberOfElements++;
  311.   return result;
  312. }
  313.  
  314. template < class Element, class ElementOps, class Base >
  315. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  316. remove (Element const& element)
  317. { Cursor cursor (*this);
  318.   if (locate (element, cursor)) {
  319.     removeAt (cursor);
  320.     return True;
  321.   }
  322.   else
  323.     return False;
  324. }
  325.  
  326. template < class Element, class ElementOps, class Base >
  327. inline INumber IWSrtBagOnKSSet < Element, ElementOps, Base >::
  328. numberOfOccurrences (Element const& element) const
  329. { Cursor cursor (*this);
  330.   if (locate (element, cursor))
  331.     return ivBase.elementAt (cursor).occurrences;
  332.   else
  333.     return 0;
  334. }
  335.  
  336. template < class Element, class ElementOps, class Base >
  337. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  338. locateNext (Element const& element, ICursor& cursor) const
  339. { if (elementOps().equal (element, elementAt (cursor))) {
  340.     if (ivBase.elementAt (cursor).occurrences ==
  341.         ((Cursor&) cursor).occurrence) {
  342.       cursor.invalidate ();
  343.       return False;
  344.     } else {
  345.       ((Cursor&) cursor).occurrence++;
  346.       return True;
  347.     }
  348.   }
  349.   else {
  350.     ((Cursor&) cursor).occurrence = 1;
  351.     return ivBase.locateElementWithKey (element, cursor);
  352.   }
  353. }
  354.  
  355. template < class Element, class ElementOps, class Base >
  356. inline INumber IWSrtBagOnKSSet < Element, ElementOps, Base >::
  357. removeAllOccurrences (Element const& element)
  358. { Cursor cursor (*this);
  359.   if (! ivBase.locateElementWithKey (element, cursor))
  360.     return 0;
  361.   INumber result = ivBase.elementAt (cursor).occurrences;
  362.   ivNumberOfElements -= result;
  363.   ivBase.removeAt (cursor);
  364.   return result;
  365. }
  366.  
  367. template < class Element, class ElementOps, class Base >
  368. inline INumber IWSrtBagOnKSSet < Element, ElementOps, Base >::
  369. numberOfDifferentElements () const
  370. { return ivBase.numberOfElements ();
  371. }
  372.  
  373. template < class Element, class ElementOps, class Base >
  374. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  375. setToNextDifferentElement (ICursor& cursor) const
  376. { ((Cursor&)cursor).occurrence = 1;
  377.   return ivBase.setToNext (cursor);
  378. }
  379.  
  380. template < class Element, class ElementOps, class Base >
  381. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  382. operator== (IWSrtBagOnKSSet < Element, ElementOps, Base > const& collection) const
  383. { if (ivNumberOfElements != collection.ivNumberOfElements)
  384.     return False;
  385.   Base::Cursor cursor (ivBase);
  386.   forCursor (cursor) {
  387.     if (collection.numberOfOccurrences (cursor.element().elem) !=
  388.         ivBase.elementAt (cursor).occurrences)
  389.       return False;
  390.   }
  391.   return True;
  392. }
  393.  
  394. template < class Element, class ElementOps, class Base >
  395. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  396. operator!= (IWSrtBagOnKSSet < Element, ElementOps, Base > const& collection) const
  397. { return ! operator== (collection);
  398. }
  399.  
  400. template < class Element, class ElementOps, class Base >
  401. inline void IWSrtBagOnKSSet < Element, ElementOps, Base >::
  402. unionWith (IWSrtBagOnKSSet < Element, ElementOps, Base > const& collection)
  403. { if (this != &collection)
  404.     addAllFrom (collection);
  405.   else
  406.   { Base::Cursor cursor (ivBase);
  407.     forCursor (cursor) {
  408.       ivBase.elementAt (cursor).occurrences *= 2;
  409.     }
  410.     ivNumberOfElements *= 2;
  411.   }
  412. }
  413.  
  414. template < class Element, class ElementOps, class Base >
  415. inline void IWSrtBagOnKSSet < Element, ElementOps, Base >::
  416. intersectionWith (IWSrtBagOnKSSet < Element, ElementOps, Base > const& collection)
  417. { if (this != &collection)
  418.   { Base::Cursor cursor (ivBase);
  419.     forCursor (cursor) {
  420.       INumber occ = collection.numberOfOccurrences (cursor.element().elem);
  421.       INumber& thisOcc = ivBase.elementAt (cursor).occurrences;
  422.       if (occ < thisOcc) {
  423.         ivNumberOfElements -= thisOcc - occ;
  424.         thisOcc = occ;
  425.       }
  426.     }
  427.     ivBase.removeAll (cleanupPredicate);
  428.   }
  429. }
  430.  
  431. template < class Element, class ElementOps, class Base >
  432. inline void IWSrtBagOnKSSet < Element, ElementOps, Base >::
  433. differenceWith (IWSrtBagOnKSSet < Element, ElementOps, Base > const& collection)
  434. { if (this == &collection)
  435.     removeAll ();
  436.   else
  437.   { Base::Cursor cursor (ivBase);
  438.     forCursor (cursor) {
  439.       INumber occ = collection.numberOfOccurrences (cursor.element ().elem);
  440.       INumber& thisOcc = ivBase.elementAt (cursor).occurrences;
  441.       INumber n = (thisOcc < occ ? thisOcc : occ);
  442.       thisOcc -= n;
  443.       ivNumberOfElements -= n;
  444.     }
  445.     ivBase.removeAll (cleanupPredicate);
  446.   }
  447. }
  448.  
  449. template < class Element, class ElementOps, class Base >
  450. inline void IWSrtBagOnKSSet < Element, ElementOps, Base >::
  451. addUnion (IWSrtBagOnKSSet < Element, ElementOps, Base > const& collection1,
  452.           IWSrtBagOnKSSet < Element, ElementOps, Base > const& collection2)
  453. { if (this == &collection1) {
  454.     if (this == &collection2) {
  455.       Base::Cursor cursor (ivBase);
  456.       forCursor (cursor) {
  457.         ivBase.elementAt (cursor).occurrences *= 3;
  458.       }
  459.       ivNumberOfElements *= 3;
  460.     }
  461.     else {
  462.       unionWith (collection1);
  463.       unionWith (collection2);
  464.     }
  465.   }
  466.   else {
  467.     unionWith (collection2);
  468.     unionWith (collection1);
  469.   }
  470. }
  471.  
  472. template < class Element, class ElementOps, class Base >
  473. inline void IWSrtBagOnKSSet < Element, ElementOps, Base >::
  474. addIntersection (IWSrtBagOnKSSet < Element, ElementOps, Base > const& collection1,
  475.                  IWSrtBagOnKSSet < Element, ElementOps, Base > const& collection2)
  476. { if (this == &collection1) {
  477.     if (this == &collection2)
  478.       unionWith (*this);
  479.     else
  480.       addIntersection (collection2, collection1);
  481.   }
  482.   else {
  483.     Base::Cursor cursor2 (collection2.ivBase);
  484.     forCursor (cursor2) {
  485.       Element const& e = cursor2.element ().elem;
  486.       INumber n1, n2;
  487.       n1 = collection1.numberOfOccurrences (e);
  488.       n2 = cursor2.element ().occurrences;
  489.       INumber n = (n1 < n2 ? n1 : n2);
  490.       if (n > 0) {
  491.         Base::Cursor cursor (ivBase);
  492.         if (ivBase.locateOrAddElementWithKey (e, cursor))
  493.           ivBase.elementAt (cursor).occurrences += n;
  494.         else
  495.           ivBase.elementAt (cursor).occurrences = n;
  496.         ivNumberOfElements += n;
  497.       }
  498.     }
  499.   }
  500. }
  501.  
  502. template < class Element, class ElementOps, class Base >
  503. inline void IWSrtBagOnKSSet < Element, ElementOps, Base >::
  504. addDifference (IWSrtBagOnKSSet < Element, ElementOps, Base > const& collection1,
  505.                IWSrtBagOnKSSet < Element, ElementOps, Base > const& collection2)
  506. { if (this == &collection1) {
  507.     if (this == &collection2)
  508.       return;
  509.     else {
  510.       unionWith (*this);
  511.       Base::Cursor cursor2 (collection2.ivBase);
  512.       forCursor (cursor2) {
  513.         Element const& e = cursor2.element ().elem;
  514.         INumber n1, n2;
  515.         n1 = numberOfOccurrences (e) / 2;
  516.         n2 = cursor2.element ().occurrences;
  517.         INumber n = (n1 < n2 ? n1 : n2);
  518.         if (n > 0) {
  519.           Base::Cursor cursor (ivBase);
  520.           ivBase.locateElementWithKey (e, cursor);
  521.           ivBase.elementAt (cursor).occurrences -= n;
  522.           ivNumberOfElements -= n;
  523.         }
  524.       }
  525.     }
  526.   }
  527.   else {
  528.     Base::Cursor cursor1 (collection1.ivBase);
  529.     forCursor (cursor1) {
  530.       Element const& e = cursor1.element ().elem;
  531.       INumber n1, n2;
  532.       n1 = cursor1.element ().occurrences;
  533.       n2 = collection2.numberOfOccurrences (e);
  534.       INumber n = (n1 < n2 ? 0 : n1 - n2);
  535.       if (n > 0) {
  536.         Base::Cursor cursor (ivBase);
  537.         if (ivBase.locateOrAddElementWithKey (e, cursor))
  538.           ivBase.elementAt (cursor).occurrences += n;
  539.         else
  540.           ivBase.elementAt (cursor).occurrences = n;
  541.         ivNumberOfElements += n;
  542.       }
  543.     }
  544.   }
  545. }
  546.  
  547. template < class Element, class ElementOps, class Base >
  548. inline void IWSrtBagOnKSSet < Element, ElementOps, Base >::
  549. removeFirst ()
  550. { checkNotEmpty ();
  551.   Cursor cursor (*this);
  552.   setToFirst (cursor);
  553.   removeAt (cursor);
  554. }
  555.  
  556. template < class Element, class ElementOps, class Base >
  557. inline void IWSrtBagOnKSSet < Element, ElementOps, Base >::
  558. removeLast ()
  559. { checkNotEmpty ();
  560.   Cursor cursor (*this);
  561.   setToLast (cursor);
  562.   removeAt (cursor);
  563. }
  564.  
  565. template < class Element, class ElementOps, class Base >
  566. inline void IWSrtBagOnKSSet < Element, ElementOps, Base >::
  567. removeAtPosition (IPosition position)
  568. { Cursor cursor (*this);
  569.   setToPosition (position, cursor);
  570.   removeAt (cursor);
  571. }
  572.  
  573. template < class Element, class ElementOps, class Base >
  574. inline Element const& IWSrtBagOnKSSet < Element, ElementOps, Base >::
  575. firstElement () const
  576. { checkNotEmpty ();
  577.   Cursor cursor (*this);
  578.   setToFirst (cursor);
  579.   return elementAt (cursor);
  580. }
  581.  
  582. template < class Element, class ElementOps, class Base >
  583. inline Element const& IWSrtBagOnKSSet < Element, ElementOps, Base >::
  584. lastElement () const
  585. { checkNotEmpty ();
  586.   Cursor cursor (*this);
  587.   setToLast (cursor);
  588.   return elementAt (cursor);
  589. }
  590.  
  591. template < class Element, class ElementOps, class Base >
  592. inline Element const& IWSrtBagOnKSSet < Element, ElementOps, Base >::
  593. elementAtPosition (IPosition position) const
  594. { Cursor cursor (*this);
  595.   setToPosition (position, cursor);
  596.   return elementAt (cursor);
  597. }
  598.  
  599. template < class Element, class ElementOps, class Base >
  600. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  601. setToLast (ICursor &cursor) const
  602. { IBoolean result = ivBase.setToLast (cursor);
  603.   if (result)
  604.     ((Cursor&)cursor).occurrence =
  605.       ivBase.elementAt (cursor).occurrences;
  606.   return result;
  607. }
  608.  
  609. template < class Element, class ElementOps, class Base >
  610. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  611. setToPrevious (ICursor &cursor) const
  612. { checkCursorIsValid (cursor);
  613.   if (((Cursor&)cursor).occurrence == 1) {
  614.     IBoolean result = ivBase.setToPrevious (cursor);
  615.     if (result)
  616.       ((Cursor&)cursor).occurrence =
  617.         ivBase.elementAt (cursor).occurrences;
  618.     return result;
  619.   }
  620.   else {
  621.     ((Cursor&)cursor).occurrence--;
  622.     return True;
  623.   }
  624. }
  625.  
  626. template < class Element, class ElementOps, class Base >
  627. inline void IWSrtBagOnKSSet < Element, ElementOps, Base >::
  628. setToPosition (IPosition position, ICursor &cursor) const
  629. { checkPositionExists (position);
  630.   setToFirst (cursor);
  631.   for (int i = 1; i < position; i++) setToNext (cursor);
  632. }
  633.  
  634. template < class Element, class ElementOps, class Base >
  635. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  636. isFirst (ICursor const& cursor) const
  637. { return ivBase.isFirst (cursor) &&
  638.     ((Cursor const&)cursor).occurrence == 1;
  639. }
  640.  
  641. template < class Element, class ElementOps, class Base >
  642. inline IBoolean IWSrtBagOnKSSet < Element, ElementOps, Base >::
  643. isLast (ICursor const& cursor) const
  644. { return ivBase.isLast (cursor) &&
  645.     ((Cursor const&)cursor).occurrence ==
  646.       ivBase.elementAt (cursor).occurrences;
  647. }
  648.  
  649. template < class Element, class ElementOps, class Base >
  650. inline long IWSrtBagOnKSSet < Element, ElementOps, Base >::
  651. compare (IWSrtBagOnKSSet < Element, ElementOps, Base > const& collection,
  652.          long (*comparisonFunction) (Element const&, Element const&)) const
  653. { long result = 0;
  654.   Cursor thisCursor (*this);
  655.   Cursor collectionCursor (collection);
  656.  
  657.   for (thisCursor.setToFirst (), collectionCursor.setToFirst ();
  658.        result == 0 && thisCursor.isValid () && collectionCursor.isValid ();
  659.        thisCursor.setToNext (), collectionCursor.setToNext ()) {
  660.     result = (*comparisonFunction) (elementAt (thisCursor),
  661.                                     collection.elementAt (collectionCursor));
  662.   }
  663.   if (result == 0) {
  664.     if (thisCursor.isValid () && ! collectionCursor.isValid ())
  665.       result = 1;
  666.     else if (! thisCursor.isValid () && collectionCursor.isValid ())
  667.       result = -1;
  668.     else {
  669.     }
  670.   }
  671.   return result;
  672. }
  673.