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