|
|
- #pragma once
-
- #include <gp/buffer.hpp>
-
- #include <initializer_list>
-
- namespace gp{
- struct zero_t{};
-
- template<typename T, std::size_t sz>
- class array{
- public:
- T ary[sz];
- using associated_iterator = pointer_iterator<T, 1>;
- using associated_const_iterator = const_pointer_iterator<T, 1>;
- using associated_riterator = pointer_iterator<T, -1>;
- using associated_const_riterator = const_pointer_iterator<T, -1>;
-
- 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<typename fn>
- array(fn& func)
- {
- for(auto& elem : ary) {
- elem = fn();
- }
- }
-
- constexpr array(zero_t)
- {
- for(auto& elem : ary) {
- elem = 0;
- }
- }
-
- template<typename ...U>
- 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<T>(
- gp::nameless_range<int*>(oth, oth+sz),
- gp::nameless_range<associated_iterator>(begin(), end())
- );
- }
-
- constexpr array(T (&& oth)[sz]) {
- gp::move_uninitialized(
- gp::nameless_range<int*>((T*)oth, (T*)oth+sz),
- gp::nameless_range<associated_iterator>(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<T, 1> begin()
- {
- return associated_iterator(&ary[0]);
- }
-
- constexpr pointer_iterator<T, 1> end()
- {
- return associated_iterator(&ary[sz]);
- }
-
- constexpr const_pointer_iterator<T, 1> cbegin() const
- {
- return associated_const_iterator(&ary[0]);
- }
-
- constexpr const_pointer_iterator<T, 1> cend() const
- {
- return associated_const_iterator(&ary[sz]);
- }
-
- constexpr pointer_iterator<T, -1> rbegin()
- {
- return associated_riterator(&ary[sz-1]);
- }
-
- constexpr pointer_iterator<T, -1> rend()
- {
- return associated_riterator(ary-1);
- }
-
- constexpr const_pointer_iterator<T, -1> crbegin() const
- {
- return associated_const_riterator(&ary[sz-1]);
- }
-
- constexpr const_pointer_iterator<T, -1> crend() const
- {
- return associated_const_riterator(ary-1);
- }
-
- constexpr bool operator==(const array& oth) const
- {
- for(size_t idx = 0; idx<sz; idx++)
- {
- if(ary[idx] != oth.ary[idx])
- {
- return false;
- }
- }
- return true;
- }
-
- constexpr bool operator!=(const array& oth) const
- {
- return !(*this == oth);
- }
-
- gp::buffer<T> as_buffer() const
- {
- return gp::buffer<T>{(T*)ary, (T*)ary+sz};
- }
- };
- }
|