Skip to content

Commit 72e3a0c

Browse files
authored
Merge pull request Aircoookie#14 from Aircoookie/linkedlist-fixes
LinkedList fixes
2 parents a68a18c + 39ac33a commit 72e3a0c

File tree

1 file changed

+45
-73
lines changed

1 file changed

+45
-73
lines changed

src/StringArray.h

Lines changed: 45 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -40,26 +40,18 @@ class LinkedList {
4040
public:
4141
typedef Item<T> ItemType;
4242
typedef std::function<void(const T&)> OnRemove;
43-
typedef std::function<bool(const T&)> Predicate;
4443
private:
4544
ItemType* _root;
4645
ItemType* _last;
4746
OnRemove _onRemove;
4847

4948
class Iterator {
5049
ItemType* _node;
51-
ItemType* _nextNode = nullptr;
5250
friend class LinkedList;
5351
public:
54-
Iterator(ItemType* current = nullptr) : _node(current) {
55-
_nextNode = _node != nullptr ? _node->next : nullptr;
56-
}
57-
Iterator(const Iterator& i) : _node(i._node) {
58-
_nextNode = _node != nullptr ? _node->next : nullptr;
59-
}
52+
Iterator(ItemType* current = nullptr) : _node(current) {};
6053
Iterator& operator ++() {
61-
_node = _nextNode;
62-
_nextNode = _node != nullptr ? _node->next : nullptr;
54+
if (_node) _node = _node->next;
6355
return *this;
6456
}
6557
bool operator != (const Iterator& i) const { return _node != i._node; }
@@ -68,23 +60,16 @@ class LinkedList {
6860
};
6961

7062
void _remove(ItemType* pit, ItemType* it) {
71-
if(pit == nullptr){ // item is root
72-
_root = _root->next;
73-
if (_root == nullptr) {
74-
_last = nullptr;
75-
}
76-
} else {
77-
pit->next = it->next;
78-
if (it == _last) {
79-
_last = pit;
80-
}
81-
}
82-
83-
if (_onRemove) {
84-
_onRemove(it->value());
85-
}
86-
87-
delete it;
63+
auto* next = pit ? &pit->next : &_root;
64+
*next = it->next;
65+
if (_last == it) {
66+
_last = pit;
67+
}
68+
69+
if (_onRemove) {
70+
_onRemove(it->value());
71+
}
72+
delete it;
8873
}
8974

9075
public:
@@ -94,6 +79,7 @@ class LinkedList {
9479

9580
LinkedList(OnRemove onRemove) : _root(nullptr), _last(nullptr), _onRemove(onRemove) {}
9681
~LinkedList() { free(); }
82+
9783
void add(T t){
9884
auto it = new ItemType(std::move(t));
9985
if(!_root){
@@ -104,102 +90,88 @@ class LinkedList {
10490
}
10591
_last = it;
10692
}
93+
10794
T& front() const {
10895
return _root->value();
10996
}
11097

11198
bool isEmpty() const {
11299
return _root == nullptr;
113100
}
101+
114102
size_t length() const {
115103
size_t i = 0;
116-
auto it = _root;
117-
while(it){
118-
i++;
119-
it = it->next;
120-
}
104+
for(auto it = _root; it != nullptr; it = it->next) { ++i; };
121105
return i;
122106
}
123-
size_t count_if(Predicate predicate) const {
107+
108+
template<typename Predicate>
109+
size_t count_if(const Predicate& predicate) const {
124110
size_t i = 0;
125-
auto it = _root;
126-
while(it){
127-
if (!predicate){
111+
for(auto it = _root; it != nullptr; it = it->next) {
112+
if (predicate(it->value())) {
128113
i++;
129114
}
130-
else if (predicate(it->value())) {
131-
i++;
132-
}
133-
it = it->next;
134115
}
135116
return i;
136117
}
118+
137119
const T* nth(size_t N) const {
138120
size_t i = 0;
139-
auto it = _root;
140-
while(it){
141-
if(i++ == N)
142-
return &(it->value());
143-
it = it->next;
144-
}
121+
for(auto it = _root; it != nullptr; it = it->next) {
122+
if(i++ == N) return &(it->value());
123+
};
145124
return nullptr;
146125
}
126+
147127
bool remove(const T& t){
148-
auto it = _root;
149-
auto pit = decltype(it) { nullptr };
150-
while(it){
128+
auto pit = (ItemType*) nullptr;
129+
for(auto it = _root; it != nullptr; pit = it, it = it->next) {
151130
if(it->value() == t){
152131
_remove(pit, it);
153132
return true;
154133
}
155-
pit = it;
156-
it = it->next;
157134
}
158135
return false;
159136
}
160-
bool remove_first(Predicate predicate){
161-
auto it = _root;
162-
auto pit = decltype(it) { nullptr };
163-
while(it){
137+
138+
template<typename Predicate>
139+
bool remove_first(const Predicate& predicate){
140+
auto pit = (ItemType*) nullptr;
141+
for(auto it = _root; it != nullptr; pit = it, it = it->next) {
164142
if(predicate(it->value())){
165143
_remove(pit, it);
166144
return true;
167145
}
168-
pit = it;
169-
it = it->next;
170146
}
171147
return false;
172148
}
173-
bool remove(const ConstIterator& t, const ConstIterator& where = ConstIterator(nullptr)) {
149+
150+
bool remove(const ConstIterator& t, const ConstIterator& where) {
174151
if (where._node) {
175-
if ((where._nextNode) != t._node) return false;
152+
if ((where._node->next) != t._node) return false;
176153
_remove(where._node, t._node);
177154
return true;
155+
} else {
156+
return remove(t);
178157
}
158+
}
179159

180-
auto it = _root;
181-
auto pit = decltype(it) { nullptr };
182-
while(it){
160+
bool remove(const ConstIterator& t) {
161+
auto pit = (ItemType*) nullptr;
162+
for(auto it = _root; it != nullptr; pit = it, it = it->next) {
183163
if(it == t._node){
184164
_remove(pit, it);
185165
return true;
186166
}
187-
pit = it;
188-
it = it->next;
189167
}
190168
return false;
191-
}
169+
}
170+
192171
void free(){
193172
while(_root != nullptr){
194-
auto it = _root;
195-
_root = _root->next;
196-
if (_onRemove) {
197-
_onRemove(it->value());
198-
}
199-
delete it;
173+
_remove(nullptr, _root);
200174
}
201-
_root = nullptr;
202-
_last = nullptr;
203175
}
204176
};
205177

0 commit comments

Comments
 (0)