wclbase.mh

来自「开放源码的编译器open watcom 1.6.0版的源代码」· MH 代码 · 共 778 行 · 第 1/2 页

MH
778
字号
//
//  wclbase.h    Definitions for the base classes used by
//               the WATCOM Container List Class
//
:keep CPP_HDR
:include crwat.sp
//
#ifndef _WCLBASE_H_INCLUDED
#define _WCLBASE_H_INCLUDED
:include readonly.sp

#ifndef __cplusplus
#error wclbase.h is for use with C++
#endif

#ifndef _WCDEFS_H_INCLUDED
 #include <wcdefs.h>
#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

:include undefnew.sp


//
//  The WCNIsvSLink class is used as a basis for non-intrusive singly
//  linked lists.
//

template<class Type>
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 Type>
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<Type> )
#define WCValDListItemSize( Type )      sizeof( WCNIsvDLink<Type> )
#define WCPtrSListItemSize( Type )      sizeof( WCNIsvSLink<void *> )
#define WCPtrDListItemSize( Type )      sizeof( WCNIsvDLink<void *> )




//
//  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 Type>
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<class Type>
inline WCIsvSListBase<Type>::~WCIsvSListBase() {};

template<class Type>
inline void WCIsvSListBase<Type>::clear() {
    base_clear();
};

template<class Type>
inline void WCIsvSListBase<Type>::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<class Type>
inline WCbool WCIsvSListBase<Type>::insert( WCSLink * datum ) {
    base_insert( datum );
    return( TRUE );
};

template<class Type>
inline WCbool WCIsvSListBase<Type>::append( WCSLink * datum ) {
    insert( datum );
    tail = datum;
    return( TRUE );
};

template<class Type>
inline WCSLink * WCIsvSListBase<Type>::get( int index ) {
    return( base_sget( index ) );
};

template<class Type>
inline WCSLink * WCIsvSListBase<Type>::find( int index ) const {
    return( base_sfind( index ) );
};

template<class Type>
inline WCSLink * WCIsvSListBase<Type>::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<class Type>
inline int WCIsvSListBase<Type>::index(
                  register 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<class Type>
inline int WCIsvSListBase<Type>::index( const WCSLink * datum ) const {
    return( base_index( datum ) );
};

template<class Type>
inline WCbool WCIsvSListBase<Type>::contains( const WCSLink * datum ) const {
    return( base_contains( datum ) );
};

template<class Type>
inline WCbool WCIsvSListBase<Type>::isEmpty() const {
    return( tail == 0 );
};

template<class Type>
inline int WCIsvSListBase<Type>::entries() const {
    return( entry_count );
};

template<class Type>
void WCIsvSListBase<Type>::forAll(
                register 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 Type>
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<class Type>
inline WCIsvDListBase<Type>::~WCIsvDListBase() {};

template<class Type>
inline void WCIsvDListBase<Type>::clear() {
    base_clear();
};

template<class Type>
inline void WCIsvDListBase<Type>::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<class Type>
WCbool WCIsvDListBase<Type>::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<class Type>
WCbool WCIsvDListBase<Type>::append( WCDLink * datum ) {
    insert( datum );
    tail = datum;
    return( TRUE );
};


template<class Type>
inline int WCIsvDListBase<Type>::entries() const {
    return( entry_count );
};

template<class Type>
inline WCDLink * WCIsvDListBase<Type>::get( int index ) {
    return( base_dget( index ) );
};

template<class Type>
inline WCDLink * WCIsvDListBase<Type>::find( int index ) const {
    return( base_dfind( index ) );
};

template<class Type>
inline WCDLink * WCIsvDListBase<Type>::findLast() const {
    if( tail == 0 ) {
        base_throw_empty_container();
    }
    return( (WCDLink *)tail );

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?