home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ocl150a.zip / OCL / Source / OCollection.cpp < prev    next >
C/C++ Source or Header  |  1996-08-12  |  7KB  |  421 lines

  1. // OCL - OS/2 Class Library
  2. // (c) Cubus 1995
  3. // All Rights Reserved
  4. // OCollection.cpp
  5.  
  6. /*
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 2. Neither the name Cubus nor the name Team OCL may be used to
  13.  *    endorse or promote products derived from this software
  14.  *    without specific prior written permission.
  15.  * 3. See OCL.INF for a detailed copyright notice.
  16.  *
  17.  *              THIS SOFTWARE IS PROVIDED ``AS IS'' AND
  18.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  21.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27.  * SUCH DAMAGE.
  28.  */
  29.  
  30.  
  31. // $Header: W:/Projects/OCL/Source/rcs/OCollection.cpp 1.50 1996/08/11 23:49:11 B.STEIN Release $
  32.  
  33. #define __OCL_SOURCE__
  34.  
  35. #define OINCL_OSTRING
  36. #define OINCL_BASE
  37.  
  38. #include <ocl.hpp>
  39. #include <OCollection.hpp>
  40.  
  41. #if defined (__EMX__)
  42.   template class OListItem<void>;
  43. #endif
  44.  
  45.  
  46. OCollection::OCollection(BOOL copyElements) 
  47.   : copyFlag(copyElements),
  48.     items(0), 
  49.     actual(NULL), 
  50.     first(NULL), 
  51.     last(NULL) 
  52.   {}
  53.  
  54.  
  55. OCollection::~OCollection()
  56. {
  57.  if (copyFlag)
  58.    reset();
  59.  else
  60.    init();
  61. #ifdef __IBMCPP__ 
  62.    _heapmin();  // return all unused memory to OS/2
  63. #endif
  64. }
  65.  
  66.  
  67. PSZ OCollection::isOfType() const
  68.  return("OListBase"); 
  69. }
  70.  
  71.  
  72. BOOL OCollection::isCopyCollection() const
  73. {
  74.  return(copyFlag);
  75. }
  76.  
  77.  
  78. ULONG OCollection::numberOfElements() const
  79. {
  80.  return(items);
  81. }
  82.  
  83.  
  84. BOOL OCollection::isEmpty() const
  85. {
  86.  return(first == NULL);
  87. }
  88.  
  89.  
  90. void OCollection::rewind()
  91. {
  92.  actual = first;
  93. }
  94.  
  95.  
  96. void OCollection::init()
  97. {
  98.  if (first)
  99.   {
  100.    PPVITEM tmp = last->prev;
  101.    while(tmp)
  102.     {
  103.      delete tmp->next;
  104.      tmp = tmp->prev;
  105.     }
  106.    delete first;
  107.   }
  108.  items = 0;
  109.  actual = first = last = NULL;
  110. }
  111.  
  112.  
  113. void OCollection::reset()
  114. {
  115.  if (first)
  116.   {
  117.    PPVITEM tmp = last->prev;
  118.  
  119.    while(tmp)
  120.     {
  121.      freeItem(tmp->next->item);
  122.      delete tmp->next;
  123.      tmp = tmp->prev;
  124.     }
  125.    freeItem(first->item);
  126.    delete first;
  127.   }
  128.  items = 0;
  129.  actual = first = last = NULL;
  130. }
  131.  
  132.  
  133.  
  134. void OCollection::addFirst(PVOID elem)
  135. {
  136.  PPVITEM aNew;
  137.  
  138.  if (!elem) return;
  139.  
  140.  aNew = new PVITEM;
  141.  aNew->next = first;
  142.  aNew->item = elem;
  143.  
  144.  if (first)
  145.    first->prev = aNew;
  146.  else
  147.    last = aNew;
  148.  
  149.  first = aNew;
  150.  items++;
  151. }
  152.  
  153.  
  154. void OCollection::addLast(PVOID elem)
  155. {
  156.  PPVITEM aNew;
  157.  
  158.  if (!elem) return;
  159.  
  160.  aNew = new PVITEM;
  161.  
  162.  if (!first)
  163.   {
  164.    aNew->item = elem;
  165.    first = actual = aNew;
  166.   }
  167.  else
  168.   {
  169.    aNew->item = elem;
  170.    aNew->prev = last;
  171.    last->next = aNew;
  172.   }
  173.  last = aNew;
  174.  items++;
  175. }
  176.  
  177.  
  178.  
  179. void OCollection::addAfter(PVOID previous, PVOID elem)
  180. {
  181.  PPVITEM tmp = first;
  182.  
  183.  if (!elem) return;
  184.  
  185.  if ((!previous) || (!first))
  186.   {
  187.    addFirst(elem);
  188.    return;
  189.   }
  190.  
  191.  while((tmp) && (tmp->item != previous))
  192.    tmp = tmp->next;
  193.  
  194.  if (tmp)
  195.    addAfter(tmp, elem);
  196.  else
  197.    addLast(elem);
  198. }
  199.  
  200.  
  201. void OCollection::addAfter(PPVITEM previous, PVOID elem)
  202. {
  203.  PPVITEM aNew;
  204.  
  205.  if (!elem) return;
  206.  
  207.  if (!previous)
  208.   {
  209.    addFirst(elem);
  210.    return;
  211.   }
  212.  
  213.  if (!previous->next)
  214.   {
  215.    addLast(elem);
  216.    return;
  217.   }
  218.  
  219.  aNew = new PVITEM;
  220.  
  221.  aNew->next = previous->next;
  222.  aNew->prev = previous;
  223.  aNew->item = elem;
  224.  
  225.  previous->next->prev = aNew;
  226.  previous->next = aNew;
  227.  
  228.  items++;
  229. }
  230.  
  231.  
  232.  
  233. PVOID OCollection::_getFirst()
  234. {
  235.  if (first)
  236.   {
  237.    rewind();
  238.    return(first->item);
  239.   }
  240.  return(NULL);
  241. }
  242.  
  243.  
  244.  
  245. PVOID OCollection::_getLast()
  246. {
  247.  if (first)
  248.   {
  249.    actual = last;
  250.    return(last->item);
  251.   }
  252.  return(NULL);
  253. }
  254.  
  255.  
  256.  
  257. PVOID OCollection::_getNext()
  258. {
  259.  if (!first)
  260.    return(NULL);
  261.  else if (actual->next)
  262.   {
  263.    actual = actual->next;
  264.    if (actual)
  265.      return(actual->item);
  266.    else
  267.      return(NULL);
  268.   }
  269.  else
  270.    return(NULL);
  271. }
  272.  
  273.  
  274.  
  275.  
  276. PVOID OCollection::_getPrev()
  277. {
  278.  if (!first)
  279.    return(NULL);
  280.  else if (actual->prev)
  281.   {
  282.    actual = actual->prev;
  283.    if (actual)
  284.      return(actual->item);
  285.    else
  286.      return(NULL);
  287.   }
  288.  else
  289.    return(NULL);
  290. }
  291.  
  292.  
  293. PVOID OCollection::_getItem(ULONG itemNum)
  294. {
  295.  ULONG i;
  296.  PVOID tmp;
  297.  
  298.  if ((!first) || (itemNum < 1))
  299.    return(NULL);
  300.  if (itemNum == 1)
  301.    return(first->item);
  302.  tmp = _getFirst();
  303.  for (i=2; ((i <= itemNum) && (tmp)); i++)
  304.    tmp = _getNext();
  305.  return(tmp);
  306. }
  307.  
  308.  
  309. PVOID OCollection::_getNext(PVOID elem)
  310. {
  311.  PPVITEM tmp = first;
  312.  
  313.  if (!elem) return(NULL);
  314.  
  315.  while((tmp) && (tmp->item != elem))
  316.    tmp = tmp->next;
  317.  
  318.  if (!tmp)
  319.    return(NULL);
  320.  else
  321.    return(tmp->item);
  322. }
  323.  
  324.  
  325.  
  326. PVOID OCollection::_getPrev(PVOID elem)
  327. {
  328.  PPVITEM tmp = last;
  329.  
  330.  if (!elem) return(NULL);
  331.  
  332.  while((tmp) && (tmp->item != elem))
  333.     tmp = tmp->prev;
  334.  
  335.  if (!tmp)
  336.    return(NULL);
  337.  else
  338.    return(tmp->item);
  339. }
  340.  
  341.  
  342.  
  343. PPVITEM OCollection::_getPrevListItem(PVOID elem)
  344. {
  345.  PPVITEM tmp = last;
  346.  
  347.  if (!elem) return(NULL);
  348.  
  349.  while((tmp) && (tmp->item != elem))
  350.    tmp = tmp->prev;
  351.  
  352.  return(tmp);
  353. }
  354.  
  355.  
  356. PPVITEM OCollection::_getNextListItem(PVOID elem)
  357. {
  358.  PPVITEM tmp = first;
  359.  
  360.  if (!elem) return(NULL);
  361.  
  362.  while((tmp) && (tmp->item != elem))
  363.    tmp = tmp->next;
  364.  
  365.  return(tmp);
  366. }
  367.  
  368.  
  369. void OCollection::remove(PVOID elem)
  370. {
  371.  PPVITEM tmp = first;
  372.  
  373.  if (!elem) return;
  374.  
  375.  while(tmp)
  376.   {
  377.    if ((tmp->item) && (tmp->item == elem))
  378.     {
  379.      if (tmp->prev)
  380.        tmp->prev->next = tmp->next;
  381.      else
  382.        first = tmp->next;
  383.      if (tmp->next)
  384.        tmp->next->prev = tmp->prev;
  385.      else
  386.        last = tmp->prev;
  387.      if (tmp == actual)
  388.       {
  389.        if (tmp->prev)
  390.          actual = tmp->prev;
  391.        else if (tmp->next)
  392.          actual = tmp->next;
  393.       }
  394.      --items;
  395.      tmp->item = NULL;
  396.      if ((!tmp->prev) && (!tmp->next))
  397.        init();
  398.      else
  399.       {
  400.        delete tmp;
  401.        tmp = NULL;
  402.        return;
  403.       }
  404.     }
  405.    tmp = tmp->next;
  406.   }
  407. }
  408.  
  409.  
  410. void OCollection::del(PVOID elem)
  411. {
  412.  if ((first) && (elem))
  413.   {
  414.    remove(elem);
  415.    freeItem(elem);
  416.   }
  417. }
  418.  
  419. // end of source
  420.