home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional Developers Kit 1992 November / Disc01 / Disc01.mdf / cppbeta / ibmcli / ilinklst.hp_ / ILINKLST.HPP
Encoding:
C/C++ Source or Header  |  1992-10-27  |  15.5 KB  |  349 lines

  1. #if !defined(_ILinkList_)
  2. #define _ILinkList_
  3.  
  4. /*--------------------------------------------------------------*/
  5. /* CLASS NAMES:   INode                                         */
  6. /*                ILinkList        -->   IGLinkList             */
  7. /*                ILinkListCursor  -->   IGLinkListCursor       */
  8. /*                                                              */
  9. /* DESCRIPTION  : This file defines a set of classes used to    */
  10. /*                implement a doubly linked list, which is the  */
  11. /*                basis of the Collection classes in ICLUI.  */
  12. /*                                                              */
  13. /*                The collection classes in ICLUI are a      */
  14. /*                merger between the SList/SLink generic        */
  15. /*                collection classes described by Bjarne        */
  16. /*                Stroustrup in Vol 1 of "The C++ Programming   */
  17. /*                Language" and the original typeless,          */
  18. /*                shallow-copy classes designed by Mike Chan    */
  19. /*                and Kevin Leong in Dallas.                    */
  20. /*                                                              */
  21. /*                The basic link list mechanism provides the    */
  22. /*                capability to deal with void* elements where  */
  23. /*                the caller is responsible for allocation and  */
  24. /*                destruction.  There is also a macro to create */
  25. /*                a "generated" collection class which allows   */
  26. /*                ICLUI collections to deal with objects of  */
  27. /*                any class in a type safe manner.              */
  28. /*                                                              */
  29. /*                The generated class is defined as:            */
  30. /*                    IGLinkList(MyObj) myObjList;              */
  31. /*                                                              */
  32. /*                The Linklist provides cursor movement both    */
  33. /*                within the ILinkList class and as a separate  */
  34. /*                ILinkListCursor class which enables the use   */
  35. /*                of multiple cursors on the same link list.    */
  36. /*                There is a macro for creating "generated"     */
  37. /*                cursors too.                                  */
  38. /*                                                              */
  39. /*                Hungarian form : "lknl"  -  linklist          */
  40. /*                               : "lknlc" -  cursor            */
  41. /*                                                              */
  42. /* CHANGE ACTIVITY:                                             */
  43. /* ---------------                                              */
  44. /*   DATE:     INITIAL:       DESCRIPTION:                      */
  45. /*                                                              */
  46. /* 03/01/91    KKL            Design & architecture             */
  47. /* 03/28/91    WC             Init declaration                  */
  48. /* 05/01/91    KKL            Extend to support IGENOBJ         */
  49. /* 06/08/91    KKL            Tidy-up and re-organize methods.  */
  50. /* 12/23/91-   RDL            Re-work to Stroustrup             */
  51. /* 03/31/92    CAJ                                              */
  52. /*--------------------------------------------------------------*/
  53. /* Copyright (c) IBM Corporation 1991                           */
  54. /*--------------------------------------------------------------*/
  55. #include <ibasetyp.hpp>   /* IBM C++ OS/2 2.0 */
  56.  
  57. #if (OS2LEVEL > 130)               
  58. extern "C"                  // RDL 32 bit
  59. {
  60.   #include <stddef.h>
  61. }
  62. #else                              
  63.   #include <stddef.h>
  64. #endif                             
  65. /*--------------------------------------------------------------*/
  66. /* Generic class construction Macros                            */
  67. /*--------------------------------------------------------------*/
  68. #if !defined(name2)
  69. // The name macro is used to patch together two words
  70. #define name2(n1,n2)              n1 ## n2
  71. #endif
  72.  
  73. #if !defined(declare)
  74. // This macro is used to construct a class name
  75. #define declare(a,type)           a##declare(type)
  76. #endif
  77.  
  78. #if !defined(implement)
  79. // This macro is used to construct a class name
  80. #define implement(a,type)         a##implement(type)
  81. #endif
  82.  
  83. class INode;
  84. class ILinkList;
  85. class ILinkListCursor;
  86.  
  87. /*--------------------------------------------------------------*/
  88. /* Definition of Comparison and Sorting function types          */
  89. /*--------------------------------------------------------------*/
  90. #if (OS2LEVEL > 130)
  91.                  /* IBM C++ OS/2 2.0 */
  92. extern "C" {
  93.   typedef long (_System FNCOMPARE)(void*   pobj1,     // RDL 32 bit
  94.                              void*   pobj2,
  95.                              ILinkList* pcoll);
  96.   typedef FNCOMPARE *PFNCOMPARE;                       // RDL 32 bit
  97.  
  98.   typedef Boolean (_System FNFILTER)(void*  pobj,     // RDL 32 bit
  99.                             ILinkList* pcoll);
  100.   typedef FNFILTER *PFNFILTER;                         // RDL 32 bit
  101. }
  102.  
  103. #else
  104.                  /* Zortech OS/2 1.3 */
  105. extern "C" {
  106.   typedef int (PASCAL FAR *PFNCOMPARE)(void*   pobj1,
  107.                              void*   pobj2,
  108.                              ILinkList* pcoll);
  109.  
  110.   typedef Boolean (PASCAL FAR *PFNFILTER)(void*  pobj,
  111.                             ILinkList* pcoll);
  112. }
  113.  
  114. #endif
  115.  
  116.  
  117. /*--------------------------------------------------------------*/
  118. /* A Node in the Linked List class definition                   */
  119. /*                Hungarian form : "node"                       */
  120. /*--------------------------------------------------------------*/
  121. class INode
  122. {
  123.           friend class ILinkList;
  124.           friend class ILinkListCursor;
  125.  
  126. public:
  127.           INode()                { pClObj = 0;    }
  128.           void* object()         { return pClObj; }
  129.  
  130. // Add later- Deal with small objects more efficiently */
  131. //        void* operator new(size_t);
  132. //        void  operator delete(void*, size_t);
  133.  
  134.           INode* pnodeClNext;
  135.           INode* pnodeClPrev;
  136.           void*  pClObj;
  137. };
  138.  
  139.  
  140. /*--------------------------------------------------------------*/
  141. /* The Double Link List of Nodes  class definition              */
  142. /*--------------------------------------------------------------*/
  143. class ILinkList
  144. {
  145.           friend class ILinkListCursor;
  146.  
  147. public:
  148.       static unsigned notInList;
  149.       /*********************************************************/
  150.       /* CONSTRUCTORS/DESTRUCTOR:                              */
  151.       /*  - If the fDestruct flag is true, the ILinkList       */
  152.       /*    destructor will delete the objects in the list.    */
  153.       /*  - The ulBase value provides the list indexing base.  */
  154.       /*********************************************************/
  155.           ILinkList(Boolean fDestruct=false, unsigned long ulBase=0);
  156.           ILinkList(void* pObj, Boolean fDestruct=false, unsigned long ulBase=0);
  157.           ILinkList(const ILinkList& lnklst);
  158.  
  159.           virtual ~ILinkList();
  160.  
  161.       /*********************************************************/
  162.       /*  Add current, first, last, and at an index.           */
  163.       /*********************************************************/
  164.           Boolean  add(void* pobj);
  165.           Boolean  addFirst(void* pobj);
  166.           Boolean  addLast(void* pobj);
  167.           Boolean  addAfter(void* pobj, unsigned long lIndex );
  168.  
  169.       /*********************************************************/
  170.       /*  Remove and return the current item and the first item*/
  171.       /*********************************************************/
  172.           void* remove();
  173.           void* remove(void* pobj);
  174.           void* removeFirst();
  175.  
  176.       /*********************************************************/
  177.       /*  Clear the list.                                      */
  178.       /*********************************************************/
  179.           void removeAll();
  180.  
  181.       /*********************************************************/
  182.       /*  Move through the list (updates current).             */
  183.       /*********************************************************/
  184.           void  toFirst();
  185.           void  toLast();
  186.           unsigned long toIndex(unsigned long lIndex);
  187.           void  toNext();
  188.           void  toPrior();
  189.  
  190.       /*********************************************************/
  191.       /*  Return some items in the List.                       */
  192.       /*********************************************************/
  193.           void* current() const;
  194.           void* first();
  195.           void* last();
  196.           void* next();
  197.           void* prior();
  198.           void* atIndex(unsigned long lIndex);
  199.  
  200.       /************************************************************/
  201.       /*  Get the index of current node or the index of a node    */
  202.       /*  pointing to a given object.  The index is adjusted for  */
  203.       /*  the indexing base.  Return code of hex all F's means    */
  204.       /*  the object is not in the list.                          */
  205.       /************************************************************/
  206.           unsigned long indexOf();
  207.           unsigned long indexOf(void* pobj);
  208.  
  209.       /************************************************************/
  210.       /*  Check if linked list is empty.                          */
  211.       /************************************************************/
  212.           Boolean isEmpty();
  213.  
  214.       /************************************************************/
  215.       /*  Data element access functions.                          */
  216.       /************************************************************/
  217.           unsigned long base();     // retrieve indexing base number
  218.           unsigned long count() const; // get number of objects on list
  219.  
  220.  
  221. protected:
  222.       /************************************************************/
  223.       /*  Get the index of a given INode in the linked list.      */
  224.       /*  The index is adjusted for the indexing base.  Return of */
  225.       /*  hex all F's indicates an object was not in the list.    */
  226.       /************************************************************/
  227.           unsigned long   indexOf(INode* pnode);
  228.  
  229.       /*********************************************************/
  230.       /*  Delete object pointed to from INode.  Virtual at this*/
  231.       /*  level as type of object is needed.  This info is     */
  232.       /*  obtained from IGLinkListTYPE class macro.            */
  233.       /*********************************************************/
  234.           virtual void ILinkList::deleteObj(void* pobj){ delete pobj;}
  235.  
  236.           // Make the connection on node.
  237.           INode* link(INode* pnode);
  238.  
  239.           // Unlink the current or specified node.
  240.           INode* unLink();
  241.           INode* unLink(INode* pnode);
  242.  
  243.           // Internal default sort functions
  244.           void   quickSort(INode* pnodeFirst, INode* pnodeLast,
  245.                           PFNCOMPARE pfnCompare );
  246.           INode* partition(INode* pnodeLeft, INode* pnodeRight,
  247.                           void *pobjPivot, PFNCOMPARE pfnCompare);
  248.  
  249.  
  250.           // Data elements
  251.           INode* pnodeClHead;         // HEAD node pointer
  252.           INode* pnodeClTail;         // TAIL node pointer
  253.           INode* pnodeClCurrent;      // CURRENT node pointer
  254.           Boolean        fClDestruct; // object destruct flag
  255.           unsigned long  ulClCount;   // number of objects in list
  256.  
  257. private:
  258.           unsigned long  ulClListBase; // indexing base number
  259. };
  260.  
  261. /*--------------------------------------------------------------*/
  262. /* The Link List Cursor.                                        */
  263. /*--------------------------------------------------------------*/
  264. class ILinkListCursor
  265. {
  266. public:
  267.           friend class ILinkList;
  268.  
  269.       /*********************************************************/
  270.       /* CONSTRUCTORS/DESTRUCTOR:                              */
  271.       /*********************************************************/
  272.           ILinkListCursor(ILinkList& lnklst);
  273.  
  274.       /*********************************************************/
  275.       /*  Return items in the list and update the cursor.      */
  276.       /*********************************************************/
  277.           void* current() const;
  278.           void* first();
  279.           void* last();
  280.           void* next();
  281.           void* prior();
  282.  
  283.       /*********************************************************/
  284.       /*  Reset the Cursor.                                    */
  285.       /*  Note: Current() is undefined following a reset().    */
  286.       /*********************************************************/
  287.           void reset()  { pnodeClCursor = plnklCl->pnodeClHead; }
  288.  
  289. protected:
  290.           INode* headNode()    { return plnklCl->pnodeClHead; }
  291.           INode* tailNode()    { return plnklCl->pnodeClTail; }
  292.  
  293.           INode*     pnodeClCursor;
  294.           ILinkList* plnklCl;
  295. };
  296.  
  297.  
  298.       /*********************************************************/
  299.       /* Generated linklist class macro definition             */
  300.       /*********************************************************/
  301. #define IGLinkList(type)       name2(IGLinkList,type)
  302. #define IGLinkListCursor(type) name2(IGLinkListCursor,type)
  303.  
  304.  
  305. #define IGLinkListdeclare(type)\
  306. class IGLinkList(type) : public ILinkList {\
  307. public:\
  308.     IGLinkList(type)(Boolean fDestruct=false,unsigned long ulBaseIn=0) \
  309.                : ILinkList(fDestruct,ulBaseIn) {}\
  310.     IGLinkList(type)(type* pobj,Boolean fDestruct=false,unsigned long ulBaseIn=0) \
  311.                : ILinkList((void *) pobj,fDestruct,ulBaseIn) {}\
  312.      Boolean add(type* pobj)      { return ILinkList::add(pobj); }\
  313.      Boolean addFirst(type* pobj) { return ILinkList::addFirst(pobj); }\
  314.      Boolean addLast(type* pobj)  { return ILinkList::addLast(pobj); }\
  315.      Boolean addAfter(type* pobj, unsigned long ul) \
  316.                                 { return ILinkList::addAfter(pobj,ul); }\
  317.      type* remove()             { return (type*)ILinkList::remove(); }\
  318.      type* remove(type* pobj)   { return (type*)ILinkList::remove((void*)pobj); }\
  319.      type* removeFirst()        { return (type*)ILinkList::removeFirst(); }\
  320.      type* current()            { return (type*)ILinkList::current(); }\
  321.      type* first()              { return (type*)ILinkList::first(); }\
  322.      type* last()               { return (type*)ILinkList::last(); }\
  323.      type* next()               { return (type*)ILinkList::next(); }\
  324.      type* prior()              { return (type*)ILinkList::prior(); }\
  325.      unsigned long indexOf()    { return ILinkList::indexOf(); }\
  326.      unsigned long indexOf(type* pobj) { return ILinkList::indexOf((void*)pobj);}\
  327. protected: \
  328.     void   deleteObj(void* pobj){ delete (type*)pobj; }\
  329. private:\
  330.     IGLinkList(type)(const IGLinkList(type) & lnklst){} \
  331.     IGLinkList(type) &operator=(const IGLinkList(type) &);\
  332. };
  333.  
  334.       /*********************************************************/
  335.       /* Generated linklist cursor class macro definition      */
  336.       /*********************************************************/
  337. #define IGLinkListCursordeclare(type)\
  338. class IGLinkListCursor(type) : public ILinkListCursor {\
  339. public:\
  340.     IGLinkListCursor(type)(IGLinkList(type)& lnklst) \
  341.                 : ILinkListCursor(lnklst) {}\
  342.     type* current() { return (type*)ILinkListCursor::current(); }\
  343.     type* first()   { return (type*)ILinkListCursor::first(); }\
  344.     type* last()    { return (type*)ILinkListCursor::last(); }\
  345.     type* next()    { return (type*)ILinkListCursor::next(); }\
  346.     type* prior()   { return (type*)ILinkListCursor::prior(); }\
  347. };
  348. #endif
  349.