summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElizabeth Hunt <elizabeth.hunt@simponic.xyz>2023-11-24 18:18:16 -0700
committerElizabeth Hunt <elizabeth.hunt@simponic.xyz>2023-11-24 18:18:16 -0700
commitc6176c05918f65b48148380f7eb41ac3f5c09d81 (patch)
treee0dfd471c678e52b4b35e91b4795a470d2c461a4
parent205bddb307a1148828ae1cdbc56e960a401834a3 (diff)
downloadgbarubik-c6176c05918f65b48148380f7eb41ac3f5c09d81.tar.gz
gbarubik-c6176c05918f65b48148380f7eb41ac3f5c09d81.zip
add dynamically sized vector from usu c++ assignment.
-rw-r--r--inc/vector.hpp311
-rw-r--r--src/vector.cpp171
2 files changed, 482 insertions, 0 deletions
diff --git a/inc/vector.hpp b/inc/vector.hpp
new file mode 100644
index 0000000..5de1fa0
--- /dev/null
+++ b/inc/vector.hpp
@@ -0,0 +1,311 @@
+
+#ifndef USU_VECTOR_HPP
+#define USU_VECTOR_HPP
+
+#include <algorithm>
+#include <cmath>
+#include <cstddef>
+#include <cstdint>
+#include <functional>
+#include <iostream>
+#include <memory>
+#include <stdexcept>
+#include <tuple>
+
+namespace usu {
+template <typename T> class vector {
+public:
+ using size_type = std::size_t;
+ using reference = T &;
+ using pointer = std::shared_ptr<T[]>;
+ using value_type = T;
+ using resize_type = std::function<size_type(size_type)>;
+
+ static resize_type DEFAULT_RESIZER;
+ static size_type DEFAULT_CAPACITY;
+
+ vector();
+ vector(size_type size);
+ vector(resize_type resize);
+ vector(std::initializer_list<T> list);
+ vector(size_type size, resize_type resize);
+ vector(std::initializer_list<T> list, resize_type resize);
+
+ class iterator {
+ public:
+ using iterator_category = std::forward_iterator_tag;
+ iterator();
+ iterator(pointer data);
+ iterator(size_type pos, pointer data);
+ iterator(const iterator &obj);
+ iterator(iterator &&obj) noexcept;
+
+ iterator &operator=(const iterator &rhs);
+ iterator &operator=(iterator &&rhs);
+ bool operator==(const iterator &rhs) const;
+ bool operator!=(const iterator &rhs) const;
+ iterator operator++();
+ iterator operator--();
+ iterator operator++(int);
+ iterator operator--(int);
+ value_type operator*();
+ std::shared_ptr<T> operator->();
+
+ private:
+ pointer m_data;
+ size_type m_pos;
+ };
+
+ reference operator[](size_type index);
+ void add(T value);
+ void insert(size_type index, T value);
+ void remove(size_type index);
+ void clear();
+ size_type size();
+ size_type capacity();
+ iterator begin();
+ iterator end();
+
+protected:
+ pointer m_data;
+ size_type m_capacity;
+ size_type m_size;
+ resize_type m_resize;
+
+ void maybe_resize();
+};
+
+template <> class vector<bool> : public vector<std::uint8_t> {
+public:
+ using size_type = std::size_t;
+ using pointer = std::shared_ptr<std::uint8_t[]>;
+ using resize_type = std::function<size_type(size_type)>;
+
+ vector();
+ vector(size_type size);
+ vector(resize_type resize);
+ vector(std::initializer_list<bool> list);
+ vector(size_type size, resize_type resize);
+ vector(std::initializer_list<bool> list, resize_type resize);
+
+ class reference {
+ public:
+ reference();
+ reference(size_type pos, pointer data);
+ reference &operator=(bool value);
+ operator bool();
+ bool operator==(const reference &rhs) const;
+ bool operator!=(const reference &rhs) const;
+
+ bool get() const;
+ void add();
+ void sub();
+
+ private:
+ size_type m_pos;
+ pointer m_data;
+ };
+
+ class iterator {
+ public:
+ using iterator_category = std::forward_iterator_tag;
+ iterator();
+ iterator(pointer data);
+ iterator(size_type pos, pointer data);
+ iterator(const iterator &obj);
+ iterator(iterator &&obj) noexcept;
+
+ iterator &operator=(const iterator &rhs);
+ iterator &operator=(iterator &&rhs);
+ bool operator==(const iterator &rhs) const;
+ bool operator!=(const iterator &rhs) const;
+ iterator operator++();
+ iterator operator--();
+ iterator operator++(int);
+ iterator operator--(int);
+ reference operator*();
+
+ private:
+ reference m_ref;
+ };
+
+ reference operator[](size_type index);
+
+ void add(bool value);
+ void insert(size_type index, bool value);
+ void remove(size_type index);
+
+ iterator begin();
+ iterator end();
+
+private:
+ void maybe_resize();
+};
+
+template <typename T>
+vector<T>::iterator::iterator() : vector<T>::iterator::iterator(nullptr) {}
+
+template <typename T>
+vector<T>::iterator::iterator(pointer data) : m_data(data), m_pos(0) {}
+
+template <typename T>
+vector<T>::iterator::iterator(size_type pos, pointer data)
+ : m_data(data), m_pos(pos) {}
+
+template <typename T> vector<T>::iterator::iterator(const iterator &obj) {
+ m_pos = obj.m_pos;
+ m_data = obj.m_data;
+}
+
+template <typename T> vector<T>::iterator::iterator(iterator &&obj) noexcept {
+ m_pos = obj.m_pos;
+ m_data = obj.m_data;
+ obj.m_pos = 0;
+ obj.m_data = nullptr;
+}
+
+template <typename T>
+bool vector<T>::iterator::operator!=(const iterator &rhs) const {
+ return m_pos != rhs.m_pos;
+}
+
+template <typename T>
+bool vector<T>::iterator::operator==(const iterator &rhs) const {
+ return m_pos == rhs.m_pos;
+}
+
+template <typename T>
+typename vector<T>::iterator vector<T>::iterator::operator++() {
+ m_pos++;
+ return *this;
+}
+
+template <typename T>
+typename vector<T>::iterator vector<T>::iterator::operator--() {
+ m_pos--;
+ return *this;
+}
+
+template <typename T>
+typename vector<T>::iterator vector<T>::iterator::operator++(int) {
+ iterator it = *this;
+ m_pos++;
+ return it;
+}
+
+template <typename T>
+typename vector<T>::iterator vector<T>::iterator::operator--(int) {
+ iterator it = *this;
+ m_pos--;
+ return it;
+}
+
+template <typename T>
+typename vector<T>::value_type vector<T>::iterator::operator*() {
+ return m_data[m_pos];
+}
+
+template <typename T> std::shared_ptr<T> vector<T>::iterator::operator->() {
+ return std::make_shared<T>(m_data[m_pos]);
+}
+
+template <typename T>
+typename vector<T>::resize_type vector<T>::DEFAULT_RESIZER =
+ [](size_type currentCapacity) -> size_type { return currentCapacity * 2; };
+
+template <typename T>
+typename vector<T>::size_type vector<T>::DEFAULT_CAPACITY = 10;
+
+template <typename T>
+vector<T>::vector() : usu::vector<T>(0, DEFAULT_RESIZER) {}
+
+template <typename T>
+usu::vector<T>::vector(size_type size)
+ : usu::vector<T>(size, DEFAULT_RESIZER) {}
+
+template <typename T>
+vector<T>::vector(resize_type resize) : usu::vector<T>(0, resize) {}
+
+template <typename T>
+vector<T>::vector(std::initializer_list<T> list)
+ : usu::vector<T>(list, DEFAULT_RESIZER) {}
+
+template <typename T>
+vector<T>::vector(std::initializer_list<T> list, resize_type resize)
+ : usu::vector<T>(0, resize) {
+ for (auto i = list.begin(); i < list.end(); ++i)
+ add(*i);
+}
+
+template <typename T>
+vector<T>::vector(size_type size, resize_type resize)
+ : m_data(nullptr),
+ m_capacity(DEFAULT_CAPACITY > size ? DEFAULT_CAPACITY
+ : DEFAULT_RESIZER(size)),
+ m_size(size), m_resize(resize) {
+ maybe_resize();
+}
+
+template <typename T> void vector<T>::maybe_resize() {
+ if (m_data == nullptr)
+ m_data = std::make_shared<T[]>(m_capacity);
+ if (m_size >= m_capacity) {
+ m_capacity = std::max(m_capacity == 0 ? 1 : m_resize(m_capacity), m_size);
+
+ pointer newData = std::make_shared<T[]>(m_capacity);
+ for (size_type i = 0; i < m_size; ++i)
+ newData[i] = m_data[i];
+
+ m_data = newData;
+ }
+}
+
+template <typename T> void vector<T>::add(T value) {
+ maybe_resize();
+ m_data[m_size++] = value;
+}
+
+template <typename T>
+typename vector<T>::reference vector<T>::operator[](size_type index) {
+ return m_data[index];
+}
+
+template <typename T> void vector<T>::insert(size_type index, T value) {
+ maybe_resize();
+
+ for (size_type i = m_size; i > index; --i)
+ m_data[i] = m_data[i - 1];
+ m_data[index] = value;
+
+ m_size++;
+}
+
+template <typename T> void vector<T>::remove(size_type index) {
+ for (size_type i = index; i < m_size; ++i)
+ m_data[i] = m_data[i + 1];
+ m_size--;
+}
+
+template <typename T> typename vector<T>::iterator vector<T>::begin() {
+ vector<T>::iterator begin(m_data);
+ return begin;
+}
+
+template <typename T> typename vector<T>::iterator vector<T>::end() {
+ vector<T>::iterator end(m_size, m_data);
+ return end;
+}
+
+template <typename T> void vector<T>::clear() { m_size = 0; }
+
+template <typename T> typename vector<T>::size_type vector<T>::size() {
+ return m_size;
+}
+
+template <typename T> typename vector<T>::size_type vector<T>::capacity() {
+ return m_capacity;
+}
+
+} // namespace usu
+
+#endif
diff --git a/src/vector.cpp b/src/vector.cpp
new file mode 100644
index 0000000..eb2158b
--- /dev/null
+++ b/src/vector.cpp
@@ -0,0 +1,171 @@
+#include "vector.hpp"
+
+usu::vector<bool>::reference::reference()
+ : usu::vector<bool>::reference(0, nullptr) {}
+
+usu::vector<bool>::reference::reference(size_type pos, pointer data)
+ : m_pos(pos), m_data(data) {}
+
+typename usu::vector<bool>::reference &
+usu::vector<bool>::reference::operator=(bool value) {
+ std::uint8_t mask = 1 << (7 - (m_pos % 8));
+ if (value)
+ m_data[m_pos / 8] |= mask;
+ else
+ m_data[m_pos / 8] &= (~mask);
+ return *this;
+}
+
+typename usu::vector<bool>::reference
+usu::vector<bool>::operator[](size_type index) {
+ reference r(index, m_data);
+ return r;
+}
+
+void usu::vector<bool>::reference::add() { m_pos++; }
+
+void usu::vector<bool>::reference::sub() { m_pos--; }
+
+bool usu::vector<bool>::reference::get() const {
+ return ((m_data[m_pos / 8] >> (7 - (m_pos % 8))) & 1) == 1;
+}
+
+usu::vector<bool>::reference::operator bool() { return get(); }
+
+bool usu::vector<bool>::reference::operator==(const reference &rhs) const {
+ return m_data == rhs.m_data && m_pos == rhs.m_pos;
+}
+
+bool usu::vector<bool>::reference::operator!=(const reference &rhs) const {
+ return m_data != rhs.m_data || m_pos != rhs.m_pos;
+}
+
+usu::vector<bool>::iterator::iterator()
+ : usu::vector<bool>::iterator(nullptr) {}
+
+usu::vector<bool>::iterator::iterator(pointer data)
+ : usu::vector<bool>::iterator(0, data) {}
+
+usu::vector<bool>::iterator::iterator(size_type pos, pointer data) {
+ m_ref = reference(pos, data);
+}
+
+usu::vector<bool>::iterator::iterator(const iterator &obj) {
+ m_ref = obj.m_ref;
+}
+
+usu::vector<bool>::iterator::iterator(iterator &&obj) noexcept {
+ m_ref = obj.m_ref;
+ obj.m_ref = reference(0, nullptr);
+}
+
+typename usu::vector<bool>::iterator usu::vector<bool>::iterator::operator++() {
+ m_ref.add();
+ return *this;
+}
+
+typename usu::vector<bool>::iterator usu::vector<bool>::iterator::operator--() {
+ m_ref.sub();
+ return *this;
+}
+
+typename usu::vector<bool>::iterator
+usu::vector<bool>::iterator::operator++(int) {
+ iterator it = *this;
+ m_ref.add();
+ return it;
+}
+
+typename usu::vector<bool>::iterator
+usu::vector<bool>::iterator::operator--(int) {
+ iterator it = *this;
+ m_ref.sub();
+ return it;
+}
+
+typename usu::vector<bool>::reference usu::vector<bool>::iterator::operator*() {
+ return m_ref;
+}
+
+bool usu::vector<bool>::iterator::operator!=(const iterator &rhs) const {
+ return m_ref != rhs.m_ref;
+}
+
+bool usu::vector<bool>::iterator::operator==(const iterator &rhs) const {
+ return m_ref == rhs.m_ref;
+}
+
+usu::vector<bool>::vector() : usu::vector<bool>(0, DEFAULT_RESIZER){};
+
+usu::vector<bool>::vector(size_type size)
+ : usu::vector<bool>(size, DEFAULT_RESIZER){};
+
+usu::vector<bool>::vector(resize_type resize) : usu::vector<bool>(0, resize){};
+
+usu::vector<bool>::vector(size_type size, resize_type resize) {
+ m_resize = resize;
+ m_size = size;
+ m_capacity = DEFAULT_CAPACITY > size ? DEFAULT_CAPACITY : resize(size);
+ maybe_resize();
+};
+
+usu::vector<bool>::vector(std::initializer_list<bool> list)
+ : usu::vector<bool>(list, DEFAULT_RESIZER){};
+
+usu::vector<bool>::vector(std::initializer_list<bool> list, resize_type resize)
+ : usu::vector<std::uint8_t>(0, resize) {
+ for (auto i = list.begin(); i != list.end(); ++i)
+ add(*i);
+};
+
+void usu::vector<bool>::add(bool value) {
+ maybe_resize();
+ reference r(m_size++, m_data);
+ r = value;
+}
+
+void usu::vector<bool>::insert(size_type index, bool value) {
+ maybe_resize();
+
+ reference r1(m_size, m_data);
+ reference r2(m_size == 0 ? 0 : m_size - 1, m_data);
+
+ for (size_type i = m_size; i > index; --i, r1.sub(), r2.sub())
+ r1 = r2.get();
+ r1 = value;
+ m_size++;
+}
+
+void usu::vector<bool>::remove(size_type index) {
+ reference r1(index, m_data);
+ reference r2(index + 1 >= m_size ? index : index + 1, m_data);
+
+ for (size_type i = index; i < m_size; ++i, r1.add(), r2.add())
+ r1 = r2.get();
+ r1 = false;
+ m_size--;
+}
+
+void usu::vector<bool>::maybe_resize() {
+ if (m_data == nullptr)
+ m_data = std::make_shared<std::uint8_t[]>(m_capacity / 8);
+ if (m_size >= m_capacity) {
+ m_capacity = std::max(m_capacity == 0 ? 1 : m_resize(m_capacity), m_size);
+
+ pointer newData = std::make_shared<std::uint8_t[]>(m_capacity / 8);
+ for (size_type i = 0; i <= m_size / 8; ++i)
+ newData[i] = m_data[i];
+
+ m_data = newData;
+ }
+}
+
+typename usu::vector<bool>::iterator usu::vector<bool>::begin() {
+ vector<bool>::iterator begin(m_data);
+ return begin;
+}
+
+typename usu::vector<bool>::iterator usu::vector<bool>::end() {
+ vector<bool>::iterator end(m_size, m_data);
+ return end;
+}