home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / yacl-012.zip / base / seqimp.cxx < prev    next >
C/C++ Source or Header  |  1995-04-08  |  20KB  |  872 lines

  1.  
  2.  
  3.  
  4.  
  5. /*
  6.  *
  7.  *          Copyright (C) 1994, M. A. Sridhar
  8.  *  
  9.  *
  10.  *     This software is Copyright M. A. Sridhar, 1994. You are free
  11.  *     to copy, modify or distribute this software  as you see fit,
  12.  *     and to use  it  for  any  purpose, provided   this copyright
  13.  *     notice and the following   disclaimer are included  with all
  14.  *     copies.
  15.  *
  16.  *                        DISCLAIMER
  17.  *
  18.  *     The author makes no warranties, either expressed or implied,
  19.  *     with respect  to  this  software, its  quality, performance,
  20.  *     merchantability, or fitness for any particular purpose. This
  21.  *     software is distributed  AS IS.  The  user of this  software
  22.  *     assumes all risks  as to its quality  and performance. In no
  23.  *     event shall the author be liable for any direct, indirect or
  24.  *     consequential damages, even if the  author has been  advised
  25.  *     as to the possibility of such damages.
  26.  *
  27.  */
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35. #ifndef _seqimp_cxx_ /* Sun Nov  7 12:38:41 1993 */
  36. #define _seqimp_cxx_
  37.  
  38.  
  39. #ifdef __GNUC__
  40. #pragma implementation
  41. #endif
  42.  
  43.  
  44.  
  45. // Implementation of the sequence data structure
  46. // Invariants maintained:
  47. //     - Initially nullify all cells from 0 to _size-1.
  48.  
  49.  
  50.  
  51.  
  52. #include "base/sequence.h" 
  53. #include "base/stream.h"
  54.  
  55.  
  56. #ifndef __GNUC__
  57. #include "base/intset.h"
  58. #endif
  59.  
  60.  
  61.  
  62. #include "base/basicops.h"
  63.  
  64. #define NEW_OP new
  65.  
  66.  
  67.  
  68. // Helper class for managing segments
  69.  
  70. struct SegDesc;
  71.  
  72. class SegmentedSequence {
  73.  
  74. public:
  75.     SegmentedSequence (long initial_cap = 8);
  76.     ~SegmentedSequence ();
  77.  
  78.     CL_VoidPtr& operator[] (long index);
  79.  
  80.     bool ResizeTo    (long new_cap);
  81.     // Guarantee that there are at least new_cap cells in the sequence.
  82.  
  83. protected:
  84.     SegDesc*         _segs;
  85.     short            _numSegs;
  86.     long             _totalCap;
  87. };
  88.  
  89.  
  90.  
  91. //                                                                     
  92. // ------------------------ Creation and destruction --------------    
  93. //
  94.  
  95.  
  96. template <class BaseType>
  97. CL_Sequence<BaseType>::CL_Sequence (long initial_size,
  98.                                     CL_ObjectIOFilter* bld)
  99. {
  100.     _idata = new SegmentedSequence (initial_size);
  101.     if (_idata)
  102.         _size = initial_size;
  103.     else
  104.         _size = 0;
  105.     if (_idata) {
  106.         SegmentedSequence& _data = (* (SegmentedSequence*) _idata);
  107.         BaseType p = CL_Basics<BaseType>::NullValue ();
  108.         for (long i = 0; i < _size; i++)
  109.             _data[i] = CL_Basics<BaseType>::MakeCopy (p);
  110.     }
  111.     _builder = bld;
  112. }
  113.  
  114.  
  115.  
  116.  
  117. template <class BaseType>
  118. CL_Sequence<BaseType>::CL_Sequence (const BaseType s[], long count,
  119.                                     CL_ObjectIOFilter* bld)
  120. {
  121.     _idata = new SegmentedSequence (count);
  122.     if (_idata)
  123.         _size = count;
  124.     else
  125.         _size = 0;
  126.     if (_idata) {
  127.         _size = count;
  128.         SegmentedSequence& _data = (* (SegmentedSequence*) _idata);
  129.         for (long i = 0; i < count; i++)
  130.             _data[i] = CL_Basics<BaseType>::MakeCopy (s[i]);
  131.     }
  132.     else
  133.         _size = 0;
  134.     _builder = bld;
  135. }
  136.  
  137.  
  138. // Copy constructor
  139. template <class BaseType>
  140. CL_Sequence<BaseType>::CL_Sequence (const CL_Sequence<BaseType>& a)
  141. {
  142.     _size = 0;
  143.     _idata = new SegmentedSequence;
  144.     if (_idata)
  145.         *this = a;
  146.     _builder = a._builder;
  147. }
  148.  
  149.  
  150.  
  151.  
  152.  
  153.  
  154. //
  155. // ------------------------ Element access ---------------------------
  156.  
  157. template <class BaseType>
  158. long CL_Sequence<BaseType>::Add (const BaseType& o)
  159. {
  160.     long pos = Size()-1;
  161.     return Insert (o, pos) ? pos+1 : -1;
  162. }
  163.  
  164.  
  165. template <class BaseType>
  166. bool CL_Sequence<BaseType>::Insert (const BaseType& o, long i)
  167. {
  168.     if (!PrepareToChange() ||  !_DoInsert (o, i))
  169.         return FALSE;
  170.     Notify ();
  171.     return TRUE;
  172. }
  173.             
  174.  
  175. template <class BaseType>
  176. BaseType& CL_Sequence<BaseType>::operator[] (long index) const
  177. {
  178.     if (!_idata) {
  179.         static BaseType junk;
  180.         junk = CL_Basics<BaseType>::NullValue ();
  181.         // This code better not be executed under BC++ 3.1: that compiler
  182.         // seems to have a bug that generates bad code for static local
  183.         // template objects, causing a program crash.
  184.         return junk;
  185.     }
  186.     if (index < 0 ||  index >= _size) {
  187.         CL_Error::Warning ("CL_Sequence::op[]: index %ld"
  188.                            " out of range 0..%ld", index, _size-1);
  189.         static BaseType junk;
  190.         junk = CL_Basics<BaseType>::NullValue ();
  191.         // This code better not be executed under BC++ 3.1: that compiler
  192.         // seems to have a bug that generates bad code for static local
  193.         // template objects, causing a program crash.
  194.         return junk;
  195.     }
  196.     SegmentedSequence& _data = (* (SegmentedSequence*) _idata);
  197.     return CL_Basics<BaseType>::Deref (_data[index]);
  198. }
  199.  
  200.  
  201.  
  202. template <class BaseType>
  203. short CL_Sequence<BaseType>::_Compare (const BaseType& o1,
  204.                                        const BaseType& o2) const
  205. {
  206.     return CL_Basics<BaseType>::Compare (o1, o2);
  207. }
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215. template <class BaseType>
  216. short CL_Sequence<BaseType>::_DoInsert (const BaseType& o, long i)
  217. {
  218.     if (i < -1 || i >= _size)
  219.         return FALSE;
  220.     if (!_idata) {
  221.         return FALSE;
  222.     }
  223.     SegmentedSequence& _data = (* (SegmentedSequence*) _idata);
  224.     if (i == _size-1) {
  225.         if (!_data.ResizeTo (_size+1))
  226.             return FALSE;
  227.         _data[i+1] = CL_Basics<BaseType>::MakeCopy (o);
  228.         _size++;
  229.     }
  230.     else {
  231.         if (!_ShiftRightAt (i+1, 1))
  232.             return FALSE;
  233.         (*this)[i+1] = o;
  234.     }
  235.     return TRUE;
  236. }
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244. template <class BaseType>
  245. long CL_Sequence<BaseType>::InsertByRank (const BaseType& o)
  246. {
  247.     if (!_idata || !PrepareToChange())
  248.         return FALSE;
  249.     register long i;
  250.     register long n = Size();
  251.     for (i = 0; i < n; i++)
  252.         if (CL_Basics<BaseType>::Compare ((*this)[i], o) >= 0)
  253.             break;
  254.     if (_DoInsert (o, i)) {
  255.         Notify();
  256.         return i;
  257.     }
  258.     return -1;
  259. }
  260.  
  261.  
  262.  
  263. template <class BaseType>
  264. BaseType CL_Sequence<BaseType>::Remove (long i)
  265. {
  266.     if (!PrepareToChange() || !_idata || _size <= 0 || i < 0 || i >= _size)
  267.         return CL_Basics<BaseType>::NullValue();
  268.     BaseType r = (*this)[i];
  269.     if (_ShiftLeftAt (i+1, 1)) {
  270.         Notify ();
  271.         return r;
  272.     }
  273.     return CL_Basics<BaseType>::NullValue();
  274. }
  275.  
  276.  
  277. template <class BaseType>
  278. BaseType CL_Sequence<BaseType>::ExtractLeftmost ()
  279. {
  280.     if (!_idata || _size <= 0 || !PrepareToChange())
  281.         return CL_Basics<BaseType>::NullValue ();
  282.     BaseType p = (*this)[0];
  283.     _ShiftLeftAt (1,1);
  284.     Notify ();
  285.     return p;
  286. }
  287.  
  288. template <class BaseType>
  289. BaseType CL_Sequence<BaseType>::ExtractRightmost ()
  290. {
  291.     BaseType p;
  292.     if (!_idata || _size <= 0 || !PrepareToChange())
  293.         return CL_Basics<BaseType>::NullValue ();
  294.     SegmentedSequence& _data = (* (SegmentedSequence*) _idata);
  295.     p = (*this)[_size-1];
  296.     CL_Basics<BaseType>::Destroy (_data[_size-1]);
  297.     _size--;
  298.     _data.ResizeTo (_size);
  299.     Notify ();
  300.     return p;
  301. }
  302.  
  303.  
  304.  
  305.  
  306. // ------------------- Sequence methods ------------------------
  307.  
  308. template <class BaseType>
  309. bool CL_Sequence<BaseType>::ShiftRightAt (long pos, long amount)
  310. {
  311.     if (!PrepareToChange ())
  312.         return FALSE;
  313.     if (!_ShiftRightAt (pos, amount))
  314.         return FALSE;
  315.     Notify();
  316.     return TRUE;
  317. }
  318.  
  319.  
  320.  
  321.  
  322. template <class BaseType>
  323. bool CL_Sequence<BaseType>::_ShiftRightAt (long pos, long amount)
  324. {
  325.     if (pos < 0 || pos > _size || amount < 0)
  326.         return FALSE;
  327.     if (!_idata) {
  328.         return FALSE;
  329.     }
  330.     SegmentedSequence& _data = (* (SegmentedSequence*) _idata);
  331.     if (!_data.ResizeTo (_size + amount))
  332.         return FALSE;
  333.     long i;
  334.     for (i = _size + amount - 1; i > pos; i--)
  335.         _data[i] = _data [i-amount];
  336.     BaseType p = CL_Basics<BaseType>::NullValue ();
  337.     for (i = pos; i < pos + amount; i++) {
  338.         _data[i] = CL_Basics<BaseType>::MakeCopy (p);
  339.     }
  340.     _size += amount;
  341.     return TRUE;
  342. }
  343.  
  344.  
  345.  
  346. template <class BaseType>
  347. void CL_Sequence<BaseType>::operator= (const CL_Object& o)
  348. {
  349.     if (CheckClassType (o, "CL_Sequence::op="))
  350.         *this = ((const CL_Sequence<BaseType>&) o);
  351. }
  352.  
  353. template <class BaseType>
  354. CL_Sequence<BaseType>& CL_Sequence<BaseType>::operator=
  355.     (const CL_Sequence<BaseType>& a)
  356. {
  357.     if (this == &a || !PrepareToChange())
  358.         return *this; // Do nothing
  359.     long i;
  360.     
  361.     if (!_idata)
  362.         return *this;
  363.     SegmentedSequence& _data = (* (SegmentedSequence*) _idata);
  364.     for (i = 0; i < _size; i++)
  365.         CL_Basics<BaseType>::Destroy (_data[i]);
  366.     if (!_data.ResizeTo (a.Size()))
  367.         return *this;
  368.     _size = a.Size();
  369.     for (i = 0; i < _size; i++) {
  370.         _data[i] = CL_Basics<BaseType>::MakeCopy (a[i]);
  371.     }
  372.     Notify ();
  373.     return *this;
  374. }
  375.  
  376.  
  377.  
  378. template <class BaseType>
  379. CL_Sequence<BaseType>& CL_Sequence<BaseType>::operator +=
  380.     (const CL_Sequence<BaseType>& a)
  381. {
  382.     if (!_idata) {
  383.         return *this;
  384.     }
  385.     if (!PrepareToChange())
  386.         return *this;
  387.     SegmentedSequence& _data = (* (SegmentedSequence*) _idata);
  388.     if (!_data.ResizeTo (_size + a._size))
  389.         return *this;
  390.     long old_size = _size;
  391.     _size += a._size;
  392.     register long n = a._size; 
  393.     for (long i = 0; i < n; i++) {
  394.         _data [old_size + i] = CL_Basics<BaseType>::MakeCopy (a[i]);
  395.     }
  396.     Notify ();
  397.     return *this;
  398. }
  399.  
  400.  
  401.  
  402. #ifndef __GNUC__
  403. template <class BaseType>
  404. CL_Sequence<BaseType> CL_Sequence<BaseType>::Subsequence
  405.     (const CL_IntegerSet& s) const
  406. {
  407.     register long m = Size();
  408.     CL_Sequence<BaseType> retVal;
  409.     // Note that we cannot declare retVal to be of a particular size,
  410.     // because we don't know how many elements of s represent legal
  411.     // indices in this sequence. Well, maybe we could do something like
  412.     //     CL_IntegerSet t (0, Size()-1); t *= s;
  413.     // and then use t's size to be the initial size of retVal. But that
  414.     // will likely not save much of the overhead incurred by expanding
  415.     // retVal if it weren't pre-sized.
  416.     for (long i = 0; i < m; i++)
  417.         if (s.Includes (i)) {
  418.             retVal.Add ((*this)[i]);
  419.         }
  420.     return retVal;
  421. }
  422.  
  423.  
  424. template <class BaseType>
  425. CL_Sequence<BaseType> CL_Sequence<BaseType>::operator-
  426.     (const CL_IntegerSet& s) const
  427. {
  428.     CL_IntegerSet t (0, Size()-1);
  429.     return Subsequence (t-s);
  430. }
  431.  
  432. template <class BaseType>
  433. void CL_Sequence<BaseType>::operator-= (const CL_IntegerSet& s)
  434. {
  435.     register long m = Size();
  436.     register long n = s.Size();
  437.     register long current = s.ItemWithRank (0);
  438.     register long next = current;
  439.     if (n <= 0 || current < 0 || current >= Size())
  440.         return;
  441.     if (!_idata)
  442.         return; // No memory
  443.     SegmentedSequence& _data = (* (SegmentedSequence*) _idata);
  444.     for (register long i = 0; i < n && next < m; i++) {
  445.         next = minl (m, s.ItemWithRank (i+1));
  446.         for (register long j = current; j < next; j++) {
  447.             CL_Basics<BaseType>::Destroy (_data[j]);
  448.             _data[j-i+1] = _data[j];
  449.         }
  450.     }
  451. }
  452.  
  453.  
  454. #endif // __GNUC__
  455.  
  456.  
  457. template <class BaseType>
  458. void CL_Sequence<BaseType>::MakeEmpty ()
  459. {
  460.     if (!_idata) {
  461.         return;
  462.     }
  463.     if (!PrepareToChange())
  464.         return;
  465.     _DoMakeEmpty ();
  466.     Notify ();
  467. }
  468.  
  469. template <class BaseType>
  470. void CL_Sequence<BaseType>::_DoMakeEmpty ()
  471. {
  472.     SegmentedSequence& _data = (* (SegmentedSequence*) _idata);
  473.     for (long i = 0; i < _size; i++)
  474.         CL_Basics<BaseType>::Destroy (_data[i]);
  475.     _size = 0;
  476.     _data.ResizeTo (0);
  477. }
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484. template <class BaseType>
  485. bool CL_Sequence<BaseType>::ChangeSize (long new_size)
  486. {
  487.     if (!PrepareToChange ())
  488.         return FALSE;
  489.     if (!_idata) {
  490.         return FALSE;
  491.     }
  492.     if (new_size == _size)
  493.         return TRUE;
  494.     SegmentedSequence& _data = (* (SegmentedSequence*) _idata);
  495.     if (new_size < _size) {
  496.         for (register long i = new_size; i < _size; i++)
  497.             CL_Basics<BaseType>::Destroy (_data[i]);
  498.     }
  499.     if (!_data.ResizeTo (new_size))
  500.         return FALSE;
  501.     if (new_size > _size)  {
  502.         BaseType nul = CL_Basics<BaseType>::NullValue ();
  503.         for (register long i = _size; i < new_size; i++)
  504.             _data[i] = CL_Basics<BaseType>::MakeCopy (nul);
  505.     }
  506.     _size = new_size;
  507.     Notify();
  508.     return TRUE;
  509. }
  510.  
  511.  
  512.  
  513.  
  514.  
  515.  
  516.  
  517.  
  518. template <class BaseType>
  519. bool CL_Sequence<BaseType>::ShiftLeftAt (long pos, long amount)
  520. {
  521.     if (!PrepareToChange ())
  522.         return FALSE;
  523.     if (!_ShiftLeftAt (pos, amount))
  524.         return FALSE;
  525.     Notify();
  526.     return TRUE;
  527. }
  528.  
  529.  
  530.  
  531. template <class BaseType>
  532. bool CL_Sequence<BaseType>::_ShiftLeftAt (long pos, long amount)
  533. {
  534.     if (!_idata || pos < 1 || pos > _size || amount > pos)
  535.         return FALSE;
  536.     SegmentedSequence& _data = (* (SegmentedSequence*) _idata);
  537.     long i;
  538.     for (i = pos-amount; i < pos; i++)
  539.         CL_Basics<BaseType>::Destroy (_data[i]);
  540.     for (i = pos; i < _size; i++) {
  541.         _data[i-amount] = _data[i];
  542.     }
  543.     for (i = _size-amount; i < _size; i++)
  544.         _data[i] = NULL;
  545.     _size -= amount;
  546.     _data.ResizeTo (_size);
  547.     return TRUE;
  548. }
  549.  
  550.  
  551. template <class BaseType>
  552. bool CL_Sequence<BaseType>::IsSorted () const
  553. {
  554.     long i;
  555.     for (i = 0; i < _size; i++)
  556.         if (_Compare ((*this)[i], (*this)[i+1]) > 0)
  557.             return FALSE;
  558.     return TRUE;
  559. }
  560.  
  561.  
  562.  
  563.  
  564.  
  565. template <class BaseType>
  566. bool CL_Sequence<BaseType>::Sort (long pos, long len)
  567. {
  568.     if (!_idata || !PrepareToChange())
  569.         return FALSE;
  570.     if (pos < 0 || pos >= _size)
  571.         return FALSE;
  572.     if (_QuickSort (pos, minl (pos + len - 1, _size - 1))) {
  573.         Notify ();
  574.         return TRUE;
  575.     }
  576.     return FALSE;
  577. }
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584. template <class BaseType>
  585. long CL_Sequence<BaseType>::LinearSearch (const BaseType& o) const
  586. {
  587.     if (!_idata || _size == 0)
  588.         return -1;
  589.     long i;
  590.     short result;
  591.     for (i = 0; i < _size; i++) {
  592.         result = _Compare ((*this)[i], o);
  593.         if (result == 0)
  594.             return i;
  595.     }
  596.     return -1;
  597. }
  598.  
  599.  
  600.  
  601. template <class BaseType>
  602. bool CL_Sequence<BaseType>::BinarySearch (const BaseType& o, long& index) const
  603. {
  604.     if (!_idata)
  605.         return FALSE;
  606.     long i;
  607.     short result;
  608.     if (_size <= 7) { // Small number of keys, do a linear search
  609.         if (_size == 0) {
  610.             index = -1;
  611.             return FALSE;
  612.         }
  613.         for (i = 0; i < _size; i++) {
  614.             result = _Compare ((*this)[i], o);
  615.             if (result >= 0)
  616.                 break;
  617.         }
  618.         if (result == 0) {
  619.             index = i;
  620.             return TRUE;
  621.         }
  622.         else  {
  623.             index = i-1;
  624.             return FALSE;
  625.         }
  626.     }
  627.  
  628.     // Do a binary search
  629.     long lo = 0, hi = _size-1, mid;
  630.     while (lo <= hi) {
  631.         mid = (lo + hi)/2;
  632.         result = _Compare ((*this)[mid], o);
  633.         if (result == 0) {
  634.             index = mid;
  635.             return TRUE;
  636.         }
  637.         if (result < 0)
  638.             lo = mid+1;
  639.         else
  640.             hi = mid-1;
  641.     }
  642.     index = (result <= 0) ? (mid) :  mid-1;
  643.     return FALSE;
  644. }
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652. // #include <stdlib.h>
  653.  
  654. template <class BaseType>
  655. bool CL_Sequence<BaseType>::_QuickSort (long left, long right)
  656. {
  657.     if (!_idata) {
  658.         return FALSE;
  659.     }
  660.     SegmentedSequence& _data = (* (SegmentedSequence*) _idata);
  661.  
  662.     // The sort code is basically stolen from Bentley's "Programming
  663.     // Pearls" book.
  664.     long i;
  665.  
  666.     for (i = left; i < right; i++) // Scan to see if already sorted
  667.         if (_Compare ((*this)[i], (*this)[i+1]) > 0)
  668.             break;
  669.     if (i >= right) // It's already sorted
  670.         return FALSE;
  671.  
  672.     while (left < right) {
  673.         CL_VoidPtr tmp;
  674.         long r, m;
  675.         // r = random (right - left - 1) + left + 1;
  676.         r = left + 1;
  677.  
  678.         tmp         = _data[r];
  679.         _data[r]    = _data[left];
  680.         _data[left] = (CL_VoidPtr) tmp;
  681.  
  682.         m = left;
  683.         for (i = left+1; i <= right; i++) {
  684.             if (_Compare ((*this)[i], (*this)[left])
  685.                 < 0) {
  686.                 m ++;
  687.                 tmp      = _data[m];
  688.                 _data[m] = _data[i];
  689.                 _data[i] = tmp;
  690.             }
  691.         }
  692.         tmp         = _data[m];
  693.         _data[m]    = _data[left];
  694.         _data[left] = tmp;
  695.  
  696.         // Now recurse on the smaller half, and loop back for the
  697.         // bigger half so as to minimize stack depth
  698.         if (m-left < right-m) {
  699.             _QuickSort (left, m-1);
  700.             left = m+1;
  701.         }
  702.         else {
  703.             _QuickSort (m+1, right);
  704.             right = m-1;
  705.         }
  706.     }
  707.     return TRUE;
  708. }
  709.  
  710.  
  711.  
  712.  
  713.  
  714.  
  715. template <class BaseType>
  716. long CL_Sequence<BaseType>::StorableFormWidth () const
  717. {
  718.     if (!_idata) {
  719.         return 0;
  720.     }
  721.     SegmentedSequence& _data = (* (SegmentedSequence*) _idata);
  722.     long l = 0;
  723.     for (long i = 0; i < _size; i++)
  724.         l += CL_Basics<BaseType>::StoreWidth
  725.             (CL_Basics<BaseType>::Deref (_data [i]));
  726.     return l + (sizeof _size) + sizeof (CL_ClassId);
  727. }
  728.  
  729.  
  730.  
  731.  
  732. template <class BaseType>
  733. bool CL_Sequence<BaseType>::ReadFrom (const CL_Stream& s)
  734. {
  735.     if (!_idata) {
  736.         return FALSE;
  737.     }
  738.     if (!PrepareToChange() || !ReadClassId (s) )
  739.         return FALSE;
  740.     SegmentedSequence& _data = (* (SegmentedSequence*) _idata);
  741.     long size;
  742.     if (!s.Read (size))
  743.         return FALSE;
  744.     for (long i = 0; i < _size; i++)
  745.         CL_Basics<BaseType>::Destroy (_data[i]);
  746.     if (!_data.ResizeTo (size))
  747.         return FALSE;
  748.     _size = size;
  749.     BaseType nul = CL_Basics<BaseType>::NullValue ();
  750.     for (i = 0; i < _size; i++) {
  751.         _data[i] = CL_Basics<BaseType>::MakeCopy (nul);
  752.         if (!_ReadElement (s, i))
  753.             return FALSE;
  754.     }
  755.     Notify();
  756.     return TRUE;
  757. };
  758.         
  759.  
  760. template <class BaseType>
  761. bool CL_Sequence<BaseType>::_ReadElement (const CL_Stream& s, long i)
  762. {
  763.     return CL_RestoreFrom ((*this)[i], s, _builder);
  764. }
  765.  
  766.  
  767.  
  768.  
  769.  
  770. template <class BaseType>
  771. bool CL_Sequence<BaseType>::WriteTo (CL_Stream& s) const
  772. {
  773.     if (!_idata) {
  774.         return FALSE;
  775.     }
  776.     if (!s.Write (ClassId())  || !s.Write (_size))
  777.         return FALSE;
  778.     for (long i = 0; i < _size; i++) {
  779.         if (!_WriteElement (s, i))
  780.             return FALSE;
  781.     }
  782.     return TRUE;
  783. }
  784.  
  785.  
  786. template <class BaseType>
  787. bool CL_Sequence<BaseType>::_WriteElement (CL_Stream& s, long i) const
  788. {
  789.     return CL_SaveTo ((*this)[i], s, _builder);
  790. }
  791.  
  792.  
  793.  
  794.  
  795. template <class BaseType>
  796. CL_Sequence<BaseType>::~CL_Sequence ()
  797. {
  798.     _DoMakeEmpty ();
  799.     if (_idata)
  800.         delete (SegmentedSequence*) _idata;
  801. }
  802.  
  803.  
  804.  
  805.  
  806.  
  807.  
  808. //
  809. //------------------------------------------------------------
  810. //
  811.  
  812. // CL_SequenceIterator methods
  813.  
  814.  
  815. template <class BaseType>
  816. CL_SequenceIterator<BaseType>::CL_SequenceIterator
  817.     (const CL_Sequence<BaseType>& o)
  818. :_seq (o) 
  819. {
  820.     _index = 0;
  821. }
  822.  
  823.  
  824.  
  825. /*----------------------------------------------------------------------- */
  826.  
  827. template <class BaseType>
  828. CL_SequenceIterator<BaseType>::CL_SequenceIterator
  829.     (const CL_SequenceIterator<BaseType>& s)
  830.     :_seq (s._seq), _index (s._index)
  831. {
  832. }
  833.  
  834.  
  835.  
  836. /*----------------------------------------------------------------------- */
  837.  
  838. template <class BaseType>
  839. void CL_SequenceIterator<BaseType>::Reset ()
  840. {   
  841.     _index = 0;
  842. }
  843.  
  844.  
  845. /*----------------------------------------------------------------------- */
  846.  
  847. template <class BaseType>
  848. const BaseType& CL_SequenceIterator<BaseType>::Next ()
  849. {
  850.     return _seq[_index++];
  851. }
  852.  
  853.  
  854.  
  855. /*----------------------------------------------------------------------- */
  856.  
  857. template <class BaseType>
  858. bool CL_SequenceIterator<BaseType>::More ()
  859. {
  860.     return _index < _seq.Size();
  861. }
  862.  
  863.  
  864.  
  865.  
  866.  
  867.  
  868.  
  869.  
  870. #endif   /* _seqimp_cxx */
  871.  
  872.