home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1997 May / Pcwk0597.iso / sybase / starbuck / h.z / WCLBASE.H < prev    next >
C/C++ Source or Header  |  1996-07-24  |  22KB  |  786 lines

  1. //
  2. //  wclbase.h    Definitions for the base classes used by
  3. //               the WATCOM Container List Class
  4. //
  5. //  Copyright by WATCOM International Corp. 1988-1996.  All rights reserved.
  6. //
  7. #ifndef _WCLBASE_H_INCLUDED
  8. #define _WCLBASE_H_INCLUDED
  9.  
  10. #ifndef __cplusplus
  11. #error wclbase.h is for use with C++
  12. #endif
  13.  
  14. #ifndef _WCDEFS_H_INCLUDED
  15.  #include <wcdefs.h>
  16. #endif
  17.  
  18. //
  19. // This warning would be generated by taking the sizeof an object derived
  20. // from WCSLink or WCDLink, required for user allocator and deallocators
  21. //
  22. // "Warning! W549: 'sizeof' operand contains compiler generated information"
  23. #pragma warning 549 9 
  24.  
  25. #if defined( new ) && defined( _WNEW_OPERATOR )
  26. #  undef new
  27. #endif
  28. #if defined( delete ) && defined( _WDELETE_OPERATOR )
  29. #  undef delete
  30. #endif
  31.  
  32.  
  33. //
  34. //  The WCNIsvSLink class is used as a basis for non-intrusive singly
  35. //  linked lists.
  36. //
  37.  
  38. template<class Type>
  39. class WCNIsvSLink : public WCSLink {
  40. public:
  41.     Type            data;
  42.  
  43.     inline WCNIsvSLink( const Type & datum ) : data( datum ) {};
  44.     inline ~WCNIsvSLink() {};
  45.  
  46.     //
  47.     // Just return ptr (passed by the new operator in WCListNew) without
  48.     // allocating any memory.
  49.     // Needed so we can call the constructor on user allocated memory.
  50.     //
  51.     inline void * operator new( size_t, void * ptr ) {
  52.         return( ptr );
  53.     }
  54. };
  55.  
  56.  
  57.  
  58.  
  59. //
  60. //  The WCNIsvDLink class is used as a basis for non-intrusive doubly
  61. //  linked lists.
  62. //
  63.  
  64. template<class Type>
  65. class WCNIsvDLink : public WCDLink {
  66. public:
  67.     Type            data;
  68.  
  69.     inline WCNIsvDLink( const Type & datum ) : data( datum ) {};
  70.     inline ~WCNIsvDLink() {};
  71.  
  72.     //
  73.     // Just return ptr (passed by the new operator in WCListNew) without
  74.     // allocating any memory.
  75.     // Needed so we can call the constructor on user allocated memory.
  76.     //
  77.     inline void * operator new( size_t, void * ptr ) {
  78.         return( ptr );
  79.     }
  80. };
  81.  
  82.  
  83.  
  84.  
  85. //
  86. // macros to allow the user to find the size of the list elements allocated
  87. // and freed by user allocator and deallocator functions
  88. //
  89.  
  90. #define WCValSListItemSize( Type )      sizeof( WCNIsvSLink<Type> )
  91. #define WCValDListItemSize( Type )      sizeof( WCNIsvDLink<Type> )
  92. #define WCPtrSListItemSize( Type )      sizeof( WCNIsvSLink<void *> )
  93. #define WCPtrDListItemSize( Type )      sizeof( WCNIsvDLink<void *> )
  94.  
  95.  
  96.  
  97.  
  98. //
  99. //  The WCIsvListBase class is used as a basis for intrusive lists.
  100. //  It provides the common data and base functionality.  The WCExcept
  101. //  class provides the common exception handling for all lists.
  102. //
  103. //  This class is also used by the value classes. The values
  104. //  are encapsulated in non-intrusive links which are then stored
  105. //  in the list intrusively.
  106. //
  107. //  It is an abstract base class to prevent objects of this class
  108. //  from being created.
  109. //
  110.  
  111. class WCIsvListBase : public WCExcept {
  112. protected:
  113.     WCSLink *       tail;
  114.     int             entry_count;
  115.  
  116.     _WPRTLINK void           base_insert( WCSLink * );
  117.     _WPRTLINK WCSLink *      base_next( const WCSLink *, WCbool ) const;
  118.     _WPRTLINK int            base_index_check( int ) const;
  119.     _WPRTLINK WCSLink *      base_sget( int );
  120.     _WPRTLINK WCDLink *      base_dget( int );
  121.     _WPRTLINK WCSLink *      base_bfind( int ) const;
  122.     _WPRTLINK WCSLink *      base_sfind( int ) const;
  123.     _WPRTLINK WCDLink *      base_dfind( int ) const;
  124.     _WPRTLINK int            base_index( const WCSLink * ) const;
  125.     inline WCbool         base_contains( const WCSLink * ) const;
  126.     _WPRTLINK void           base_clear( void );
  127.     _WPRTLINK void           base_destroy( void );
  128.     virtual void         WCListDelete( WCSLink * datum ) = 0;
  129.  
  130. public:
  131.     inline WCIsvListBase() : tail(0), entry_count(0) {};
  132.     virtual ~WCIsvListBase() = 0;
  133.  
  134.     int operator==( const WCIsvListBase &rhs ) const {
  135.         return( this == &rhs );
  136.     };
  137.  
  138.     friend class WCListIterBase;
  139. };
  140.  
  141. WCbool WCIsvListBase::base_contains( const WCSLink * elem ) const {
  142.     return( base_index( elem ) != -1 );
  143. };
  144.  
  145.  
  146.  
  147.  
  148. //
  149. //  The WCIsvSListBase class defines an intrusive singly linked list
  150. //  base class.
  151. //
  152. //  It is an abstract base class to prevent objects of this class
  153. //  from being created.
  154. //
  155.  
  156. template<class Type>
  157. class WCIsvSListBase : public WCIsvListBase {
  158. protected:
  159.     void            clear();
  160.     void            clearAndDestroy();
  161.     WCbool          insert( WCSLink * );
  162.     WCbool          append( WCSLink * );
  163.     WCSLink *       get( int = 0 );
  164.     WCSLink *       find( int = 0 ) const;
  165.     WCSLink *       findLast() const;
  166.     int             index( int (*test_fn)( const Type *, void * )
  167.                          , void * ) const;
  168.     int             index( const WCSLink * ) const;
  169.     WCbool          contains( const WCSLink * ) const;
  170.     WCbool          isEmpty() const;
  171.     int             entries() const;
  172.     void            forAll( void (*)( Type *, void * ), void *) const;
  173.  
  174.     // used by clearAndDestroy
  175.     virtual void    WCListDelete( WCSLink * datum ) {
  176.         delete (Type *)datum;
  177.     };
  178.  
  179. public:
  180.     inline WCIsvSListBase( void * (*)( size_t )
  181.                 , void (*)( void *, size_t )
  182.                 ) { };
  183.  
  184.     inline WCIsvSListBase() {};
  185.     inline virtual ~WCIsvSListBase() = 0;
  186. };
  187.  
  188. template<class Type>
  189. inline WCIsvSListBase<Type>::~WCIsvSListBase() {};
  190.  
  191. template<class Type>
  192. inline void WCIsvSListBase<Type>::clear() {
  193.     base_clear();
  194. };
  195.  
  196. template<class Type>
  197. inline void WCIsvSListBase<Type>::clearAndDestroy() {
  198.     base_destroy();
  199. };
  200.  
  201. //
  202. // insert and append always return TRUE in an intrusive list, so that
  203. // intrusive and pointer classes have the same prototypes for the
  204. // WCPtrListBase class
  205. //
  206. template<class Type>
  207. inline WCbool WCIsvSListBase<Type>::insert( WCSLink * datum ) {
  208.     base_insert( datum );
  209.     return( TRUE );
  210. };
  211.  
  212. template<class Type>
  213. inline WCbool WCIsvSListBase<Type>::append( WCSLink * datum ) {
  214.     insert( datum );
  215.     tail = datum;
  216.     return( TRUE );
  217. };
  218.  
  219. template<class Type>
  220. inline WCSLink * WCIsvSListBase<Type>::get( int index ) {
  221.     return( base_sget( index ) );
  222. };
  223.  
  224. template<class Type>
  225. inline WCSLink * WCIsvSListBase<Type>::find( int index ) const {
  226.     return( base_sfind( index ) );
  227. };
  228.  
  229. template<class Type>
  230. inline WCSLink * WCIsvSListBase<Type>::findLast() const {
  231.     if( tail == 0 ) {
  232.         base_throw_empty_container();
  233.     }
  234.     return( tail );
  235. };
  236.  
  237. //
  238. // This index member function which is passed a test_fn is define for only
  239. // the WCIsvSList classes.  Only a single index function is
  240. // defined in WCValListBase and WCPtrSList to ensure this
  241. // member function is unavailable to the value and pointer classes.
  242. //
  243. template<class Type>
  244. inline int WCIsvSListBase<Type>::index(
  245.                   register int (*test_fn)( const Type *elem, void *datum )
  246.                 , void *datum ) const {
  247.     int index = 0;
  248.  
  249.     Type * rover = (Type *)base_next( rover, TRUE );
  250.     while( rover != 0 ) {
  251.         if( (*test_fn)( rover, datum ) ) {
  252.             return( index );
  253.         }
  254.         rover = (Type *)base_next( rover, FALSE );
  255.         index++;
  256.     } 
  257.     return( -1 );
  258. };
  259.  
  260. template<class Type>
  261. inline int WCIsvSListBase<Type>::index( const WCSLink * datum ) const {
  262.     return( base_index( datum ) );
  263. };
  264.  
  265. template<class Type>
  266. inline WCbool WCIsvSListBase<Type>::contains( const WCSLink * datum ) const {
  267.     return( base_contains( datum ) );
  268. };
  269.  
  270. template<class Type>
  271. inline WCbool WCIsvSListBase<Type>::isEmpty() const {
  272.     return( tail == 0 );
  273. };
  274.  
  275. template<class Type>
  276. inline int WCIsvSListBase<Type>::entries() const {
  277.     return( entry_count );
  278. };
  279.  
  280. template<class Type>
  281. void WCIsvSListBase<Type>::forAll(
  282.                 register void (* func)( Type *, void * ), void * datum ) const {
  283.     Type * rover = (Type *)base_next( rover, TRUE );
  284.     while( rover != 0 ) {
  285.         (*func)( rover, datum );
  286.         rover = (Type *)base_next( rover, FALSE );
  287.     } 
  288. };
  289.  
  290.  
  291.  
  292.  
  293. //
  294. //  The WCIsvDListBase class defines an intrusive doubly linked list
  295. //  base class.
  296. //
  297. //  It is an abstract base class to prevent objects of this class
  298. //  from being created.
  299. //
  300.  
  301. template<class Type>
  302. class WCIsvDListBase : public WCIsvListBase {
  303. protected:
  304.     void            clear();
  305.     void            clearAndDestroy();
  306.     WCbool          insert( WCDLink * );
  307.     WCbool          append( WCDLink * );
  308.     WCDLink *       get( int = 0 );
  309.     WCDLink *       find( int = 0 ) const;
  310.     WCDLink *       findLast() const;
  311.     int             index( int (*test_fn)( const Type *, void * )
  312.                          , void * ) const;
  313.     int             index( const WCDLink * ) const;
  314.     WCbool          contains( const WCDLink * ) const;
  315.     WCbool          isEmpty() const;
  316.     int             entries() const;
  317.     void            forAll( void (*)( Type *, void * ), void *) const;
  318.  
  319.     // used by clearAndDestroy
  320.     virtual void    WCListDelete( WCSLink * datum ) {
  321.         delete (Type *)datum;
  322.     };
  323.  
  324. public:
  325.     inline WCIsvDListBase( void * (*)( size_t )
  326.                 , void (*)( void *, size_t )
  327.                 ) {};
  328.     inline WCIsvDListBase() {};
  329.  
  330.     inline virtual ~WCIsvDListBase() = 0;
  331. };
  332.  
  333. template<class Type>
  334. inline WCIsvDListBase<Type>::~WCIsvDListBase() {};
  335.  
  336. template<class Type>
  337. inline void WCIsvDListBase<Type>::clear() {
  338.     base_clear();
  339. };
  340.  
  341. template<class Type>
  342. inline void WCIsvDListBase<Type>::clearAndDestroy() {
  343.     base_destroy();
  344. };
  345.  
  346. //
  347. // insert and append always return TRUE in an intrusive list, so that
  348. // intrusive and pointer classes have the same prototypes for the
  349. // WCPtrListBase class
  350. //
  351. template<class Type>
  352. WCbool WCIsvDListBase<Type>::insert( WCDLink * datum ) {
  353.     WCbool empty_list = (tail == 0);
  354.     base_insert( datum );
  355.     if( empty_list ) {
  356.         datum->prev.link = datum;
  357.     } else {
  358.         datum->prev.link = tail;
  359.         ((WCDLink *)datum->link)->prev.link = datum;
  360.     }
  361.     return( TRUE );
  362. };
  363.  
  364. template<class Type>
  365. WCbool WCIsvDListBase<Type>::append( WCDLink * datum ) {
  366.     insert( datum );
  367.     tail = datum;
  368.     return( TRUE );
  369. };
  370.  
  371.  
  372. template<class Type>
  373. inline int WCIsvDListBase<Type>::entries() const {
  374.     return( entry_count );
  375. };
  376.  
  377. template<class Type>
  378. inline WCDLink * WCIsvDListBase<Type>::get( int index ) {
  379.     return( base_dget( index ) );
  380. };
  381.  
  382. template<class Type>
  383. inline WCDLink * WCIsvDListBase<Type>::find( int index ) const {
  384.     return( base_dfind( index ) );
  385. };
  386.  
  387. template<class Type>
  388. inline WCDLink * WCIsvDListBase<Type>::findLast() const {
  389.     if( tail == 0 ) {
  390.         base_throw_empty_container();
  391.     }
  392.     return( (WCDLink *)tail );
  393. };
  394.  
  395. //
  396. // This index member function which is passed a test_fn is define for only
  397. // the WCIsvDList class.  Only a single index function is
  398. // defined in WCValListBase and WCPtrDList to ensure this
  399. // member function is unavailable to the value and pointer classes.
  400. //
  401. template<class Type>
  402. inline int WCIsvDListBase<Type>::index(
  403.                   register int (*test_fn)( const Type *elem, void *datum )
  404.                 , void *datum ) const {
  405.     int index = 0;
  406.  
  407.     Type * rover = (Type *)base_next( rover, TRUE );
  408.     while( rover != 0 ) {
  409.         if( (*test_fn)( rover, datum ) ) {
  410.             return( index );
  411.         }
  412.         rover = (Type *)base_next( rover, FALSE );
  413.         index++;
  414.     } 
  415.     return( -1 );
  416. };
  417.  
  418. template<class Type>
  419. inline int WCIsvDListBase<Type>::index( const WCDLink * datum ) const {
  420.     return( base_index( datum ) );
  421. };
  422.  
  423. template<class Type>
  424. inline WCbool WCIsvDListBase<Type>::contains( const WCDLink * datum ) const {
  425.     return( base_contains( datum ) );
  426. };
  427.  
  428. template<class Type>
  429. inline WCbool WCIsvDListBase<Type>::isEmpty() const {
  430.     return( tail == 0 );
  431. };
  432.  
  433. template<class Type>
  434. void WCIsvDListBase<Type>::forAll(
  435.                 register void (* func)( Type *, void * ), void * datum ) const {
  436.     Type * rover = (Type *)base_next( rover, TRUE );
  437.     while( rover != 0 ) {
  438.         (*func)( rover, datum );
  439.         rover = (Type *)base_next( rover, FALSE );
  440.     } 
  441. };
  442.  
  443.  
  444.  
  445.  
  446. //
  447. //  The WCValListBase template class is used as a basis for non-intrusive
  448. //  (value) lists.  The template supplies the type of the list data,
  449. //  the methods for manipulating the list, and the link type of the list.
  450. //
  451. //  The member functions clear() and clearAndDestroy() perform the same
  452. //  action since this is a value list (the list elements were created by
  453. //  the list to contain the values, so we must destroy them.  But we can't
  454. //  get rid of the list elements without getting rid of the values).
  455. //
  456. //  It is an abstract base class to prevent objects of this class
  457. //  from being created.
  458. //
  459.  
  460. template<class Type, class FType, class LType >
  461. class WCValListBase : public FType {
  462. private:
  463.     //
  464.     // These store the user allocator and deallocator functions for getting
  465.     // and freeing raw memory for list links.
  466.     // If NULL, then new and delete are used to get and destroy raw memory.
  467.     // (see WCListNew and WCListDelete)
  468.     //
  469.     void * (* alloc_fn)( size_t );
  470.     void (* dealloc_fn)( void *, size_t );
  471.     //
  472.     // For the value list classes, this virtual function does equivalence
  473.     // based on Type's equivalence operator, and for pointer list classes,
  474.     // this does equivalence based on the equivalence operator of the type
  475.     // pointed to.  (Type's equivalence operator for WCValSList<Type>,
  476.     // WCValDList<Type> AND WCPtrSList<Type> and WCPtrDList<Type>)
  477.     //
  478.     virtual int base_equivalent( const Type&, const Type& ) const = 0;
  479. protected:    
  480.     //
  481.     // new and delete a link, where user_alloc and user_alloc functions
  482.     // will be called if the user supplied them.  If the user did not
  483.     // supply the user_alloc and user_dealloc functions, then these call
  484.     // the standard new and delete operators.
  485.     //
  486.     LType * WCListNew( const Type& datum );
  487.     virtual void WCListDelete( WCSLink * );
  488.  
  489.     // value and pointer list classes copy constructor base
  490.     void base_construct( const WCValListBase * );
  491.     // value and pointer list classes assignment operator base
  492.     void base_assign( const WCValListBase * );
  493.  
  494. public:
  495.     inline WCValListBase( void * (*user_alloc)( size_t )
  496.                 , void (*user_dealloc)( void *, size_t )
  497.                 ) : alloc_fn( user_alloc ), dealloc_fn( user_dealloc ) {};
  498.     inline WCValListBase() : alloc_fn( 0 ), dealloc_fn( 0 ) {};
  499.     virtual ~WCValListBase() = 0;
  500.  
  501.     inline void clear()  {
  502.         FType::clearAndDestroy();
  503.     };
  504.  
  505.     inline void clearAndDestroy()  {
  506.         FType::clearAndDestroy();
  507.     };
  508.  
  509.     inline WCbool isEmpty() const {
  510.         return( FType::isEmpty() );
  511.     };
  512.  
  513.     inline int entries() const {
  514.         return( FType::entries() );
  515.     };
  516.  
  517.     inline WCbool contains( const Type &elem ) const {
  518.         return( index( elem ) != -1 );
  519.     };
  520.  
  521.     int index( const Type & ) const;
  522.  
  523.     Type get( int = 0 );
  524.     Type find( int = 0 ) const;
  525.     Type findLast() const;
  526.     void forAll( void (*)( Type, void * ), void *) const;
  527.     WCbool insert( const Type& datum );
  528.     WCbool append( const Type& datum );
  529. };
  530.  
  531.  
  532. template<class Type, class FType, class LType>
  533. LType * WCValListBase<Type,FType,LType>::WCListNew( const Type& datum ){
  534.     LType *new_link;
  535.  
  536.     if( alloc_fn ) {
  537.         new_link = (LType *)alloc_fn( sizeof( LType ) );
  538.     } else {
  539.         // assuming sizeof( char ) == 1
  540.         new_link = (LType *)new char[ sizeof( LType ) ];
  541.     }
  542.     //
  543.     // call constructor on the uninitialized memory new_link using
  544.     // WCNIsvLinkAlloc's operator new
  545.     // 
  546.     if( new_link ) {
  547.         new( new_link ) LType( datum );
  548.     }
  549.     return( new_link );
  550. }
  551.  
  552.  
  553. template<class Type, class FType, class LType>
  554. void WCValListBase<Type,FType,LType>::WCListDelete( WCSLink * old_link ){
  555.     if( old_link ) {
  556.         ( (LType *)old_link )->~LType();
  557.         if( dealloc_fn ) {
  558.             dealloc_fn( old_link, sizeof( LType ) );
  559.         } else {
  560.             delete [] (char *)old_link;
  561.         }
  562.     }
  563. }
  564.         
  565.  
  566. template<class Type, class FType, class LType>
  567. void WCValListBase<Type,FType,LType>::base_construct(
  568.                              const WCValListBase<Type,FType,LType> * olist ) {
  569.     
  570.     WCExcept::base_construct( olist );
  571.     alloc_fn = olist->alloc_fn;
  572.     dealloc_fn = olist->dealloc_fn;
  573.     LType * rover = (LType *)( olist->base_next( rover, TRUE ) );
  574.     while( rover != 0 ) {
  575.         append( rover->data );
  576.         rover = (LType *)( olist->base_next( rover, FALSE ) );
  577.     } 
  578. };
  579.  
  580.  
  581. template<class Type, class FType, class LType>
  582. void WCValListBase<Type,FType,LType>::base_assign(
  583.                               const WCValListBase<Type,FType,LType> * olist ) {
  584.     if( this != (WCValListBase * const)olist ) {
  585.         base_destroy();
  586.         base_construct( olist );
  587.     }
  588. };
  589.  
  590.  
  591. template<class Type, class FType, class LType>
  592. WCValListBase<Type,FType,LType>::~WCValListBase() {
  593.     if( tail != 0 ) {
  594.         base_throw_not_empty();
  595.         // we can destroy the list, since we allocated it
  596.         base_destroy();
  597.     }
  598. };
  599.  
  600.  
  601. template<class Type, class FType, class LType>
  602. WCbool WCValListBase<Type,FType,LType>::insert( const Type& datum ) {
  603.     LType * new_link = WCListNew( datum );
  604.     if( new_link != 0 ) {
  605.         return( FType::insert( new_link ) );
  606.     } else {
  607.         base_throw_out_of_memory();
  608.         return( FALSE );
  609.     }
  610. };
  611.  
  612.  
  613. template<class Type, class FType, class LType>
  614. WCbool WCValListBase<Type,FType,LType>::append( const Type& datum ) {
  615.     LType * new_link = WCListNew( datum );
  616.     if( new_link != 0 ) {
  617.         return( FType::append( new_link ) );
  618.     } else {
  619.         base_throw_out_of_memory();
  620.         return( FALSE );
  621.     }
  622. };
  623.  
  624.  
  625. template<class Type, class FType, class LType>
  626. int WCValListBase<Type,FType,LType>::index(
  627.                                         const Type & lookup_data ) const {
  628.     int index = 0;
  629.     LType * rover = (LType *)base_next( rover, TRUE );
  630.  
  631.     while( rover != 0 ) {
  632.         if( base_equivalent( rover->data, lookup_data ) ) {
  633.             return( index );
  634.         }
  635.         rover = (LType *)base_next( rover, FALSE );
  636.         index++;
  637.     } 
  638.     return( -1 );
  639. };
  640.  
  641.  
  642. template<class Type, class FType, class LType>
  643. Type WCValListBase<Type,FType,LType>::get( int index ) {
  644.     LType * ret_obj = (LType *)FType::get( index );
  645.     if( ret_obj == 0 ) {
  646.         Type ret_val;
  647.         return( ret_val );
  648.     } else {
  649.         Type ret_val = ret_obj->data;
  650.         WCListDelete( ret_obj );
  651.         return( ret_val );
  652.     }
  653. };
  654.  
  655.  
  656. template<class Type, class FType, class LType>
  657. Type WCValListBase<Type,FType,LType>::find( int index ) const {
  658.     LType * ret_obj = (LType *)FType::find( index );
  659.     if( ret_obj == 0 ) {
  660.         Type ret_val;
  661.         return( ret_val );
  662.     } else {
  663.         Type ret_val = ret_obj->data;
  664.         return( ret_val );
  665.     }
  666. };
  667.  
  668.  
  669. template<class Type, class FType, class LType>
  670. Type WCValListBase<Type,FType,LType>::findLast() const {
  671.     LType * ret_obj = (LType *)FType::findLast();
  672.     if( ret_obj == 0 ) {
  673.         Type ret_val;
  674.         return( ret_val );
  675.     } else {
  676.         Type ret_val = ret_obj->data;
  677.         return( ret_val );
  678.     }
  679. };
  680.  
  681.  
  682. template<class Type, class FType, class LType>
  683. void WCValListBase<Type,FType,LType>::forAll(
  684.                   register void (* func)( Type, void * ), void * datum ) const {
  685.     LType * rover = (LType *)base_next( rover, TRUE );
  686.     while( rover != 0 ) {
  687.         (*func)( rover->data, datum );
  688.         rover = (LType *)base_next( rover, FALSE );
  689.     } 
  690. };
  691.  
  692.  
  693.  
  694.  
  695. //
  696. //  The WCPtrListBase template class is used as a basis for the WCPtrSList,
  697. //  WCPtrDList, WCIsvSList and WCIsvDList classes. The template supplies
  698. //  the type of the list data and the methods for manipulating the list.
  699. //
  700. //  It is an abstract base class to prevent objects of this class
  701. //  from being created.
  702. //
  703.  
  704. template<class Type, class FType>
  705. class WCPtrListBase : public FType {
  706. public:
  707.     inline WCPtrListBase( void * (*user_alloc)( size_t )
  708.                 , void (*user_dealloc)( void *, size_t )
  709.                 ) : FType ( user_alloc, user_dealloc ) {};
  710.  
  711.     inline WCPtrListBase() : FType( 0, 0 ) {};
  712.  
  713.     inline virtual ~WCPtrListBase() = 0;
  714.  
  715.     inline void clear() {
  716.         FType::clear();
  717.     };
  718.  
  719.     inline WCbool insert( Type * ptr )  {
  720.         return( FType::insert( ptr ) );
  721.     };
  722.  
  723.     inline WCbool append( Type * ptr )  {
  724.         return( FType::append( ptr ) );
  725.     };
  726.  
  727.     inline WCbool contains( const Type * ptr ) const {
  728.         return( FType::contains( (Type *)ptr ) );
  729.     };
  730.  
  731.     //
  732.     // the index member function is not inlined here since intrusive
  733.     // and pointer classes inherit the index member functions with different
  734.     // prototypes
  735.     //
  736.  
  737.     inline WCbool isEmpty() const {
  738.         return( FType::isEmpty() );
  739.     };
  740.  
  741.     inline int entries() const {
  742.         return( FType::entries() );
  743.     };
  744.  
  745.     inline Type * get( int index = 0 ) {
  746.         return( (Type *)FType::get( index ) );
  747.     };
  748.  
  749.     inline Type * find( int index = 0 ) const {
  750.         return( (Type *)FType::find( index ) );
  751.     };
  752.  
  753.     inline Type * findLast() const {
  754.         return( (Type *)FType::findLast() );
  755.     };
  756.  
  757.     inline void forAll( void (* func)( Type *, void * ), void * datum ) const {
  758.         FType::forAll( func, datum );
  759.     };
  760.  
  761.     void clearAndDestroy();
  762. };
  763.  
  764. template<class Type, class FType>
  765. inline WCPtrListBase<Type,FType>::~WCPtrListBase() {};
  766.  
  767.  
  768. template<class Type, class FType>
  769. void WCPtrListBase<Type,FType>::clearAndDestroy() {
  770.     Type *  ptr_val;
  771.     while( !isEmpty() ) {
  772.         ptr_val = get();
  773.         delete ptr_val;
  774.     }
  775.     clear();
  776. }
  777.  
  778. #if defined( _WNEW_OPERATOR )
  779. #  define new _WNEW_OPERATOR
  780. #endif
  781. #if defined( _WDELETE_OPERATOR )
  782. #  define delete _WDELETE_OPERATOR
  783. #endif
  784.  
  785. #endif
  786.