diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-11-04 22:09:50 +0100 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-12-20 15:35:58 +0100 |
commit | 8b1110c61c9090e9535d106c9cdcee6e46db1dc8 (patch) | |
tree | 498e8c0a618d8244d070d28e11078e324caaa2d1 /asl/span.hpp | |
parent | cb5967d8f46fbba7c7e30f436032fef0ed671fe9 (diff) |
Add span::subspan
Diffstat (limited to 'asl/span.hpp')
-rw-r--r-- | asl/span.hpp | 55 |
1 files changed, 49 insertions, 6 deletions
diff --git a/asl/span.hpp b/asl/span.hpp index efc9eec..5ffcf68 100644 --- a/asl/span.hpp +++ b/asl/span.hpp @@ -13,7 +13,12 @@ static constexpr int64_t dynamic_size = -1; template<is_object T, int64_t kSize = dynamic_size> class span { - static constexpr bool kIsDynamic = kSize < 0; + static constexpr bool is_dynamic(int64_t size) + { + return size < 0; + } + + static constexpr bool kIsDynamic = is_dynamic(kSize); using SizeType = select_t<kIsDynamic, int64_t, empty>; @@ -21,7 +26,7 @@ class span ASL_NO_UNIQUE_ADDRESS SizeType m_size{}; public: - constexpr span() = default; + constexpr span() requires (kIsDynamic || kSize == 0) = default; constexpr span(T* data, int64_t size) requires kIsDynamic @@ -55,7 +60,7 @@ public: requires ( ( kIsDynamic || - span<U, kOtherSize>::kIsDynamic || + is_dynamic(kOtherSize) || kOtherSize == kSize ) && convertible_from<T(&)[], U(&)[]> ) @@ -92,11 +97,49 @@ public: return m_data[i]; // NOLINT(*-pointer-arithmetic) } - // @Todo subspan, first, last + // @Todo first, last // @Todo as_(mutable_)bytes - template<is_object U, int64_t kOtherSize> - friend class span; + template<int64_t kOffset, int64_t kSubSize = dynamic_size> + constexpr auto subspan() const + requires ( + kOffset >= 0 && + (kIsDynamic || kOffset <= kSize) && + (kIsDynamic || is_dynamic(kSubSize) || kSubSize <= kSize - kOffset) + ) + { + ASL_ASSERT(kOffset <= size()); + + if constexpr (is_dynamic(kSubSize)) + { + if constexpr (kIsDynamic) + { + return span<T>(data() + kOffset, size() - kOffset); + } + else + { + return span<T, kSize - kOffset>(data() + kOffset, size() - kOffset); + } + } + else + { + ASL_ASSERT(kSubSize <= size() - kOffset); + return span<T, kSubSize>(data() + kOffset, kSubSize); + } + } + + constexpr span<T> subspan(int64_t offset, int64_t sub_size = dynamic_size) const + { + ASL_ASSERT(offset <= size()); + + if (is_dynamic(sub_size)) + { + return span<T>{ data() + offset, size() - offset }; + } + + ASL_ASSERT(sub_size <= size() - offset); + return span<T>{ data() + offset, sub_size }; + } }; } // namespace asl |