summaryrefslogtreecommitdiff
path: root/asl
diff options
context:
space:
mode:
authorSteven Le Rouzic <steven.lerouzic@gmail.com>2024-11-04 18:11:37 +0100
committerSteven Le Rouzic <steven.lerouzic@gmail.com>2024-12-20 15:35:58 +0100
commitcb5967d8f46fbba7c7e30f436032fef0ed671fe9 (patch)
tree2039919b237f5ccc7b24f9eb81cd0f15b90b47ea /asl
parent5682cb422c39eea6b4d5d54c2f31260785dc256f (diff)
More work on span
Diffstat (limited to 'asl')
-rw-r--r--asl/span.hpp58
-rw-r--r--asl/tests/meta_tests.cpp8
-rw-r--r--asl/tests/span_tests.cpp63
3 files changed, 129 insertions, 0 deletions
diff --git a/asl/span.hpp b/asl/span.hpp
index f3d4036..efc9eec 100644
--- a/asl/span.hpp
+++ b/asl/span.hpp
@@ -3,6 +3,7 @@
#include "asl/meta.hpp"
#include "asl/annotations.hpp"
#include "asl/layout.hpp"
+#include "asl/assert.hpp"
namespace asl
{
@@ -22,6 +23,46 @@ class span
public:
constexpr span() = default;
+ constexpr span(T* data, int64_t size)
+ requires kIsDynamic
+ : m_data{data}
+ , m_size{size}
+ {}
+
+ constexpr explicit span(T* data, int64_t size)
+ requires (!kIsDynamic)
+ : m_data{data}
+ {
+ ASL_ASSERT(size == kSize);
+ }
+
+ template<int64_t N>
+ constexpr span(T (&array)[N]) // NOLINT(*-explicit-conversions)
+ requires (kIsDynamic)
+ : m_data{array}
+ , m_size{N}
+ {}
+
+ template<int64_t N>
+ constexpr span(T (&array)[N]) // NOLINT(*-explicit-conversions)
+ requires (!kIsDynamic) && (N == kSize)
+ : m_data{array}
+ {}
+
+ template<is_object U, int64_t kOtherSize>
+ constexpr explicit(!kIsDynamic)
+ span(const span<U, kOtherSize>& other) // NOLINT(*-explicit-conversions)
+ requires (
+ (
+ kIsDynamic ||
+ span<U, kOtherSize>::kIsDynamic ||
+ kOtherSize == kSize
+ ) && convertible_from<T(&)[], U(&)[]>
+ )
+ : span{static_cast<U*>(other.data()), other.size()}
+ {
+ }
+
constexpr span(const span&) = default;
constexpr span(span&&) = default;
@@ -39,6 +80,23 @@ public:
constexpr int64_t size_bytes() const { return size() * size_of<T>; }
constexpr bool is_empty() const { return size() == 0; }
+
+ constexpr T* data() const { return m_data; }
+
+ constexpr T* begin() const { return m_data; }
+ constexpr T* end() const { return m_data + size(); }
+
+ constexpr T& operator[](int64_t i) const
+ {
+ ASL_ASSERT(i >= 0 && i < size());
+ return m_data[i]; // NOLINT(*-pointer-arithmetic)
+ }
+
+ // @Todo subspan, first, last
+ // @Todo as_(mutable_)bytes
+
+ template<is_object U, int64_t kOtherSize>
+ friend class span;
};
} // namespace asl
diff --git a/asl/tests/meta_tests.cpp b/asl/tests/meta_tests.cpp
index 94edc50..5fc4ef4 100644
--- a/asl/tests/meta_tests.cpp
+++ b/asl/tests/meta_tests.cpp
@@ -181,6 +181,14 @@ static_assert(asl::convertible_from<C, D>);
static_assert(!asl::convertible_from<C*, Derived*>);
static_assert(asl::convertible_from<E, Base>);
+static_assert(!asl::convertible_from<int16_t(&)[], int32_t(&)[]>);
+static_assert(asl::convertible_from<const int16_t(&)[], int16_t(&)[]>);
+static_assert(asl::convertible_from<const int16_t(&)[], const int16_t(&)[]>);
+static_assert(asl::convertible_from<int16_t(&)[], int16_t(&)[]>);
+static_assert(!asl::convertible_from<int32_t(&)[], int16_t(&)[]>);
+static_assert(!asl::convertible_from<int16_t(&)[], const int16_t(&)[]>);
+static_assert(!asl::convertible_from<C(&)[], D(&)[]>);
+
static_assert(asl::derived_from<Derived, Base>);
static_assert(!asl::derived_from<Base, Derived>);
static_assert(!asl::derived_from<D, C>);
diff --git a/asl/tests/span_tests.cpp b/asl/tests/span_tests.cpp
index 276d50a..11510c6 100644
--- a/asl/tests/span_tests.cpp
+++ b/asl/tests/span_tests.cpp
@@ -19,6 +19,7 @@ ASL_TEST(empty_dynamic)
ASL_TEST_EXPECT(s.is_empty());
}
+
ASL_TEST(empty_static)
{
asl::span<int, 0> s;
@@ -26,3 +27,65 @@ ASL_TEST(empty_static)
ASL_TEST_EXPECT(s.size_bytes() == 0);
ASL_TEST_EXPECT(s.is_empty());
}
+
+ASL_TEST(from_array_dynamic)
+{
+ int array[] = {1, 2, 3};
+ asl::span<int> span = array;
+ ASL_TEST_ASSERT(span.size() == 3);
+ ASL_TEST_EXPECT(span[0] == 1);
+ ASL_TEST_EXPECT(span[1] == 2);
+ ASL_TEST_EXPECT(span[2] == 3);
+}
+
+static_assert(asl::constructible_from<asl::span<int32_t>, int32_t(&)[8]>);
+static_assert(!asl::constructible_from<asl::span<int32_t>, const int32_t(&)[8]>);
+static_assert(asl::constructible_from<asl::span<const int32_t>, int32_t(&)[8]>);
+static_assert(asl::constructible_from<asl::span<const int32_t>, const int32_t(&)[8]>);
+static_assert(asl::constructible_from<asl::span<int32_t, 8>, int32_t(&)[8]>);
+static_assert(!asl::constructible_from<asl::span<int32_t, 8>, int32_t(&)[10]>);
+
+ASL_TEST(from_array_static)
+{
+ int array[] = {1, 2, 3};
+ asl::span<int, 3> span = array;
+ ASL_TEST_ASSERT(span.size() == 3);
+ ASL_TEST_EXPECT(span[0] == 1);
+ ASL_TEST_EXPECT(span[1] == 2);
+ ASL_TEST_EXPECT(span[2] == 3);
+}
+
+static_assert(asl::constructible_from<asl::span<const int32_t>, asl::span<int32_t>>);
+static_assert(!asl::constructible_from<asl::span<int32_t>, asl::span<const int32_t>>);
+static_assert(!asl::constructible_from<asl::span<int32_t>, asl::span<int16_t>>);
+static_assert(!asl::constructible_from<asl::span<int32_t>, asl::span<uint32_t>>);
+static_assert(asl::constructible_from<asl::span<int32_t>, asl::span<int32_t, 6>>);
+static_assert(asl::constructible_from<asl::span<int32_t, 6>, asl::span<int32_t>>);
+static_assert(asl::constructible_from<asl::span<int32_t>, asl::span<int32_t, 6>>);
+static_assert(asl::constructible_from<asl::span<int32_t, 6>, asl::span<int32_t, 6>>);
+static_assert(!asl::constructible_from<asl::span<int32_t, 6>, asl::span<int32_t, 7>>);
+
+ASL_TEST(conversion)
+{
+ int array[] = {1, 2, 3};
+
+ asl::span<int> span1 = array;
+
+ asl::span<int, 3> span2{span1};
+ ASL_TEST_ASSERT(span2.size() == 3);
+ ASL_TEST_EXPECT(span2[0] == 1);
+ ASL_TEST_EXPECT(span2[1] == 2);
+ ASL_TEST_EXPECT(span2[2] == 3);
+
+ asl::span<int> span3 = span2;
+ ASL_TEST_ASSERT(span3.size() == 3);
+ ASL_TEST_EXPECT(span3[0] == 1);
+ ASL_TEST_EXPECT(span3[1] == 2);
+ ASL_TEST_EXPECT(span3[2] == 3);
+
+ asl::span<const int, 3> span4{span2};
+ ASL_TEST_ASSERT(span4.size() == 3);
+ ASL_TEST_EXPECT(span4[0] == 1);
+ ASL_TEST_EXPECT(span4[1] == 2);
+ ASL_TEST_EXPECT(span4[2] == 3);
+}