[llvm-branch-commits] [libc] [libc][wctype] Upstream custom slice implementation from PtrHash-cc prototype to LLVM libc (PR #174779)
Muhammad Bassiouni via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Jan 7 06:51:36 PST 2026
https://github.com/bassiounix updated https://github.com/llvm/llvm-project/pull/174779
>From 5876cee59b66365497d3c1430f9c6529d200ddb5 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] [libc][wctype] Upstream custom slice implementation from
PtrHash-cc prototype to LLVM libc
---
.../wctype/conversion/utils/CMakeLists.txt | 12 ++
.../__support/wctype/conversion/utils/slice.h | 113 ++++++++++++++++++
2 files changed, 125 insertions(+)
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
index 2bda389065f38..9e119f38641ff 100644
--- a/libc/src/__support/wctype/conversion/utils/CMakeLists.txt
+++ b/libc/src/__support/wctype/conversion/utils/CMakeLists.txt
@@ -1,3 +1,15 @@
+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
+)
+
add_header_library(
zip
HDRS
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..3d10a5decdd50
--- /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
More information about the llvm-branch-commits
mailing list