[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