1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
#pragma once
#include <nall/array-span.hpp>
#include <nall/array-view.hpp>
#include <nall/range.hpp>
#include <nall/view.hpp>
namespace nall {
template<typename T> struct array;
//usage: s32 x[256] => array<s32[256]> x
template<typename T, u32 Size> struct array<T[Size]> {
array() = default;
array(const initializer_list<T>& source) {
u32 index = 0;
for(auto& value : source) {
operator[](index++) = value;
}
}
operator array_span<T>() {
return {data(), size()};
}
operator array_view<T>() const {
return {data(), size()};
}
alwaysinline auto operator[](u32 index) -> T& {
#ifdef DEBUG
struct out_of_bounds {};
if(index >= Size) throw out_of_bounds{};
#endif
return values[index];
}
alwaysinline auto operator[](u32 index) const -> const T& {
#ifdef DEBUG
struct out_of_bounds {};
if(index >= Size) throw out_of_bounds{};
#endif
return values[index];
}
alwaysinline auto operator()(u32 index, const T& fallback = {}) const -> const T& {
if(index >= Size) return fallback;
return values[index];
}
auto fill(const T& fill = {}) -> array& {
for(auto& value : values) value = fill;
return *this;
}
auto data() -> T* { return values; }
auto data() const -> const T* { return values; }
auto size() const -> u32 { return Size; }
auto begin() -> T* { return &values[0]; }
auto end() -> T* { return &values[Size]; }
auto begin() const -> const T* { return &values[0]; }
auto end() const -> const T* { return &values[Size]; }
private:
T values[Size];
};
template<typename T, T... p> inline auto from_array(u32 index) -> T {
static const array<T[sizeof...(p)]> table{p...};
struct out_of_bounds {};
#if defined(DEBUG)
if(index >= sizeof...(p)) throw out_of_bounds{};
#endif
return table[index];
}
template<s64... p> inline auto from_array(u32 index) -> s64 {
static const array<s64[sizeof...(p)]> table{p...};
struct out_of_bounds {};
#if defined(DEBUG)
if(index >= sizeof...(p)) throw out_of_bounds{};
#endif
return table[index];
}
}
|