General Purpose library for Freestanding C++ and POSIX systems
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

177 rivejä
3.1 KiB

#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};
}
};
}