Skip to content

Commit e83db1d

Browse files
committed
LinkedList: Simplify and standardize
Template on the predicate functions to avoid std::function overhead, and clean up the looping logic.
1 parent 1f27685 commit e83db1d

File tree

1 file changed

+31
-38
lines changed

1 file changed

+31
-38
lines changed

src/StringArray.h

Lines changed: 31 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ 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;
@@ -87,6 +86,7 @@ class LinkedList {
8786

8887
LinkedList(OnRemove onRemove) : _root(nullptr), _last(nullptr), _onRemove(onRemove) {}
8988
~LinkedList() { free(); }
89+
9090
void add(T t){
9191
auto it = new ItemType(std::move(t));
9292
if(!_root){
@@ -97,91 +97,84 @@ class LinkedList {
9797
}
9898
_last = it;
9999
}
100+
100101
T& front() const {
101102
return _root->value();
102103
}
103104

104105
bool isEmpty() const {
105106
return _root == nullptr;
106107
}
108+
107109
size_t length() const {
108110
size_t i = 0;
109-
auto it = _root;
110-
while(it){
111-
i++;
112-
it = it->next;
113-
}
111+
for(auto it = _root; it != nullptr; it = it->next) { ++i; };
114112
return i;
115113
}
116-
size_t count_if(Predicate predicate) const {
114+
115+
template<typename Predicate>
116+
size_t count_if(const Predicate& predicate) const {
117117
size_t i = 0;
118-
auto it = _root;
119-
while(it){
120-
if (!predicate){
121-
i++;
122-
}
123-
else if (predicate(it->value())) {
118+
for(auto it = _root; it != nullptr; it = it->next) {
119+
if (predicate(it->value())) {
124120
i++;
125121
}
126-
it = it->next;
127122
}
128123
return i;
129124
}
125+
130126
const T* nth(size_t N) const {
131127
size_t i = 0;
132-
auto it = _root;
133-
while(it){
134-
if(i++ == N)
135-
return &(it->value());
136-
it = it->next;
137-
}
128+
for(auto it = _root; it != nullptr; it = it->next) {
129+
if(i++ == N) return &(it->value());
130+
};
138131
return nullptr;
139132
}
133+
140134
bool remove(const T& t){
141-
auto it = _root;
142-
auto pit = decltype(it) { nullptr };
143-
while(it){
135+
auto pit = (ItemType*) nullptr;
136+
for(auto it = _root; it != nullptr; pit = it, it = it->next) {
144137
if(it->value() == t){
145138
_remove(pit, it);
146139
return true;
147140
}
148-
pit = it;
149-
it = it->next;
150141
}
151142
return false;
152143
}
153-
bool remove_first(Predicate predicate){
154-
auto it = _root;
155-
auto pit = decltype(it) { nullptr };
156-
while(it){
144+
145+
template<typename Predicate>
146+
bool remove_first(const Predicate& predicate){
147+
auto pit = (ItemType*) nullptr;
148+
for(auto it = _root; it != nullptr; pit = it, it = it->next) {
157149
if(predicate(it->value())){
158150
_remove(pit, it);
159151
return true;
160152
}
161-
pit = it;
162-
it = it->next;
163153
}
164154
return false;
165155
}
166-
bool remove(const ConstIterator& t, const ConstIterator& where = ConstIterator(nullptr)) {
156+
157+
bool remove(const ConstIterator& t, const ConstIterator& where) {
167158
if (where._node) {
168159
if ((where._node->next) != t._node) return false;
169160
_remove(where._node, t._node);
170161
return true;
162+
} else {
163+
return remove(t);
171164
}
165+
}
172166

173-
auto it = _root;
174-
auto pit = decltype(it) { nullptr };
175-
while(it){
167+
bool remove(const ConstIterator& t) {
168+
auto pit = (ItemType*) nullptr;
169+
for(auto it = _root; it != nullptr; pit = it, it = it->next) {
176170
if(it == t._node){
177171
_remove(pit, it);
178172
return true;
179173
}
180-
pit = it;
181-
it = it->next;
182174
}
183175
return false;
184-
}
176+
}
177+
185178
void free(){
186179
while(_root != nullptr){
187180
auto it = _root;

0 commit comments

Comments
 (0)