#pragma once #include "gp/containers/array.hpp" namespace gp { template class dynarray { struct build_order{}; struct v_element{ char data[sizeof(T)]; operator T&() { return *(T*)data; } v_element() : data{} {} template v_element(build_order, Args&&... argv) { new(data) T(gp::forward(argv)...); } template T& operator=(arg& argv) { return *(T*)data = argv; } template T& operator=(arg&& argv) { return *(T*)data = gp::forward(argv); } template void build(Args&&... argv) { new(data) T(gp::forward(argv)...); } T& value() { return *(T*)data; } T& value() const { return *(T*)data; } void clear(){ ((T*)data)->~T(); } }; using associated_iterator = pointer_iterator; using associated_const_iterator = const_pointer_iterator; using associated_riterator = pointer_iterator; using associated_const_riterator = const_pointer_iterator; v_element data[cap]; size_t sz = 0; public: dynarray() = default; dynarray(dynarray& oth) { for(auto& ref : oth) { push_back(ref); } } dynarray(dynarray&& oth) { for(auto& ref : oth) { emplace_back(gp::move(ref)); } oth.sz = 0; } dynarray& operator=(const dynarray& oth) { for(auto& self : data) { self.clear(); } sz = 0; for(auto& ref : oth) { push_back(ref); } return *this; } dynarray& operator=(dynarray&& oth) { for(auto& self : data) { self.clear(); } sz = 0; for(auto& ref : oth) { emplace_back(gp::forward(ref)); } oth.sz = 0; return *this; } constexpr associated_iterator begin() { return associated_iterator((T*)&data[0]); } constexpr associated_iterator end() { return associated_iterator((T*)&data[sz]); } constexpr const associated_iterator begin() const { return associated_iterator((T*)&data[0]); } constexpr const associated_iterator end() const { return associated_iterator((T*)&data[sz]); } constexpr associated_const_iterator cbegin() const { return associated_const_iterator((T*)&data[0]); } constexpr associated_const_iterator cend() const { return associated_const_iterator((T*)&data[sz]); } constexpr associated_riterator rbegin() { return associated_riterator((T*)&data[sz-1]); } constexpr associated_riterator rend() { return associated_riterator((T*)data-1); } constexpr associated_const_riterator crbegin() const { return associated_const_riterator((T*)&data[sz-1]); } constexpr associated_const_riterator crend() const { return associated_const_riterator((T*)data-1); } constexpr bool operator==(const dynarray& oth) const { if(size() != oth.size()) return false; for(size_t idx = 0; idx void emplace_back(Args&&... argv) { data[sz].build(gp::forward(argv)...); ++sz; } void remove_back() { --sz; data[sz].clear(); } gp::buffer as_buffer() { return gp::buffer{(T*)data, (T*)data+sz}; } ~dynarray() { auto it = data; auto end = data + size(); while(it != end) { (*it).clear(); ++it; } } }; }