#pragma once #include #include #include #include "RetroTypes.hpp" namespace aurora { template class ArrayRef { public: using value_type = std::remove_cvref_t; using pointer = value_type*; using const_pointer = const value_type*; using reference = value_type&; using const_reference = const value_type&; using iterator = const_pointer; using const_iterator = const_pointer; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; using size_type = std::size_t; using difference_type = std::ptrdiff_t; ArrayRef() = default; explicit ArrayRef(const T& one) : ptr(&one), length(1) {} ArrayRef(const T* data, size_t length) : ptr(data), length(length) {} ArrayRef(const T* begin, const T* end) : ptr(begin), length(end - begin) {} template constexpr ArrayRef(const T (&arr)[N]) : ptr(arr), length(N) {} template constexpr ArrayRef(const std::array& arr) : ptr(arr.data()), length(arr.size()) {} ArrayRef(const std::vector& vec) : ptr(vec.data()), length(vec.size()) {} template ArrayRef(const rstl::reserved_vector& vec) : ptr(vec.data()), length(vec.size()) {} const T* data() const { return ptr; } size_t size() const { return length; } bool empty() const { return length == 0; } const T& front() const { assert(!empty()); return ptr[0]; } const T& back() const { assert(!empty()); return ptr[length - 1]; } const T& operator[](size_t i) const { assert(i < length && "Invalid index!"); return ptr[i]; } iterator begin() const { return ptr; } iterator end() const { return ptr + length; } reverse_iterator rbegin() const { return reverse_iterator(end()); } reverse_iterator rend() const { return reverse_iterator(begin()); } /// Disallow accidental assignment from a temporary. template std::enable_if_t::value, ArrayRef>& operator=(U&& Temporary) = delete; /// Disallow accidental assignment from a temporary. template std::enable_if_t::value, ArrayRef>& operator=(std::initializer_list) = delete; private: const T* ptr = nullptr; size_t length = 0; }; } // namespace aurora