Skip to content

Commit af2bbc3

Browse files
authored
feat: String.Internal.ugetUTF8Byte (#14388)
This PR adds a `String.Internal.ugetUTF8Byte` function. For now, this function is just for internal use and does not have a definition. We might also add a public `String.ugetUTF8Byte` function in the future which has a definition.
1 parent fe3f1d3 commit af2bbc3

3 files changed

Lines changed: 19 additions & 1 deletion

File tree

src/Init/Data/String/Bootstrap.lean

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module
77

88
prelude
99
public import Init.Data.ByteArray.Bootstrap
10+
public import Init.Data.UInt.BasicAux
1011
import Init.Data.Char.Basic
1112

1213
public section
@@ -136,6 +137,13 @@ opaque dropRight (s : String) (n : Nat) : String
136137
@[extern "lean_string_get_byte_fast"]
137138
opaque getUTF8Byte (s : @& String) (n : Nat) (h : n < s.utf8ByteSize) : UInt8
138139

140+
/--
141+
Variant of `getUTF8Byte` that takes the byte index as a `USize`, which avoids `Nat` boxing
142+
in tight loops over the bytes of a string.
143+
-/
144+
@[extern "lean_string_uget_byte_fast"]
145+
opaque ugetUTF8Byte (s : @& String) (n : USize) (h : n.toNat < s.utf8ByteSize) : UInt8
146+
139147
end String.Internal
140148

141149
@[extern "lean_string_mk", expose, deprecated String.ofList (since := "2025-10-30")]

src/include/lean/lean.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,9 @@ static inline uint8_t lean_string_get_byte_fast(b_lean_obj_arg s, b_lean_obj_arg
12181218
size_t idx = lean_unbox(i);
12191219
return str[idx];
12201220
}
1221+
static inline uint8_t lean_string_uget_byte_fast(b_lean_obj_arg s, size_t i) {
1222+
return (uint8_t)lean_string_cstr(s)[i];
1223+
}
12211224

12221225
LEAN_EXPORT lean_obj_res lean_string_utf8_next(b_lean_obj_arg s, b_lean_obj_arg i);
12231226
LEAN_EXPORT lean_obj_res lean_string_utf8_next_fast_cold(size_t i, unsigned char c);

tests/elab/utf8英語.lean

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import Lean.Util.TestExtern
22

3+
/-!
4+
Tests UTF-8 encoding and decoding: `String.toUTF8`, `String.ofByteArray`,
5+
`ByteArray.validateUTF8`, and byte access via `String.getUTF8Byte` and
6+
`String.Internal.ugetUTF8Byte`.
7+
-/
8+
39
deriving instance DecidableEq for ByteArray
410

511
test_extern String.toUTF8 ""
@@ -13,7 +19,8 @@ macro "test_extern'" t:term " => " v:term : command =>
1319
def checkGet (s : String) (arr : Array UInt8) :=
1420
(List.range s.utf8ByteSize).all fun i =>
1521
let c := if h : _ then s.getUTF8Byte ⟨i⟩ h else unreachable!
16-
c == arr[i]!
22+
let c' := if h : _ then String.Internal.ugetUTF8Byte s (USize.ofNat i) h else unreachable!
23+
c == arr[i]! && c' == arr[i]!
1724

1825
macro "validate" arr:term " => " "↯" : command =>
1926
`(test_extern' ByteArray.validateUTF8 $arr => false)

0 commit comments

Comments
 (0)