comparison packages/infra/current/include/clist.hxx @ 145:2e9a636d9de9 ecos-sw-2000-12-21

Merge from eCos master repository on 2000-12-21-14:18:40-GMT
author jlarmour
date Fri, 22 Dec 2000 02:37:28 +0000
parents
children 8f2f7615e727
comparison
equal deleted inserted replaced
144:da1052144c56 145:2e9a636d9de9
1 #ifndef CYGONCE_INFRA_CLIST_HXX
2 #define CYGONCE_INFRA_CLIST_HXX
3
4 //==========================================================================
5 //
6 // clist.hxx
7 //
8 // Standard types, and some useful coding macros.
9 //
10 //==========================================================================
11 //####COPYRIGHTBEGIN####
12 //
13 // -------------------------------------------
14 // The contents of this file are subject to the Red Hat eCos Public License
15 // Version 1.1 (the "License"); you may not use this file except in
16 // compliance with the License. You may obtain a copy of the License at
17 // http://www.redhat.com/
18 //
19 // Software distributed under the License is distributed on an "AS IS"
20 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
21 // License for the specific language governing rights and limitations under
22 // the License.
23 //
24 // The Original Code is eCos - Embedded Configurable Operating System,
25 // released September 30, 1998.
26 //
27 // The Initial Developer of the Original Code is Red Hat.
28 // Portions created by Red Hat are
29 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
30 // All Rights Reserved.
31 // -------------------------------------------
32 //
33 //####COPYRIGHTEND####
34 //==========================================================================
35 //#####DESCRIPTIONBEGIN####
36 //
37 // Author(s): nickg
38 // Contributors: nickg
39 // Date: 2000-11-08
40 // Purpose: Simple circular list implementation
41 // Description: A simple implementation of circular lists.
42 // Usage: #include "cyg/infra/clist.hxx"
43 // ...
44 //
45 //####DESCRIPTIONEND####
46 //
47 //==========================================================================
48
49 #include <cyg/infra/cyg_type.h>
50
51 // -------------------------------------------------------------------------
52 // Class and structure conversion macros.
53 // CYG_CLASSFROMFIELD translates a pointer to a field of a struct or
54 // class into a pointer to the class.
55 // CYG_OFFSETOFBASE yields the offset of a base class of a derived
56 // class.
57 // CYG_CLASSFROMBASE translates a pointer to a base class into a pointer
58 // to a selected derived class. The base class object _must_ be part of
59 // the specified derived class. This is essentially a poor mans version
60 // of the RTTI dynamic_cast operator.
61 // Caveat: These macros do not work for virtual base classes.
62
63 // Note: These definitions are exact duplicates of definitions in
64 // ktypes.h. If either definition is changed, the other should be too
65 // to avoid compiler messages.
66
67 #define CYG_CLASSFROMFIELD(_type_,_member_,_ptr_)\
68 ((_type_ *)((char *)(_ptr_)-((char *)&(((_type_ *)0)->_member_))))
69
70 #define CYG_OFFSETOFBASE(_type_,_base_)\
71 ((char *)((_base_ *)((_type_ *)4)) - (char *)4)
72
73 # define CYG_CLASSFROMBASE(_class_,_base_,_ptr_)\
74 ((_class_ *)((char *)(_ptr_) - CYG_OFFSETOFBASE(_class_,_base_)))
75
76
77 // -------------------------------------------------------------------------
78 // Cyg_DNode class.
79 // This simply represents a double linked node that is intended to
80 // be a base member of the class that is being managed.
81
82 class Cyg_DNode
83 {
84 Cyg_DNode *next;
85 Cyg_DNode *prev;
86
87 public:
88
89 Cyg_DNode()
90 {
91 // Initialize pointers to point here
92 next = prev = this;
93 };
94
95 ~Cyg_DNode()
96 {
97 // If this node is still linked, unlink it.
98 if( next != this )
99 unlink();
100 };
101
102 // Accessor and test functions
103 Cyg_DNode *get_next() { return next; };
104 Cyg_DNode *get_prev() { return prev; };
105 cyg_bool in_list() { return next != this; };
106
107 // Insert a node into the list before this one.
108 void insert( Cyg_DNode *node )
109 {
110 node->next = this;
111 node->prev = prev;
112 prev->next = node;
113 prev = node;
114 };
115
116 // Append a node after this one
117 void append( Cyg_DNode *node )
118 {
119 node->prev = this;
120 node->next = next;
121 next->prev = node;
122 next = node;
123 };
124
125 // Unlink this node from it's list. It is safe to apply this to an
126 // already unlinked node.
127 void unlink()
128 {
129 next->prev = prev;
130 prev->next = next;
131 next = prev = this;
132 };
133 };
134
135 // -------------------------------------------------------------------------
136 // Cyg_CList class.
137
138 // This is a simple class that manages a circular list of DNodes. This
139 // object points to the head of the list and provides functions to
140 // manipulate the head and tail of the list.
141
142 class Cyg_CList
143 {
144 Cyg_DNode *head; // list head pointer
145
146 public:
147
148 Cyg_CList()
149 {
150 head = NULL;
151 };
152
153 ~Cyg_CList()
154 {
155 while( head != NULL )
156 rem_head();
157 };
158
159 // Accessor and test functions
160 Cyg_DNode *get_head() { return head; };
161 Cyg_DNode *get_tail() { return head?head->get_prev():NULL; };
162 cyg_bool empty() { return head == NULL; };
163
164 // Add a node at the head of the list
165 void add_head( Cyg_DNode *node )
166 {
167 if( head == NULL )
168 head = node;
169 else
170 {
171 head->append( node );
172 head = node;
173 }
174 };
175
176 // Remove the node at the head of the list
177 Cyg_DNode *rem_head()
178 {
179 Cyg_DNode *node = head;
180 if( node != NULL )
181 {
182 // There is a node available
183 Cyg_DNode *next = node->get_next();
184 if( next == node )
185 {
186 // Only node on list
187 head = NULL;
188 }
189 else
190 {
191 // remove head node and move head to next.
192 node->unlink();
193 head = next;
194 }
195 }
196 return node;
197 };
198
199
200 // Add a node at the tail of the list
201 void add_tail( Cyg_DNode *node )
202 {
203 if( head == NULL )
204 head = node;
205 else
206 head->append( node );
207 };
208
209 // Remove the node at the tail of the list
210 Cyg_DNode *rem_tail()
211 {
212 if( head == NULL )
213 return NULL;
214
215 Cyg_DNode *node = head->get_prev();
216
217 if( node == head )
218 head = NULL;
219 else node->unlink();
220
221 return node;
222 };
223
224 // General removal. Deals with what happend if this is only
225 // object on list, or is the head.
226 void remove( Cyg_DNode *node )
227 {
228 if( node == head )
229 rem_head();
230 else node->unlink();
231 };
232 };
233
234 // -------------------------------------------------------------------------
235 // Cyg_CList_T
236 // Template class that allows us to make use of the CList class in a
237 // type-specific way.
238
239 template <class T> class Cyg_CList_T
240 : public Cyg_CList
241 {
242 public:
243
244 Cyg_CList_T<T>() {};
245 ~Cyg_CList_T<T>() {};
246
247 T *get_head() { return CYG_CLASSFROMBASE( T, Cyg_DNode, Cyg_CList::get_head() ); };
248 T *get_tail() { return CYG_CLASSFROMBASE( T, Cyg_DNode, Cyg_CList::get_tail() ); };
249
250 T *rem_head()
251 {
252 Cyg_DNode *node = Cyg_CList::rem_head();
253 return CYG_CLASSFROMBASE( T, Cyg_DNode, node );
254 };
255
256 T *rem_tail()
257 {
258 Cyg_DNode *node = Cyg_CList::rem_tail();
259 return CYG_CLASSFROMBASE( T, Cyg_DNode, node );
260 };
261
262 // The rest just default to the Cyg_CList class operations.
263 };
264
265 // -------------------------------------------------------------------------
266 // Cyg_DNode_T
267 // Template class that allows us to make use of the DNode class in a
268 // type-specific way.
269
270 template <class T> class Cyg_DNode_T
271 : public Cyg_DNode
272 {
273 public:
274
275 Cyg_DNode_T<T>() {};
276 ~Cyg_DNode_T<T>() {};
277
278 T *get_next() { return CYG_CLASSFROMBASE( T, Cyg_DNode, Cyg_DNode::get_next() ); };
279 T *get_prev() { return CYG_CLASSFROMBASE( T, Cyg_DNode, Cyg_DNode::get_prev() ); };
280
281 // The rest just default to the Cyg_DNode class operations.
282 };
283
284 // -------------------------------------------------------------------------
285 #endif // CYGONCE_INFRA_CLIST_HXX multiple inclusion protection
286 // EOF clist.hxx
287