From 5789f5372177d0ff4190b45641eecf51d9b34bc5 Mon Sep 17 00:00:00 2001 From: Dan Cojocaru Date: Sun, 21 Nov 2021 00:38:43 +0200 Subject: [PATCH] First commit --- .gitignore | 2 + Makefile | 22 +++++++ README.md | 29 ++++++++++ dynarray.hpp | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++ example.cpp | 38 ++++++++++++ 5 files changed, 251 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 dynarray.hpp create mode 100644 example.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..39e99c7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +obj +example diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..825a31c --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +CXX?=g++ + +.PHONY: debug run clean + +example: obj/example.o + ${CXX} $^ -o $@ + +run: example + ./example + +debug: + COMPILE_FLAGS="-D DEBUG" make -B example + +obj: + @if [ ! -d obj ]; then mkdir obj; fi + +obj/%.o: %.cpp | obj + ${CXX} ${COMPILE_FLAGS} -c $^ -o $@ + +clean: + @if [ -d obj ]; then echo rm -r obj; rm -r obj; fi + @if [ -f example ]; then echo rm example; rm example; fi diff --git a/README.md b/README.md new file mode 100644 index 0000000..532aa86 --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# DynArray: basic dynamic array (list/vector) implementation + +Why? Why not. + +## How to run? + +### Got make? + +```shell +make run +``` + +### No make? + +```shell +g++ example.cpp -o example +./example +``` + +### Windows? + +```powershell +g++ example.cpp -o example.exe +.\example.exe +``` + +### Windows without `g++`? + +I never compiled something using `msvc` from the terminal. I guess make a new Visual Studio project, copy-paste the files in there and have fun, idk. diff --git a/dynarray.hpp b/dynarray.hpp new file mode 100644 index 0000000..81de0cc --- /dev/null +++ b/dynarray.hpp @@ -0,0 +1,160 @@ +#pragma once + +#ifdef DEBUG +#define TMP_DEBUG_12345 DEBUG +#undef DEBUG +#include +using std::cerr; +#define DEBUG (cerr << "[DynArray " << this << "] ") +#endif + +template +class DynArray { +private: + T* _buffer; + size_t _length; + size_t _capacity; + +public: + explicit DynArray(size_t capacity = 64) + : _buffer(new T[capacity]) + , _length(0) + , _capacity(capacity) { + #ifdef DEBUG + DEBUG << "New array with capacity " << capacity << '\n'; + #endif + } + + ~DynArray() { + #ifdef DEBUG + DEBUG << "Destroyed" << '\n'; + #endif + delete[] _buffer; + } + + size_t size() const { + return _length; + } + + size_t length() const { + return _length; + } + + operator bool() const { + return length() > 0; + } + + size_t capacity() const { + return _capacity; + } + + void push_back(T element) { + if (_length + 1 > _capacity) { + #ifdef DEBUG + DEBUG << "Push attempt when length and capacity are " << _capacity << ", reallocating" << '\n'; + #endif + T *new_buffer = new T[_capacity * 2]; + for (size_t i = 0; i < _capacity; ++i) { + new_buffer[i] = _buffer[i]; + } + delete[] _buffer; + _buffer = new_buffer; + _capacity *= 2; + } + _buffer[_length++] = element; + } + + DynArray& operator<<(T element) { + push_back(element); + return *this; + } + + void pop_back() { + _length--; + } + + T& operator[](size_t index) { + return _buffer[index]; + } + + const T& operator[](size_t index) const { + return _buffer[index]; + } + + // Iterator bullshit + class iterator { + private: + DynArray* _arr; + size_t _index; + public: + // Default constructible + iterator() : _arr(nullptr), _index(-1) {} + iterator(DynArray &arr, size_t index = 0) : _arr(&arr), _index(index) {} + // Copy constructible + iterator(const iterator &it) : _arr(it._arr), _index(it._index) {} + + // Copy assignable + iterator& operator=(const iterator& it) { + _arr = it._arr; + _index = it._index; + } + + // Comparable + bool operator==(const iterator& it) const { + return _arr == it._arr && _index == it._index; + } + + bool operator!=(const iterator& it) const { + return !(*this == it); + } + + // Dereferencable + T& operator*() { + return (*_arr)[_index]; + } + const T& operator*() const { + return (*_arr)[_index]; + } + + T* operator->() { + return &((*_arr)[_index]); + } + const T* operator->() const { + return &((*_arr)[_index]); + } + + // Can be incremented + iterator& operator++() { + _index++; + return *this; + } + + iterator operator++(int) { + auto copy = *this; + ++*this; + return copy; + } + }; + + iterator begin() { + return iterator(*this); + } + const iterator begin() const { + return iterator(*this); + } + + iterator end() { + return iterator(*this, size()); + } + const iterator end() const { + return iterator(*this, size()); + } +}; + +#ifdef TMP_DEBUG_12345 +#ifdef DEBUG +#undef DEBUG +#endif +#define DEBUG TMP_DEBUG_12345 +#undef TMP_DEBUG_12345 +#endif diff --git a/example.cpp b/example.cpp new file mode 100644 index 0000000..67790f0 --- /dev/null +++ b/example.cpp @@ -0,0 +1,38 @@ +#include +#include +using std::cout; +using std::cin; + +#include "dynarray.hpp" + +int main() { + size_t n; + cout << "How many numbers to generate? "; + cin >> n; + + std::default_random_engine r_eng; + DynArray arr; + for (auto i = 0; i < n; i++) + { + arr << r_eng(); + } + cout << '\n'; + + cout << "Size: " << arr.size() << '\n'; + cout << "Capacity: " << arr.capacity() << '\n'; + cout << "Elements: ["; + bool first = true; + for (auto elem : arr) + { + if (!first) { + cout << ", "; + } + else { + first = false; + } + cout << elem; + } + cout << "]\n"; + + return 0; +} \ No newline at end of file