// // wclbase.h Definitions for the base classes used by // the WATCOM Container List Class // // ========================================================================= // // Open Watcom Project // // Copyright (c) 2002-2010 Open Watcom Contributors. All Rights Reserved. // Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. // // This file is automatically generated. Do not edit directly. // // ========================================================================= // #ifndef _WCLBASE_H_INCLUDED #define _WCLBASE_H_INCLUDED #ifndef _ENABLE_AUTODEPEND #pragma read_only_file; #endif #ifndef __cplusplus #error This header file requires C++ #endif #ifndef _COMDEF_H_INCLUDED #include <_comdef.h> #endif #ifndef _WCDEFS_H_INCLUDED #include #endif // // This warning would be generated by taking the sizeof an object derived // from WCSLink or WCDLink, required for user allocator and deallocators // // "Warning! W549: 'sizeof' operand contains compiler generated information" #pragma warning 549 9 #if defined( new ) && defined( _WNEW_OPERATOR ) #undef new #endif #if defined( delete ) && defined( _WDELETE_OPERATOR ) #undef delete #endif // // The WCNIsvSLink class is used as a basis for non-intrusive singly // linked lists. // template class WCNIsvSLink : public WCSLink { public: Type data; inline WCNIsvSLink( const Type & datum ) : data( datum ) {}; inline ~WCNIsvSLink() {}; // // Just return ptr (passed by the new operator in WCListNew) without // allocating any memory. // Needed so we can call the constructor on user allocated memory. // inline void * operator new( size_t, void * ptr ) { return( ptr ); } }; // // The WCNIsvDLink class is used as a basis for non-intrusive doubly // linked lists. // template class WCNIsvDLink : public WCDLink { public: Type data; inline WCNIsvDLink( const Type & datum ) : data( datum ) {}; inline ~WCNIsvDLink() {}; // // Just return ptr (passed by the new operator in WCListNew) without // allocating any memory. // Needed so we can call the constructor on user allocated memory. // inline void * operator new( size_t, void * ptr ) { return( ptr ); } }; // // macros to allow the user to find the size of the list elements allocated // and freed by user allocator and deallocator functions // #define WCValSListItemSize( Type ) sizeof( WCNIsvSLink ) #define WCValDListItemSize( Type ) sizeof( WCNIsvDLink ) #define WCPtrSListItemSize( Type ) sizeof( WCNIsvSLink ) #define WCPtrDListItemSize( Type ) sizeof( WCNIsvDLink ) // // The WCIsvListBase class is used as a basis for intrusive lists. // It provides the common data and base functionality. The WCExcept // class provides the common exception handling for all lists. // // This class is also used by the value classes. The values // are encapsulated in non-intrusive links which are then stored // in the list intrusively. // // It is an abstract base class to prevent objects of this class // from being created. // class WCIsvListBase : public WCExcept { protected: WCSLink * tail; int entry_count; _WPRTLINK void base_insert( WCSLink * ); _WPRTLINK WCSLink * base_next( const WCSLink *, WCbool ) const; _WPRTLINK int base_index_check( int ) const; _WPRTLINK WCSLink * base_sget( int ); _WPRTLINK WCDLink * base_dget( int ); _WPRTLINK WCSLink * base_bfind( int ) const; _WPRTLINK WCSLink * base_sfind( int ) const; _WPRTLINK WCDLink * base_dfind( int ) const; _WPRTLINK int base_index( const WCSLink * ) const; inline WCbool base_contains( const WCSLink * ) const; _WPRTLINK void base_clear( void ); _WPRTLINK void base_destroy( void ); virtual void WCListDelete( WCSLink * datum ) = 0; public: inline WCIsvListBase() : tail(0), entry_count(0) {}; virtual ~WCIsvListBase() = 0; int operator==( const WCIsvListBase &rhs ) const { return( this == &rhs ); }; friend class WCListIterBase; }; WCbool WCIsvListBase::base_contains( const WCSLink * elem ) const { return( base_index( elem ) != -1 ); }; // // The WCIsvSListBase class defines an intrusive singly linked list // base class. // // It is an abstract base class to prevent objects of this class // from being created. // template class WCIsvSListBase : public WCIsvListBase { protected: void clear(); void clearAndDestroy(); WCbool insert( WCSLink * ); WCbool append( WCSLink * ); WCSLink * get( int = 0 ); WCSLink * find( int = 0 ) const; WCSLink * findLast() const; int index( int (*test_fn)( const Type *, void * ) , void * ) const; int index( const WCSLink * ) const; WCbool contains( const WCSLink * ) const; WCbool isEmpty() const; int entries() const; void forAll( void (*)( Type *, void * ), void *) const; // used by clearAndDestroy virtual void WCListDelete( WCSLink * datum ) { delete (Type *)datum; }; public: inline WCIsvSListBase( void * (*)( size_t ) , void (*)( void *, size_t ) ) { }; inline WCIsvSListBase() {}; inline virtual ~WCIsvSListBase() = 0; }; template inline WCIsvSListBase::~WCIsvSListBase() {}; template inline void WCIsvSListBase::clear() { base_clear(); }; template inline void WCIsvSListBase::clearAndDestroy() { base_destroy(); }; // // insert and append always return TRUE in an intrusive list, so that // intrusive and pointer classes have the same prototypes for the // WCPtrListBase class // template inline WCbool WCIsvSListBase::insert( WCSLink * datum ) { base_insert( datum ); return( TRUE ); }; template inline WCbool WCIsvSListBase::append( WCSLink * datum ) { insert( datum ); tail = datum; return( TRUE ); }; template inline WCSLink * WCIsvSListBase::get( int index ) { return( base_sget( index ) ); }; template inline WCSLink * WCIsvSListBase::find( int index ) const { return( base_sfind( index ) ); }; template inline WCSLink * WCIsvSListBase::findLast() const { if( tail == 0 ) { base_throw_empty_container(); } return( tail ); }; // // This index member function which is passed a test_fn is define for only // the WCIsvSList classes. Only a single index function is // defined in WCValListBase and WCPtrSList to ensure this // member function is unavailable to the value and pointer classes. // template inline int WCIsvSListBase::index( int (*test_fn)( const Type *elem, void *datum ) , void *datum ) const { int index = 0; Type * rover = (Type *)base_next( rover, TRUE ); while( rover != 0 ) { if( (*test_fn)( rover, datum ) ) { return( index ); } rover = (Type *)base_next( rover, FALSE ); index++; } return( -1 ); }; template inline int WCIsvSListBase::index( const WCSLink * datum ) const { return( base_index( datum ) ); }; template inline WCbool WCIsvSListBase::contains( const WCSLink * datum ) const { return( base_contains( datum ) ); }; template inline WCbool WCIsvSListBase::isEmpty() const { return( tail == 0 ); }; template inline int WCIsvSListBase::entries() const { return( entry_count ); }; template void WCIsvSListBase::forAll( void (* func)( Type *, void * ), void * datum ) const { Type * rover = (Type *)base_next( rover, TRUE ); while( rover != 0 ) { (*func)( rover, datum ); rover = (Type *)base_next( rover, FALSE ); } }; // // The WCIsvDListBase class defines an intrusive doubly linked list // base class. // // It is an abstract base class to prevent objects of this class // from being created. // template class WCIsvDListBase : public WCIsvListBase { protected: void clear(); void clearAndDestroy(); WCbool insert( WCDLink * ); WCbool append( WCDLink * ); WCDLink * get( int = 0 ); WCDLink * find( int = 0 ) const; WCDLink * findLast() const; int index( int (*test_fn)( const Type *, void * ) , void * ) const; int index( const WCDLink * ) const; WCbool contains( const WCDLink * ) const; WCbool isEmpty() const; int entries() const; void forAll( void (*)( Type *, void * ), void *) const; // used by clearAndDestroy virtual void WCListDelete( WCSLink * datum ) { delete (Type *)datum; }; public: inline WCIsvDListBase( void * (*)( size_t ) , void (*)( void *, size_t ) ) {}; inline WCIsvDListBase() {}; inline virtual ~WCIsvDListBase() = 0; }; template inline WCIsvDListBase::~WCIsvDListBase() {}; template inline void WCIsvDListBase::clear() { base_clear(); }; template inline void WCIsvDListBase::clearAndDestroy() { base_destroy(); }; // // insert and append always return TRUE in an intrusive list, so that // intrusive and pointer classes have the same prototypes for the // WCPtrListBase class // template WCbool WCIsvDListBase::insert( WCDLink * datum ) { WCbool empty_list = (tail == 0); base_insert( datum ); if( empty_list ) { datum->prev.link = datum; } else { datum->prev.link = tail; ((WCDLink *)datum->link)->prev.link = datum; } return( TRUE ); }; template WCbool WCIsvDListBase::append( WCDLink * datum ) { insert( datum ); tail = datum; return( TRUE ); }; template inline int WCIsvDListBase::entries() const { return( entry_count ); }; template inline WCDLink * WCIsvDListBase::get( int index ) { return( base_dget( index ) ); }; template inline WCDLink * WCIsvDListBase::find( int index ) const { return( base_dfind( index ) ); }; template inline WCDLink * WCIsvDListBase::findLast() const { if( tail == 0 ) { base_throw_empty_container(); } return( (WCDLink *)tail ); }; // // This index member function which is passed a test_fn is define for only // the WCIsvDList class. Only a single index function is // defined in WCValListBase and WCPtrDList to ensure this // member function is unavailable to the value and pointer classes. // template inline int WCIsvDListBase::index( int (*test_fn)( const Type *elem, void *datum ) , void *datum ) const { int index = 0; Type * rover = (Type *)base_next( rover, TRUE ); while( rover != 0 ) { if( (*test_fn)( rover, datum ) ) { return( index ); } rover = (Type *)base_next( rover, FALSE ); index++; } return( -1 ); }; template inline int WCIsvDListBase::index( const WCDLink * datum ) const { return( base_index( datum ) ); }; template inline WCbool WCIsvDListBase::contains( const WCDLink * datum ) const { return( base_contains( datum ) ); }; template inline WCbool WCIsvDListBase::isEmpty() const { return( tail == 0 ); }; template void WCIsvDListBase::forAll( void (* func)( Type *, void * ), void * datum ) const { Type * rover = (Type *)base_next( rover, TRUE ); while( rover != 0 ) { (*func)( rover, datum ); rover = (Type *)base_next( rover, FALSE ); } }; // // The WCValListBase template class is used as a basis for non-intrusive // (value) lists. The template supplies the type of the list data, // the methods for manipulating the list, and the link type of the list. // // The member functions clear() and clearAndDestroy() perform the same // action since this is a value list (the list elements were created by // the list to contain the values, so we must destroy them. But we can't // get rid of the list elements without getting rid of the values). // // It is an abstract base class to prevent objects of this class // from being created. // template class WCValListBase : public FType { private: // // These store the user allocator and deallocator functions for getting // and freeing raw memory for list links. // If NULL, then new and delete are used to get and destroy raw memory. // (see WCListNew and WCListDelete) // void * (* alloc_fn)( size_t ); void (* dealloc_fn)( void *, size_t ); // // For the value list classes, this virtual function does equivalence // based on Type's equivalence operator, and for pointer list classes, // this does equivalence based on the equivalence operator of the type // pointed to. (Type's equivalence operator for WCValSList, // WCValDList AND WCPtrSList and WCPtrDList) // virtual int base_equivalent( const Type&, const Type& ) const = 0; protected: // // new and delete a link, where user_alloc and user_alloc functions // will be called if the user supplied them. If the user did not // supply the user_alloc and user_dealloc functions, then these call // the standard new and delete operators. // LType * WCListNew( const Type& datum ); virtual void WCListDelete( WCSLink * ); // value and pointer list classes copy constructor base void base_construct( const WCValListBase * ); // value and pointer list classes assignment operator base void base_assign( const WCValListBase * ); public: inline WCValListBase( void * (*user_alloc)( size_t ) , void (*user_dealloc)( void *, size_t ) ) : alloc_fn( user_alloc ), dealloc_fn( user_dealloc ) {}; inline WCValListBase() : alloc_fn( 0 ), dealloc_fn( 0 ) {}; virtual ~WCValListBase() = 0; inline void clear() { FType::clearAndDestroy(); }; inline void clearAndDestroy() { FType::clearAndDestroy(); }; inline WCbool isEmpty() const { return( FType::isEmpty() ); }; inline int entries() const { return( FType::entries() ); }; inline WCbool contains( const Type &elem ) const { return( index( elem ) != -1 ); }; int index( const Type & ) const; Type get( int = 0 ); Type find( int = 0 ) const; Type findLast() const; void forAll( void (*)( Type, void * ), void *) const; WCbool insert( const Type& datum ); WCbool append( const Type& datum ); }; template LType * WCValListBase::WCListNew( const Type& datum ){ LType *new_link; if( alloc_fn ) { new_link = (LType *)alloc_fn( sizeof( LType ) ); } else { // assuming sizeof( char ) == 1 new_link = (LType *)new char[ sizeof( LType ) ]; } // // call constructor on the uninitialized memory new_link using // WCNIsvLinkAlloc's operator new // if( new_link ) { new( new_link ) LType( datum ); } return( new_link ); } template void WCValListBase::WCListDelete( WCSLink * old_link ){ if( old_link ) { ( (LType *)old_link )->~LType(); if( dealloc_fn ) { dealloc_fn( old_link, sizeof( LType ) ); } else { delete [] (char *)old_link; } } } template void WCValListBase::base_construct( const WCValListBase * olist ) { WCExcept::base_construct( olist ); alloc_fn = olist->alloc_fn; dealloc_fn = olist->dealloc_fn; LType * rover = (LType *)( olist->base_next( rover, TRUE ) ); while( rover != 0 ) { append( rover->data ); rover = (LType *)( olist->base_next( rover, FALSE ) ); } }; template void WCValListBase::base_assign( const WCValListBase * olist ) { if( this != (WCValListBase * const)olist ) { base_destroy(); base_construct( olist ); } }; template WCValListBase::~WCValListBase() { if( tail != 0 ) { base_throw_not_empty(); // we can destroy the list, since we allocated it base_destroy(); } }; template WCbool WCValListBase::insert( const Type& datum ) { LType * new_link = WCListNew( datum ); if( new_link != 0 ) { return( FType::insert( new_link ) ); } else { base_throw_out_of_memory(); return( FALSE ); } }; template WCbool WCValListBase::append( const Type& datum ) { LType * new_link = WCListNew( datum ); if( new_link != 0 ) { return( FType::append( new_link ) ); } else { base_throw_out_of_memory(); return( FALSE ); } }; template int WCValListBase::index( const Type & lookup_data ) const { int index = 0; LType * rover = (LType *)base_next( rover, TRUE ); while( rover != 0 ) { if( base_equivalent( rover->data, lookup_data ) ) { return( index ); } rover = (LType *)base_next( rover, FALSE ); index++; } return( -1 ); }; template Type WCValListBase::get( int index ) { LType * ret_obj = (LType *)FType::get( index ); if( ret_obj == 0 ) { Type ret_val; return( ret_val ); } else { Type ret_val = ret_obj->data; WCListDelete( ret_obj ); return( ret_val ); } }; template Type WCValListBase::find( int index ) const { LType * ret_obj = (LType *)FType::find( index ); if( ret_obj == 0 ) { Type ret_val; return( ret_val ); } else { Type ret_val = ret_obj->data; return( ret_val ); } }; template Type WCValListBase::findLast() const { LType * ret_obj = (LType *)FType::findLast(); if( ret_obj == 0 ) { Type ret_val; return( ret_val ); } else { Type ret_val = ret_obj->data; return( ret_val ); } }; template void WCValListBase::forAll( void (* func)( Type, void * ), void * datum ) const { LType * rover = (LType *)base_next( rover, TRUE ); while( rover != 0 ) { (*func)( rover->data, datum ); rover = (LType *)base_next( rover, FALSE ); } }; // // The WCPtrListBase template class is used as a basis for the WCPtrSList, // WCPtrDList, WCIsvSList and WCIsvDList classes. The template supplies // the type of the list data and the methods for manipulating the list. // // It is an abstract base class to prevent objects of this class // from being created. // template class WCPtrListBase : public FType { public: inline WCPtrListBase( void * (*user_alloc)( size_t ) , void (*user_dealloc)( void *, size_t ) ) : FType ( user_alloc, user_dealloc ) {}; inline WCPtrListBase() : FType( 0, 0 ) {}; inline virtual ~WCPtrListBase() = 0; inline void clear() { FType::clear(); }; inline WCbool insert( Type * ptr ) { return( FType::insert( ptr ) ); }; inline WCbool append( Type * ptr ) { return( FType::append( ptr ) ); }; inline WCbool contains( const Type * ptr ) const { return( FType::contains( (Type *)ptr ) ); }; // // the index member function is not inlined here since intrusive // and pointer classes inherit the index member functions with different // prototypes // inline WCbool isEmpty() const { return( FType::isEmpty() ); }; inline int entries() const { return( FType::entries() ); }; inline Type * get( int index = 0 ) { return( (Type *)FType::get( index ) ); }; inline Type * find( int index = 0 ) const { return( (Type *)FType::find( index ) ); }; inline Type * findLast() const { return( (Type *)FType::findLast() ); }; inline void forAll( void (* func)( Type *, void * ), void * datum ) const { FType::forAll( func, datum ); }; void clearAndDestroy(); }; template inline WCPtrListBase::~WCPtrListBase() {}; template void WCPtrListBase::clearAndDestroy() { Type * ptr_val; while( !isEmpty() ) { ptr_val = get(); delete ptr_val; } clear(); } #ifdef _WNEW_OPERATOR #define new _WNEW_OPERATOR #endif #ifdef _WDELETE_OPERATOR #define delete _WDELETE_OPERATOR #endif #endif