aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Haines <mjark@negativecurvature.net>2015-02-24 11:30:28 +0000
committerMark Haines <mjark@negativecurvature.net>2015-02-24 11:30:28 +0000
commit38332e0a122fdb93a7b8d736dc6520545aa177c3 (patch)
tree74e14c45659570f7e9ed8a514c9dfbdc91f9ebbd
parent0e13cd35626e58fee436b390a523c53effab8d8c (diff)
Add a simple fixed size list class
-rw-r--r--include/axolotl/list.hh90
-rw-r--r--tests/test_list.cpp56
2 files changed, 146 insertions, 0 deletions
diff --git a/include/axolotl/list.hh b/include/axolotl/list.hh
new file mode 100644
index 0000000..b76abdd
--- /dev/null
+++ b/include/axolotl/list.hh
@@ -0,0 +1,90 @@
+#include <cstddef>
+
+namespace axolotl {
+
+template<typename T, std::size_t max_size>
+class List {
+public:
+ List() : _end(_data) {}
+
+ typedef T * iterator;
+ typedef T const * const_iterator;
+
+ T * begin() { return _data; }
+ T * end() { return _end; }
+ T const * begin() const { return _data; }
+ T const * end() const { return _end; }
+
+ /**
+ * The number of items in the list.
+ */
+ std::size_t size() { return _end - _data; }
+
+ T & operator[](std::size_t index) { return _data[index]; }
+
+ T const & operator[](std::size_t index) const { return _data[index]; }
+
+ /**
+ * Erase the item from the list at the given position.
+ */
+ void erase(T * pos) {
+ --_end;
+ while (pos != _end) {
+ *pos = *(pos + 1);
+ ++pos;
+ }
+ }
+
+ /**
+ * Make space for an item in the list at a given position.
+ * If inserting the item makes the list longer than max_size then
+ * the end of the list is discarded.
+ * Returns the where the item is inserted.
+ */
+ T * insert(T * pos) {
+ if (_end != _data + max_size) {
+ ++_end;
+ } else if (pos == _end) {
+ --pos;
+ }
+ T * tmp = pos;
+ while (tmp != _end - 1) {
+ *(tmp + 1) = *tmp;
+ ++tmp;
+ }
+ return pos;
+ }
+
+ /**
+ * Insert an item into the list at a given position.
+ * If inserting the item makes the list longer than max_size then
+ * the end of the list is discarded.
+ * Returns the where the item is inserted.
+ */
+ T * insert(T * pos, T const & value) {
+ pos = insert(pos);
+ *pos = value;
+ return pos;
+ }
+
+ List<T, max_size> & operator=(List<T, max_size> const & other) {
+ if (this = &other) {
+ return *this;
+ }
+ T * this_pos = _data;
+ T * const other_pos = other._data;
+ while (other_pos != other._end) {
+ *this_pos = *other;
+ ++this_pos;
+ ++other_pos;
+ }
+ _end = this_pos;
+ return *this;
+ }
+
+private:
+ T * _end;
+ T _data[max_size];
+};
+
+} // namespace axolotl
diff --git a/tests/test_list.cpp b/tests/test_list.cpp
new file mode 100644
index 0000000..27b3d58
--- /dev/null
+++ b/tests/test_list.cpp
@@ -0,0 +1,56 @@
+#include "axolotl/list.hh"
+#include "unittest.hh"
+
+int main() {
+
+{ /** List insert test **/
+
+TestCase test_case("List insert");
+
+axolotl::List<int, 4> test_list;
+
+assert_equals(std::size_t(0), test_list.size());
+
+for (int i = 0; i < 4; ++i) {
+ test_list.insert(test_list.end(), i);
+}
+
+assert_equals(std::size_t(4), test_list.size());
+
+int i = 0;
+for (auto item : test_list) {
+ assert_equals(i++, item);
+}
+
+assert_equals(4, i);
+
+test_list.insert(test_list.end(), 4);
+
+assert_equals(4, test_list[3]);
+
+} /** List insert test **/
+
+{ /** List erase test **/
+TestCase test_case("List erase");
+
+axolotl::List<int, 4> test_list;
+assert_equals(std::size_t(0), test_list.size());
+
+for (int i = 0; i < 4; ++i) {
+ test_list.insert(test_list.end(), i);
+}
+assert_equals(std::size_t(4), test_list.size());
+
+test_list.erase(test_list.begin());
+assert_equals(std::size_t(3), test_list.size());
+
+int i = 0;
+for (auto item : test_list) {
+ assert_equals(i + 1, item);
+ ++i;
+}
+assert_equals(3, i);
+
+}
+
+}