[libc-commits] [libc] [libc][CPP] Align span copy and conversion with std::span (PR #220619)
via libc-commits
libc-commits at lists.llvm.org
Wed Sep 2 10:47:33 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: Jeff Bailey (kaladron)
<details>
<summary>Changes</summary>
Bring cpp::span copy and converting operations in line with C++20 std::span ([span.overview], [span.cons]):
* Add defaulted copy assignment operator: C++20 std::span declares constexpr span& operator=(const span&) noexcept = default; Providing an explicit defaulted copy assignment operator matches std::span and avoids -Wdeprecated-copy-with-dtor warnings in consuming code when copy-assigning spans.
* Take const span<U>& in converting constructor and operator=: C++20 [span.cons] specifies converting construction from const span&. Previously taking span<U>& prevented converting from const spans and binding to rvalue temporaries (such as s = s.subspan(1)).
* Update span.h and span_test.cpp headers to standard LLVM style.
* Add unit tests for copy assignment, rvalue temporaries, and converting assignment.
Assisted-by: Automated tooling, human reviewed.
---
Full diff: https://github.com/llvm/llvm-project/pull/220619.diff
2 Files Affected:
- (modified) libc/src/__support/CPP/span.h (+9-3)
- (modified) libc/test/src/__support/CPP/span_test.cpp (+80-3)
``````````diff
diff --git a/libc/src/__support/CPP/span.h b/libc/src/__support/CPP/span.h
index 9234a26d201cd..859ba24d1442e 100644
--- a/libc/src/__support/CPP/span.h
+++ b/libc/src/__support/CPP/span.h
@@ -1,10 +1,15 @@
-//===-- Standalone implementation std::span ---------------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation of cpp::span.
+///
+//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_SPAN_H
#define LLVM_LIBC_SRC___SUPPORT_CPP_SPAN_H
@@ -55,6 +60,7 @@ template <typename T> class span {
LIBC_INLINE constexpr span() : span_data(nullptr), span_size(0) {}
LIBC_INLINE constexpr span(const span &) = default;
+ LIBC_INLINE constexpr span &operator=(const span &) = default;
LIBC_INLINE constexpr span(pointer first, size_type count)
: span_data(first), span_size(count) {}
@@ -72,11 +78,11 @@ template <typename T> class span {
: span_data(arr.data()), span_size(arr.size()) {}
template <typename U, cpp::enable_if_t<is_compatible_v<U>, bool> = true>
- LIBC_INLINE constexpr span(span<U> &s)
+ LIBC_INLINE constexpr span(const span<U> &s)
: span_data(s.data()), span_size(s.size()) {}
template <typename U, cpp::enable_if_t<is_compatible_v<U>, bool> = true>
- LIBC_INLINE constexpr span &operator=(span<U> &s) {
+ LIBC_INLINE constexpr span &operator=(const span<U> &s) {
span_data = s.data();
span_size = s.size();
return *this;
diff --git a/libc/test/src/__support/CPP/span_test.cpp b/libc/test/src/__support/CPP/span_test.cpp
index 6da06c31e7adf..9d83e722c69c6 100644
--- a/libc/test/src/__support/CPP/span_test.cpp
+++ b/libc/test/src/__support/CPP/span_test.cpp
@@ -1,10 +1,15 @@
-//===-- Unittests for span ------------------------------------------------===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Unit tests for cpp::span.
+///
+//===----------------------------------------------------------------------===//
#include "src/__support/CPP/array.h"
#include "src/__support/CPP/span.h"
@@ -82,9 +87,25 @@ TEST(LlvmLibcSpanTest, InitializeViewFormMutableArray) {
}
TEST(LlvmLibcSpanTest, InitializeFromMutable) {
- span<int> s;
+ int a[] = {1, 2, 3};
+ span<int> s(a);
span<const int> view(s);
- (void)view;
+ ASSERT_EQ(view.size(), size_t(3));
+ ASSERT_TRUE(view.data() == &a[0]);
+ ASSERT_EQ(view[0], 1);
+ ASSERT_EQ(view[1], 2);
+ ASSERT_EQ(view[2], 3);
+
+ const span<int> const_s(a);
+ span<const int> view_from_const(const_s);
+ ASSERT_EQ(view_from_const.size(), size_t(3));
+ ASSERT_TRUE(view_from_const.data() == &a[0]);
+
+ span<const int> view_from_rvalue(s.subspan(1));
+ ASSERT_EQ(view_from_rvalue.size(), size_t(2));
+ ASSERT_TRUE(view_from_rvalue.data() == &a[1]);
+ ASSERT_EQ(view_from_rvalue[0], 2);
+ ASSERT_EQ(view_from_rvalue[1], 3);
}
TEST(LlvmLibcSpanTest, Assign) {
@@ -93,12 +114,68 @@ TEST(LlvmLibcSpanTest, Assign) {
other = s;
}
+TEST(LlvmLibcSpanTest, CopyAssignment) {
+ int a[] = {1, 2, 3};
+ span<int> s1(a);
+ span<int> s2;
+ s2 = s1;
+ ASSERT_EQ(s2.size(), size_t(3));
+ ASSERT_TRUE(s2.data() == &a[0]);
+ ASSERT_EQ(s2[0], 1);
+ ASSERT_EQ(s2[1], 2);
+ ASSERT_EQ(s2[2], 3);
+}
+
+TEST(LlvmLibcSpanTest, ReassignFromRValueTemporary) {
+ int a[] = {1, 2, 3, 4};
+ span<int> s(a);
+ s = s.subspan(1);
+ ASSERT_EQ(s.size(), size_t(3));
+ ASSERT_TRUE(s.data() == &a[1]);
+ ASSERT_EQ(s[0], 2);
+ ASSERT_EQ(s[1], 3);
+ ASSERT_EQ(s[2], 4);
+
+ s = span<int>();
+ ASSERT_EQ(s.size(), size_t(0));
+ ASSERT_TRUE(s.empty());
+ ASSERT_TRUE(s.data() == nullptr);
+}
+
TEST(LlvmLibcSpanTest, AssignFromMutable) {
span<int> s;
span<const int> view;
view = s;
}
+TEST(LlvmLibcSpanTest, ConvertingAssignment) {
+ int a[] = {1, 2, 3};
+ span<int> s(a);
+ span<const int> view;
+ view = s;
+ ASSERT_EQ(view.size(), size_t(3));
+ ASSERT_TRUE(view.data() == &a[0]);
+ ASSERT_EQ(view[0], 1);
+ ASSERT_EQ(view[1], 2);
+ ASSERT_EQ(view[2], 3);
+
+ view = s.subspan(1);
+ ASSERT_EQ(view.size(), size_t(2));
+ ASSERT_TRUE(view.data() == &a[1]);
+ ASSERT_EQ(view[0], 2);
+ ASSERT_EQ(view[1], 3);
+
+ const span<int> const_s(a);
+ view = const_s;
+ ASSERT_EQ(view.size(), size_t(3));
+ ASSERT_TRUE(view.data() == &a[0]);
+
+ view = span<int>();
+ ASSERT_EQ(view.size(), size_t(0));
+ ASSERT_TRUE(view.empty());
+ ASSERT_TRUE(view.data() == nullptr);
+}
+
TEST(LlvmLibcSpanTest, Modify) {
int a[] = {1, 2, 3};
span<int> s(a);
``````````
</details>
https://github.com/llvm/llvm-project/pull/220619
More information about the libc-commits
mailing list