[libc-commits] [libc] [libc][wctype] Upstream custom slice implementation from PtrHash-cc prototype to LLVM libc (PR #174779)
Muhammad Bassiouni via libc-commits
libc-commits at lists.llvm.org
Fri Jan 9 12:13:12 PST 2026
https://github.com/bassiounix updated https://github.com/llvm/llvm-project/pull/174779
>From 81dbf6bb866481eb72f37070075934b31c40d583 Mon Sep 17 00:00:00 2001
From: bassiounix <muhammad.m.bassiouni at gmail.com>
Date: Wed, 7 Jan 2026 16:42:29 +0200
Subject: [PATCH 01/10] [libc][wctype] Upstream custom slice implementation
from PtrHash-cc prototype to LLVM libc
---
.../wctype/conversion/utils/CMakeLists.txt | 11 ++
.../__support/wctype/conversion/utils/slice.h | 113 ++++++++++++++++++
2 files changed, 124 insertions(+)
create mode 100644 libc/src/__support/wctype/conversion/utils/CMakeLists.txt
create mode 100644 libc/src/__support/wctype/conversion/utils/slice.h
diff --git a/libc/src/__support/wctype/conversion/utils/CMakeLists.txt b/libc/src/__support/wctype/conversion/utils/CMakeLists.txt
new file mode 100644
index 0000000000000..edd6270f47126
--- /dev/null
+++ b/libc/src/__support/wctype/conversion/utils/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_header_library(
+ slice
+ HDRS
+ slice.h
+ DEPENDS
+ libc.hdr.types.size_t
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.CPP.expected
+ libc.src.__support.CPP.span
+ libc.src.__support.libc_assert
+)
diff --git a/libc/src/__support/wctype/conversion/utils/slice.h b/libc/src/__support/wctype/conversion/utils/slice.h
new file mode 100644
index 0000000000000..f630ad21d73c2
--- /dev/null
+++ b/libc/src/__support/wctype/conversion/utils/slice.h
@@ -0,0 +1,113 @@
+//===-- Internal utils for wctype conversion code - slice -------*- 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
+//
+//===----------------------------------------------------------------------===//
+// Similar to cpp::span with additional functionality
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_WCTYPE_CONVERSION_UTILS_SLICE_H
+#define LLVM_LIBC_SRC___SUPPORT_WCTYPE_CONVERSION_UTILS_SLICE_H
+
+#include "hdr/types/size_t.h"
+#include "src/__support/CPP/algorithm.h"
+#include "src/__support/CPP/expected.h"
+#include "src/__support/CPP/span.h"
+#include "src/__support/libc_assert.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace internal_wctype_conversion_utils {
+
+enum class Ordering {
+ /// An ordering where a compared value is less than another.
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ Greater = 1,
+};
+
+template <typename T> struct Slice : public cpp::span<T> {
+ LIBC_INLINE constexpr Slice() : cpp::span<T>() {}
+
+ LIBC_INLINE constexpr Slice(T *ptr, size_t len) : cpp::span<T>(ptr, len) {}
+ LIBC_INLINE constexpr Slice(T const *ptr, size_t len)
+ : cpp::span<T>(ptr, len) {}
+
+ template <typename U, size_t N>
+ LIBC_INLINE constexpr Slice<U>(cpp::array<U, N> &arr) : cpp::span<T>(arr) {}
+
+ LIBC_INLINE constexpr Slice(const Slice<T> &) = default;
+ LIBC_INLINE constexpr Slice(Slice<T> &&) = default;
+
+ LIBC_INLINE constexpr Slice(const cpp::span<T> &s) : cpp::span<T>(s) {}
+ LIBC_INLINE constexpr Slice(cpp::span<T> &&s) : cpp::span<T>(s) {}
+
+ LIBC_INLINE constexpr Slice &operator=(const Slice<T> &n) = default;
+ LIBC_INLINE constexpr Slice &operator=(Slice<T> &&n) = default;
+
+ LIBC_INLINE constexpr Slice &operator=(const cpp::span<T> &n) {
+ this->operator=(n);
+ return *this;
+ }
+ LIBC_INLINE constexpr Slice &operator=(cpp::span<T> &&n) {
+ this->operator=(n);
+ return *this;
+ }
+
+ template <typename Fn>
+ LIBC_INLINE constexpr cpp::expected<size_t, size_t>
+ binary_search_by(Fn func) const {
+ auto size = this->size();
+ if (size == 0) {
+ return cpp::unexpected<size_t>(0);
+ }
+
+ auto base = 0;
+
+ while (size > 1) {
+ auto half = size / 2;
+ auto mid = base + half;
+ auto cmp = func(this->operator[](mid));
+ base = (cmp == Ordering::Greater) ? base : mid;
+ size -= half;
+ }
+
+ auto cmp = func(this->operator[](base));
+ if (cmp == Ordering::Equal) {
+ LIBC_ASSERT(base < this->size());
+ return base;
+ } else {
+ auto result = base + static_cast<size_t>(cmp == Ordering::Less);
+ LIBC_ASSERT(result <= this->size());
+ return cpp::unexpected(result);
+ }
+ }
+
+ LIBC_INLINE constexpr Slice<T> range(size_t start, size_t end) const {
+ return Slice<T>(this->data() + start, end - start);
+ }
+
+ LIBC_INLINE constexpr bool contains(T elm) const {
+ for (auto it : *this) {
+ if (elm == it) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ LIBC_INLINE constexpr void copy_from_slice(Slice<T> other) const {
+ for (size_t i = 0; i < cpp::min(this->size(), other.size()); i++) {
+ this->data()[i] = other.data()[i];
+ }
+ }
+};
+
+} // namespace internal_wctype_conversion_utils
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_WCTYPE_CONVERSION_UTILS_SLICE_H
>From 957172402986bebf946b589cae5be20eae3a10ea Mon Sep 17 00:00:00 2001
From: bassiounix <muhammad.m.bassiouni at gmail.com>
Date: Wed, 7 Jan 2026 20:22:03 +0200
Subject: [PATCH 02/10] fix nesting
---
libc/src/__support/wctype/conversion/utils/slice.h | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/libc/src/__support/wctype/conversion/utils/slice.h b/libc/src/__support/wctype/conversion/utils/slice.h
index f630ad21d73c2..69f8e58fc568e 100644
--- a/libc/src/__support/wctype/conversion/utils/slice.h
+++ b/libc/src/__support/wctype/conversion/utils/slice.h
@@ -18,7 +18,9 @@
namespace LIBC_NAMESPACE_DECL {
-namespace internal_wctype_conversion_utils {
+namespace wctype_internal {
+
+namespace conversion_utils {
enum class Ordering {
/// An ordering where a compared value is less than another.
@@ -106,7 +108,10 @@ template <typename T> struct Slice : public cpp::span<T> {
}
};
-} // namespace internal_wctype_conversion_utils
+
+} // namespace conversion_utils
+
+} // namespace wctype_internal
} // namespace LIBC_NAMESPACE_DECL
>From a306d1f2b22665df3db58f9103b719761907ba14 Mon Sep 17 00:00:00 2001
From: bassiounix <muhammad.m.bassiouni at gmail.com>
Date: Wed, 7 Jan 2026 20:28:12 +0200
Subject: [PATCH 03/10] format
---
libc/src/__support/wctype/conversion/utils/slice.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/libc/src/__support/wctype/conversion/utils/slice.h b/libc/src/__support/wctype/conversion/utils/slice.h
index 69f8e58fc568e..fa5831f053529 100644
--- a/libc/src/__support/wctype/conversion/utils/slice.h
+++ b/libc/src/__support/wctype/conversion/utils/slice.h
@@ -108,7 +108,6 @@ template <typename T> struct Slice : public cpp::span<T> {
}
};
-
} // namespace conversion_utils
} // namespace wctype_internal
>From 394b3fa5d4cb29e8989a06522997b8214b6c707a Mon Sep 17 00:00:00 2001
From: bassiounix <muhammad.m.bassiouni at gmail.com>
Date: Fri, 9 Jan 2026 18:16:47 +0200
Subject: [PATCH 04/10] call explicit operator
---
libc/src/__support/wctype/conversion/utils/slice.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libc/src/__support/wctype/conversion/utils/slice.h b/libc/src/__support/wctype/conversion/utils/slice.h
index fa5831f053529..4b90c2504db15 100644
--- a/libc/src/__support/wctype/conversion/utils/slice.h
+++ b/libc/src/__support/wctype/conversion/utils/slice.h
@@ -51,11 +51,11 @@ template <typename T> struct Slice : public cpp::span<T> {
LIBC_INLINE constexpr Slice &operator=(Slice<T> &&n) = default;
LIBC_INLINE constexpr Slice &operator=(const cpp::span<T> &n) {
- this->operator=(n);
+ cpp::span<T>::operator=(n);
return *this;
}
LIBC_INLINE constexpr Slice &operator=(cpp::span<T> &&n) {
- this->operator=(n);
+ cpp::span<T>::operator=(n);
return *this;
}
>From 42b6d9dba0c4f0878061e012d3e591b81f69735f Mon Sep 17 00:00:00 2001
From: bassiounix <muhammad.m.bassiouni at gmail.com>
Date: Fri, 9 Jan 2026 18:19:45 +0200
Subject: [PATCH 05/10] Add bounds checking asserts
---
libc/src/__support/wctype/conversion/utils/slice.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/libc/src/__support/wctype/conversion/utils/slice.h b/libc/src/__support/wctype/conversion/utils/slice.h
index 4b90c2504db15..d7fd7bd8dcc7d 100644
--- a/libc/src/__support/wctype/conversion/utils/slice.h
+++ b/libc/src/__support/wctype/conversion/utils/slice.h
@@ -89,6 +89,7 @@ template <typename T> struct Slice : public cpp::span<T> {
}
LIBC_INLINE constexpr Slice<T> range(size_t start, size_t end) const {
+ LIBC_ASSERT(start <= end && end <= this->size());
return Slice<T>(this->data() + start, end - start);
}
>From 9de4f4d7b48f19648f12dc60a46af3bc8413068e Mon Sep 17 00:00:00 2001
From: bassiounix <muhammad.m.bassiouni at gmail.com>
Date: Fri, 9 Jan 2026 19:20:38 +0200
Subject: [PATCH 06/10] add docs comment
---
.../src/__support/wctype/conversion/utils/slice.h | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/libc/src/__support/wctype/conversion/utils/slice.h b/libc/src/__support/wctype/conversion/utils/slice.h
index d7fd7bd8dcc7d..90a5268342d06 100644
--- a/libc/src/__support/wctype/conversion/utils/slice.h
+++ b/libc/src/__support/wctype/conversion/utils/slice.h
@@ -59,6 +59,21 @@ template <typename T> struct Slice : public cpp::span<T> {
return *this;
}
+ // Binary searches this slice with a comparator function.
+ //
+ // The comparator function should return an order code that indicates whether
+ // its argument is `Less`, `Equal` or `Greater` the desired target.
+ // If the slice is not sorted or if the comparator function does not
+ // implement an order consistent with the sort order of the underlying
+ // slice, the returned result is unspecified and meaningless.
+ //
+ // If the value is found then `cpp::expected<size_t>` is returned,
+ // containing the index of the matching element. If there are multiple
+ // matches, then any one of the matches could be returned. The index is chosen
+ // deterministically.
+ // If the value is not found then `cpp::unexpected<size_t>` is returned,
+ // containing the index where a matching element could be inserted while
+ // maintaining sorted order.
template <typename Fn>
LIBC_INLINE constexpr cpp::expected<size_t, size_t>
binary_search_by(Fn func) const {
>From cd09aabdb2565f7ed7f07cccb108a5e7fbb23295 Mon Sep 17 00:00:00 2001
From: bassiounix <muhammad.m.bassiouni at gmail.com>
Date: Fri, 9 Jan 2026 20:00:56 +0200
Subject: [PATCH 07/10] make type size_t
---
libc/src/__support/wctype/conversion/utils/slice.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/__support/wctype/conversion/utils/slice.h b/libc/src/__support/wctype/conversion/utils/slice.h
index 90a5268342d06..4aa6fb919e761 100644
--- a/libc/src/__support/wctype/conversion/utils/slice.h
+++ b/libc/src/__support/wctype/conversion/utils/slice.h
@@ -82,7 +82,7 @@ template <typename T> struct Slice : public cpp::span<T> {
return cpp::unexpected<size_t>(0);
}
- auto base = 0;
+ size_t base = 0;
while (size > 1) {
auto half = size / 2;
>From 84e97b7648506a08fddf27711e9db3cc1a841b1c Mon Sep 17 00:00:00 2001
From: bassiounix <muhammad.m.bassiouni at gmail.com>
Date: Fri, 9 Jan 2026 20:01:16 +0200
Subject: [PATCH 08/10] rename method to `slice_form_range`
---
libc/src/__support/wctype/conversion/utils/slice.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libc/src/__support/wctype/conversion/utils/slice.h b/libc/src/__support/wctype/conversion/utils/slice.h
index 4aa6fb919e761..7eaa2da2d5c5c 100644
--- a/libc/src/__support/wctype/conversion/utils/slice.h
+++ b/libc/src/__support/wctype/conversion/utils/slice.h
@@ -103,7 +103,8 @@ template <typename T> struct Slice : public cpp::span<T> {
}
}
- LIBC_INLINE constexpr Slice<T> range(size_t start, size_t end) const {
+ LIBC_INLINE constexpr Slice<T> slice_form_range(size_t start,
+ size_t end) const {
LIBC_ASSERT(start <= end && end <= this->size());
return Slice<T>(this->data() + start, end - start);
}
>From 41bd7d3007da05d21357894d19758ba574345454 Mon Sep 17 00:00:00 2001
From: bassiounix <muhammad.m.bassiouni at gmail.com>
Date: Fri, 9 Jan 2026 20:14:50 +0200
Subject: [PATCH 09/10] remove explicit U
---
libc/src/__support/wctype/conversion/utils/slice.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/__support/wctype/conversion/utils/slice.h b/libc/src/__support/wctype/conversion/utils/slice.h
index 7eaa2da2d5c5c..a3e08bc1b5c5d 100644
--- a/libc/src/__support/wctype/conversion/utils/slice.h
+++ b/libc/src/__support/wctype/conversion/utils/slice.h
@@ -39,7 +39,7 @@ template <typename T> struct Slice : public cpp::span<T> {
: cpp::span<T>(ptr, len) {}
template <typename U, size_t N>
- LIBC_INLINE constexpr Slice<U>(cpp::array<U, N> &arr) : cpp::span<T>(arr) {}
+ LIBC_INLINE constexpr Slice(cpp::array<U, N> &arr) : cpp::span<T>(arr) {}
LIBC_INLINE constexpr Slice(const Slice<T> &) = default;
LIBC_INLINE constexpr Slice(Slice<T> &&) = default;
>From 5f0591ac17f9cb501187ceef88425fd87605bd2f Mon Sep 17 00:00:00 2001
From: bassiounix <muhammad.m.bassiouni at gmail.com>
Date: Fri, 9 Jan 2026 22:13:54 +0200
Subject: [PATCH 10/10] add tests
---
libc/src/__support/wctype/CMakeLists.txt | 2 +
.../wctype/conversion/CMakeLists.txt | 1 +
libc/test/src/__support/wctype/CMakeLists.txt | 3 +-
.../wctype/conversion/CMakeLists.txt | 2 +
.../wctype/conversion/utils/CMakeLists.txt | 11 ++
.../wctype/conversion/utils/slice_test.cpp | 169 ++++++++++++++++++
6 files changed, 187 insertions(+), 1 deletion(-)
create mode 100644 libc/src/__support/wctype/conversion/CMakeLists.txt
create mode 100644 libc/test/src/__support/wctype/conversion/CMakeLists.txt
create mode 100644 libc/test/src/__support/wctype/conversion/utils/CMakeLists.txt
create mode 100644 libc/test/src/__support/wctype/conversion/utils/slice_test.cpp
diff --git a/libc/src/__support/wctype/CMakeLists.txt b/libc/src/__support/wctype/CMakeLists.txt
index 48d9cd9d056c7..be2f5883afbde 100644
--- a/libc/src/__support/wctype/CMakeLists.txt
+++ b/libc/src/__support/wctype/CMakeLists.txt
@@ -1,3 +1,5 @@
+add_subdirectory(conversion)
+
add_header_library(
wctype_classification_utils
HDRS
diff --git a/libc/src/__support/wctype/conversion/CMakeLists.txt b/libc/src/__support/wctype/conversion/CMakeLists.txt
new file mode 100644
index 0000000000000..512d2b1553c8c
--- /dev/null
+++ b/libc/src/__support/wctype/conversion/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(utils)
diff --git a/libc/test/src/__support/wctype/CMakeLists.txt b/libc/test/src/__support/wctype/CMakeLists.txt
index abfdc9c4d7d11..cbe9fe6f55917 100644
--- a/libc/test/src/__support/wctype/CMakeLists.txt
+++ b/libc/test/src/__support/wctype/CMakeLists.txt
@@ -3,7 +3,7 @@ add_custom_target(libc-support-wctype-tests)
add_libc_test(
wctype_classification_utils_test
SUITE
- libc-support-tests
+ libc-support-wctype-tests
SRCS
wctype_classification_utils_test.cpp
DEPENDS
@@ -11,3 +11,4 @@ add_libc_test(
libc.src.__support.wctype.wctype_classification_utils
)
+add_subdirectory(conversion)
diff --git a/libc/test/src/__support/wctype/conversion/CMakeLists.txt b/libc/test/src/__support/wctype/conversion/CMakeLists.txt
new file mode 100644
index 0000000000000..17dc6c7d43f08
--- /dev/null
+++ b/libc/test/src/__support/wctype/conversion/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_custom_target(libc-support-wctype-conversion-tests)
+add_subdirectory(utils)
diff --git a/libc/test/src/__support/wctype/conversion/utils/CMakeLists.txt b/libc/test/src/__support/wctype/conversion/utils/CMakeLists.txt
new file mode 100644
index 0000000000000..63cd50b33a995
--- /dev/null
+++ b/libc/test/src/__support/wctype/conversion/utils/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_custom_target(libc-support-wctype-conversion-utils-tests)
+
+add_libc_test(
+ slice_test
+ SUITE
+ libc-support-wctype-conversion-utils-tests
+ SRCS
+ slice_test.cpp
+ DEPENDS
+ libc.src.__support.wctype.conversion.utils.slice
+)
diff --git a/libc/test/src/__support/wctype/conversion/utils/slice_test.cpp b/libc/test/src/__support/wctype/conversion/utils/slice_test.cpp
new file mode 100644
index 0000000000000..226a3385a5b74
--- /dev/null
+++ b/libc/test/src/__support/wctype/conversion/utils/slice_test.cpp
@@ -0,0 +1,169 @@
+//===-- Unittests for slice - wctype conversion utils ---------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/wctype/conversion/utils/slice.h"
+#include "test/UnitTest/Test.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+using wctype_internal::conversion_utils::Ordering;
+using wctype_internal::conversion_utils::Slice;
+
+struct IntComparator {
+ int target;
+ constexpr Ordering operator()(int value) const {
+ if (value < target)
+ return Ordering::Less;
+ if (value > target)
+ return Ordering::Greater;
+ return Ordering::Equal;
+ }
+};
+
+TEST(LlvmLibcSliceBinarySearchTest, EmptySlice) {
+ Slice<int> s;
+
+ auto result = s.binary_search_by(IntComparator{10});
+
+ EXPECT_EQ(result.error(), static_cast<size_t>(0));
+ EXPECT_FALSE(result.has_value());
+}
+
+TEST(LlvmLibcSliceBinarySearchTest, SingleElementFound) {
+ int data[] = {42};
+ Slice<int> s(data, 1);
+
+ auto result = s.binary_search_by(IntComparator{42});
+
+ ASSERT_TRUE(result.has_value());
+ EXPECT_EQ(*result, static_cast<size_t>(0));
+}
+
+TEST(LlvmLibcSliceBinarySearchTest, SingleElementNotFound) {
+ int data[] = {42};
+ Slice<int> s(data, 1);
+
+ auto result = s.binary_search_by(IntComparator{10});
+
+ EXPECT_FALSE(result.has_value());
+ EXPECT_EQ(result.error(), static_cast<size_t>(0));
+}
+
+TEST(LlvmLibcSliceBinarySearchTest, FoundInMiddle) {
+ int data[] = {1, 3, 5, 7, 9};
+ Slice<int> s(data, 5);
+
+ auto result = s.binary_search_by(IntComparator{7});
+
+ ASSERT_TRUE(result.has_value());
+ EXPECT_EQ(*result, static_cast<size_t>(3));
+}
+
+TEST(LlvmLibcSliceBinarySearchTest, InsertPositionMiddle) {
+ int data[] = {1, 3, 5, 7, 9};
+ Slice<int> s(data, 5);
+
+ auto result = s.binary_search_by(IntComparator{6});
+
+ EXPECT_FALSE(result.has_value());
+ EXPECT_EQ(result.error(), static_cast<size_t>(3));
+}
+
+TEST(LlvmLibcSliceBinarySearchTest, InsertAtBeginning) {
+ int data[] = {10, 20, 30};
+ Slice<int> s(data, 3);
+
+ auto result = s.binary_search_by(IntComparator{5});
+
+ EXPECT_FALSE(result.has_value());
+ EXPECT_EQ(result.error(), static_cast<size_t>(0));
+}
+
+TEST(LlvmLibcSliceBinarySearchTest, InsertAtEnd) {
+ int data[] = {10, 20, 30};
+ Slice<int> s(data, 3);
+
+ auto result = s.binary_search_by(IntComparator{40});
+
+ EXPECT_FALSE(result.has_value());
+ EXPECT_EQ(result.error(), static_cast<size_t>(3));
+}
+
+TEST(LlvmLibcSliceBinarySearchTest, DuplicateValues) {
+ int data[] = {1, 2, 2, 2, 3};
+ Slice<int> s(data, 5);
+
+ auto result = s.binary_search_by(IntComparator{2});
+
+ ASSERT_TRUE(result.has_value());
+ EXPECT_GE(*result, static_cast<size_t>(1));
+ EXPECT_LE(*result, static_cast<size_t>(3));
+}
+
+TEST(LlvmLibcSliceRangeTest, BasicRange) {
+ int data[] = {0, 1, 2, 3, 4};
+ Slice<int> s(data, 5);
+
+ Slice<int> sub = s.slice_form_range(1, 4);
+
+ ASSERT_EQ(sub.size(), static_cast<size_t>(3));
+ EXPECT_EQ(sub[0], 1);
+ EXPECT_EQ(sub[1], 2);
+ EXPECT_EQ(sub[2], 3);
+}
+
+TEST(LlvmLibcSliceContainsTest, ContainsElement) {
+ int data[] = {5, 10, 15};
+ Slice<int> s(data, 3);
+
+ EXPECT_TRUE(s.contains(10));
+ EXPECT_FALSE(s.contains(7));
+}
+
+TEST(LlvmLibcSliceCopyTest, SameSizeCopy) {
+ int src_data[] = {1, 2, 3};
+ int dst_data[] = {0, 0, 0};
+
+ Slice<int> src(src_data, 3);
+ Slice<int> dst(dst_data, 3);
+
+ dst.copy_from_slice(src);
+
+ EXPECT_EQ(dst[0], 1);
+ EXPECT_EQ(dst[1], 2);
+ EXPECT_EQ(dst[2], 3);
+}
+
+TEST(LlvmLibcSliceCopyTest, SourceLargerThanDestination) {
+ int src_data[] = {1, 2, 3, 4};
+ int dst_data[] = {0, 0};
+
+ Slice<int> src(src_data, 4);
+ Slice<int> dst(dst_data, 2);
+
+ dst.copy_from_slice(src);
+
+ EXPECT_EQ(dst[0], 1);
+ EXPECT_EQ(dst[1], 2);
+}
+
+TEST(LlvmLibcSliceCopyTest, DestinationLargerThanSource) {
+ int src_data[] = {1, 2};
+ int dst_data[] = {0, 0, 0};
+
+ Slice<int> src(src_data, 2);
+ Slice<int> dst(dst_data, 3);
+
+ dst.copy_from_slice(src);
+
+ EXPECT_EQ(dst[0], 1);
+ EXPECT_EQ(dst[1], 2);
+ EXPECT_EQ(dst[2], 0);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
More information about the libc-commits
mailing list