From 2efd3407ac6703d3914f239a378620a93a7980a8 Mon Sep 17 00:00:00 2001 From: karl Date: Fri, 5 Mar 2021 14:14:27 +0100 Subject: [PATCH] Basic implementation aside from resizing done --- .clang-format | 15 ++++---- Vector.cpp | 6 --- Vector.h | 102 +++++++++++++++++++++++++++++++++++++++++++++++++- main.cpp | 44 +++++++++++++++++++++- 4 files changed, 151 insertions(+), 16 deletions(-) delete mode 100644 Vector.cpp diff --git a/.clang-format b/.clang-format index a63e137..1e5484c 100644 --- a/.clang-format +++ b/.clang-format @@ -1,13 +1,14 @@ --- BasedOnStyle: LLVM -AllowShortBlocksOnASingleLine: 'true' -AllowShortCaseLabelsOnASingleLine: 'true' -AllowShortFunctionsOnASingleLine: Inline +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: None AllowShortIfStatementsOnASingleLine: WithoutElse AllowShortLambdasOnASingleLine: Inline -AllowShortLoopsOnASingleLine: 'false' -AlwaysBreakBeforeMultilineStrings: 'true' -IndentWidth: '4' -ColumnLimit: 100 +AllowShortLoopsOnASingleLine: false +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: true +IndentWidth: 4 +ColumnLimit: 80 ... diff --git a/Vector.cpp b/Vector.cpp deleted file mode 100644 index 670384a..0000000 --- a/Vector.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "Vector.h" -#include - -Vector::Vector() { - std::cout << "Vector created" << std::endl; -} diff --git a/Vector.h b/Vector.h index abdb1a7..e5dd201 100644 --- a/Vector.h +++ b/Vector.h @@ -1,4 +1,104 @@ +#pragma once +#include +#include +#include + +template class Vector { public: - Vector(); + // Constructor + Vector(unsigned int capacity = 10) + : capacity(capacity), element_count(0), data(new T[capacity]) { + std::cout << "Vector created" << std::endl; + } + + // Copy Constructor + Vector(const Vector &other) + : capacity(other.capacity), element_count(other.element_count), + data(new T[capacity]) { + // `std::copy` is used because it is more flexible than `std::memcpy`, + // and the compiler will replace it with `memcpy` anyway if appropriate, + // so there is no performance loss. + std::copy(other.data, other.data + element_count, data); + } + + // Move Constructor using the copy-and-swap-idiom + Vector(Vector &&other) : data(new T[capacity]) { + swap(*this, other); + } + + // Copy Assignment Operator using the copy-and-swap-idiom + // Since this takes a value rather than a const reference due to + // copy-and-swap, this is also the Move Assignment Operator + Vector &operator=(Vector other) { + swap(*this, other); + + return *this; + } + + // Destructor + ~Vector() { + delete[] data; + + std::cout << "Vector deleted" << std::endl; + } + + // Bracket Operator + T &operator[](unsigned int position) const { + return at(position); + } + + // Swap function for the copy-and-swap idiom. + // See also: + // https://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom + // The `friend` keyword is used so it is found through ADL. + friend void swap(Vector &first, Vector &second) { + // Enable ADL (good practice) + using std::swap; + + swap(first.capacity, second.capacity); + swap(first.element_count, second.element_count); + swap(first.data, second.data); + } + + void push_back(const T &element) { + if (element_count >= capacity) { + // TODO: Increase capacity! + } + + // Use placement new to directly use pre-allocated memory + new (data + element_count) T(element); + element_count++; + } + + void erase(unsigned int position) { + assert(position < element_count); + + std::copy_backward(data + position + 1, data + element_count, + data + element_count - 1); + + element_count--; + } + + unsigned int size() const { + return element_count; + } + + unsigned int length() const { + return capacity; + } + + T &at(unsigned int position) const { + assert(position < element_count); + return data[position]; + } + + void reserve(unsigned int); + + void resize(unsigned int); + + private: + T *data; + unsigned int element_count; + unsigned int capacity; }; diff --git a/main.cpp b/main.cpp index 8f8e0b8..364d456 100644 --- a/main.cpp +++ b/main.cpp @@ -1,6 +1,46 @@ #include "Vector.h" #include -int main() { - Vector vector; +void print_float_vector(const Vector &v) { + for (int i = 0; i < v.size(); i++) { + std::cout << v[i] << ", "; + } + std::cout << std::endl; +} + +int main() { + Vector vector1; + + vector1.push_back(0.5); + vector1.push_back(0.7); + vector1.push_back(1.2); + vector1.push_back(2.0); + vector1.push_back(3.0); + + std::cout << "Before erase at 2" << std::endl; + print_float_vector(vector1); + + vector1.erase(2); + + std::cout << "After erase at 2" << std::endl; + print_float_vector(vector1); + + Vector vector2 = std::move(vector1); + + std::cout << "After std::move" << std::endl; + print_float_vector(vector2); + + Vector vector3 = vector2; + + std::cout << "After copy construction" << std::endl; + print_float_vector(vector2); + print_float_vector(vector3); + + Vector vector4; + vector4.push_back(7353.0); + vector4 = vector3; + + std::cout << "After copy assignment" << std::endl; + print_float_vector(vector3); + print_float_vector(vector4); }