221 lines
10 KiB
C++
221 lines
10 KiB
C++
|
//+-------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Microsoft Windows
|
|||
|
//
|
|||
|
// Copyright (C) Microsoft Corporation, 1990 - 1999
|
|||
|
//
|
|||
|
// File: linklist.hxx
|
|||
|
//
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
|
|||
|
/* --------------------------------------------------------------------
|
|||
|
|
|||
|
Microsoft OS/2 LAN Manager
|
|||
|
Copyright(c) Microsoft Corp., 1990
|
|||
|
|
|||
|
RPC locator - Written by Steven Zeck
|
|||
|
|
|||
|
|
|||
|
This file contains a linked list class definition.
|
|||
|
This base class for Link and Item just contains a set of
|
|||
|
two pointers. Derived classes are created with the
|
|||
|
macros LinkList or LinkListClass (used for nested inheritance).
|
|||
|
These derived classes take your member data items and add them
|
|||
|
to the base class.
|
|||
|
|
|||
|
If you define a macro ASSERT_VCLASS/ASSERT_CLASS, then you must
|
|||
|
define a member method Assert for each class you derived which checks
|
|||
|
the runtime data consistance of the members you have added.
|
|||
|
-------------------------------------------------------------------- */
|
|||
|
|
|||
|
#ifndef _LINKLIST_
|
|||
|
#define _LINKLIST_
|
|||
|
|
|||
|
#ifndef ASSERT_VCLASS
|
|||
|
#define ASSERT_CLASS void Assert() {(void)(0);}
|
|||
|
#define ASSERT_VCLASS ASSERT_CLASS
|
|||
|
#endif
|
|||
|
|
|||
|
class LinkItem { // Linked list Item (LI) class *&
|
|||
|
|
|||
|
private:
|
|||
|
|
|||
|
LinkItem *pLINext; // Next and Previous Nodes
|
|||
|
LinkItem *pLIPrev;
|
|||
|
|
|||
|
public:
|
|||
|
friend class LinkList;
|
|||
|
ASSERT_VCLASS;
|
|||
|
|
|||
|
LinkItem *Next( // return the Next element on the list
|
|||
|
) {
|
|||
|
return (pLINext);
|
|||
|
}
|
|||
|
|
|||
|
void Remove(LinkList& pLLHead); // delete a LI from a LinkList
|
|||
|
};
|
|||
|
|
|||
|
class LinkList { // A Linked List (LL) class *&
|
|||
|
|
|||
|
friend class LinkItem;
|
|||
|
|
|||
|
private:
|
|||
|
|
|||
|
LinkItem *pLIHead; // Head of list
|
|||
|
LinkItem *pLITail; // Tail of list
|
|||
|
|
|||
|
public:
|
|||
|
|
|||
|
ASSERT_CLASS;
|
|||
|
|
|||
|
LinkList( // constructure for a new LL
|
|||
|
) {
|
|||
|
pLIHead = pLITail = Nil;
|
|||
|
}
|
|||
|
|
|||
|
void Add(LinkItem *pLInew); // Add new item item at head of list
|
|||
|
void Append(LinkItem *pLInew); // Append new item item at end of list
|
|||
|
|
|||
|
LinkItem *First( // return the First element on the list
|
|||
|
) {
|
|||
|
this->Assert();
|
|||
|
return (pLIHead);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// This macro is used to dervive a linked list from an existing class
|
|||
|
// This is a way to do multiple inheritance before C++ 2.0
|
|||
|
|
|||
|
#define LINK_LIST_DERVIVED(CLASS, DERVIVED, MEMBERS) \
|
|||
|
\
|
|||
|
class CLASS: public DERVIVED { \
|
|||
|
\
|
|||
|
private: \
|
|||
|
CLASS *pLINext; \
|
|||
|
CLASS *pLIPrev; \
|
|||
|
\
|
|||
|
MEMBERS \
|
|||
|
public: \
|
|||
|
friend class CLASS##List; \
|
|||
|
ASSERT_VCLASS; \
|
|||
|
\
|
|||
|
CLASS *Next( \
|
|||
|
) { \
|
|||
|
return ((pLINext)? (CLASS *) ((char *)pLINext - \
|
|||
|
(int) &(((CLASS *) 0)->pLINext) ): Nil); \
|
|||
|
} \
|
|||
|
\
|
|||
|
void Remove(CLASS##List& pLLHead) { \
|
|||
|
((LinkItem *)(&this->pLINext))->LinkItem::Remove(*(LinkList *) &pLLHead); \
|
|||
|
} \
|
|||
|
}; \
|
|||
|
\
|
|||
|
class CLASS##List { \
|
|||
|
\
|
|||
|
friend class CLASS; \
|
|||
|
\
|
|||
|
private: \
|
|||
|
\
|
|||
|
CLASS *pLIHead; \
|
|||
|
CLASS *pLITail; \
|
|||
|
public: \
|
|||
|
\
|
|||
|
ASSERT_CLASS; \
|
|||
|
\
|
|||
|
CLASS##List( \
|
|||
|
) { \
|
|||
|
pLIHead = pLITail = Nil; \
|
|||
|
} \
|
|||
|
\
|
|||
|
CLASS * Add(CLASS *pLInew) { \
|
|||
|
((LinkList *)(&this->pLIHead))->Add((LinkItem *) &pLInew->pLINext); \
|
|||
|
return(pLInew); \
|
|||
|
} \
|
|||
|
CLASS * Append(CLASS *pLInew) { \
|
|||
|
((LinkList *)(&this->pLIHead))->Append((LinkItem *) &pLInew->pLINext); \
|
|||
|
return(pLInew); \
|
|||
|
} \
|
|||
|
\
|
|||
|
CLASS *First( \
|
|||
|
) { \
|
|||
|
this->Assert(); \
|
|||
|
return ((pLIHead)? (CLASS *) ((char *)pLIHead - \
|
|||
|
(int) &(((CLASS *) 0)->pLINext) ): Nil); \
|
|||
|
} \
|
|||
|
}; \
|
|||
|
|
|||
|
#define ToItem(TYPE, arg) ((TYPE##Item *) ((char *)arg-sizeof(LinkList)))
|
|||
|
|
|||
|
// Include NIL_NEW, if you want Add/Append with default NEW constructors
|
|||
|
|
|||
|
#define NIL_NEW \
|
|||
|
\
|
|||
|
CLASS_PREFIX##Item *Add() { \
|
|||
|
\
|
|||
|
CLASS_PREFIX##Item *pLLI = new CLASS_PREFIX##Item; \
|
|||
|
if (pLLI != 0) \
|
|||
|
LinkList::Add(pLLI); \
|
|||
|
return (pLLI); \
|
|||
|
} \
|
|||
|
\
|
|||
|
\
|
|||
|
CLASS_PREFIX##Item *Append() { \
|
|||
|
\
|
|||
|
CLASS_PREFIX##Item *pLLI = new CLASS_PREFIX##Item; \
|
|||
|
if (pLLI != 0) \
|
|||
|
LinkList::Append(pLLI); \
|
|||
|
return (pLLI); \
|
|||
|
} \
|
|||
|
\
|
|||
|
|
|||
|
//** This macro defines a instance of a linklist item **//
|
|||
|
|
|||
|
#define LINK_LIST(CLASS_PREFIX, MEMBERS) LINK_LIST_CLASS(CLASS_PREFIX, Link, MEMBERS)
|
|||
|
|
|||
|
#define LINK_LIST_CLASS(CLASS_PREFIX, BASE, MEMBERS) \
|
|||
|
\
|
|||
|
class CLASS_PREFIX##List; \
|
|||
|
\
|
|||
|
class CLASS_PREFIX##Item:public BASE##Item { \
|
|||
|
\
|
|||
|
public: \
|
|||
|
\
|
|||
|
CLASS_PREFIX##Item *Next( \
|
|||
|
) { \
|
|||
|
this->Assert(); \
|
|||
|
return ((CLASS_PREFIX##Item *)(this->LinkItem::Next())); \
|
|||
|
} \
|
|||
|
\
|
|||
|
/* Put an ASSERT_VCLASS in MEMBERS if desired */ \
|
|||
|
\
|
|||
|
MEMBERS \
|
|||
|
\
|
|||
|
}; \
|
|||
|
\
|
|||
|
class CLASS_PREFIX##List:public BASE##List { \
|
|||
|
\
|
|||
|
public: \
|
|||
|
\
|
|||
|
CLASS_PREFIX##Item *Add(CLASS_PREFIX##Item *pLLI) { \
|
|||
|
\
|
|||
|
LinkList::Add(pLLI); \
|
|||
|
return (pLLI); \
|
|||
|
} \
|
|||
|
\
|
|||
|
CLASS_PREFIX##Item *Append(CLASS_PREFIX##Item *pLLI) { \
|
|||
|
\
|
|||
|
LinkList::Append(pLLI); \
|
|||
|
return (pLLI); \
|
|||
|
} \
|
|||
|
\
|
|||
|
\
|
|||
|
CLASS_PREFIX##Item *First( \
|
|||
|
) { \
|
|||
|
return ((CLASS_PREFIX##Item *)LinkList::First()); \
|
|||
|
} \
|
|||
|
\
|
|||
|
\
|
|||
|
};
|
|||
|
|
|||
|
#endif // _LINKLIST_
|
|||
|
|