summaryrefslogtreecommitdiff
path: root/utils/List.h
blob: 5067da664e3adb21ad45744b392295685bfdc7e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/*
 *	CENA C++ Utilities
 *
 *	by Stephane Chatty
 *
 *	Copyright 1992-1995
 *	Centre d'Etudes de la Navigation Aerienne (CENA)
 *
 *	plain and generic lists (original ideas by Yves Berteaud)
 *
 *	$Id$
 *	$CurLog$
 */

#ifndef List_H_
#define List_H_

#include "cplus_bugs.h"
#include <sys/types.h>

class CcuAllocator;

typedef void CcuListItem;
typedef void* CcuListIndex;

#ifdef CPLUS_BUG20
class CcuListLink;
#endif

class CcuList {
friend	class	CcuListIter;

#ifndef CPLUS_BUG20
	class CcuListLink {
	static	CcuAllocator*	ListLinkMem;
	public:
		CcuListItem*	Entry;
		CcuListLink*	Next;
	inline		CcuListLink (CcuListItem* e, CcuListLink* n = 0)	{ Entry = e; Next = n ? n : this; }
		CcuListLink*	Previous ();
		void*	operator new (size_t);
		void	operator delete (void*);
	};
#endif

public:
	enum	list_status	{ NoError, WasEmpty, TooEarly, TooFar, BadIterator };
	enum	list_remove	{ All = -1 };

private:

	CcuListLink*	LastLink;
	list_status	StatusFlag;

	CcuListIndex	InsertAfterLink (CcuListLink*, CcuListItem*);
	CcuListIndex	InsertBeforeLink (CcuListLink*, CcuListItem*);
	CcuListItem*	RemoveAfterLink (CcuListLink*);

public:
inline		CcuList () : LastLink (0), StatusFlag (NoError)	{ }
		CcuList (CcuListItem*);
		CcuList (const CcuList&);
		~CcuList ();
		CcuList&	operator = (const CcuList&);
inline	list_status	GetStatus () const		{ return StatusFlag; }

inline	int	IsEmpty () const			{ return !LastLink; }
	CcuListItem*	First ();
	CcuListItem*	Last ();
	CcuListItem*	Nth (int n);
	int	Length () const;
	int	Find (CcuListItem*, int* = 0) const;

	CcuListIndex	Append (CcuListItem*);
	CcuListIndex	Prepend (CcuListItem*);
inline	CcuList&	operator << (CcuListItem* it)	{ Append (it); return *this; }

	CcuListItem*	RemoveFirst ();
	CcuListItem*	RemoveLast ();
	int	Remove (CcuListItem*, int = 1);
	int	Remove (int (*) (CcuListItem*), int = 1);
	void	Clear ();

	CcuListIndex	InsertAfter (const CcuListIter&, CcuListItem*);
	CcuListIndex	InsertBefore (const CcuListIter&, CcuListItem*);
	CcuListItem*	RemoveAfter (const CcuListIter&);
};

class CcuListIter {
friend	class	CcuList;

public:
	enum	listiter_status	{ Normal, StartOfList, EndOfList };

private:
	const CcuList*	TheList;
#ifdef CPLUS_BUG20
	CcuListLink*	CurLink;
#else
	CcuList::CcuListLink*	CurLink;
#endif
	listiter_status	StatusFlag;

public:
inline		CcuListIter (const CcuList& l) : TheList (&l), CurLink (0), StatusFlag (StartOfList)	{ }
		CcuListIter (const CcuList&, CcuListIndex);
inline	void	Reset ()		{ CurLink = 0; StatusFlag = StartOfList; }
inline	CcuListIter&	operator = (const CcuList& l)	{ TheList = &l; CurLink = 0; StatusFlag = StartOfList; return *this; }
inline	CcuListIter&	operator = (const CcuListIter& li)	{ TheList = li.TheList; CurLink = li.CurLink; StatusFlag = li.StatusFlag; return *this; }
	CcuListIter&	operator ++ ();
#ifndef CPLUS_BUG16
	CcuListIter&	operator ++ (int);
#endif
	CcuListItem*	operator * () const;
		int	Find (CcuListItem*);
inline	listiter_status	GetStatus () const		{ return StatusFlag; }
inline	operator int () const	{ return StatusFlag == Normal; }
};

#ifndef CPLUS_BUG19
template <class ITEM> class CcuListIterOf;

template <class ITEM> class CcuListOf : public CcuList {
public:
inline		CcuListOf () : CcuList ()	{}
inline		CcuListOf (ITEM* it) : CcuList (it)	{}
inline	ITEM*	First ()	{ return (ITEM*) (CcuList::First ()); }
inline	ITEM*	Last ()	{ return (ITEM*) (CcuList::Last ()); }
inline	ITEM*	Nth (int n)	{ return (ITEM*) (CcuList::Nth (n)); }
inline	int	Find (ITEM* it, int* r = 0) const	{ return CcuList::Find (it, r); }

inline	CcuListIndex	Append (ITEM* it)	{ return CcuList::Append (it); }
inline	CcuListIndex	Prepend (ITEM* it)	{ return CcuList::Prepend (it); }
inline	CcuListOf<ITEM>&	operator << (ITEM* it)	{ CcuList::Append (it); return *this; }

inline	ITEM*	RemoveFirst ()	{ return (ITEM*) (CcuList::RemoveFirst ()); }
inline	ITEM*	RemoveLast ()	{ return (ITEM*) (CcuList::RemoveLast ()); }
inline	int	Remove (ITEM* it, int nb = 1)	{ return CcuList::Remove (it, nb); }
inline	int	Remove (int (*p) (ITEM*), int nb = 1)	{ return CcuList::Remove ((int (*) (void*)) p, nb); }

inline	CcuListIndex	InsertAfter (const CcuListIterOf <ITEM>& li, ITEM*it)	{ return CcuList::InsertAfter (li, it); }
inline	CcuListIndex	InsertBefore (const CcuListIterOf <ITEM>& li, ITEM* it)	{ return CcuList::InsertBefore (li, it); }
inline	ITEM*	RemoveAfter (const CcuListIterOf <ITEM>& li)		{ return (ITEM*) CcuList::RemoveAfter (li); }
};

template <class ITEM> class CcuListIterOf : public CcuListIter {
public:
inline		CcuListIterOf (const CcuListOf <ITEM>& l) : CcuListIter (l)	{ }
inline	CcuListIterOf<ITEM>&	operator =  (const CcuListOf <ITEM>& l)	{ return (CcuListIterOf <ITEM>&) CcuListIter::operator = (l); }
inline	CcuListIterOf<ITEM>&	operator =  (const CcuListIterOf <ITEM>& li)	{ return (CcuListIterOf <ITEM>&) CcuListIter::operator = (li); }
inline	CcuListIterOf<ITEM>&	operator ++ ()	{ return (CcuListIterOf <ITEM>&) CcuListIter::operator ++ (); }
inline	ITEM*	operator * () const	{ return (ITEM*) CcuListIter::operator * (); }
inline	int	Find (ITEM* it)		{ return CcuListIter::Find (it); }
};
#endif	/* CPLUS_BUG19 */

typedef CcuListItem CcuStackItem;

/* CPLUS_BUG10 */
class CcuStack : _private CcuList {
public:
		CcuList :: Clear;
		CcuList :: IsEmpty;
		CcuList :: GetStatus;
inline void	Push (CcuStackItem* p)	{ Prepend (p); }
inline CcuStackItem*	Pop ()		{ return RemoveFirst (); }
inline CcuStackItem*	Top ()		{ return First (); }
};

#ifndef CPLUS_BUG19
template <class ITEM> class CcuStackOf : public CcuStack {
public:
inline void	Push (ITEM* p)	{ CcuStack::Push (p); }
inline ITEM*	Pop ()		{ return (ITEM*) CcuStack::Pop (); }
inline ITEM*	Top ()		{ return (ITEM*) CcuStack::Top (); }
inline		operator const CcuListOf <ITEM>& ()	{ return *(CcuListOf <ITEM>*) this; }
};
#endif	/* CPLUS_BUG19 */

typedef CcuListItem CcuQueueItem;

/* CPLUS_BUG10 */
class CcuQueue : _private CcuList {
public:
		CcuList :: Clear;
		CcuList :: IsEmpty;
		CcuList :: GetStatus;
inline void	Put (CcuQueueItem* p)	{ Append (p); }
inline CcuQueueItem*	Get ()		{ return RemoveFirst (); }
inline		operator const CcuList& ()	{ return *this; }
};

#ifndef CPLUS_BUG19
template <class ITEM> class CcuQueueOf : public CcuQueue {
public:
inline void	Put (ITEM* p)	{ CcuQueue::Put (p); }
inline ITEM*	Get ()		{ return (ITEM*) CcuQueue::Get (); }
inline		operator const CcuListOf <ITEM>& ()	{ return *(CcuListOf <ITEM>*) this; }
};
#endif	/* CPLUS_BUG19 */

#endif	/* List_H_ */