[libc-commits] [libc] e5d5146 - [libc] Allow construction of const span from mutable span

Guillaume Chatelet via libc-commits libc-commits at lists.llvm.org
Mon Aug 22 01:54:46 PDT 2022


Author: Guillaume Chatelet
Date: 2022-08-22T08:54:31Z
New Revision: e5d5146323ffaa13eb5185616c6ae5c36b69352d

URL: https://github.com/llvm/llvm-project/commit/e5d5146323ffaa13eb5185616c6ae5c36b69352d
DIFF: https://github.com/llvm/llvm-project/commit/e5d5146323ffaa13eb5185616c6ae5c36b69352d.diff

LOG: [libc] Allow construction of const span from mutable span

Added: 
    

Modified: 
    libc/src/__support/CPP/span.h
    libc/src/__support/CPP/type_traits.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 6dac9d123983..5aab1bb76a60 100644
--- a/libc/src/__support/CPP/span.h
+++ b/libc/src/__support/CPP/span.h
@@ -11,7 +11,7 @@
 #include <stddef.h> // For size_t
 
 #include "array.h"       // For array
-#include "type_traits.h" // For remove_cv_t
+#include "type_traits.h" // For remove_cv_t, enable_if_t, is_same_v, is_const_v
 
 namespace __llvm_libc::cpp {
 
@@ -52,6 +52,12 @@ template <typename T> class span {
   constexpr span(array<T, 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()) {}
+
   constexpr span(const span &s) = default;
   constexpr span &operator=(const span &s) = default;
   ~span() = default;

diff  --git a/libc/src/__support/CPP/type_traits.h b/libc/src/__support/CPP/type_traits.h
index bccd4eb76579..3f5c162a63e1 100644
--- a/libc/src/__support/CPP/type_traits.h
+++ b/libc/src/__support/CPP/type_traits.h
@@ -15,9 +15,7 @@ namespace __llvm_libc {
 namespace cpp {
 
 template <bool B, typename T> struct enable_if;
-template <typename T> struct enable_if<true, T> {
-  using type = T;
-};
+template <typename T> struct enable_if<true, T> { using type = T; };
 template <bool B, typename T = void>
 using enable_if_t = typename enable_if<B, T>::type;
 
@@ -28,15 +26,17 @@ template <typename T, T v> struct integral_constant {
 using true_type = cpp::integral_constant<bool, true>;
 using false_type = cpp::integral_constant<bool, false>;
 
-template <typename T> struct type_identity {
-  using type = T;
-};
+template <typename T> struct type_identity { using type = T; };
 
 template <typename T, typename U> struct is_same : cpp::false_type {};
 template <typename T> struct is_same<T, T> : cpp::true_type {};
 template <typename T, typename U>
 inline constexpr bool is_same_v = is_same<T, U>::value;
 
+template <class T> struct is_const : cpp::false_type {};
+template <class T> struct is_const<const T> : cpp::true_type {};
+template <class T> inline constexpr bool is_const_v = is_const<T>::value;
+
 template <typename T> struct remove_cv : public type_identity<T> {};
 template <typename T> struct remove_cv<const T> : public type_identity<T> {};
 template <typename T> struct remove_cv<volatile T> : public type_identity<T> {};
@@ -114,46 +114,26 @@ template <typename T> struct is_signed {
 template <typename T> inline constexpr bool is_signed_v = is_signed<T>::value;
 
 template <typename T> struct make_unsigned;
-template <> struct make_unsigned<char> {
-  using type = unsigned char;
-};
-template <> struct make_unsigned<signed char> {
-  using type = unsigned char;
-};
-template <> struct make_unsigned<short> {
-  using type = unsigned short;
-};
-template <> struct make_unsigned<int> {
-  using type = unsigned int;
-};
-template <> struct make_unsigned<long> {
-  using type = unsigned long;
-};
+template <> struct make_unsigned<char> { using type = unsigned char; };
+template <> struct make_unsigned<signed char> { using type = unsigned char; };
+template <> struct make_unsigned<short> { using type = unsigned short; };
+template <> struct make_unsigned<int> { using type = unsigned int; };
+template <> struct make_unsigned<long> { using type = unsigned long; };
 template <> struct make_unsigned<long long> {
   using type = unsigned long long;
 };
-template <> struct make_unsigned<unsigned char> {
-  using type = unsigned char;
-};
+template <> struct make_unsigned<unsigned char> { using type = unsigned char; };
 template <> struct make_unsigned<unsigned short> {
   using type = unsigned short;
 };
-template <> struct make_unsigned<unsigned int> {
-  using type = unsigned int;
-};
-template <> struct make_unsigned<unsigned long> {
-  using type = unsigned long;
-};
+template <> struct make_unsigned<unsigned int> { using type = unsigned int; };
+template <> struct make_unsigned<unsigned long> { using type = unsigned long; };
 template <> struct make_unsigned<unsigned long long> {
   using type = unsigned long long;
 };
 #ifdef __SIZEOF_INT128__
-template <> struct make_unsigned<__int128_t> {
-  using type = __uint128_t;
-};
-template <> struct make_unsigned<__uint128_t> {
-  using type = __uint128_t;
-};
+template <> struct make_unsigned<__int128_t> { using type = __uint128_t; };
+template <> struct make_unsigned<__uint128_t> { using type = __uint128_t; };
 #endif
 template <typename T> using make_unsigned_t = typename make_unsigned<T>::type;
 

diff  --git a/libc/test/src/__support/CPP/span_test.cpp b/libc/test/src/__support/CPP/span_test.cpp
index 6cb775a662ac..831188d427de 100644
--- a/libc/test/src/__support/CPP/span_test.cpp
+++ b/libc/test/src/__support/CPP/span_test.cpp
@@ -56,6 +56,16 @@ TEST(LlvmLibcSpanTest, InitializeArray) {
   ASSERT_EQ(s[2], 3);
 }
 
+TEST(LlvmLibcSpanTest, ConstFromMutable) {
+  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);
+}
+
 TEST(LlvmLibcSpanTest, Modify) {
   int a[] = {1, 2, 3};
   span<int> s(a);


        


More information about the libc-commits mailing list