home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / CL187A.ZIP / CL.H < prev    next >
C/C++ Source or Header  |  1994-03-15  |  29KB  |  1,060 lines

  1. /*
  2.     cl.h -- Container Lite v 1.87a
  3.     (C) Copyright 1994  John Webster Small
  4.     All rights reserved
  5. */
  6.  
  7. #ifndef cl_h
  8. #define cl_h
  9.  
  10.  
  11. ///////////////////////////////////////////////////////
  12. //                                                   //
  13. //   If your compiler doesn't support templates      //
  14. //   define CL_NO_TEMPLATES below.                   //
  15. //                                                   //
  16. ///////////////////////////////////////////////////////
  17.  
  18.  
  19. #ifndef CL_NO_TEMPLATES
  20.     #ifdef _MSC_VER
  21.       #if  _MSC_VER <= 900
  22.         //   Microsoft's C 7.0 and Visual C++
  23.         //   8.0 do not support templates.
  24.         //   Assume for now MS C++ 9.0 won't.
  25.         #define CL_NO_TEMPLATES
  26.       #endif
  27.     #endif
  28. //    #if YOUR_NO_TEMPLATES_CC
  29. //        #define CL_NO_TEMPLATES
  30. //    #endif
  31. #endif
  32.  
  33.  
  34. ///////////////////////////////////////////////////////
  35. //                                                   //
  36. //   If your compiler doesn't support exceptions     //
  37. //   define CL_NO_EXCEPTIONS below.                  //
  38. //                                                   //
  39. ///////////////////////////////////////////////////////
  40.  
  41.  
  42. #ifndef CL_NO_EXCEPTIONS
  43.   #if defined(_MSC_VER)
  44.     #if _MSC_VER <= 900
  45.     //   Microsoft's C 7.0 and Visual C++ 8.0 do
  46.     //   not support exceptions.  Assume for now
  47.     //   MS C++ 9.0 won't.
  48.     #define CL_NO_EXCEPTIONS
  49.     #endif
  50.   #elif defined(__BCPLUSPLUS)
  51.     #if __BCPLUSPLUS__ < 0x320
  52.     //   Borland C++ compilers prior to 4.0 did 
  53.     //   not support exceptions.
  54.     #define CL_NO_EXCEPTIONS
  55.     #endif
  56. //#elif YOUR_NO_EXCEPTIONS_CC
  57. //    #define CL_NO_EXCEPTIONS
  58.   #endif
  59. #endif // !defined(CL_NO_EXCEPTIONS)
  60.  
  61.  
  62. ///////////////////////////////////////////////////////
  63. //                                                   //
  64. //   To enable Container Lite methods to             //
  65. //   throw the xalloc exception comment              //
  66. //   out the define CL_NO_THROW_XALLOC below.        //
  67. //                                                   //
  68. ///////////////////////////////////////////////////////
  69.  
  70.  
  71. #if !defined(CL_THROW_XALLOC)  \
  72.  && !defined(CL_NO_THROW_XALLOC)  \
  73.  && !defined(CL_NO_EXCEPTIONS)
  74.     #define CL_NO_THROW_XALLOC
  75. #endif
  76.  
  77.  
  78. #if defined(CL_NO_THROW_XALLOC)\
  79.     && !defined(CL_NO_EXCEPTIONS)
  80.     #define CL_try_new   try {
  81.     // Flesh in catch (xalloc) {} as required.
  82.     // CL primitives will return 0 on failures
  83.     // as before unless you throw an additional
  84.     // exception!
  85.     #define CL_catch_xalloc(NULLD)           \
  86.         } catch (xalloc)  { NULLD = 0; }
  87.     // CL will return 0 if the catch block doesn't
  88.     // terminate the program, even with
  89.     // set_new_handler(0)!
  90. #else
  91.     #define CL_try_new
  92.     #define CL_catch_xalloc(NULLD)
  93. #endif
  94.  
  95.  
  96. ///////////////////////////////////////////////////////
  97. //                                                   //
  98. //   If your compiler doesn't support the            //
  99. //   ANSI C header file "stdarg.h" define            //
  100. //   CL_NO_STDARG_H below.                           //
  101. //                                                   //
  102. ///////////////////////////////////////////////////////
  103.  
  104.  
  105. #ifndef CL_NO_STDARG_H
  106.   #if defined(_MSC_VER)
  107.     #if  _MSC_VER == 800
  108.     //   Visual C++ 8.00 doesn't correctly support
  109.     //   variable-length arguments when the first
  110.     //   formal parameter is a function pointer.
  111.     #define CL_NO_STDARG_H
  112.     #endif
  113. //#elif YOUR_UNIX_V_CC
  114. //    #define CL_NO_STDARG_H
  115.   #endif
  116. #endif
  117.  
  118.  
  119. ///////////////////////////////////////////////////////
  120. //                                                   //
  121. //   If you compiler allows for other than           //
  122. //   the normal C calling convention, define         //
  123. //   CL_CDECL below appropriately to force           //
  124. //   a C call modifier where required by CL.         //
  125. //                                                   //
  126. ///////////////////////////////////////////////////////
  127.  
  128.  
  129. #ifndef CL_CDECL
  130.   #if defined(__BORLANDC__) || defined(_MSC_VER)
  131.     //   Borland and Microsoft use same modifier
  132.     #define CL_CDECL __cdecl
  133. //#elif YOUR_NON_C_CALL_CC
  134. //    #define CL_CDECL ???
  135.   #else
  136.     #define CL_CDECL
  137.   #endif
  138. #endif
  139.  
  140.  
  141. #ifndef  CL_NO_STDARG_H
  142.     #include <stdarg.h>
  143.     #define CL_vforEach_decl                    \
  144.     void    vforEach(voidApplY B, va_list args);
  145.     #define CL_vforEach_promote                 \
  146.     cl::     vforEach;
  147.     #define CL_forEach_def(ITEM)                \
  148.     void CL_CDECL forEach(CLapplY(B,ITEM), ...) \
  149.     {                                           \
  150.         va_list args;                       \
  151.         va_start(args,B);                   \
  152.         vforEach((voidApplY)B,args);        \
  153.         va_end(args);                       \
  154.     };
  155. #else
  156.     #define CL_vforEach_decl
  157.     #define CL_vforEach_promote
  158.     #define CL_forEach_def(ITEM)
  159. #endif
  160.  
  161. #include <limits.h>    // UINT_MAX
  162. #include <iostream.h>
  163. #include <iomanip.h>
  164. #include <string.h>
  165. #ifndef CL_NO_EXCEPTIONS
  166.     #include <except.h>
  167. #endif
  168.  
  169.  
  170. /*  stream delimiters/manipulators  */
  171.  
  172. inline ostream& endm(ostream& os)
  173. { return os << endl; }
  174.  
  175. inline istream& nextm(istream& is)
  176. { is.get(); return is; }
  177.  
  178. /*  special functions for strings  */
  179.  
  180. extern ostream&  CL_fputCharArray(ostream& os, char * D);
  181. extern istream&  CL_fgetCharArray(istream& is, char *& D);
  182. inline ostream&  operator<<(ostream& os, char ** D)
  183.     { return CL_fputCharArray(os,*D); }
  184. inline istream&  operator>>(istream& is, char ** D)
  185.     { return CL_fgetCharArray(is,*D); }
  186.  
  187. /*  cl pointer types  */
  188.  
  189. #define CLblank
  190. #define CLcmP(ID,ITEM)  \
  191.     int (*ID)(const ITEM * D1, const ITEM * D2)
  192. typedef CLcmP(voidCmP,void);
  193. #define CLcmPcast(ID,ITEM)  \
  194.     (CLcmP(CLblank,ITEM)) ID
  195. #define CLcmP0(ITEM)  CLcmPcast(0,ITEM)
  196. #define voidCmP0 ((voidCmP)0)
  197. #define CmPfnc CmP() const
  198.  
  199. #ifndef  CL_NO_STDARG_H
  200. #define CLapplY(ID,ITEM)  \
  201.     void (*ID)(ITEM * D, va_list args)
  202. typedef CLapplY(voidApplY,void);
  203. #define CLapplYcast(ID,ITEM)  \
  204.     (CLapplY(CLblank,ITEM)) ID
  205. #define CLapplY0(ITEM)  (CLapplYcast(0,ITEM))
  206. #define voidApplY0 ((voidApplY)0)
  207. #endif
  208.  
  209. #define CLdetecT(ID,ITEM)  \
  210.     int (*ID)(ITEM * D, void * V)
  211. typedef CLdetecT(voidDetecT,void);
  212. #define CLdetecTcast(ID,ITEM)  \
  213.     (CLdetecT(CLblank,ITEM)) ID
  214. #define CLdetecT0(ITEM)  (CLdetecTcast(0,ITEM))
  215. #define voidDetecT0 ((voidDetecT)0)
  216.  
  217. #define CLcollecT(ID,ITEM)  \
  218.     void * (*ID)(ITEM * D, void * V)
  219. typedef CLcollecT(voidCollecT,void);
  220. #define CLcollecTcast(ID,ITEM)  \
  221.     (CLcollecT(CLblank,ITEM)) ID
  222. #define CLcollecT0(ITEM)  (CLcollecTcast(0,ITEM))
  223. #define voidcollecT0 ((voidCollecT)0)
  224.  
  225. typedef struct uniquenessGimmick  { int x; }
  226.     * defaultConstructor;
  227. #define defaultConstruct    ((defaultConstructor)0)
  228.  
  229. /*  cl constants  */
  230.  
  231. #define CL_MAXNODES    ((unsigned) \
  232.             (UINT_MAX/sizeof(void *)))
  233. #define CL_LIMIT    20U
  234. #define CL_DELTA    10U
  235. #define CL_NOTFOUND    CL_MAXNODES
  236.  
  237. #define CL_SORTED    0x0001U
  238. #define CL_BIND_ONLY    0x0000U
  239. #define CL_ASG        0x0002U
  240. #define CL_READ        0x0004U
  241. #define CL_READ_DEL    0x0008U
  242. #define CL_NEW        0x0010U
  243. #define CL_NEWED    0x0020U
  244. #define CL_DEL        0x0040U
  245. #define CL_SAVE        0x0080U
  246. #define CL_ALL_FLAGS    0x00FFU
  247. #define CL_ANDS        (CL_ASG|CL_NEW|CL_DEL|CL_SAVE)
  248.  
  249. #define CL_0U        -0    // avoid [0U] ambiguity
  250.  
  251.  
  252. class cl {
  253.  
  254.  
  255. #ifdef CL_NO_EXCEPTIONS
  256.  
  257.   protected:
  258.     void setND(void *)  {}
  259.     void resetND()  {}
  260.     void setVL(void *)  {}
  261.     void resetVL()  {}
  262.     static void setVD(void *)  {}
  263.     static void resetVD()  {}
  264.     friend istream& CL_fgetCharArray
  265.         (istream& is, char *& D);
  266.   public:
  267.     void catch_reset()  {}
  268.  
  269. #else
  270.  
  271.   private:
  272.     void * nD, * vL;
  273.     static void * vD;
  274.         // pointers to danglers
  275.   protected:
  276.     void setND(void * ND = 0)
  277.         { if (nD) deleteD(nD); nD = ND; }
  278.     void resetND()  { nD = 0; }
  279.     void setVL(void * vL = 0)
  280.         { if (vL) delete vL; vL = vL; }
  281.     void resetVL()  { vL = 0; }
  282.     static void setVD(void * VD = 0)
  283.         { if (vD) delete vD; vD = VD; }
  284.     static void resetVD()  { vD = 0; }
  285.     friend istream& CL_fgetCharArray
  286.         (istream& is, char *& D);
  287.   public:
  288.     void catch_reset()
  289.         { setND(); setVL(); setVD(); }
  290.  
  291. #endif
  292.  
  293.  
  294. public:
  295.  
  296.     enum RelCmp { EQ, NE, GT, GE, LT, LE };
  297.  
  298. private:
  299.  
  300.     unsigned lowLimit, lowThreshold, first;
  301.     void **  linkS;
  302.     unsigned limit,    delta,   nodes;
  303.     unsigned maxNodes, curNode, flags;
  304.     voidCmP  cmP;
  305.  
  306.     int  rcmp(const void * K, const void * D, 
  307.         cl::RelCmp rc);
  308.     void init(unsigned flags = CL_BIND_ONLY,
  309.         unsigned maxNodes = CL_MAXNODES,
  310.         unsigned limit = CL_LIMIT,
  311.         unsigned delta = CL_DELTA);
  312.  
  313. protected:
  314.  
  315.     cl  (defaultConstructor)
  316.             { init(); }
  317.     void    assign(const cl& b);
  318.     void    destruct();
  319.     virtual voidCmP cmPD(voidCmP cmP)
  320.             { return cmP; }
  321.     virtual void * assignD(void *, const void *)
  322.             { return (void *)0; }
  323.     virtual void * newD(const void *)
  324.             { return (void *)0; }
  325.     virtual void   deleteD(void * D)
  326.             { delete D; }
  327.     virtual int    attachD(void *)
  328.             { return 1; }
  329.     virtual void   detachD(void *)
  330.             {}
  331.     virtual    int    putD(ostream&, void *)
  332.             { return 0; }
  333.     virtual    void * getD(istream&)
  334.             { return (void *)0; }
  335.     virtual int    put(ostream& os);
  336.     virtual int    get(istream& is);
  337.     int     load(const char * filename);
  338.     int     save(const char * filename);
  339.     friend  ostream& operator<<(ostream& os,
  340.             cl&);
  341.     friend  istream& operator>>(istream& is,
  342.             cl&);
  343.     CL_vforEach_decl
  344.  
  345. public:
  346.  
  347. /*  Constructors and destructor  */
  348.  
  349.     cl     (unsigned flags = CL_BIND_ONLY,
  350.         unsigned maxNodes = CL_MAXNODES,
  351.         unsigned limit = CL_LIMIT,
  352.         unsigned delta = CL_DELTA)
  353.         { init(flags,maxNodes,limit,delta); }
  354.     cl     (void ** argv, unsigned argc = 0U,
  355.         unsigned flags = CL_BIND_ONLY);
  356.     cl&     operator=(const cl& b)
  357.         { return *this; }
  358.     int     operator==(const cl& b) const;
  359.     int     operator> (const cl& b) const;
  360.     void ** vector(void ** argv = (void **)0,
  361.             unsigned argc = 0U) const;
  362.     virtual ~cl()  { destruct(); }
  363. /*
  364.     You must override this destructor in any
  365.     descendant that overrides deleteD() or
  366.     detachD(), i.e.
  367.  
  368.     virtual ~DerivedFromCL()
  369.         { cl::destruct(); }
  370.  
  371.     This is because base destructors are called
  372.     after vfts are reset to their default values
  373.     for the base level.  This means that
  374.     cl::~cl() calls cl::detachD()
  375.     and perhaps cl::deleteD() instead of
  376.     the intended DerivedFromCL::detachD()
  377.     or DerivedFromCL::deleteD().
  378. */
  379.  
  380. /*  Housekeeping Primitives  */
  381.  
  382.     unsigned Limit() const { return limit; }
  383.     unsigned setLimit(unsigned newLimit);
  384.     unsigned pack()  { return setLimit(nodes); }
  385.     unsigned Delta() const { return delta; }
  386.     unsigned setDelta(unsigned newDelta
  387.             = CL_DELTA);
  388.     unsigned Nodes() const { return nodes; }
  389.     unsigned MaxNodes() const { return maxNodes; }
  390.     unsigned setMaxNodes(unsigned newMaxNodes
  391.             = CL_MAXNODES);
  392.     unsigned vacancy() const
  393.             { return maxNodes - nodes; }
  394.     unsigned vacancyNonElastic() const
  395.             { return limit - nodes; }
  396.     unsigned Flags(unsigned flags = CL_ALL_FLAGS)
  397.             const
  398.             { return (this->flags & flags); }
  399.     unsigned setFlags(unsigned flags)
  400.             { return (this->flags |= flags); }
  401.     unsigned resetFlags(unsigned flags)
  402.             { return (this->flags &= ~flags); }
  403.     cl&  operator<<(cl& (*manipulator)
  404.             (cl&))
  405.             { return (manipulator?
  406.                 (*manipulator)(*this)
  407.                 : *this); }
  408.  
  409. /*  Elastic Array Primitives  */
  410.  
  411.     void *   atIns(unsigned n, void * D);
  412.     void *   atInsNew(unsigned n, const void * D);
  413.     void *   atRmv(unsigned n);
  414.     void     allRmv();
  415.     int      atDel(unsigned n);
  416.     void *   atDelAsg(unsigned n, void * D);
  417.     int      allDel();
  418.     void     allClr()  { destruct(); }
  419.     void *   atPut(unsigned n, void * D);
  420.     void *   atPutNew(unsigned n, const void * D);
  421.     void *   atPutAsg(unsigned n, const void * D);
  422.     void *   atGet(unsigned n) const;
  423.     void *   operator[](unsigned n) const
  424.             { return atGet(n); }
  425.     void *   atGetAsg(unsigned n, void * D);
  426.     void *   atXchg(unsigned n, void * D);
  427.     unsigned index(const void * D) const;
  428.     CL_forEach_def(void)
  429.     int      detect(void *& D, 
  430.             voidDetecT B,
  431.             void * V = 0);
  432.     int      detect(unsigned& i,
  433.             voidDetecT B,
  434.             void * V = 0);
  435.     unsigned select(cl& c,
  436.             voidDetecT B,
  437.             void * V = 0);
  438.     unsigned reject(cl& c,
  439.             voidDetecT B,
  440.             void * V = 0);
  441.     unsigned collect(cl& c,
  442.             voidCollecT B,
  443.             void * V = 0);
  444.  
  445. /*  Stack - Deque - Queue Primitives  */
  446.  
  447.     void *   push(void * D)
  448.             { return atIns(0U,D); }
  449.     void *   pushNew(const void * D)
  450.             { return atInsNew(0U,D); }
  451.     void *   pop()  { return atRmv(0U); }
  452.     cl&      operator>>(void *& D)
  453.             { D = atRmv(0U);
  454.             return *this; }
  455.     int      popDel()  { return atDel(0U); }
  456.     void *   popDelAsg(void * D)
  457.             { return atDelAsg(0U,D); }
  458.     void *   top() const { return atGet(0U); }
  459.     void *   topAsg(void * D)
  460.             { return atGetAsg(0U,D); }
  461.     void *   insQ(void * D)
  462.             { return atIns(nodes,D); }
  463.     cl&      operator<<(void * D)
  464.             { atIns(nodes,D); return *this; }
  465.     void *   insQNew(const void * D)
  466.             { return atInsNew(nodes,D); }
  467.     void *   unQ()  { return atRmv(nodes-1); }
  468.     int      unQDel()  { return atDel(nodes-1); }
  469.     void *   unQDelAsg(void * D)
  470.             { return atDelAsg(nodes-1,D); }
  471.     void *   rear() const
  472.             { return atGet(nodes-1); }
  473.     void *   rearAsg(void * D)
  474.             { return atGetAsg(nodes-1,D); }
  475.  
  476. /*  List (single and double linked) Primitives  */
  477.  
  478.     unsigned CurNode() const;
  479.     int      setCurNode(unsigned n = CL_NOTFOUND);
  480.     void *   ins(void * D);
  481.     void *   insNew(const void * D);
  482.     void *   rmv();
  483.     int      del();
  484.     void *   delAsg(void * D);
  485.     void *   put(void * D)
  486.             { return atPut(curNode,D); }
  487.     void *   putNew(const void * D)
  488.             { return atPutNew(curNode,D); }
  489.     void *   putAsg(const void * D)
  490.             { return atPutAsg(curNode,D); }
  491.     void *   get() const { return atGet(curNode); }
  492.     void *   getAsg(void * D)
  493.             { return atGetAsg(curNode,D); }
  494.     void *   next();
  495.     void *   operator++()  { return next(); }
  496.     void *   nextAsg(void * D);
  497.     void *   prev();
  498.     void *   operator--()  { return prev(); }
  499.     void *   prevAsg(void * D);
  500.  
  501. /* Priority Q, Set, Bag, Dictionary, Sort Primitives */
  502.  
  503.     unsigned Sorted() const
  504.             { return (flags & CL_SORTED); }
  505.     void     unSort()  { flags &= ~CL_SORTED; }
  506.     void     setCmP(voidCmP cmP = voidCmP0)
  507.             { this->cmP = cmPD(cmP);
  508.             flags &= ~CL_SORTED; }
  509.     voidCmP  CmP() const { return cmP; }
  510.     int      sort(voidCmP cmP = voidCmP0);
  511.     void *   insSort(void * D);
  512.     void *   insSortNew(const void * D);
  513.     void *   insUnique(void * D);
  514.     void *   insUniqueNew(const void * D);
  515.     void *   findFirst(const void * K,
  516.             cl::RelCmp rc = EQ);
  517.     void *   findNext(const void * K,
  518.             cl::RelCmp rc = EQ);
  519.     void *   findLast(const void * K,
  520.             cl::RelCmp rc = EQ);
  521.     void *   findPrev(const void * K,
  522.             cl::RelCmp rc = EQ);
  523.     unsigned findAll(cl& b,
  524.             const void * K,
  525.             cl::RelCmp rc = EQ);
  526.     unsigned tallyAll(const void * K,
  527.             cl::RelCmp rc = EQ);
  528.  
  529. };    /*  class cl  */
  530.  
  531.  
  532. inline ostream& operator<<(ostream& os, cl& b)
  533. {
  534.     if (b.Flags(CL_SAVE))
  535.         (void) b.put(os);
  536.     return os;
  537. }
  538.  
  539. inline istream& operator>>(istream& is, cl& b)
  540. {
  541.     (void) b.get(is);
  542.     return is;
  543. }
  544.  
  545. typedef void (*GenericFnC)();
  546. #define GenericFnC0  ((GenericFnC)0)
  547.  
  548. class FunctionRegistry : cl  {
  549.  
  550. public:
  551.     FunctionRegistry() : cl(CL_DEL) {}
  552.     int regFnC(GenericFnC fnC, unsigned id);
  553.     unsigned fnC_2_ID(GenericFnC fnC);
  554.     GenericFnC ID_2_fnC(unsigned id);
  555.     void forget() { allDel(); }
  556.     ~FunctionRegistry() {}
  557. };
  558.  
  559. extern  FunctionRegistry fnCv;
  560.  
  561. #define Forget_Functions() fnCv.forget()
  562. #define Register_Function(fnC,id)  \
  563.         fnCv.regFnC((GenericFnC)fnC,id)
  564. #define Register_CmP(cmP,id)  \
  565.         Register_Function(cmP,id)
  566. #define fnC2ID(fnC) fnCv.fnC_2_ID((GenericFnC)fnC)
  567. #define ID2fnC(id)  fnCv.ID_2_fnC(id)
  568. #define cmP2ID(cmP) fnC2ID(cmP)
  569. #define ID2cmP(id) ((voidCmP)ID2fnC(id))
  570.  
  571.  
  572. /*  CL's C++ TEMPLATES  */
  573.  
  574. #ifndef CL_NO_TEMPLATES
  575.  
  576. /*  ITEM descriptors  */
  577.  
  578. #define CL_ALL_DEF(ITEM)  CL_CMP_DEF(ITEM)
  579. #define ITEM_char
  580.  
  581. #define CL_CMP_DEF(ITEM)                              \
  582.     inline CLcmP(CL_cmPD(CLcmP(cmP,ITEM)),void)   \
  583.     { CLcmP(defaultCmP,ITEM) = CL_cmpD;           \
  584.     return CLcmPcast((cmP? cmP :                  \
  585.     defaultCmP),void); }
  586. #define CL_CMP_CHAR
  587. inline int CL_cmpD(const char * D1, const char * D2)
  588.     { return strcmp(D1,D2); }
  589.     CL_CMP_DEF(char)
  590. template <class ITEM>
  591.     inline CLcmP(CL_cmPD(CLcmP(cmP,ITEM)),void)
  592.     { return CLcmPcast(cmP,void); }
  593. #define CL_EQ_GT_OPS(ITEM) inline                     \
  594.     int CL_cmpD(const ITEM * D1, const ITEM * D2) \
  595.     { return ((*D1 == *D2)? 0 :                   \
  596.     ((*D1 > *D2)? 1 : -1)); }                     \
  597.         CL_CMP_DEF(ITEM)
  598. #define CL_CMP_BYTES(ITEM) inline                     \
  599.     int CL_cmpD(const ITEM * D1, const ITEM * D2) \
  600.     { return memcmp(D1,D2,sizeof(ITEM)); }        \
  601.         CL_CMP_DEF(ITEM)
  602.  
  603. #define CL_ASSIGN_OP(ITEM)                       \
  604.     inline void * CL_assignD(ITEM * D,       \
  605.         const ITEM * S, unsigned)        \
  606.     {                                        \
  607.         *D = *S;                         \
  608.         return (void *) D;               \
  609.     }
  610. #define CL_ASSIGN_BYTES(ITEM)                    \
  611.     inline void * CL_assignD(ITEM * D,       \
  612.         const ITEM * S, unsigned)        \
  613.     { return memcpy(D,S,sizeof(ITEM)); }
  614. #define CL_ASSIGN_DEF(ITEM)
  615. template <class ITEM>
  616.     inline void * CL_assignD(ITEM *,
  617.         const ITEM *, unsigned)
  618.     { return (void *) 0; }
  619.  
  620. #define CL_DUP_CHAR
  621. inline void * CL_newD(const char * D)
  622.     { return (void *) strdup(D); }
  623. #define CL_COPYINIT(ITEM) inline                 \
  624.     void * CL_newD(const ITEM * D)           \
  625.     { return (void *) new ITEM(*D); }
  626. #define CL_CLONE_BYTES(ITEM) inline              \
  627.     void * CL_newD(const ITEM * D)           \
  628.     {                                        \
  629.       void * newD = (void *)             \
  630.         new char[sizeof(ITEM)];          \
  631.       if (newD)                              \
  632.         (void) memcpy(newD,D,sizeof(ITEM));\
  633.       return newD;                           \
  634.     }
  635. #define CL_NEW_DEF(ITEM)
  636. template <class ITEM>
  637.     inline void * CL_newD(const ITEM *)
  638.     { return (void *) 0; }
  639.  
  640. template <class ITEM>
  641.     inline void CL_deleteD(ITEM * D)
  642.     { delete D; }
  643. #define CL_DELETE_OFF(ITEM)                      \
  644.     inline void CL_deleteD(ITEM *)           \
  645.     { return; }
  646. #define CL_DELETE_DEF(ITEM)
  647.  
  648. template <class ITEM>
  649.     inline int CL_attachD(ITEM *, const void *)
  650.     { return 1; }
  651. #define CL_ATTACH_DEF(ITEM)
  652.  
  653. template <class ITEM>
  654.     inline void CL_detachD(ITEM *, const void *)
  655.     {}
  656. #define CL_DETACH_DEF(ITEM)
  657.  
  658. #define CL_STRM_INSERT_CHAR
  659. inline ostream&  CL_putD(ostream& os, char * D)
  660.     { return CL_fputCharArray(os,D); }
  661. template <class ITEM>
  662.     inline ostream& CL_putD(ostream& os,  ITEM *)
  663.     { return os; }
  664. #define CL_STRM_INSERT_OP(ITEM)                       \
  665.     inline ostream& CL_putD(ostream& os, ITEM * D)\
  666.     { return os << *D << endm; }
  667. #define CL_STRM_INSERT_BYTES(ITEM)                    \
  668.     inline ostream& CL_putD(ostream& os, ITEM * D)\
  669.     { return os.write((char *)D,sizeof(ITEM)); }
  670. #define CL_STRM_INSERT_DEF(ITEM)
  671.  
  672. #define CL_STRM_EXTRACT_CHAR
  673. inline istream&  CL_getD(istream& is, char *& D)
  674.     { return CL_fgetCharArray(is,D); }
  675. template <class ITEM>
  676.     inline istream& CL_getD(istream& is,
  677.         ITEM *&) { return is; }
  678. #define CL_STRM_EXTRACT_OP(ITEM)                 \
  679.     inline istream& CL_getD                  \
  680.         (istream& is, ITEM *& D)         \
  681.     {                                        \
  682.         if (D) delete D;                 \
  683.         D = new ITEM;                    \
  684.         if (D)                           \
  685.             is >> *D >> nextm;       \
  686.         return is;                       \
  687.     }
  688. #define CL_STRM_EXTRACT_BYTES(ITEM)              \
  689.     inline istream& CL_getD(istream& is,     \
  690.         ITEM *& D)                       \
  691.     {                                        \
  692.      if (D) delete D;                        \
  693.      D = new ITEM;                           \
  694.      if (D)                                  \
  695.       return is.read((char *)D,sizeof(ITEM));\
  696.      return is;                              \
  697.     }
  698. #define CL_STRM_EXTRACT_DEF(ITEM)
  699.  
  700. #define CL_STRM_OPS(ITEM)                        \
  701.     CL_STRM_INSERT_OP(ITEM)                  \
  702.     CL_STRM_EXTRACT_OP(ITEM)
  703. #define CL_STRM_BYTES(ITEM)                      \
  704.     CL_STRM_INSERT_BYTES(ITEM)               \
  705.     CL_STRM_EXTRACT_BYTES(ITEM)
  706. #define CL_STRM_CHAR
  707.  
  708. #define CL_WELL_ENDOWED(ITEM)                    \
  709.     CL_EQ_GT_OPS(ITEM)                       \
  710.     CL_ASSIGN_OP(ITEM)                       \
  711.     CL_COPYINIT(ITEM)                        \
  712.     CL_STRM_OPS(ITEM)
  713.  
  714. #define CL_char CL<char>
  715.  
  716.  
  717. template <class ITEM>
  718.  
  719. class CL : public cl {
  720.  
  721. protected:
  722.  
  723.     CL  (defaultConstructor)
  724.             : cl(defaultConstruct) {}
  725.     void     assign(const CL<ITEM>& b)
  726.             { cl::assign(b); }
  727.     cl::     destruct;
  728.     virtual  voidCmP cmPD(voidCmP cmP)
  729.             { return CL_cmPD
  730.             (CLcmPcast(cmP,ITEM)); }
  731.     virtual  void * assignD(void * D,
  732.             const void * S)
  733.             { return CL_assignD
  734.             ((ITEM *)D,(const ITEM *)S,
  735.             cl::Flags()); }
  736.     virtual  void * newD(const void * D)
  737.             { return  CL_newD
  738.             ((const ITEM *)D); }
  739.     virtual  void   deleteD(void * D)
  740.             { CL_deleteD((ITEM *)D); }
  741.     virtual  int    attachD(void * D)
  742.             { return CL_attachD((ITEM *)D,
  743.             (const void *) this); }
  744.     virtual  void   detachD(void * D)
  745.             { CL_detachD((ITEM *)D,
  746.             (const void *) this); }
  747.     virtual     int    putD(ostream& os, void * D)
  748.             { return (CL_putD(os,(ITEM *)D)
  749.             ? 1 : 0); }
  750.     virtual     void * getD(istream& is)
  751.             { ITEM * D = 0; CL_getD(is,D);
  752.             return (void *) D; }
  753.     virtual  int    put(ostream& os)
  754.             { return cl::put(os); }
  755.     virtual  int    get(istream& is)
  756.             { return cl::get(is); }
  757.     friend   ostream& operator<<
  758.             (ostream& os, CL<ITEM>& b);
  759.     friend   istream& operator>>
  760.             (istream& is, CL<ITEM>& b);
  761.     CL_vforEach_promote
  762.  
  763. public:
  764.  
  765. /*  Constructors and destructor  */
  766.  
  767.     CL (unsigned flags = CL_BIND_ONLY,
  768.         unsigned maxNodes = CL_MAXNODES,
  769.         unsigned limit = CL_LIMIT,
  770.         unsigned delta = CL_DELTA) :
  771.         cl(flags,maxNodes,limit,delta)
  772.         {}
  773.     CL (ITEM * argv[],
  774.         unsigned argc = 0U,
  775.         unsigned flags = CL_BIND_ONLY)
  776.         : cl((void **)argv,argc,flags)
  777.         {}
  778.     CL (CL<ITEM>& b)
  779.         : cl(defaultConstruct)
  780.         { assign(b); }
  781.     CL<ITEM>& operator=(CL<ITEM>& b)
  782.         { assign(b); return *this; }
  783.     int     operator==(const CL<ITEM>& b) const
  784.         { return cl::operator==(b); }
  785.     int     operator> (const CL<ITEM>& b) const
  786.         { return cl::operator>(b); }
  787.     CL (const char * filename)
  788.         : cl(defaultConstruct)
  789.         { (void) cl::load(filename); }
  790.     int     load(const char * filename)
  791.         { return cl::load(filename); }
  792.     int     save(const char * filename)
  793.         { return cl::save(filename); }
  794.     ITEM ** vector(ITEM ** argv = (ITEM **)0,
  795.         unsigned argc = 0U) const
  796.         { return (ITEM **)cl::
  797.         vector((void **)argv,argc); }
  798.     virtual ~CL() { destruct(); }
  799.  
  800. /*  Housekeeping Primitives  */
  801.  
  802.     cl::    Limit;
  803.     cl::    setLimit;
  804.     cl::    pack;
  805.     cl::    Delta;
  806.     cl::    setDelta;
  807.     cl::    Nodes;
  808.     cl::    MaxNodes;
  809.     cl::    setMaxNodes;
  810.     cl::    vacancy;
  811.     cl::    vacancyNonElastic;
  812.     cl::    Flags;
  813.     cl::    setFlags;
  814.     cl::    resetFlags;
  815.     CL<ITEM>&  operator<<(CL<ITEM>&
  816.             (*manipulator)(CL<ITEM>&))
  817.             { return (manipulator?
  818.             (*manipulator)
  819.             (*this)    : *this); }
  820.  
  821. /*  Elastic Array Primitives  */
  822.  
  823.     ITEM *   atIns(unsigned n, ITEM * D)
  824.             { return (ITEM *)cl::
  825.             atIns(n,(void *)D); }
  826.     ITEM *   atInsNew(unsigned n, const ITEM * D)
  827.             { return (ITEM *)cl::
  828.             atInsNew(n,(const void *)D); }
  829.     ITEM *   atRmv(unsigned n)
  830.             { return (ITEM *)cl::
  831.             atRmv(n); }
  832.     cl::     allRmv;
  833.     cl::     atDel;
  834.     ITEM *   atDelAsg(unsigned n, ITEM * D)
  835.             { return (ITEM *)cl::
  836.             atDelAsg(n,(void *)D); }
  837.     cl::     allDel;
  838.     cl::     allClr;
  839.     ITEM *   atPut(unsigned n, ITEM * D)
  840.             { return (ITEM *)cl::
  841.             atPut(n,(void *)D); }
  842.     ITEM *   atPutNew(unsigned n, const ITEM * D)
  843.             { return (ITEM *)cl::
  844.             atPutNew(n,(const void *)D); }
  845.     ITEM *   atPutAsg(unsigned n, const ITEM * D)
  846.             { return (ITEM *)cl::
  847.             atPutAsg(n,(const void *)D); }
  848.     ITEM *   atGet(unsigned n) const
  849.             { return (ITEM *)cl::
  850.             atGet(n); }
  851.     ITEM *   operator[](unsigned n) const
  852.             { return atGet(n); }
  853.     ITEM *   atGetAsg(unsigned n, ITEM * D)
  854.             { return (ITEM *)cl::
  855.             atGetAsg(n,(void *) D); }
  856.     ITEM *   atXchg(unsigned n, ITEM * D)
  857.             { return (ITEM *)cl::
  858.             atXchg(n,(void *) D); }
  859.     unsigned index(const ITEM * D) const
  860.             { return cl::
  861.             index((const void *)D); }
  862.     CL_forEach_def(ITEM)
  863.     int      detect(ITEM *& D,
  864.             CLdetecT(B,ITEM),
  865.             void * V = 0)
  866.             { return cl::detect
  867.             ((void *&)D,(voidDetecT)B,V); }
  868.     int      detect(unsigned& i,
  869.             CLdetecT(B,ITEM),
  870.             void * V = 0)
  871.             { return cl::detect
  872.             (i,(voidDetecT)B,V); }
  873.     unsigned select(CL<ITEM>& c,
  874.             CLdetecT(B,ITEM),
  875.             void * V = 0)
  876.             { return cl::select
  877.             ((cl &)c,(voidDetecT)B,V); }
  878.     unsigned reject(CL<ITEM>& c,
  879.             CLdetecT(B,ITEM),
  880.             void * V = 0)
  881.             { return cl::reject
  882.             ((cl &)c,(voidDetecT)B,V); }
  883.     unsigned collect(cl & c,
  884.             CLcollecT(B,ITEM),
  885.             void * V = 0)
  886.             { return cl::collect
  887.             (c,(voidCollecT)B,V); }
  888.  
  889. /*  Stack - Deque - Queue Primitives  */
  890.  
  891.     ITEM *   push(ITEM * D)
  892.             { return (ITEM *)cl::
  893.             push((void *) D); }
  894.     ITEM *   pushNew(const ITEM * D)
  895.             { return (ITEM *)cl::
  896.             pushNew((const void *)D); }
  897.     ITEM *   pop()
  898.             { return (ITEM *)cl::
  899.             pop(); }
  900.     CL<ITEM>&  operator>>(ITEM *& D)
  901.             { D = atRmv(0U);
  902.             return *this; }
  903.     cl::     popDel;
  904.     ITEM *   popDelAsg(ITEM * D)
  905.             { return (ITEM *)cl::
  906.             popDelAsg((void *)D); }
  907.     ITEM *   top() const
  908.             { return (ITEM *)cl::
  909.                 top(); }
  910.     ITEM *   topAsg(ITEM * D)
  911.             { return (ITEM *)cl::
  912.             topAsg((void *)D); }
  913.     ITEM *   insQ(ITEM * D)
  914.             { return (ITEM *)cl::
  915.             insQ((void *)D); }
  916.     CL<ITEM>&  operator<<(ITEM * D)
  917.             { atIns(Nodes(),D);
  918.             return *this; }
  919.     ITEM *   insQNew(const ITEM * D)
  920.             { return (ITEM *)cl::
  921.             insQNew((const void *)D); }
  922.     ITEM *   unQ()
  923.             { return (ITEM *)cl::
  924.             unQ(); }
  925.     cl::     unQDel;
  926.     ITEM *   unQDelAsg(ITEM * D)
  927.             { return (ITEM *)cl::
  928.             unQDelAsg((void *)D); }
  929.     ITEM *   rear() const
  930.             { return (ITEM *)cl::
  931.                 rear(); }
  932.     ITEM *   rearAsg(ITEM * D)
  933.             { return (ITEM *)cl::
  934.             rearAsg((void *)D); }
  935.  
  936. /*  List (single and double linked) Primitives  */
  937.  
  938.     cl::     CurNode;
  939.     cl::     setCurNode;
  940.     ITEM *   ins(ITEM * D)
  941.             { return (ITEM *)cl::
  942.             ins((void *)D); }
  943.     ITEM *   insNew(const ITEM * D)
  944.             { return (ITEM *)cl::
  945.             insNew((const void *)D); }
  946.     ITEM *   rmv()
  947.             { return (ITEM *)cl::
  948.             rmv(); }
  949.     cl::     del;
  950.     ITEM *   delAsg(ITEM * D)
  951.             { return (ITEM *)cl::
  952.             delAsg((void *)D); }
  953.     ITEM *   put(ITEM * D)
  954.             { return (ITEM *)cl::
  955.             put((void *)D); }
  956.     ITEM *   putNew(const ITEM * D)
  957.             { return (ITEM *)cl::
  958.             putNew((const void *)D); }
  959.     ITEM *   putAsg(const ITEM * D)
  960.             { return (ITEM *)cl::
  961.             putAsg((const void *)D); }
  962.     ITEM *   get() const
  963.             { return (ITEM *)cl::
  964.             get(); }
  965.     operator ITEM *() const { return get(); }
  966.     ITEM *   getAsg(ITEM * D)
  967.             { return (ITEM *)cl::
  968.             getAsg((void *)D); }
  969.     ITEM *   next()
  970.             { return (ITEM *)cl::
  971.             next(); }
  972.     ITEM *   operator++()
  973.             { return next(); }
  974.     ITEM *   nextAsg(ITEM * D)
  975.             { return (ITEM *)cl::
  976.             nextAsg((void *)D); }
  977.     ITEM *   prev()
  978.             { return (ITEM *)cl::
  979.             prev(); }
  980.     ITEM *   operator--()
  981.             { return prev(); }
  982.     ITEM *   prevAsg(ITEM * D)
  983.             { return (ITEM *)cl::
  984.             prevAsg((void *)D); }
  985.  
  986. /* Priority Q, Set, Bag, Dictionary, Sort Primitives */
  987.  
  988.     cl::     Sorted;
  989.     cl::     unSort;
  990.     void     setCmP(CLcmP(cmP,ITEM)
  991.             = CLcmP0(ITEM))
  992.             { cl::setCmP
  993.             ((voidCmP)cmP); }
  994.     CLcmP(CmPfnc,ITEM) { return CLcmPcast
  995.             (cl::CmP(),ITEM); }
  996.     int      sort(CLcmP(cmP,ITEM)
  997.             = CLcmP0(ITEM))
  998.             { return cl::sort
  999.             ((voidCmP)cmP); }
  1000.     ITEM *   insSort(ITEM * D)
  1001.             { return (ITEM *)cl::
  1002.             insSort((void *)D); }
  1003.     ITEM *   insSortNew(const ITEM * D)
  1004.             { return (ITEM *)cl::
  1005.             insSortNew((const void *)D); }
  1006.     ITEM *   insUnique(ITEM * D)
  1007.             { return (ITEM *)cl::
  1008.             insUnique((void *)D); }
  1009.     ITEM *   insUniqueNew(const ITEM * D)
  1010.             { return (ITEM *)cl::
  1011.             insUniqueNew((const void *)D);}
  1012.     ITEM *   findFirst(const ITEM * K,
  1013.             cl::RelCmp rc = EQ)
  1014.             { return (ITEM *)cl::
  1015.             findFirst((const void *)K,
  1016.             rc); }
  1017.     ITEM *   operator[](const ITEM * K)
  1018.             { return (ITEM *)cl::
  1019.             findFirst((const void *)K); }
  1020.     ITEM *   findNext(const ITEM * K, 
  1021.             cl::RelCmp rc = EQ)
  1022.             { return (ITEM *)cl::
  1023.             findNext((const void *)K,rc); }
  1024.     ITEM *   findLast (const ITEM * K,
  1025.             cl::RelCmp rc = EQ)
  1026.             { return (ITEM *)cl::
  1027.             findLast((const void *)K,
  1028.             rc); }
  1029.     ITEM *   findPrev(const ITEM * K,
  1030.             cl::RelCmp rc = EQ)
  1031.             { return (ITEM *)cl::
  1032.             findPrev((const void *)K,rc); }
  1033.     unsigned findAll(CL<ITEM>& b,
  1034.             const ITEM * K,
  1035.             cl::RelCmp rc = EQ)
  1036.             { return cl::findAll
  1037.             ((cl &)b,(const void *)K,
  1038.             rc); }
  1039.     unsigned tallyAll(const ITEM * K,
  1040.             cl::RelCmp rc = EQ)
  1041.             { return cl::tallyAll
  1042.             ((const void *)K,
  1043.             rc); }
  1044.  
  1045.  
  1046. };    /*  class CL  */
  1047.  
  1048.  
  1049. template <class ITEM>
  1050. inline ostream& operator<<(ostream& os, CL<ITEM>& b)
  1051. { return os << *(cl *)&b; }
  1052.  
  1053. template <class ITEM>
  1054. inline istream& operator>>(istream& is, CL<ITEM>& b)
  1055. { return is >> *(cl *)&b; }
  1056.  
  1057.  
  1058. #endif    /*  !CL_NO_TEMPLATES  */
  1059. #endif  /*  cl_h  */
  1060.