[libc-commits] [libc] f890f80 - [libc] Allow span views over mutable data
Guillaume Chatelet via libc-commits
libc-commits at lists.llvm.org
Mon Aug 22 02:43:22 PDT 2022
Author: Guillaume Chatelet
Date: 2022-08-22T09:43:08Z
New Revision: f890f80d67664b2d7ddb2acae5b29ac5e8a88950
URL: https://github.com/llvm/llvm-project/commit/f890f80d67664b2d7ddb2acae5b29ac5e8a88950
DIFF: https://github.com/llvm/llvm-project/commit/f890f80d67664b2d7ddb2acae5b29ac5e8a88950.diff
LOG: [libc] Allow span views over mutable data
Added:
Modified:
libc/src/__support/CPP/span.h
libc/test/src/__support/CPP/span_test.cpp
Removed:
################################################################################
diff --git a/libc/src/__support/CPP/span.h b/libc/src/__support/CPP/span.h
index 5aab1bb76a60..dc3960e75f61 100644
--- a/libc/src/__support/CPP/span.h
+++ b/libc/src/__support/CPP/span.h
@@ -24,6 +24,15 @@ namespace __llvm_libc::cpp {
// inherits from B),
// - No reverse iterators
template <typename T> class span {
+ template <typename U>
+ inline static constexpr bool is_const_view_v =
+ !cpp::is_const_v<U> && cpp::is_const_v<T> &&
+ cpp::is_same_v<U, remove_cv_t<T>>;
+
+ template <typename U>
+ inline static constexpr bool is_compatible_v =
+ cpp::is_same_v<U, T> || is_const_view_v<U>;
+
public:
using element_type = T;
using value_type = remove_cv_t<T>;
@@ -45,21 +54,25 @@ template <typename T> class span {
constexpr span(pointer first, pointer end)
: span_data(first), span_size(end - first) {}
- template <size_t N>
- constexpr span(element_type (&arr)[N]) : span_data(arr), span_size(N) {}
+ template <typename U, size_t N,
+ cpp::enable_if_t<is_compatible_v<U>, bool> = true>
+ constexpr span(U (&arr)[N]) : span_data(arr), span_size(N) {}
- template <size_t N>
- constexpr span(array<T, N> &arr)
+ template <typename U, size_t N,
+ cpp::enable_if_t<is_compatible_v<U>, bool> = true>
+ constexpr span(array<U, N> &arr)
: span_data(arr.data()), span_size(arr.size()) {}
- template <typename U,
- cpp::enable_if_t<!cpp::is_const_v<U> && cpp::is_const_v<T> &&
- cpp::is_same_v<U, value_type>,
- bool> = true>
- constexpr span(span<U> &s) : span(s.data(), s.size()) {}
+ template <typename U, cpp::enable_if_t<is_compatible_v<U>, bool> = true>
+ constexpr span(span<U> &s) : span_data(s.data()), span_size(s.size()) {}
+
+ template <typename U, cpp::enable_if_t<is_compatible_v<U>, bool> = true>
+ constexpr span &operator=(span<U> &s) {
+ span_data = s.data();
+ span_size = s.size();
+ return *this;
+ }
- constexpr span(const span &s) = default;
- constexpr span &operator=(const span &s) = default;
~span() = default;
constexpr reference operator[](size_type index) const {
return data()[index];
diff --git a/libc/test/src/__support/CPP/span_test.cpp b/libc/test/src/__support/CPP/span_test.cpp
index 831188d427de..c0da1cf1ce78 100644
--- a/libc/test/src/__support/CPP/span_test.cpp
+++ b/libc/test/src/__support/CPP/span_test.cpp
@@ -56,14 +56,47 @@ TEST(LlvmLibcSpanTest, InitializeArray) {
ASSERT_EQ(s[2], 3);
}
-TEST(LlvmLibcSpanTest, ConstFromMutable) {
+TEST(LlvmLibcSpanTest, InitializeViewFormMutableSingleton) {
+ int a = 42;
+ span<const int> s(&a, 1);
+ ASSERT_EQ(s.size(), size_t(1));
+ ASSERT_TRUE(s.data() == &a);
+}
+
+TEST(LlvmLibcSpanTest, InitializeViewFormMutableCArray) {
+ int a[] = {1, 2, 3};
+ span<const int> s(a);
+ ASSERT_EQ(s.size(), size_t(3));
+ ASSERT_EQ(s[0], 1);
+ ASSERT_EQ(s[1], 2);
+ ASSERT_EQ(s[2], 3);
+}
+
+TEST(LlvmLibcSpanTest, InitializeViewFormMutableArray) {
array<int, 3> a = {1, 2, 3};
- span<int> mutable_view(a);
- span<const int> const_view(mutable_view);
- ASSERT_EQ(const_view.size(), size_t(3));
- ASSERT_EQ(const_view[0], 1);
- ASSERT_EQ(const_view[1], 2);
- ASSERT_EQ(const_view[2], 3);
+ span<const int> s(a);
+ ASSERT_EQ(s.size(), size_t(3));
+ ASSERT_EQ(s[0], 1);
+ ASSERT_EQ(s[1], 2);
+ ASSERT_EQ(s[2], 3);
+}
+
+TEST(LlvmLibcSpanTest, InitializeFromMutable) {
+ span<int> s;
+ span<const int> view(s);
+ (void)view;
+}
+
+TEST(LlvmLibcSpanTest, Assign) {
+ span<int> s;
+ span<int> other;
+ other = s;
+}
+
+TEST(LlvmLibcSpanTest, AssignFromMutable) {
+ span<int> s;
+ span<const int> view;
+ view = s;
}
TEST(LlvmLibcSpanTest, Modify) {
More information about the libc-commits
mailing list