diff options
Diffstat (limited to 'src/generic/array.hpp')
-rw-r--r-- | src/generic/array.hpp | 94 |
1 files changed, 85 insertions, 9 deletions
diff --git a/src/generic/array.hpp b/src/generic/array.hpp index e6fefae..5e4dd67 100644 --- a/src/generic/array.hpp +++ b/src/generic/array.hpp @@ -24,18 +24,94 @@ # include <cassert> # include <cstddef> -template<class T, size_t n> -struct Array +# include "oops.hpp" + +template<class I, I be, I en> +struct ExclusiveIndexing +{ + using index_type = I; + constexpr static size_t index_to_offset(index_type idx) + { return static_cast<size_t>(idx) - static_cast<size_t>(be); } + constexpr static index_type offset_to_index(size_t off) + { return static_cast<I>(off + static_cast<size_t>(be)); } + constexpr static size_t alloc_size = index_to_offset(en) - index_to_offset(be); +}; + +template<size_t n> +using SimpleIndexing = ExclusiveIndexing<size_t, 0, n>; + +template<class I, I lo, I hi> +struct InclusiveIndexing +{ + using index_type = I; + constexpr static size_t index_to_offset(index_type idx) + { return static_cast<size_t>(idx) - static_cast<size_t>(lo); } + constexpr static index_type offset_to_index(size_t off) + { return static_cast<I>(off + static_cast<size_t>(lo)); } + constexpr static size_t alloc_size = index_to_offset(hi) - index_to_offset(lo) + 1; +}; + +template<class E, E n=E::COUNT> +struct EnumIndexing : ExclusiveIndexing<E, static_cast<E>(0), n> { - T data[n]; +}; + +template<class I, size_t limit> +struct InventoryIndexing +{ + using index_type = I; + constexpr static size_t index_to_offset(index_type idx) + { return idx.get0(); } + constexpr static index_type offset_to_index(size_t off) + { return I::from(off); } + constexpr static size_t alloc_size = limit; +}; + +template<class T, class I> +struct GenericArray +{ + T data[I::alloc_size]; public: - T& operator [](size_t i) { assert (i < n); return data[i]; } - const T& operator [](size_t i) const { assert (i < n); return data[i]; } + T *begin() + { return data + 0; } + T *end() + { return data + I::alloc_size; } + const T *begin() const + { return data + 0; } + const T *end() const + { return data + I::alloc_size; } + size_t size() const + { return I::alloc_size; } + + T& operator [](typename I::index_type i_) + { + size_t i = I::index_to_offset(i_); + ALLEGE ("index in bounds", i < size()); + return data[i]; + } + const T& operator [](typename I::index_type i_) const + { + size_t i = I::index_to_offset(i_); + ALLEGE ("index in bounds", i < size()); + return data[i]; + } - T *begin() { return data + 0; } - T *end() { return data + n; } - const T *begin() const { return data + 0; } - const T *end() const { return data + n; } + friend bool operator == (GenericArray& lhs, GenericArray& rhs) + { + for (size_t i = 0; i < I::alloc_size; ++i) + { + if (lhs.data[i] != rhs.data[i]) + return false; + } + return true; + } + friend bool operator != (GenericArray& lhs, GenericArray& rhs) + { + return !(lhs == rhs); + } }; +template<class T, size_t n> +using Array = GenericArray<T, SimpleIndexing<n>>; + #endif // TMWA_GENERIC_ARRAY_HPP |