From cf98c43db150e8e0437ae1a5d36cce0d072c6770 Mon Sep 17 00:00:00 2001 From: Ludovic 'Archivist' Lagouardette Date: Mon, 5 Oct 2020 17:32:10 +0200 Subject: [PATCH] Untested vector added --- include/gp/vector.hpp | 251 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 include/gp/vector.hpp diff --git a/include/gp/vector.hpp b/include/gp/vector.hpp new file mode 100644 index 0000000..fe9cdb4 --- /dev/null +++ b/include/gp/vector.hpp @@ -0,0 +1,251 @@ +#pragma once + +#include +#include + +#include + +namespace gp{ + template + class vector{ + public: + T* ary; + size_t sz; + size_t cap; + gp::reference_wrapper alloc; + using associated_iterator = pointer_iterator; + using associated_const_iterator = const_pointer_iterator; + using associated_riterator = pointer_iterator; + using associated_const_riterator = const_pointer_iterator; + + vector(allocator& v) + : ary() + , alloc(v) + {} + + vector(const vector& oth) + { + sz = 0; + cap = 0; + ary = nullptr; + alloc = oth.alloc; + gp_config::assertion(reserve(oth.size()), "could not reserve space on building"); + sz = oth.size(); + cap = oth.size(); + auto it_l = begin(); + auto it_o = oth.cbegin(); + for(size_t i = 0; i < sz; ++i) + { + new(&*(it_l++)) T(*(it_o++)); + } + } + + vector(vector&& oth) + : ary(oth.ary) + , sz(oth.sz) + , cap(oth.cap) + , alloc(oth.alloc) + { + oth.ary = nullptr; + } + + /* TODO: Build the templated equivalents + array(T (& oth)[sz]) { + gp::move_uninitialized( + gp::nameless_range(oth, oth+sz), + gp::nameless_range(begin(), end()) + ); + } + + array(T (&& oth)[sz]) { + gp::move_uninitialized( + gp::nameless_range((T*)oth, (T*)oth+sz), + gp::nameless_range(begin(), end()) + ); + }*/ + + vector& operator=(vector& oth) + { + gp_config::assertion(reserve(oth.size()), "could not reserve space on assign"); + for(size_t i = 0; i < gp::min(sz, oth.sz); ++i) + { + ary[i]=oth[i]; + } + if(sz < oth.sz) { + for(size_t i = sz; i < oth.sz; ++i) { + new(ary+i) T(oth[i]); + } + } else if(sz > oth.sz) { + for(size_t i = oth.sz; i < sz; ++i) { + ary[i]->~T(); + } + } + sz = oth.sz; + return *this; + } + + vector& operator=(vector&& oth) + { + gp::swap(ary, oth.ary); + gp::swap(alloc, oth.alloc); + gp::swap(sz, oth.sz); + gp::swap(cap, oth.cap); + return *this; + } + + constexpr T& operator[] (size_t off) + { + if constexpr (gp_config::has_buffer_bounds) + { + gp_config::assertion( + off < sz, + "Array bounds infringed" + ); + } + return ary[off]; + } + + ~vector() + { + if(ary) + { + for(auto& elem : *this) { + elem->~T(); + } + gp_config::assertion(alloc.get().deallocate(ary), "could not deallocate"); + } + } + + bool grow() { + if(sz == cap) return reserve(sz + (sz >> 1)); + return true; + } + + bool reserve(size_t new_cap) { + if(new_cap <= cap) return true; + + size_t new_data_size = new_cap*sizeof(T); + + if(alloc.get().try_reallocate(ary, new_data_size)) return true; + + if(T* new_ary = alloc.get().allocate(new_data_size); new_ary) { + auto new_it = new_ary; + for(auto* elem : *this) { + ++new_it = gp::move(elem); + } + + gp_config::assertion(alloc.get().deallocate(ary), "failed to deallocate old range"); + + ary = new_ary; + cap = new_cap; + + return true; + } + + return false; + } + + constexpr const T& operator[] (size_t off) const + { + return ary[off]; + } + + constexpr size_t size() const + { + return sz; + } + + constexpr size_t capacity() const + { + return cap; + } + + constexpr bool push_back(T& value) { + if(grow()) { + new(ary+sz) T(value); + sz++; + return true; + } + return false; + } + + constexpr bool push_back(T&& value) { + if(grow()) { + new(ary+sz) T(gp::move(value)); + sz++; + return true; + } + return false; + } + + constexpr gp::optional pop_back() { + if(sz == 0) return gp::nullopt; + sz--; + gp::optional ret_val = gp::move(ary[sz]); + ary[sz]->~T(); + return gp::move(ret_val); + } + + constexpr pointer_iterator begin() + { + return associated_iterator(&ary[0]); + } + + constexpr pointer_iterator end() + { + return associated_iterator(&ary[sz]); + } + + constexpr const_pointer_iterator cbegin() const + { + return associated_const_iterator(&ary[0]); + } + + constexpr const_pointer_iterator cend() const + { + return associated_const_iterator(&ary[sz]); + } + + constexpr pointer_iterator rbegin() + { + return associated_riterator(&ary[sz-1]); + } + + constexpr pointer_iterator rend() + { + return associated_riterator(ary-1); + } + + constexpr const_pointer_iterator crbegin() const + { + return associated_const_riterator(&ary[sz-1]); + } + + constexpr const_pointer_iterator crend() const + { + return associated_const_riterator(ary-1); + } + + constexpr bool operator==(const vector& oth) const + { + for(size_t idx = 0; idx as_buffer() + { + return gp::buffer{(T*)ary, (T*)ary+sz}; + } + }; +} \ No newline at end of file