-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdlist.cpp
207 lines (182 loc) · 4.8 KB
/
dlist.cpp
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
204
205
206
207
/**
*
* Copyright (c) 2010-2015 Voidware Ltd. All Rights Reserved.
*
* This file contains Original Code and/or Modifications of Original Code as
* defined in and that are subject to the Voidware Public Source Licence version
* 1.0 (the 'Licence'). You may not use this file except in compliance with the
* Licence or with expressly written permission from Voidware. Please obtain a
* copy of the Licence at http://www.voidware.com/legal/vpsl1.txt and read it
* before using this file.
*
* The Original Code and all software distributed under the Licence are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
* OR IMPLIED, AND VOIDWARE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING
* WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Please see the Licence for the specific language governing rights and
* limitations under the Licence.
*
*/
#include "dlist.h"
namespace Utils
{
/******************* DList, methods for ***************************/
void DList::insert(DListRec* rec)
{
/* Put at the start of the list.
* No need to remove from list first.
*/
extract(rec);
if (list_) rec->insert(list_);
list_ = rec;
}
void DList::append(DListRec* rec)
{
/* Put at the end of the list.
* Do not need to remove from original list before append.
*/
extract(rec);
if (list_)
rec->insert(list_);
else
list_ = rec;
}
DListRec* DList::extractFirst()
{
DListRec* rec = list_;
if (rec)
{
list_ = rec->next_;
if (list_ == rec) list_ = 0;
rec->remove();
}
return rec;
}
void DList::extract(DListRec *rec)
{
/* if this is the first element in the list
* we need to promote the next record to pole
* position. This needs to be done before the
* remove because remove resets a records next
* and previous pointers.
*/
if (rec) {
if (list_ == rec) {
list_ = rec->next_;
if (list_ == rec) list_ = 0;
}
rec->remove();
}
}
bool DList::member(DListRec* rec) const
{
DListIterator i(*this);
i.find(rec);
return *i != 0;
}
unsigned int DList::size() const
{
/* Return the number of elements in this list */
unsigned int n = 0;
DListRec* l = list_;
if (l) {
do {
++n;
l = l->next();
} while (l != list_);
}
return n;
}
/***************** DListIterator, methods for ***********************/
DListIterator::DListIterator(const DList& list)
{
init();
list_ = (DList*)&list;
reset();
}
DListIterator& DListIterator::operator=(const DListIterator& i)
{
list_ = i.list_;
pos_ = i.pos_;
return *this;
}
DListIterator& DListIterator::operator++()
{
/* Advance the iterator position to the next element of this list.
* If advanced from the last element, the position will become
* invalid. If iterated when the position is invalid, the iterator
* will move to the front of the list.
*/
if (pos_) {
DListRec* rec = pos_->next();
if (rec == list_->first() || pos_ == rec) pos_ = 0;
else pos_ = rec;
}
else pos_ = list_->first();
return *this;
}
DListIterator& DListIterator::operator--()
{
/* Step back one place of iteration. If we step back from the
* first element, the position becomes invalid. If we step back
* from the invalid position, the iterator is set to the end
* of the list.
*/
if (pos_) {
pos_ = pos_->previous();
if (pos_ == list_->last()) pos_ = 0;
}
else pos_ = list_->last();
return *this;
}
void DListIterator::remove()
{
/* Remove the element at the current iterator position.
* The iterator will now point to the previous element of the list
* or be invalid, if we removed the first member.
*/
DListRec* rec = pos_;
if (rec)
{
--*this;
list_->remove(rec);
}
}
void DListIterator::extract()
{
/* Remove the element at the current iterator position.
* The iterator will now point to the previous element of the list
* or be invalid, if we removed the first member.
*/
DListRec* rec = pos_;
if (rec)
{
--*this;
list_->extract(rec);
}
}
void DListIterator::insert(DListRec* rec)
{
/* Insert the given `rec'ord at this point, we will then
* be pointing to the inserted record.
*/
if (pos_)
list_->insertAt(rec, pos_);
else
list_->insert(rec);
pos_ = rec;
}
DListIterator& DListIterator::find(const DListRec* rec)
{
if (pos_)
{
do {
if (pos_ == rec) break;
} while (*++*this);
}
return *this;
}
}; // Utils