From e5d5146323ffaa13eb5185616c6ae5c36b69352d Mon Sep 17 00:00:00 2001 From: Guillaume Chatelet Date: Mon, 22 Aug 2022 08:54:13 +0000 Subject: [PATCH] [libc] Allow construction of const span from mutable span --- libc/src/__support/CPP/span.h | 8 ++++- libc/src/__support/CPP/type_traits.h | 52 ++++++++++--------------------- libc/test/src/__support/CPP/span_test.cpp | 10 ++++++ 3 files changed, 33 insertions(+), 37 deletions(-) diff --git a/libc/src/__support/CPP/span.h b/libc/src/__support/CPP/span.h index 6dac9d1..5aab1bb7 100644 --- a/libc/src/__support/CPP/span.h +++ b/libc/src/__support/CPP/span.h @@ -11,7 +11,7 @@ #include // 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 @@ public: constexpr span(array &arr) : span_data(arr.data()), span_size(arr.size()) {} + template && cpp::is_const_v && + cpp::is_same_v, + bool> = true> + constexpr span(span &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 bccd4eb..3f5c162 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 struct enable_if; -template struct enable_if { - using type = T; -}; +template struct enable_if { using type = T; }; template using enable_if_t = typename enable_if::type; @@ -28,15 +26,17 @@ template struct integral_constant { using true_type = cpp::integral_constant; using false_type = cpp::integral_constant; -template struct type_identity { - using type = T; -}; +template struct type_identity { using type = T; }; template struct is_same : cpp::false_type {}; template struct is_same : cpp::true_type {}; template inline constexpr bool is_same_v = is_same::value; +template struct is_const : cpp::false_type {}; +template struct is_const : cpp::true_type {}; +template inline constexpr bool is_const_v = is_const::value; + template struct remove_cv : public type_identity {}; template struct remove_cv : public type_identity {}; template struct remove_cv : public type_identity {}; @@ -114,46 +114,26 @@ template struct is_signed { template inline constexpr bool is_signed_v = is_signed::value; template struct make_unsigned; -template <> struct make_unsigned { - using type = unsigned char; -}; -template <> struct make_unsigned { - using type = unsigned char; -}; -template <> struct make_unsigned { - using type = unsigned short; -}; -template <> struct make_unsigned { - using type = unsigned int; -}; -template <> struct make_unsigned { - using type = unsigned long; -}; +template <> struct make_unsigned { using type = unsigned char; }; +template <> struct make_unsigned { using type = unsigned char; }; +template <> struct make_unsigned { using type = unsigned short; }; +template <> struct make_unsigned { using type = unsigned int; }; +template <> struct make_unsigned { using type = unsigned long; }; template <> struct make_unsigned { using type = unsigned long long; }; -template <> struct make_unsigned { - using type = unsigned char; -}; +template <> struct make_unsigned { using type = unsigned char; }; template <> struct make_unsigned { using type = unsigned short; }; -template <> struct make_unsigned { - using type = unsigned int; -}; -template <> struct make_unsigned { - using type = unsigned long; -}; +template <> struct make_unsigned { using type = unsigned int; }; +template <> struct make_unsigned { using type = unsigned long; }; template <> struct make_unsigned { 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 using make_unsigned_t = typename make_unsigned::type; diff --git a/libc/test/src/__support/CPP/span_test.cpp b/libc/test/src/__support/CPP/span_test.cpp index 6cb775a..831188d 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 a = {1, 2, 3}; + span mutable_view(a); + span 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 s(a); -- 2.7.4