home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mandlcpp.zip / chain.cpp < prev    next >
C/C++ Source or Header  |  1993-06-26  |  8KB  |  375 lines

  1. extern "C"
  2. {
  3. #include <stdlib.h>
  4. };
  5.  
  6.  
  7. #include "chain.h"
  8. #ifdef INCLUDESOURCE
  9. #include "object.cc"
  10. #endif
  11.  
  12.  
  13. chain::chain(void):mtxObject()
  14. {    pFirst = pLast = (chainElement*)0;
  15.     iNumberOfElements = 0;
  16. }
  17.  
  18.  
  19. chain::~chain(void)
  20. {       foreach(idForeachChainElementDestruct, (void*)0);
  21. }
  22.  
  23.  
  24. int chain::foreach(unsigned int iMsg, void *pDummy)
  25. {    chainElement *pScan, *pSucc;
  26.     int ret;
  27.  
  28.     getMutualExclusiveAccess();
  29.     for ((pScan = pFirst) ? (pSucc = pScan->pSucc)
  30.         : (pSucc = (chainElement*)0);
  31.         pScan;
  32.         (pScan = pSucc) ? (pSucc = pSucc->pSucc)
  33.         : (pSucc = (chainElement*)0))
  34.         if (ret = pScan->toBeCalledForeachElement(iMsg, pDummy))
  35.         {    freeMutualExclusiveAccess();
  36.             return ret;
  37.         }
  38.     freeMutualExclusiveAccess();
  39.     return 0;
  40. }
  41.  
  42.  
  43. /*
  44. BubbleSort
  45. */
  46. void chain::bubbleSort(unsigned int iMsg)
  47. {    Boolean bSorted;
  48.     unsigned int iIndex, iMax;
  49.  
  50.     getMutualExclusiveAccess();
  51. #ifdef DEBUG
  52.     if (pFirst)
  53.         pFirst->checkConsistence();
  54.     else
  55.         assert(!iNumberOfElements);
  56. #endif
  57.     for (iMax = iNumberOfElements, bSorted = TRUE;
  58.         iMax > 1;
  59.         iMax--, bSorted = TRUE)
  60.     {    chainElement *pScan;
  61.  
  62.         for (pScan = pFirst, iIndex = 1;
  63.             iIndex < iMax;
  64.             pScan = pScan->pSucc, iIndex++)
  65.             if (!pScan->laterThenThis(pScan->pSucc, iMsg))
  66.             {    pScan->exchange(pScan->pSucc);
  67.                 pScan = pScan->pPrev;
  68.                 bSorted = FALSE;
  69.             }
  70.         if (bSorted)
  71.             break;
  72.     }
  73. #ifdef DEBUG
  74.     if (pFirst)
  75.         pFirst->checkConsistence();
  76.     else
  77.         assert(!iNumberOfElements);
  78. #endif
  79.     freeMutualExclusiveAccess();
  80. }
  81.  
  82.  
  83. void chainElement::exchange(chainElement *pElement)
  84. {    chainElement *pHelp;
  85.  
  86.     assert(pParent);
  87.     assert(pElement->pParent);
  88.     getMutualExclusiveAccess();
  89.     pElement->getMutualExclusiveAccess();
  90. #ifdef DEBUG
  91.     pParent->pFirst->checkConsistence();
  92. #endif
  93.     if (this == pElement)
  94.         return;
  95.     if (pParent != pElement->pParent)
  96.     {    chain *pHelp;
  97.  
  98.         if (pParent->pFirst == this)
  99.             pParent->pFirst = pElement;
  100.         if (pParent->pLast == this)
  101.             pParent->pLast = pElement;
  102.         if (pElement->pParent->pFirst == pElement)
  103.             pElement->pParent->pFirst = this;
  104.         if (pElement->pParent->pLast == pElement)
  105.             pElement->pParent->pLast = this;
  106.         pHelp = pParent;
  107.         pParent = pElement->pParent;
  108.         pElement->pParent = pHelp;
  109.     }
  110.     else
  111.     {    if (pParent->pFirst == this)
  112.             pParent->pFirst = pElement;
  113.         else
  114.             if (pParent->pFirst == pElement)
  115.                 pParent->pFirst = this;
  116.         if (pParent->pLast == this)
  117.             pParent->pLast = pElement;
  118.         else
  119.             if (pParent->pLast == pElement)
  120.                 pParent->pLast = this;
  121.     }
  122.     if (pPrev != pElement && pSucc != pElement)
  123.     {    pHelp = pPrev;
  124.         pPrev = pElement->pPrev;
  125.         pElement->pPrev = pHelp;
  126.         pHelp = pSucc;
  127.         pSucc = pElement->pSucc;
  128.         pElement->pSucc = pHelp;
  129. #ifdef DEBUG
  130.         pParent->pFirst->checkConsistence();
  131. #endif
  132.     }
  133.     else
  134.         if (pPrev == pElement)
  135.         {    pPrev = pElement->pPrev;
  136.             pElement->pSucc = pSucc;
  137.             pSucc = pElement;
  138.             pElement->pPrev = this;
  139.         }
  140.         else
  141.             if (pSucc == pElement)
  142.             {    pSucc = pElement->pSucc;
  143.                 pElement->pPrev = pPrev;
  144.                 pPrev = pElement;
  145.                 pElement->pSucc = this;
  146.             }
  147.     if (pSucc)
  148.         pSucc->pPrev = this;
  149.     if (pPrev)
  150.         pPrev->pSucc = this;
  151.     if (pElement->pSucc)
  152.         pElement->pSucc->pPrev = pElement;
  153.     if (pElement->pPrev)
  154.         pElement->pPrev->pSucc = pElement;
  155. #ifdef DEBUG
  156.     pParent->pFirst->checkConsistence();
  157. #endif
  158.     freeMutualExclusiveAccess();
  159.     pElement->freeMutualExclusiveAccess();}
  160.  
  161.  
  162. int chainElement::toBeCalledForeachElement(unsigned int iMsg, void *pDummy)
  163. {    switch (iMsg)
  164.     {    case idForeachChainElementDestruct:
  165.             delete this;
  166.             return 0;
  167.         case idForeachChainElementMove:
  168.             move((chain*)pDummy);
  169.             return 0;
  170.         default:
  171.             fprintf(stderr,
  172.                "Unknown Message Type (%u) to function \"chainElement::toBeCalledForeachElement\"\n",
  173.                iMsg);
  174.             abort();
  175.             return 0;
  176.     }
  177. }
  178.  
  179.  
  180. #ifdef undefined
  181. Boolean chainElement::isEqual(void *pDummy)
  182. {    (void)pDummy;
  183.  
  184.     abort();
  185.     return FALSE;
  186. }
  187. #endif
  188.  
  189.  
  190. chainElement::chainElement(void):mtxObject()
  191. {    pParent = (chain*)0;
  192.     pPrev = pSucc = (chainElement*)0;
  193. }
  194.  
  195.  
  196. void chainElement::insertSorted(chain *pParentNew, unsigned int iMsg)
  197. {    assert(!pParent);
  198.     assert(pParentNew);
  199.     pParent = pParentNew;
  200.     getMutualExclusiveAccess();
  201.     if (!pParentNew->pLast)
  202.     {    pParentNew->pFirst = pParentNew->pLast = this;
  203.         pPrev = pSucc = (chainElement*)0;
  204.     }
  205.     else
  206.     {    chainElement *pScan;
  207.  
  208.         for (pScan = pParent->pFirst; pScan; pScan = pScan->pSucc)
  209.             if (laterThenThis(pScan, iMsg))
  210.             {    pSucc = pScan;
  211.                 pPrev = pScan->pPrev;
  212.                 pScan->pPrev = this;
  213.                 if (pScan == pParent->pFirst)
  214.                     pParent->pFirst = pScan;
  215.                 break;
  216.             }
  217.         if (!pScan)
  218.         {    pPrev = pParent->pLast;
  219.             pParent->pLast->pSucc = this;
  220.             pParent->pLast = this;
  221.         }
  222.     }
  223.     pParent->iNumberOfElements++;
  224. #ifdef DEBUG
  225.     pParent->pFirst->checkConsistence();
  226. #endif
  227.     freeMutualExclusiveAccess();
  228. }
  229.  
  230.  
  231. chainElement::chainElement(chain *pParentNew):mtxObject()
  232. {    assert(!pPrev);
  233.     assert(!pSucc);
  234.     assert(!pParent);
  235.     if (!(pParent = pParentNew))
  236.     {    pPrev = pSucc = (chainElement*)0;
  237.         return;
  238.     }
  239.     else
  240.         getMutualExclusiveAccess();
  241.     if (!pParentNew->pLast)
  242.         pParentNew->pFirst = pParentNew->pLast = this;
  243.     else
  244.     {    pParentNew->pLast->pSucc = this;
  245.         pPrev = pParentNew->pLast;
  246.         pParentNew->pLast = this;
  247.     }
  248.     pParent->iNumberOfElements++;
  249. #ifdef DEBUG
  250.     pParent->pFirst->checkConsistence();
  251. #endif /* DEBUG */
  252.     freeMutualExclusiveAccess();
  253. }
  254.  
  255.  
  256. chainElement::~chainElement(void)
  257. {    if (!pParent)
  258.         return;
  259.     getMutualExclusiveAccess();
  260. #ifdef DEBUG    pParent->pFirst->checkConsistence();
  261. #endif /* DEBUG */
  262.     if (pPrev)
  263.         pPrev->pSucc = pSucc;
  264.     else
  265.         pParent->pFirst = pSucc;
  266.     if (pSucc)
  267.         pSucc->pPrev = pPrev;
  268.     else
  269.         pParent->pLast = pPrev;
  270.     pParent->iNumberOfElements--;
  271.     freeMutualExclusiveAccess();
  272. }
  273.  
  274.  
  275. void chainElement::move(chain *pChain)
  276. {    if (pParent == pChain)
  277.         return;
  278.  
  279.     getMutualExclusiveAccess();
  280.     if (pParent)
  281.     {    if (pPrev)
  282.             pPrev->pSucc = pSucc;
  283.         else
  284.             pParent->pFirst = pSucc;
  285.         if (pSucc)
  286.             pSucc->pPrev = pPrev;
  287.         else
  288.             pParent->pLast = pPrev;
  289.         pParent->iNumberOfElements--;
  290.         pParent->freeMutualExclusiveAccess();
  291.     }
  292.     if (pChain)
  293.     {    pParent = pChain;            // container
  294.         pParent->getMutualExclusiveAccess();
  295.         if (!pChain->pLast)
  296.         {    pChain->pFirst = pChain->pLast = this;
  297.             pPrev = pSucc = (chainElement*)0;
  298.         }
  299.         else
  300.         {
  301.             (pPrev = pChain->pLast)->pSucc = this;
  302.             pChain->pLast = this;
  303.             pSucc = (chainElement*)0;
  304.         }
  305.         pParent->iNumberOfElements++;
  306.     }
  307.     freeMutualExclusiveAccess();
  308. }
  309.  
  310.  
  311. #ifdef DEBUG
  312.  
  313.  
  314. void chainElement::checkConsistence(void)
  315. {    getMutualExclusiveAccess();
  316.     if (pPrev)
  317.     {    assert(pParent->pFirst != this);
  318.         assert(pPrev->pSucc == this);
  319.         assert(pParent == pPrev->pParent);
  320.     }
  321.     else
  322.     {    chainElement *pScan;
  323.         unsigned int iNumberOfElements;
  324.  
  325.         assert(pParent->pFirst == this);
  326.         for (pScan = this, iNumberOfElements = 0;
  327.             pScan;
  328.             pScan = pScan->pSucc)
  329.             iNumberOfElements++;
  330.         assert(iNumberOfElements == pParent->iNumberOfElements);
  331.     }
  332.     if (pSucc)
  333.     {    assert(pParent->pLast != this);
  334.         assert(pSucc->pPrev == this);
  335.         assert(pParent == pSucc->pParent);
  336.         pSucc->checkConsistence();
  337.     }
  338.     else
  339.         assert(pParent->pLast == this);
  340.     freeMutualExclusiveAccess();
  341. }
  342.  
  343.  
  344. #endif /* DEBUG */
  345.  
  346.  
  347. Boolean chainElement::laterThenThis(chainElement *pElement, unsigned int iMsg)
  348. {    (void)pElement;
  349.     (void)iMsg;
  350.     return FALSE;
  351. }
  352.  
  353.  
  354. #ifdef undefined
  355. Boolean chainElement::isLocked(void)
  356. {    return pParent ? pParent->isLocked() : FALSE
  357.         || mtxObject::isLocked();
  358. }
  359. #endif undefined
  360.  
  361.  
  362. void chainElement::getMutualExclusiveAccess(void)
  363. {       if (pParent)
  364.         pParent->getMutualExclusiveAccess();
  365.     mtxObject::getMutualExclusiveAccess();
  366. }
  367.  
  368.  
  369. void chainElement::freeMutualExclusiveAccess(void)
  370. {    mtxObject::freeMutualExclusiveAccess();
  371.     if (pParent)
  372.         pParent->freeMutualExclusiveAccess();
  373. }
  374.  
  375.