windows-nt/Source/XPSP1/NT/com/rpc/ndrmem/linklist.hxx

221 lines
10 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//+-------------------------------------------------------------------------
//
// 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_