#pragma once #include #include namespace gp{ struct zero_t{}; template class array{ public: T ary[sz]; using associated_iterator = pointer_iterator; using associated_const_iterator = const_pointer_iterator; using associated_riterator = pointer_iterator; using associated_const_riterator = const_pointer_iterator; array() : ary() {} array(const array& oth) { auto it_l = begin(); auto it_o = oth.cbegin(); for(size_t i = 0; i < sz; ++i) { new(&*(it_l++)) T(*(it_o++)); } } template array(fn& func) { for(auto& elem : ary) { elem = fn(); } } constexpr array(zero_t) { for(auto& elem : ary) { elem = 0; } } template constexpr array(U&& ...values) : ary{gp::move((T&&)values)...} {} array(array&& values) { gp::move_uninitialized( values, *this ); } constexpr array(T (& oth)[sz]) { gp::move_uninitialized( gp::nameless_range(oth, oth+sz), gp::nameless_range(begin(), end()) ); } constexpr array(T (&& oth)[sz]) { gp::move_uninitialized( gp::nameless_range((T*)oth, (T*)oth+sz), gp::nameless_range(begin(), end()) ); } array& operator=(array& oth) { for(size_t i = 0; i < sz; ++i) { ary[i]=oth[i]; } return *this; } array& operator=(array&& oth) { for(size_t i = 0; i < sz; ++i) { ary[i]=gp::move(oth[i]); } 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]; } constexpr const T& operator[] (size_t off) const { return ary[off]; } constexpr size_t size() const { return sz; } 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 array& oth) const { for(size_t idx = 0; idx as_buffer() const { return gp::buffer{(T*)ary, (T*)ary+sz}; } }; }