1 /*****************************************************************************/
2 /* */
3 /* LISTNODE.CC */
4 /* */
5 /* (C) 1993,94 Ullrich von Bassewitz */
6 /* Zwehrenbuehlstrasse 33 */
7 /* D-72070 Tuebingen */
8 /* EMail: uz@ibb.schwaben.com */
9 /* */
10 /*****************************************************************************/
11
12
13
14 // $Id$
15 //
16 // $Log$
17 //
18 //
19
20
21
22 #include "listnode.h"
23
24
25
26 /*****************************************************************************/
27 /* class _ListNode */
28 /*****************************************************************************/
29
30
31
_ListNode(void * DataPtr)32 _ListNode::_ListNode (void* DataPtr)
33 {
34 NextNode = PrevNode = this;
35 ContentsPtr = DataPtr;
36 }
37
38
39
~_ListNode()40 _ListNode::~_ListNode ()
41 {
42 Unlink ();
43 }
44
45
46
InsertAfter(_ListNode * N)47 void _ListNode::InsertAfter (_ListNode* N)
48 // inserts one node after another
49 {
50 // the node cannot be inserted after itself
51 PRECONDITION (N != this);
52
53 // switch pointers
54 NextNode = N->NextNode;
55 PrevNode = N;
56 N->NextNode = this;
57 NextNode->PrevNode = this;
58 }
59
60
61
InsertBefore(_ListNode * N)62 void _ListNode::InsertBefore (_ListNode* N)
63 // inserts one node before another
64 {
65 // the node cannot be inserted before itself
66 PRECONDITION (N != this);
67
68 // switch pointers
69 PrevNode = N->PrevNode;
70 NextNode = N;
71 N->PrevNode = this;
72 PrevNode->NextNode = this;
73 }
74
75
76
Unlink()77 void _ListNode::Unlink ()
78 // Unlinks a node from a list.
79 {
80 // If the list constists only of this element, no unlink is necessary
81 if (NextNode == this) {
82 return;
83 }
84
85 // unlink node
86 PrevNode->NextNode = NextNode;
87 NextNode->PrevNode = PrevNode;
88
89 // the unlinked node is a list with one node
90 NextNode = PrevNode = this;
91 }
92
93
94
Traverse(int Forward,int (* F)(_ListNode *,void *),void * UserPtr)95 _ListNode* _ListNode::Traverse (int Forward, int (*F) (_ListNode*, void*),
96 void *UserPtr)
97 // Traverse through a list, starting with the current node and calling the
98 // given function F with every node as argument. Ends if finally the current
99 // node is reached again (all nodes have been visited in this case) or if the
100 // called function returns a value != 0. In the former case, Traverse returns
101 // a NULL pointer, in the latter, a pointer to the node is returned.
102 {
103 _ListNode* N = this;
104
105 do {
106
107 if (F (N, UserPtr)) {
108 // function returned true
109 return N;
110 }
111
112 if (Forward) {
113 N = N->NextNode;
114 } else {
115 N = N->PrevNode;
116 }
117
118 } while (N != this);
119
120 // Walked through the whole list, return NULL
121 return NULL;
122 }
123
124
125
NodeCount()126 u16 _ListNode::NodeCount ()
127 // Returns the node count of the list
128 {
129 register u16 Count = 0;
130
131 _ListNode* N = this;
132
133 do {
134 Count++;
135 N = N->NextNode;
136 } while (N != this);
137
138 return Count;
139 }
140
141
142
NodeWithNumber(u16 X)143 _ListNode* _ListNode::NodeWithNumber (u16 X)
144 // Returns the node with number X. Counting begins with "this", (which has
145 // number 0) and proceeds in "Next" direction.
146 // Warning: If X is greater than the number of nodes in the list, the
147 // result is undefined (wraping around).
148 {
149 _ListNode* N = this;
150
151 while (X--) {
152 N = N->NextNode;
153 }
154
155 return N;
156 }
157
158
159
NumberOfNode(_ListNode * N)160 u16 _ListNode::NumberOfNode (_ListNode* N)
161 // Returns the number of node N. Counting begins with "this" node
162 // (which has number 0) and proceeds in "Next" direction.
163 {
164 register u16 Count = 0;
165 _ListNode* R = this;
166
167 while (R != N) {
168 Count++;
169 R = R->NextNode;
170 CHECK (R != this); // Means N is not in list
171 }
172
173 return Count;
174 }
175
176
177
178