summaryrefslogtreecommitdiff
path: root/asl/span.hpp
diff options
context:
space:
mode:
authorSteven Le Rouzic <steven.lerouzic@gmail.com>2024-11-04 22:09:50 +0100
committerSteven Le Rouzic <steven.lerouzic@gmail.com>2024-12-20 15:35:58 +0100
commit8b1110c61c9090e9535d106c9cdcee6e46db1dc8 (patch)
tree498e8c0a618d8244d070d28e11078e324caaa2d1 /asl/span.hpp
parentcb5967d8f46fbba7c7e30f436032fef0ed671fe9 (diff)
Add span::subspan
Diffstat (limited to 'asl/span.hpp')
-rw-r--r--asl/span.hpp55
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