Skip to content

Commit 006dd20

Browse files
committed
Start moving containers to new Container interface
1 parent dc96683 commit 006dd20

5 files changed

Lines changed: 255 additions & 78 deletions

File tree

include/ds/ArrayList.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@
2727
#include <string>
2828
#include <cmath>
2929
#include <utility>
30-
#include <type_traits>
3130
#include "Range.h"
3231
#include "MonkeyIterator.h"
32+
#include "Container.h"
3333

3434
/*
3535
* This class was originally designed for use in larger embedded systems.
@@ -38,7 +38,7 @@
3838
*/
3939

4040
template<class T>
41-
class ArrayList {
41+
class ArrayList : public Container<T, T*, const T*> {
4242
public:
4343

4444
ArrayList() {
@@ -311,10 +311,10 @@ class ArrayList {
311311
return tmp;
312312
}
313313

314-
T* begin() { return elements; }
315-
T* end() { return &(elements[length]); }
316-
const T* begin() const { return elements; }
317-
const T* end() const { return &(elements[length]); }
314+
T* begin() override { return elements; }
315+
T* end() override { return &(elements[length]); }
316+
const T* begin() const override { return elements; }
317+
const T* end() const override { return &(elements[length]); }
318318

319319
template<class E>
320320
Range<MonkeyIterator<T*, E>> rangeOf() {
@@ -347,6 +347,8 @@ class ArrayList {
347347
free((void*)elements);
348348
}
349349

350+
protected:
351+
350352
private:
351353
int length, allocated;
352354
T* elements;

include/ds/ArraySet.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@
1919
#ifndef EXCESSIVE_ARRAYSET_H
2020
#define EXCESSIVE_ARRAYSET_H
2121

22+
#include "Container.h"
2223
#include "ArrayList.h"
2324
#include "Set.h"
2425

2526

2627
template<class T>
27-
class ArraySet: public Set<T> {
28+
class ArraySet: public Set<T>, public Container<T, T*, const T*> {
2829
public:
2930

3031
ArraySet() {
@@ -145,13 +146,13 @@ class ArraySet: public Set<T> {
145146
return elements;
146147
}
147148

148-
T* begin() { return elements; }
149-
T* end() { return &(elements[length]); }
150-
const T* begin() const { return elements; }
151-
const T* end() const { return &(elements[length]); }
149+
T* begin() override { return elements; }
150+
T* end() override { return &(elements[length]); }
151+
const T* begin() const override { return elements; }
152+
const T* end() const override { return &(elements[length]); }
152153

153154

154-
~ArraySet() { free(elements); }
155+
~ArraySet() override { free(elements); }
155156

156157
inline void clear() override { length = 0; }
157158

@@ -163,6 +164,8 @@ class ArraySet: public Set<T> {
163164
return elements[0];
164165
}
165166

167+
protected:
168+
166169
private:
167170

168171
// Adds elements without checking if there's enough memory

include/ds/LinkedList.h

Lines changed: 98 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -22,134 +22,165 @@
2222

2323
#include <cstdlib>
2424
#include <cstdio>
25-
#include <cstring>
26-
#include <cmath>
2725
#include <iterator>
2826
#include <cstddef>
27+
#include "Container.h"
28+
29+
30+
template<class T>
31+
class LinkedList;
2932

3033

3134
template<class T>
3235
class linkedlist_value_container_t {
3336
public:
34-
explicit inline linkedlist_value_container_t(const T& value) : value(value) {}
37+
explicit inline linkedlist_value_container_t(const T& value) : value(value), next(nullptr), previous(nullptr) {}
38+
3539
T value;
3640
linkedlist_value_container_t* next;
3741
linkedlist_value_container_t* previous;
38-
};
39-
40-
41-
template<class T>
42-
class LinkedList {
43-
public:
4442

45-
class iterator {
43+
class Iterator {
4644
public:
45+
// Needed for reverse_iterator
4746
typedef std::bidirectional_iterator_tag iterator_category;
4847
typedef T value_type;
4948
typedef std::ptrdiff_t difference_type;
5049
typedef T* pointer;
5150
typedef T& reference;
5251

53-
iterator() : node(nullptr), list(nullptr) {}
54-
iterator(linkedlist_value_container_t<T>* node, LinkedList<T>* list) : node(node), list(list) {}
52+
Iterator() : node(nullptr), atEnd(true) {}
53+
Iterator(linkedlist_value_container_t* node, bool atEnd) : node(node), atEnd(atEnd) {}
54+
55+
T& operator*() const {
56+
return node->value;
57+
}
5558

56-
reference operator*() const { return node->value; }
57-
pointer operator->() const { return &node->value; }
59+
T* operator->() const {
60+
if (atEnd)
61+
return nullptr;
62+
return &node->value;
63+
}
5864

59-
iterator& operator++() {
60-
if (node) node = node->next;
65+
Iterator& operator++() {
66+
if (!atEnd && node) {
67+
if (node->next)
68+
node = node->next;
69+
else
70+
atEnd = true;
71+
}
6172
return *this;
6273
}
6374

64-
iterator operator++(int) {
65-
iterator tmp = *this;
75+
Iterator operator++(int) {
76+
Iterator tmp = *this;
6677
++(*this);
6778
return tmp;
6879
}
6980

70-
iterator& operator--() {
71-
node = node ? node->previous : (list ? list->last : nullptr);
81+
Iterator& operator--() {
82+
if (atEnd)
83+
atEnd = false;
84+
else
85+
node = node ? node->previous : nullptr;
7286
return *this;
7387
}
7488

75-
iterator operator--(int) {
76-
iterator tmp = *this;
89+
Iterator operator--(int) {
90+
Iterator tmp = *this;
7791
--(*this);
7892
return tmp;
7993
}
8094

81-
bool operator==(const iterator& other) const { return node == other.node; }
82-
bool operator!=(const iterator& other) const { return node != other.node; }
95+
bool operator==(const Iterator& other) const {
96+
if (atEnd != other.atEnd) return false;
97+
if (atEnd) return true; // Both are at end, node doesn't matter (or should both be last)
98+
return node == other.node;
99+
}
100+
bool operator!=(const Iterator& other) const { return !(*this == other); }
83101

84102
private:
85-
linkedlist_value_container_t<T>* node;
86-
LinkedList<T>* list;
87-
friend class LinkedList;
88-
friend class const_iterator;
103+
linkedlist_value_container_t* node;
104+
bool atEnd;
89105
};
90106

91-
class const_iterator {
107+
class ConstIterator {
92108
public:
109+
// Needed for reverse_iterator
93110
typedef std::bidirectional_iterator_tag iterator_category;
94111
typedef const T value_type;
95112
typedef std::ptrdiff_t difference_type;
96113
typedef const T* pointer;
97114
typedef const T& reference;
98115

99-
const_iterator() : node(nullptr), list(nullptr) {}
100-
const_iterator(const linkedlist_value_container_t<T>* node, const LinkedList<T>* list) : node(node), list(list) {}
101-
const_iterator(const iterator& other) : node(other.node), list(other.list) {}
116+
ConstIterator() : node(nullptr), atEnd(true) {}
117+
ConstIterator(const linkedlist_value_container_t* node, bool atEnd) : node(node), atEnd(atEnd) {}
118+
ConstIterator(const Iterator& other) : node(other.node), atEnd(other.atEnd) {}
102119

103-
reference operator*() const { return node->value; }
104-
pointer operator->() const { return &node->value; }
120+
const T& operator*() const { return node->value; }
121+
const T* operator->() const {
122+
if (atEnd)
123+
return nullptr;
124+
return &node->value;
125+
}
105126

106-
const_iterator& operator++() {
107-
if (node) node = node->next;
127+
ConstIterator& operator++() {
128+
if (!atEnd && node) {
129+
if (node->next)
130+
node = node->next;
131+
else
132+
atEnd = true;
133+
}
108134
return *this;
109135
}
110136

111-
const_iterator operator++(int) {
112-
const_iterator tmp = *this;
137+
ConstIterator operator++(int) {
138+
ConstIterator tmp = *this;
113139
++(*this);
114140
return tmp;
115141
}
116142

117-
const_iterator& operator--() {
118-
node = node ? node->previous : (list ? list->last : nullptr);
143+
ConstIterator& operator--() {
144+
if (atEnd)
145+
atEnd = false;
146+
else
147+
node = node ? node->previous : nullptr;
119148
return *this;
120149
}
121150

122-
const_iterator operator--(int) {
123-
const_iterator tmp = *this;
151+
ConstIterator operator--(int) {
152+
ConstIterator tmp = *this;
124153
--(*this);
125154
return tmp;
126155
}
127156

128-
bool operator==(const const_iterator& other) const { return node == other.node; }
129-
bool operator!=(const const_iterator& other) const { return node != other.node; }
157+
bool operator==(const ConstIterator& other) const {
158+
if (atEnd != other.atEnd) return false;
159+
if (atEnd) return true;
160+
return node == other.node;
161+
}
162+
bool operator!=(const ConstIterator& other) const { return !(*this == other); }
130163

131164
private:
132-
const linkedlist_value_container_t<T>* node;
133-
const LinkedList<T>* list;
134-
friend class LinkedList;
165+
const linkedlist_value_container_t* node;
166+
bool atEnd;
135167
};
168+
};
136169

137-
iterator begin() { return iterator(first, this); }
138-
iterator end() { return iterator(nullptr, this); }
139-
const_iterator begin() const { return const_iterator(first, this); }
140-
const_iterator end() const { return const_iterator(nullptr, this); }
141-
const_iterator cbegin() const { return const_iterator(first, this); }
142-
const_iterator cend() const { return const_iterator(nullptr, this); }
143170

144-
typedef std::reverse_iterator<iterator> reverse_iterator;
145-
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
171+
template<class T>
172+
class LinkedList : public Container<T, typename linkedlist_value_container_t<T>::Iterator, typename linkedlist_value_container_t<T>::ConstIterator> {
173+
public:
174+
175+
typedef typename linkedlist_value_container_t<T>::Iterator iterator;
176+
typedef typename linkedlist_value_container_t<T>::ConstIterator const_iterator;
146177

147-
reverse_iterator rbegin() { return reverse_iterator(end()); }
148-
reverse_iterator rend() { return reverse_iterator(begin()); }
149-
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
150-
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
151-
const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); }
152-
const_reverse_iterator crend() const { return const_reverse_iterator(begin()); }
178+
iterator begin() override { return iterator(first, first == nullptr); }
179+
iterator end() override { return iterator(last, true); }
180+
const_iterator begin() const override { return const_iterator(first, first == nullptr); }
181+
const_iterator end() const override { return const_iterator(last, true); }
182+
const_iterator cbegin() const { return const_iterator(first, first == nullptr); }
183+
const_iterator cend() const { return const_iterator(last, true); }
153184

154185
/**
155186
* Creates an empty LinkedList.
@@ -394,6 +425,12 @@ class LinkedList {
394425
inline linkedlist_value_container_t<T>* getRawCursor() { return cursor; }
395426
inline void setRawCursor(linkedlist_value_container_t<T>* newCursor) { cursor = newCursor; }
396427

428+
public:
429+
int length;
430+
linkedlist_value_container_t<T>* first = nullptr;
431+
linkedlist_value_container_t<T>* last = nullptr;
432+
linkedlist_value_container_t<T>* cursor = nullptr;
433+
397434
private:
398435
T removeRaw(linkedlist_value_container_t<T>* containerToRemove) {
399436
if (containerToRemove == last)
@@ -415,11 +452,6 @@ class LinkedList {
415452
delete containerToRemove;
416453
return value;
417454
}
418-
419-
int length;
420-
linkedlist_value_container_t<T>* first = nullptr;
421-
linkedlist_value_container_t<T>* last = nullptr;
422-
linkedlist_value_container_t<T>* cursor = nullptr;
423455
};
424456

425457
#endif //EXCESSIVE_LINKEDLIST_H

src/tests/test_ArrayList.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,18 @@ TEST(ArrayListTest, ExportMemoryTransfersOwnership) {
212212

213213
free(mem); // caller now owns memory
214214
}
215+
216+
TEST(ArrayListTest, ContainerInterface) {
217+
ArrayList<int> list;
218+
list.add(10);
219+
list.add(20);
220+
list.add(30);
221+
222+
Container<int, int*, const int*>* container = &list;
223+
EXPECT_EQ(container->getElement(0), 10);
224+
EXPECT_EQ(container->getElement(1), 20);
225+
EXPECT_EQ(container->getElement(2), 30);
226+
227+
EXPECT_EQ(container->find(20), 1);
228+
EXPECT_EQ(container->find(40), -1);
229+
}

0 commit comments

Comments
 (0)