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

  1. //
  2. //  wclibase.h    Defines for the WATCOM Container List Iterator Base Classes
  3. //
  4. //  Copyright by WATCOM International Corp. 1988-1996.  All rights reserved.
  5. //
  6. #ifndef _WCLIBASE_H_INCLUDED
  7. #define _WCLIBASE_H_INCLUDED
  8.  
  9. #ifndef __cplusplus
  10. #error wclibase.h is for use with C++
  11. #endif
  12.  
  13. #ifndef _WCDEFS_H_INCLUDED
  14.  #include <wcdefs.h>
  15. #endif
  16. #ifndef _WCEXCEPT_H_INCLUDED
  17.  #include <wcexcept.h>
  18. #endif
  19.  
  20.  
  21. //
  22. //  The WCListIterBase class is used as a basis for the iterator
  23. //  classes for the various list containers. 
  24. //
  25. //  It is an abstract base class to prevent objects of this class
  26. //  from being created.
  27. //
  28.  
  29. class WCListIterBase : public WCIterExcept {
  30. protected:
  31.     enum {                      // flags for outside_list
  32.         before_first    = 1,
  33.         after_last
  34.     };
  35.     WCIsvListBase *     curr_list;
  36.     WCSLink *           curr_item;
  37.     // if outside_list is non-zero, curr_item must be 0.
  38.     int                 outside_list;
  39.  
  40.     _WPRTLINK WCSLink *          base_advance( int );
  41.     _WPRTLINK WCDLink *          base_retreat( int );
  42.     inline WCSLink *         base_get_tail() {
  43.         return( curr_list->tail );
  44.     };
  45.  
  46.     // helpers for insert and append
  47.     _WPRTLINK WCSLink *          base_tail_hit( WCSLink * );
  48.     _WPRTLINK void               base_tail_unhit( WCSLink * );
  49.  
  50.     inline void base_reset();
  51.     inline void base_reset_list( WCIsvListBase * list );
  52.  
  53. public:
  54.     inline WCListIterBase() : curr_item( 0 ), curr_list( 0 )
  55.                                 , outside_list( 0 ) {};
  56.     inline WCListIterBase( WCIsvListBase * list )
  57.                          : curr_item( 0 ), curr_list( list )
  58.                          , outside_list( before_first ) {};
  59.     inline virtual ~WCListIterBase() = 0;
  60.  
  61.     inline WCSLink * operator()();
  62.     inline WCSLink * operator++();
  63.     inline WCSLink * operator+=( int );
  64.     inline WCDLink * operator--();
  65.     inline WCDLink * operator-=( int );
  66. };
  67.  
  68. inline WCListIterBase::~WCListIterBase() {};
  69.  
  70. inline void WCListIterBase::base_reset() {
  71.     curr_item = 0;
  72.     outside_list = before_first;
  73. }
  74.  
  75. inline void WCListIterBase::base_reset_list( WCIsvListBase * list ) {
  76.     curr_list = list;
  77.     base_reset();
  78. }
  79.  
  80. inline WCSLink * WCListIterBase::operator()() {
  81.     return( base_advance( 1 ) );
  82. }
  83.  
  84. inline WCSLink * WCListIterBase::operator++() {
  85.     return( base_advance( 1 ) );
  86. }
  87.  
  88. inline WCDLink * WCListIterBase::operator--() {
  89.     return( base_retreat( 1 ) );
  90. }
  91.  
  92. inline WCSLink * WCListIterBase::operator+=( int incr_amount ) {
  93.     return( base_advance( incr_amount ) );
  94. }
  95.  
  96. inline WCDLink * WCListIterBase::operator-=( int incr_amount ) {
  97.     return( base_retreat( incr_amount ) );
  98. }
  99.  
  100.  
  101.  
  102.  
  103. //
  104. //  The WCIsvListIterBase defines the base iterator class for intrusive
  105. //  value type containers.
  106. //
  107.  
  108. template<class Type, class FType>
  109. class WCIsvListIterBase : public WCListIterBase {
  110. public:
  111.     inline WCIsvListIterBase() {};
  112.     inline virtual ~WCIsvListIterBase() = 0;
  113.     inline WCIsvListIterBase( FType * slist ) : WCListIterBase( slist ) {};
  114.  
  115.     inline void reset( FType & slist ) {
  116.         WCListIterBase::base_reset_list( &slist );
  117.     };
  118.  
  119.     inline void reset() {
  120.         WCListIterBase::base_reset();
  121.     };
  122.  
  123.     inline Type * operator()() {
  124.         return( (Type *)WCListIterBase::operator()() );
  125.     };
  126.     
  127.     inline Type * operator++() {
  128.         return( (Type *)WCListIterBase::operator++() );
  129.     };
  130.     
  131.     inline Type * operator--() {
  132.         return( (Type *)WCListIterBase::operator--() );
  133.     };
  134.     
  135.     inline Type * operator+=( int adv_amount ) {
  136.         return( (Type *)WCListIterBase::operator+=( adv_amount ) );
  137.     };
  138.     
  139.     inline Type * operator-=( int adv_amount ) {
  140.         return( (Type *)WCListIterBase::operator-=( adv_amount ) );
  141.     };
  142.     
  143.     inline Type * current() const {
  144.         if( ( curr_list == 0 )||( curr_item == 0 ) ) {
  145.             base_throw_undef_item();
  146.             return( 0 );
  147.         }
  148.         return( (Type *)curr_item );
  149.     };
  150.     
  151.     inline FType * container() const {
  152.         if( curr_list == 0 ) {
  153.             base_throw_undef_iter();
  154.         }
  155.         return( (FType *)curr_list );
  156.     };
  157.  
  158.     WCbool insert( Type * );
  159.  
  160.     WCbool append( Type * );
  161. };
  162.  
  163. template<class Type, class FType>
  164. inline WCIsvListIterBase<Type,FType>::~WCIsvListIterBase() {};
  165.  
  166. template<class Type, class FType>
  167. WCbool WCIsvListIterBase<Type,FType>::insert( Type * datum ) {
  168.     if( ( curr_list == 0 )||( curr_item == 0 ) ) {
  169.         base_throw_undef_iter();
  170.         return( FALSE );
  171.     }
  172.     WCSLink * prev_item = curr_item;
  173.     WCbool ret_val;
  174.     if( prev_item != 0 ) {
  175.         prev_item = ((WCDLink *)prev_item)->prev.link;
  176.     }
  177.     // make the tail the element before the element being inserted
  178.     WCSLink * curr_tail = base_tail_hit( prev_item );
  179.     ret_val = ((FType *)curr_list)->insert( datum );
  180.     // restore the tail
  181.     base_tail_unhit( curr_tail );
  182.     return( ret_val );
  183. };
  184.  
  185. template<class Type, class FType>
  186. WCbool WCIsvListIterBase<Type,FType>::append( Type * datum ) {
  187.     if( ( curr_list == 0 )||( curr_item == 0 ) ) {
  188.         base_throw_undef_iter();
  189.         return( FALSE );
  190.     }
  191.     WCbool ret_val;
  192.     if( curr_item == base_get_tail() ) {
  193.         // append the new element to the end of the list
  194.         ret_val = ((FType *)curr_list)->append( datum );
  195.     } else {
  196.         // the new element is not the last element in the list, so make
  197.         // the tail the element before the new element (curr_item)
  198.         WCSLink * curr_tail = base_tail_hit( curr_item );
  199.         ret_val = ((FType *)curr_list)->insert( datum );
  200.         // restore the tail
  201.         base_tail_unhit( curr_tail );
  202.     }
  203.     return( ret_val );
  204. };
  205.  
  206.  
  207.  
  208.  
  209. //
  210. //  The WCValListIterBase defines the base iterator class for value type
  211. //  containers.
  212. //
  213.  
  214. template<class Type, class FType, class LType>
  215. class WCValListIterBase : public WCListIterBase {
  216. public:
  217.     inline WCValListIterBase() {};
  218.     inline virtual ~WCValListIterBase() = 0;
  219.     inline WCValListIterBase( FType * slist ) : WCListIterBase( slist ) {};
  220.  
  221.     inline void reset( FType & dlist ) {
  222.         WCListIterBase::base_reset_list( &dlist );
  223.     };
  224.  
  225.     inline void reset() {
  226.         WCListIterBase::base_reset();
  227.     };
  228.  
  229.     inline int operator()() {
  230.         return( WCListIterBase::operator()() != 0 );
  231.     };
  232.     
  233.     inline int operator++() {
  234.         return( WCListIterBase::operator++() != 0 );
  235.     };
  236.     
  237.     inline int operator--() {
  238.         return( WCListIterBase::operator--() != 0 );
  239.     };
  240.     
  241.     inline int operator+=( int adv_amount ) {
  242.         return( WCListIterBase::operator+=( adv_amount ) != 0 );
  243.     };
  244.     
  245.     inline int operator-=( int adv_amount ) {
  246.         return( WCListIterBase::operator-=( adv_amount ) != 0 );
  247.     };
  248.  
  249.     inline FType * container() const {
  250.         if( curr_list == 0 ) {
  251.             base_throw_undef_iter();
  252.         }
  253.         return( (FType *)curr_list );
  254.     };
  255.  
  256.     Type current() const;
  257.  
  258.     WCbool insert( Type& );
  259.     
  260.     WCbool append( Type& );
  261. };
  262.  
  263. template<class Type, class FType, class LType>
  264. inline WCValListIterBase<Type,FType,LType>::~WCValListIterBase() {};
  265.  
  266. template<class Type, class FType, class LType>
  267. Type WCValListIterBase<Type,FType,LType>::current() const {
  268.     if( ( curr_list == 0 )||( curr_item == 0 ) ) {
  269.         base_throw_undef_item();
  270.         Type ret_val;
  271.         return( ret_val );
  272.     } else {
  273.         return( ((LType *)curr_item)->data );
  274.     }
  275. };
  276.  
  277. template<class Type, class FType, class LType>
  278. WCbool WCValListIterBase<Type,FType,LType>::insert( Type& datum ) {
  279.     if( ( curr_list == 0 )||( curr_item == 0 ) ) {
  280.         base_throw_undef_iter();
  281.         return( FALSE );
  282.     }
  283.     WCSLink * prev_item = curr_item;
  284.     WCbool ret_val;
  285.     if( prev_item != 0 ) {
  286.         prev_item = ((WCDLink *)prev_item)->prev.link;
  287.     }
  288.     // make the tail the element before the element being inserted
  289.     WCSLink * curr_tail = base_tail_hit( prev_item );
  290.     ret_val = ((FType *)curr_list)->insert( datum );
  291.     // restore the tail
  292.     base_tail_unhit( curr_tail );
  293.     return( ret_val );
  294. };
  295.  
  296. template<class Type, class FType, class LType>
  297. WCbool WCValListIterBase<Type,FType,LType>::append( Type& datum ) {
  298.     if( ( curr_list == 0 )||( curr_item == 0 ) ) {
  299.         base_throw_undef_iter();
  300.         return( FALSE );
  301.     }
  302.     WCbool ret_val;
  303.     if( curr_item == base_get_tail() ) {
  304.         // append the new element to the end of the list
  305.         ret_val = ((FType *)curr_list)->append( datum );
  306.     } else {
  307.         // the new element is not the last element in the list, so make
  308.         // the tail the element before the new element (curr_item)
  309.         WCSLink * curr_tail = base_tail_hit( curr_item );
  310.         ret_val = ((FType *)curr_list)->insert( datum );
  311.         // restore the tail
  312.         base_tail_unhit( curr_tail );
  313.     }
  314.     return( ret_val );
  315. };
  316.  
  317. #endif
  318.