#pragma once #include #include namespace hv { /// A typed span of continuous memory with a bound. template struct span { inline span(T* ptr, std::size_t len) : ptr(ptr),len(len){} inline operator T*() {return ptr;} inline operator const T* const() {return ptr;} inline T& operator*() {return *ptr;} inline const T& operator*() const {return *ptr;} inline T& operator[](std::size_t index) { #ifdef DEBUG if (index>=len) throw "tried to index out of bounds of array"; #endif return ptr[index]; } inline const T& operator[](std::size_t index) const { #ifdef DEBUG if (index>=len) throw "tried to index out of bounds of array"; #endif return ptr[index]; } inline span slice(std::size_t off, std::size_t len) { len = std::min(this->len, len); if(len+off>=len || len < off) throw "tried to index out of bounds of array"; return span(ptr+off, len-off); } inline span slice(std::size_t off) { if(len+off>=len || len < off) throw "tried to index out of bounds of array"; return span(ptr+off, len-off); } template inline span reinterpret() { return span((U*)ptr, size_bytes() / sizeof(U)); } inline T* operator ->() { return ptr; } inline const T* operator ->() const { return ptr; } inline T* raw() { return ptr; } inline const T* raw() const { return ptr; } inline std::size_t size() const { return len; } inline std::size_t size_bytes() const { return len * sizeof(T); } private: T* const ptr; std::size_t len; }; }