diff options
| author | Hannes Schulze <haschu0103@outlook.de> | 2025-02-04 23:11:08 +0100 |
|---|---|---|
| committer | Hannes Schulze <haschu0103@outlook.de> | 2025-02-04 23:11:08 +0100 |
| commit | 79553ab1fa3d707612e80dd03bf95ca65fa0c411 (patch) | |
| tree | f44bec41548d569cfca43c44e0e4ffa7b72ed4ed /lib/nes/common/span.hh | |
| parent | 9c45e9c7df1efa5bc1c8e73b6eaef4726b828d3e (diff) | |
refactor file browser
Diffstat (limited to 'lib/nes/common/span.hh')
| -rw-r--r-- | lib/nes/common/span.hh | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/lib/nes/common/span.hh b/lib/nes/common/span.hh index 16eb129..6779c37 100644 --- a/lib/nes/common/span.hh +++ b/lib/nes/common/span.hh @@ -1,6 +1,7 @@ #pragma once #include "nes/common/types.hh" +#include "nes/common/debug.hh" namespace nes { @@ -21,6 +22,9 @@ namespace nes { using type = T; }; + + template<typename T> + using remove_const_type = typename remove_const<T>::type; } // namespace detail /// Implementation of a container similar to std::span in C++20. @@ -54,7 +58,7 @@ namespace nes static_assert(Length == ActualLength || Length == detail::span_dynamic_length); } - span(span<typename detail::remove_const<T>::type, Length> const other) + span(span<detail::remove_const_type<T>, Length> const other) : span{ other.data_, other.length_, {} } { } @@ -65,12 +69,31 @@ namespace nes auto begin() const -> iterator { return data_; } auto end() const -> iterator { return data_ + length_; } - auto subspan(u32 const first, u32 const length) const -> span<T> { return span{ data_ + first, length }; } - auto subspan(u32 const first) const -> span<T> { return subspan(length_ - first); } + auto subspan(u32 const first, u32 const length) const -> span<T> + { + NES_ASSERT(first + length <= get_length() && "subspan out of bounds"); + return span{ data_ + first, length }; + } + + auto subspan(u32 const first) const -> span<T> + { + NES_ASSERT(first <= get_length() && "subspan out of bounds"); + return subspan(length_ - first); + } + template<u32 OtherLength> - auto subspan(u32 const first) const -> span<T, OtherLength> { return span<T, OtherLength>{ data_ + first, OtherLength, {} }; } + auto subspan(u32 const first) const -> span<T, OtherLength> + { + static_assert(OtherLength < Length); + NES_ASSERT(first + OtherLength <= get_length() && "subspan out of bounds"); + return span<T, OtherLength>{ data_ + first, OtherLength, {} }; + } - auto operator[](u32 const index) const -> T& { return data_[index]; } + auto operator[](u32 const index) const -> T& + { + NES_ASSERT(index < get_length() && "index out of bounds"); + return data_[index]; + } private: explicit span(T* data, u32 const length, detail::span_unchecked) |
