diff --git a/data.hpp b/data.hpp index b0f0de0..8f59234 100644 --- a/data.hpp +++ b/data.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include #include #include @@ -11,93 +10,101 @@ namespace asp { template struct Array { - std::shared_ptr data; + T* data = nullptr; size_t length = 0; + size_t* refcount = nullptr; constexpr Array(void) noexcept = delete; - constexpr Array(const size_t& size) noexcept : data(std::shared_ptr(new T[size])), length(size) { + constexpr Array(const size_t& size) noexcept : data(new T[size]), length(size), refcount(new size_t(1)) { #ifdef __DEBUG printf("Creating array of size %lu\n", size); #endif } - constexpr Array(const std::initializer_list& other) noexcept : data(std::shared_ptr(new T[other.size()])), length(other.size()) { + constexpr Array(const std::initializer_list& init_list) noexcept : data(new T[init_list.size()]), length(init_list.size()), refcount(new size_t(1)) { #ifdef __DEBUG - printf("Copying array of size %lu\n", other.size()); + printf("Copying initializer_list of size %lu\n", init_list.size()); #endif - memcpy(data.get(), other.begin(), length * sizeof(T)); + memcpy(data, init_list.begin(), length * sizeof(T)); } - constexpr Array(const Array& other) noexcept : data(std::shared_ptr(new T[other.length])), length(other.length) { + constexpr Array(const Array& other) noexcept : Array(other.length) { #ifdef __DEBUG printf("Copying array of size %lu\n", other.length); #endif - memcpy(data.get(), other.data.get(), length * sizeof(T)); + memcpy(data, other.data, length * sizeof(T)); } constexpr Array(Array&& other) noexcept { #ifdef __DEBUG printf("Moving array of size %lu\n", other.length); #endif + if (refcount != nullptr){ + delete[] data; + delete refcount; + } data = other.data; length = other.length; + refcount = other.refcount; other.data = nullptr; other.length = 0; + other.refcount = nullptr; } - constexpr T& operator[](const size_t& index) const { + inline ~Array() noexcept { + if (refcount == nullptr) + return; +#ifdef __DEBUG + printf("Destructing array of size %lu and refcount %lu\n", length, *refcount); +#endif + + if (--(*refcount) == 0){ +#ifdef __DEBUG + printf("Freeing array of size %lu\n", length); +#endif + delete[] data; + data = nullptr; + delete refcount; + refcount = nullptr; + } + } + + constexpr Array& operator=(const Array& other) noexcept { + if (this != &other) { + if (--(*refcount) == 0) { + delete[] data; + delete refcount; + } + data = other.data; + length = other.length; + refcount = other.refcount; + ++(*refcount); + } + return *this; + } + + constexpr T& operator[](const size_t& index) { #ifdef __DEBUG if (index > length) { fprintf(stderr, "Index %ld out of range in Array of length %ld !\n", index, length); throw std::out_of_range("Index out of range !"); } #endif - return data.get()[index]; + return data[index]; + } + + constexpr const T& operator[](const size_t& index) const { +#ifdef __DEBUG + if (index > length) { + fprintf(stderr, "Index %ld out of range in Array of length %ld !\n", index, length); + throw std::out_of_range("Index out of range !"); + } +#endif + return data[index]; } }; - template - constexpr int32_t print(const Array& a, const char* const format) noexcept { - int32_t num_written = 0; - num_written += printf("["); - char formatter[256] = { 0 }; - sprintf(formatter, "%s,", format); - for (size_t i = 0; i < a.length; ++i) - num_written += printf(formatter, a[i]); - sprintf(formatter, "%s]\n", format); - num_written += printf(formatter, a[a.length - 1]); - return num_written; - } - - constexpr int32_t print(const Array& a) noexcept { - return print(a, "%b"); - } - - constexpr int32_t print(const Array& a) noexcept { - return print(a, "%i"); - } - - constexpr int32_t print(const Array& a) noexcept { - return print(a, "%u"); - } - - constexpr int32_t print(const Array& a) noexcept { - return print(a, "%lu"); - } - - constexpr int32_t print(const Array& a) noexcept { - return print(a, "%i"); - } - - constexpr int32_t print(const std::string_view& s) noexcept { - return printf("%s\n", s.data()); - } - - constexpr int32_t print(const char* const s) noexcept { - return printf("%s\n", s); - } - template constexpr T& max(const Array& a) noexcept { T& max_el = a[0];