1use crate::codepointtrie::error::Error;
6use crate::codepointtrie::impl_const::*;
7
8#[cfg(feature = "alloc")]
9use crate::codepointinvlist::CodePointInversionList;
10use core::char::CharTryFromError;
11use core::convert::Infallible;
12use core::convert::TryFrom;
13use core::fmt::Display;
14#[cfg(feature = "alloc")]
15use core::iter::FromIterator;
16use core::num::TryFromIntError;
17use core::ops::RangeInclusive;
18use yoke::Yokeable;
19use zerofrom::ZeroFrom;
20use zerovec::ule::AsULE;
21#[cfg(feature = "alloc")]
22use zerovec::ule::UleError;
23use zerovec::ZeroSlice;
24use zerovec::ZeroVec;
25
26#[derive(#[automatically_derived]
#[allow(clippy::exhaustive_enums)]
impl ::core::clone::Clone for TrieType {
#[inline]
fn clone(&self) -> TrieType { *self }
}Clone, #[automatically_derived]
#[allow(clippy::exhaustive_enums)]
impl ::core::marker::Copy for TrieType { }Copy, #[automatically_derived]
#[allow(clippy::exhaustive_enums)]
impl ::core::cmp::PartialEq for TrieType {
#[inline]
fn eq(&self, other: &TrieType) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
#[allow(clippy::exhaustive_enums)]
impl ::core::fmt::Debug for TrieType {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
TrieType::Fast => "Fast",
TrieType::Small => "Small",
})
}
}Debug, #[automatically_derived]
#[allow(clippy::exhaustive_enums)]
impl ::core::cmp::Eq for TrieType {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq)]
43#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
44#[cfg_attr(feature = "databake", derive(databake::Bake))]
45#[cfg_attr(feature = "databake", databake(path = icu_collections::codepointtrie))]
46#[allow(clippy::exhaustive_enums)] pub enum TrieType {
48 Fast = 0,
51 Small = 1,
54}
55
56pub trait TrieValue: Copy + Eq + PartialEq + AsULE + 'static {
65 type TryFromU32Error: Display;
71 fn try_from_u32(i: u32) -> Result<Self, Self::TryFromU32Error>;
75
76 fn to_u32(self) -> u32;
83}
84
85macro_rules! impl_primitive_trie_value {
86 ($primitive:ty, $error:ty) => {
87 impl TrieValue for $primitive {
88 type TryFromU32Error = $error;
89 fn try_from_u32(i: u32) -> Result<Self, Self::TryFromU32Error> {
90 Self::try_from(i)
91 }
92
93 #[allow(trivial_numeric_casts)]
94 fn to_u32(self) -> u32 {
95 self as u32
98 }
99 }
100 };
101}
102
103impl TrieValue for u8 {
type TryFromU32Error = TryFromIntError;
fn try_from_u32(i: u32) -> Result<Self, Self::TryFromU32Error> {
Self::try_from(i)
}
#[allow(trivial_numeric_casts)]
fn to_u32(self) -> u32 { self as u32 }
}impl_primitive_trie_value!(u8, TryFromIntError);
104impl TrieValue for u16 {
type TryFromU32Error = TryFromIntError;
fn try_from_u32(i: u32) -> Result<Self, Self::TryFromU32Error> {
Self::try_from(i)
}
#[allow(trivial_numeric_casts)]
fn to_u32(self) -> u32 { self as u32 }
}impl_primitive_trie_value!(u16, TryFromIntError);
105impl TrieValue for u32 {
type TryFromU32Error = Infallible;
fn try_from_u32(i: u32) -> Result<Self, Self::TryFromU32Error> {
Self::try_from(i)
}
#[allow(trivial_numeric_casts)]
fn to_u32(self) -> u32 { self as u32 }
}impl_primitive_trie_value!(u32, Infallible);
106impl TrieValue for i8 {
type TryFromU32Error = TryFromIntError;
fn try_from_u32(i: u32) -> Result<Self, Self::TryFromU32Error> {
Self::try_from(i)
}
#[allow(trivial_numeric_casts)]
fn to_u32(self) -> u32 { self as u32 }
}impl_primitive_trie_value!(i8, TryFromIntError);
107impl TrieValue for i16 {
type TryFromU32Error = TryFromIntError;
fn try_from_u32(i: u32) -> Result<Self, Self::TryFromU32Error> {
Self::try_from(i)
}
#[allow(trivial_numeric_casts)]
fn to_u32(self) -> u32 { self as u32 }
}impl_primitive_trie_value!(i16, TryFromIntError);
108impl TrieValue for i32 {
type TryFromU32Error = TryFromIntError;
fn try_from_u32(i: u32) -> Result<Self, Self::TryFromU32Error> {
Self::try_from(i)
}
#[allow(trivial_numeric_casts)]
fn to_u32(self) -> u32 { self as u32 }
}impl_primitive_trie_value!(i32, TryFromIntError);
109impl TrieValue for char {
type TryFromU32Error = CharTryFromError;
fn try_from_u32(i: u32) -> Result<Self, Self::TryFromU32Error> {
Self::try_from(i)
}
#[allow(trivial_numeric_casts)]
fn to_u32(self) -> u32 { self as u32 }
}impl_primitive_trie_value!(char, CharTryFromError);
110
111fn maybe_filter_value<T: TrieValue>(value: T, trie_null_value: T, null_value: T) -> T {
120 if value == trie_null_value {
121 null_value
122 } else {
123 value
124 }
125}
126
127#[derive(#[automatically_derived]
impl<'trie, T: ::core::fmt::Debug + TrieValue> ::core::fmt::Debug for
CodePointTrie<'trie, T> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field4_finish(f, "CodePointTrie",
"header", &self.header, "index", &self.index, "data", &self.data,
"error_value", &&self.error_value)
}
}Debug, #[automatically_derived]
impl<'trie, T: ::core::cmp::Eq + TrieValue> ::core::cmp::Eq for
CodePointTrie<'trie, T> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<CodePointTrieHeader>;
let _: ::core::cmp::AssertParamIsEq<ZeroVec<'trie, u16>>;
let _: ::core::cmp::AssertParamIsEq<ZeroVec<'trie, T>>;
let _: ::core::cmp::AssertParamIsEq<T>;
}
}Eq, #[automatically_derived]
impl<'trie, T: ::core::cmp::PartialEq + TrieValue> ::core::cmp::PartialEq for
CodePointTrie<'trie, T> {
#[inline]
fn eq(&self, other: &CodePointTrie<'trie, T>) -> bool {
self.header == other.header && self.index == other.index &&
self.data == other.data &&
self.error_value == other.error_value
}
}PartialEq, unsafe impl<'yoke, T: TrieValue> yoke::Yokeable<'yoke> for
CodePointTrie<'static, T> where T: 'static {
type Output = CodePointTrie<'yoke, T>;
#[inline]
fn transform(&'yoke self) -> &'yoke Self::Output {
if false { let _: *const &'yoke Self::Output = &raw const self; }
self
}
#[inline]
fn transform_owned(self) -> Self::Output { self }
#[inline]
unsafe fn make(from: Self::Output) -> Self {
::core::mem::transmute::<Self::Output, Self>(from)
}
#[inline]
fn transform_mut<F>(&'yoke mut self, f: F) where F: 'static +
for<'_yoke> FnOnce(&'_yoke mut Self::Output) {
let y = unsafe { &mut *(self as *mut Self as *mut Self::Output) };
f(y)
}
}Yokeable, impl<'zf, 'zf_inner, T: TrieValue>
zerofrom::ZeroFrom<'zf, CodePointTrie<'zf_inner, T>> for
CodePointTrie<'zf, T> where
ZeroVec<'zf, T>: zerofrom::ZeroFrom<'zf, ZeroVec<'zf_inner, T>> {
fn zero_from(this: &'zf CodePointTrie<'zf_inner, T>) -> Self {
match *this {
CodePointTrie {
header: ref __binding_0,
index: ref __binding_1,
data: ref __binding_2,
error_value: ref __binding_3 } => {
CodePointTrie {
header: *__binding_0,
index: <ZeroVec<'zf, u16> as
zerofrom::ZeroFrom<'zf,
ZeroVec<'zf_inner, u16>>>::zero_from(__binding_1),
data: <ZeroVec<'zf, T> as
zerofrom::ZeroFrom<'zf,
ZeroVec<'zf_inner, T>>>::zero_from(__binding_2),
error_value: __binding_3.clone(),
}
}
}
}
}ZeroFrom)]
135pub struct CodePointTrie<'trie, T: TrieValue> {
136 pub(crate) header: CodePointTrieHeader,
140 pub(crate) index: ZeroVec<'trie, u16>,
149 pub(crate) data: ZeroVec<'trie, T>,
159 #[zerofrom(clone)] pub(crate) error_value: T,
163}
164
165#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
174#[cfg_attr(feature = "databake", derive(databake::Bake))]
175#[cfg_attr(feature = "databake", databake(path = icu_collections::codepointtrie))]
176#[derive(#[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl ::core::marker::Copy for CodePointTrieHeader { }Copy, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl ::core::clone::Clone for CodePointTrieHeader {
#[inline]
fn clone(&self) -> CodePointTrieHeader {
let _: ::core::clone::AssertParamIsClone<u32>;
let _: ::core::clone::AssertParamIsClone<u16>;
let _: ::core::clone::AssertParamIsClone<TrieType>;
*self
}
}Clone, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl ::core::fmt::Debug for CodePointTrieHeader {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let names: &'static _ =
&["high_start", "shifted12_high_start", "index3_null_offset",
"data_null_offset", "null_value", "trie_type"];
let values: &[&dyn ::core::fmt::Debug] =
&[&self.high_start, &self.shifted12_high_start,
&self.index3_null_offset, &self.data_null_offset,
&self.null_value, &&self.trie_type];
::core::fmt::Formatter::debug_struct_fields_finish(f,
"CodePointTrieHeader", names, values)
}
}Debug, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl ::core::cmp::Eq for CodePointTrieHeader {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<u32>;
let _: ::core::cmp::AssertParamIsEq<u16>;
let _: ::core::cmp::AssertParamIsEq<TrieType>;
}
}Eq, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl ::core::cmp::PartialEq for CodePointTrieHeader {
#[inline]
fn eq(&self, other: &CodePointTrieHeader) -> bool {
self.high_start == other.high_start &&
self.shifted12_high_start == other.shifted12_high_start &&
self.index3_null_offset == other.index3_null_offset &&
self.data_null_offset == other.data_null_offset &&
self.null_value == other.null_value &&
self.trie_type == other.trie_type
}
}PartialEq, unsafe impl<'yoke> yoke::Yokeable<'yoke> for CodePointTrieHeader<> where
Self: Sized {
type Output = Self;
#[inline]
fn transform(&self) -> &Self::Output { self }
#[inline]
fn transform_owned(self) -> Self::Output { self }
#[inline]
unsafe fn make(this: Self::Output) -> Self { this }
#[inline]
fn transform_mut<F>(&'yoke mut self, f: F) where F: 'static +
for<'_yoke> FnOnce(&'_yoke mut Self::Output) {
f(self)
}
}Yokeable, impl<'zf> zerofrom::ZeroFrom<'zf, CodePointTrieHeader<>> for
CodePointTrieHeader<> where {
fn zero_from(this: &'zf Self) -> Self { *this }
}ZeroFrom)]
177#[allow(clippy::exhaustive_structs)] pub struct CodePointTrieHeader {
179 pub high_start: u32,
191 pub shifted12_high_start: u16,
195 pub index3_null_offset: u16,
199 pub data_null_offset: u32,
203 pub null_value: u32,
206 pub trie_type: TrieType,
213}
214
215impl TryFrom<u8> for TrieType {
216 type Error = Error;
217
218 fn try_from(trie_type_int: u8) -> Result<TrieType, Error> {
219 match trie_type_int {
220 0 => Ok(TrieType::Fast),
221 1 => Ok(TrieType::Small),
222 _ => Err(Error::FromDeserialized {
223 reason: "Cannot parse value for trie_type",
224 }),
225 }
226 }
227}
228
229macro_rules! w(
237 ($a:tt + $b:expr) => {
240 {
241 #[allow(unused_parens)]
242 let a = $a;
243 let b = $b;
244 debug_assert!(a.checked_add(b).is_some());
245 $a.wrapping_add($b)
246 }
247 };
248 ($a:tt - $b:expr) => {
249
250 {
251 #[allow(unused_parens)]
252 let a = $a;
253 let b = $b;
254 debug_assert!(a.checked_sub(b).is_some());
255 $a.wrapping_sub($b)
256 }
257 };
258 ($a:tt * $b:expr) => {
259 {
260 #[allow(unused_parens)]
261 let a = $a;
262 let b = $b;
263 debug_assert!(a.checked_mul(b).is_some());
264 $a.wrapping_mul($b)
265 }
266 };
267);
268
269impl<'trie, T: TrieValue> CodePointTrie<'trie, T> {
270 #[doc(hidden)] pub const unsafe fn from_parts_unstable_unchecked_v1(
277 header: CodePointTrieHeader,
278 index: ZeroVec<'trie, u16>,
279 data: ZeroVec<'trie, T>,
280 error_value: T,
281 ) -> Self {
282 Self {
287 header,
288 index,
289 data,
290 error_value,
291 }
292 }
293
294 pub fn try_new(
297 header: CodePointTrieHeader,
298 index: ZeroVec<'trie, u16>,
299 data: ZeroVec<'trie, T>,
300 ) -> Result<CodePointTrie<'trie, T>, Error> {
301 let error_value = Self::validate_fields(&header, &index, &data)?;
302 let trie: CodePointTrie<'trie, T> = CodePointTrie {
304 header,
305 index,
306 data,
307 error_value,
308 };
309 Ok(trie)
310 }
311
312 pub(crate) fn validate_fields(
322 header: &CodePointTrieHeader,
323 index: &ZeroSlice<u16>,
324 data: &ZeroSlice<T>,
325 ) -> Result<T, Error> {
326 let error_value = data.last().ok_or(Error::EmptyDataVector)?;
327
328 let fast_max = match header.trie_type {
357 TrieType::Fast => FAST_TYPE_FAST_INDEXING_MAX,
358 TrieType::Small => SMALL_TYPE_FAST_INDEXING_MAX,
359 };
360 let max_bit_prefix = fast_max >> FAST_TYPE_SHIFT;
362 let fast_index = index
367 .get_subslice(0..(max_bit_prefix as usize) + 1)
368 .ok_or(Error::IndexTooShortForFastAccess)?;
369 let max_offset = fast_index
378 .iter()
379 .max()
380 .ok_or(Error::IndexTooShortForFastAccess)?;
381 if (max_offset) as usize + (FAST_TYPE_DATA_MASK as usize) >= data.len() {
385 return Err(Error::DataTooShortForFastAccess);
386 }
387
388 Ok(error_value)
394 }
395
396 #[inline]
398 pub fn to_typed(self) -> Typed<FastCodePointTrie<'trie, T>, SmallCodePointTrie<'trie, T>> {
399 match self.header.trie_type {
400 TrieType::Fast => Typed::Fast(FastCodePointTrie { inner: self }),
401 TrieType::Small => Typed::Small(SmallCodePointTrie { inner: self }),
402 }
403 }
404
405 #[inline]
407 pub fn as_typed_ref(
408 &self,
409 ) -> Typed<&FastCodePointTrie<'trie, T>, &SmallCodePointTrie<'trie, T>> {
410 match self.header.trie_type {
414 TrieType::Fast => Typed::Fast(unsafe {
415 &*(self as *const CodePointTrie<'trie, T> as *const FastCodePointTrie<'trie, T>)
416 }),
417 TrieType::Small => Typed::Small(unsafe {
418 &*(self as *const CodePointTrie<'trie, T> as *const SmallCodePointTrie<'trie, T>)
419 }),
420 }
421 }
422
423 #[inline(always)] fn trie_error_val_index(&self) -> u32 {
427 if true {
if !(self.data.len() as u32 >= ERROR_VALUE_NEG_DATA_OFFSET) {
::core::panicking::panic("assertion failed: self.data.len() as u32 >= ERROR_VALUE_NEG_DATA_OFFSET")
};
};debug_assert!(self.data.len() as u32 >= ERROR_VALUE_NEG_DATA_OFFSET);
431 {
#[allow(unused_parens)]
let a = (self.data.len() as u32);
let b = ERROR_VALUE_NEG_DATA_OFFSET;
if true {
if !a.checked_sub(b).is_some() {
::core::panicking::panic("assertion failed: a.checked_sub(b).is_some()")
};
};
(self.data.len() as u32).wrapping_sub(ERROR_VALUE_NEG_DATA_OFFSET)
}w!((self.data.len() as u32) - ERROR_VALUE_NEG_DATA_OFFSET)
432 }
433
434 fn internal_small_index(&self, code_point: u32) -> u32 {
435 let mut index1_pos: u32 = code_point >> SHIFT_1;
439 if self.header.trie_type == TrieType::Fast {
440 if true {
if !(FAST_TYPE_FAST_INDEXING_MAX < code_point &&
code_point < self.header.high_start) {
::core::panicking::panic("assertion failed: FAST_TYPE_FAST_INDEXING_MAX < code_point &&\n code_point < self.header.high_start")
};
};debug_assert!(
441 FAST_TYPE_FAST_INDEXING_MAX < code_point && code_point < self.header.high_start
442 );
443 index1_pos = {
#[allow(unused_parens)]
let a = index1_pos;
let b = BMP_INDEX_LENGTH - OMITTED_BMP_INDEX_1_LENGTH;
if true {
if !a.checked_add(b).is_some() {
::core::panicking::panic("assertion failed: a.checked_add(b).is_some()")
};
};
index1_pos.wrapping_add(BMP_INDEX_LENGTH - OMITTED_BMP_INDEX_1_LENGTH)
}w!(index1_pos + BMP_INDEX_LENGTH - OMITTED_BMP_INDEX_1_LENGTH);
444 } else {
445 if !(code_point < self.header.high_start &&
self.header.high_start > SMALL_LIMIT) {
::core::panicking::panic("assertion failed: code_point < self.header.high_start && self.header.high_start > SMALL_LIMIT")
};assert!(code_point < self.header.high_start && self.header.high_start > SMALL_LIMIT);
446 index1_pos = {
#[allow(unused_parens)]
let a = index1_pos;
let b = SMALL_INDEX_LENGTH;
if true {
if !a.checked_add(b).is_some() {
::core::panicking::panic("assertion failed: a.checked_add(b).is_some()")
};
};
index1_pos.wrapping_add(SMALL_INDEX_LENGTH)
}w!(index1_pos + SMALL_INDEX_LENGTH);
447 }
448 let index1_val = if let Some(index1_val) = self.index.get(index1_pos as usize) {
449 index1_val
450 } else {
451 return self.trie_error_val_index();
452 };
453 let index3_block_idx: u32 =
454 {
#[allow(unused_parens)]
let a = (index1_val as u32);
let b = (code_point >> SHIFT_2) & INDEX_2_MASK;
if true {
if !a.checked_add(b).is_some() {
::core::panicking::panic("assertion failed: a.checked_add(b).is_some()")
};
};
(index1_val as u32).wrapping_add((code_point >> SHIFT_2) & INDEX_2_MASK)
}w!((index1_val as u32) + (code_point >> SHIFT_2) & INDEX_2_MASK);
455 let mut index3_block: u32 =
456 if let Some(index3_block) = self.index.get(index3_block_idx as usize) {
457 index3_block as u32
458 } else {
459 return self.trie_error_val_index();
460 };
461 let mut index3_pos: u32 = (code_point >> SHIFT_3) & INDEX_3_MASK;
462 let mut data_block: u32;
463 if index3_block & 0x8000 == 0 {
464 data_block =
466 if let Some(data_block) = self.index.get({
#[allow(unused_parens)]
let a = index3_block;
let b = index3_pos;
if true {
if !a.checked_add(b).is_some() {
::core::panicking::panic("assertion failed: a.checked_add(b).is_some()")
};
};
index3_block.wrapping_add(index3_pos)
}w!(index3_block + index3_pos) as usize) {
467 data_block as u32
468 } else {
469 return self.trie_error_val_index();
470 };
471 } else {
472 index3_block = {
#[allow(unused_parens)]
let a = (index3_block & 0x7fff);
let b =
{
#[allow(unused_parens)]
let a = (index3_pos & !7);
let b = index3_pos >> 3;
if true {
if !a.checked_add(b).is_some() {
::core::panicking::panic("assertion failed: a.checked_add(b).is_some()")
};
};
(index3_pos & !7).wrapping_add(index3_pos >> 3)
};
if true {
if !a.checked_add(b).is_some() {
::core::panicking::panic("assertion failed: a.checked_add(b).is_some()")
};
};
(index3_block &
0x7fff).wrapping_add({
#[allow(unused_parens)]
let a = (index3_pos & !7);
let b = index3_pos >> 3;
if true {
if !a.checked_add(b).is_some() {
::core::panicking::panic("assertion failed: a.checked_add(b).is_some()")
};
};
(index3_pos & !7).wrapping_add(index3_pos >> 3)
})
}w!((index3_block & 0x7fff) + w!((index3_pos & !7) + index3_pos >> 3));
474 index3_pos &= 7;
475 data_block = if let Some(data_block) = self.index.get(index3_block as usize) {
476 data_block as u32
477 } else {
478 return self.trie_error_val_index();
479 };
480 data_block = (data_block << {
#[allow(unused_parens)]
let a = 2u32;
let b =
{
#[allow(unused_parens)]
let a = 2u32;
let b = index3_pos;
if true {
if !a.checked_mul(b).is_some() {
::core::panicking::panic("assertion failed: a.checked_mul(b).is_some()")
};
};
2u32.wrapping_mul(index3_pos)
};
if true {
if !a.checked_add(b).is_some() {
::core::panicking::panic("assertion failed: a.checked_add(b).is_some()")
};
};
2u32.wrapping_add({
#[allow(unused_parens)]
let a = 2u32;
let b = index3_pos;
if true {
if !a.checked_mul(b).is_some() {
::core::panicking::panic("assertion failed: a.checked_mul(b).is_some()")
};
};
2u32.wrapping_mul(index3_pos)
})
}w!(2u32 + w!(2u32 * index3_pos))) & 0x30000;
481 index3_block += 1;
482 data_block =
483 if let Some(index3_val) = self.index.get({
#[allow(unused_parens)]
let a = index3_block;
let b = index3_pos;
if true {
if !a.checked_add(b).is_some() {
::core::panicking::panic("assertion failed: a.checked_add(b).is_some()")
};
};
index3_block.wrapping_add(index3_pos)
}w!(index3_block + index3_pos) as usize) {
484 data_block | (index3_val as u32)
485 } else {
486 return self.trie_error_val_index();
487 };
488 }
489 {
#[allow(unused_parens)]
let a = data_block;
let b = code_point & SMALL_DATA_MASK;
if true {
if !a.checked_add(b).is_some() {
::core::panicking::panic("assertion failed: a.checked_add(b).is_some()")
};
};
data_block.wrapping_add(code_point & SMALL_DATA_MASK)
}w!(data_block + code_point & SMALL_DATA_MASK)
492 }
493
494 fn small_index(&self, code_point: u32) -> u32 {
505 if code_point >= self.header.high_start {
506 {
#[allow(unused_parens)]
let a = (self.data.len() as u32);
let b = HIGH_VALUE_NEG_DATA_OFFSET;
if true {
if !a.checked_sub(b).is_some() {
::core::panicking::panic("assertion failed: a.checked_sub(b).is_some()")
};
};
(self.data.len() as u32).wrapping_sub(HIGH_VALUE_NEG_DATA_OFFSET)
}w!((self.data.len() as u32) - HIGH_VALUE_NEG_DATA_OFFSET)
507 } else {
508 self.internal_small_index(code_point) }
510 }
511
512 fn fast_index(&self, code_point: u32) -> u32 {
524 let index_array_pos: u32 = code_point >> FAST_TYPE_SHIFT;
525 let index_array_val: u16 =
526 if let Some(index_array_val) = self.index.get(index_array_pos as usize) {
527 index_array_val
528 } else {
529 return self.trie_error_val_index();
530 };
531 let masked_cp = code_point & FAST_TYPE_DATA_MASK;
532 let index_array_val = index_array_val as u32;
533 let fast_index_val: u32 = {
#[allow(unused_parens)]
let a = index_array_val;
let b = masked_cp;
if true {
if !a.checked_add(b).is_some() {
::core::panicking::panic("assertion failed: a.checked_add(b).is_some()")
};
};
index_array_val.wrapping_add(masked_cp)
}w!(index_array_val + masked_cp);
534 fast_index_val
535 }
536
537 #[inline(always)] fn get32_by_fast_index(&self, code_point: u32) -> Option<T> {
542 let fast_max = match self.header.trie_type {
543 TrieType::Fast => FAST_TYPE_FAST_INDEXING_MAX,
544 TrieType::Small => SMALL_TYPE_FAST_INDEXING_MAX,
545 };
546 if code_point <= fast_max {
547 Some(unsafe { self.get32_assuming_fast_index(code_point) })
554 } else {
555 None
558 }
559 }
560
561 #[inline(always)]
569 unsafe fn get32_assuming_fast_index(&self, code_point: u32) -> T {
570 if true {
if !(code_point <=
match self.header.trie_type {
TrieType::Fast => FAST_TYPE_FAST_INDEXING_MAX,
TrieType::Small => SMALL_TYPE_FAST_INDEXING_MAX,
}) {
::core::panicking::panic("assertion failed: code_point <=\n match self.header.trie_type {\n TrieType::Fast => FAST_TYPE_FAST_INDEXING_MAX,\n TrieType::Small => SMALL_TYPE_FAST_INDEXING_MAX,\n }")
};
};debug_assert!(
572 code_point
573 <= match self.header.trie_type {
574 TrieType::Fast => FAST_TYPE_FAST_INDEXING_MAX,
575 TrieType::Small => SMALL_TYPE_FAST_INDEXING_MAX,
576 }
577 );
578
579 let bit_prefix = (code_point as usize) >> FAST_TYPE_SHIFT;
580 if true {
if !(bit_prefix < self.index.len()) {
::core::panicking::panic("assertion failed: bit_prefix < self.index.len()")
};
};debug_assert!(bit_prefix < self.index.len());
581 let base_offset_to_data: usize = usize::from(u16::from_unaligned(*unsafe {
585 self.index.as_ule_slice().get_unchecked(bit_prefix)
586 }));
587 let bit_suffix = (code_point & FAST_TYPE_DATA_MASK) as usize;
588 let offset_to_data = {
#[allow(unused_parens)]
let a = base_offset_to_data;
let b = bit_suffix;
if true {
if !a.checked_add(b).is_some() {
::core::panicking::panic("assertion failed: a.checked_add(b).is_some()")
};
};
base_offset_to_data.wrapping_add(bit_suffix)
}w!(base_offset_to_data + bit_suffix);
594 if true {
if !(offset_to_data < self.data.len()) {
::core::panicking::panic("assertion failed: offset_to_data < self.data.len()")
};
};debug_assert!(offset_to_data < self.data.len());
595 T::from_unaligned(*unsafe { self.data.as_ule_slice().get_unchecked(offset_to_data) })
599 }
600
601 #[cold]
604 #[inline(always)]
605 fn get32_by_small_index_cold(&self, code_point: u32) -> T {
606 self.get32_by_small_index(code_point)
607 }
608
609 #[inline(never)]
622 fn get32_by_small_index(&self, code_point: u32) -> T {
623 if true {
if !(code_point <= CODE_POINT_MAX) {
::core::panicking::panic("assertion failed: code_point <= CODE_POINT_MAX")
};
};debug_assert!(code_point <= CODE_POINT_MAX);
624 if true {
if !(code_point >
match self.header.trie_type {
TrieType::Fast => FAST_TYPE_FAST_INDEXING_MAX,
TrieType::Small => SMALL_TYPE_FAST_INDEXING_MAX,
}) {
::core::panicking::panic("assertion failed: code_point >\n match self.header.trie_type {\n TrieType::Fast => FAST_TYPE_FAST_INDEXING_MAX,\n TrieType::Small => SMALL_TYPE_FAST_INDEXING_MAX,\n }")
};
};debug_assert!(
625 code_point
626 > match self.header.trie_type {
627 TrieType::Fast => FAST_TYPE_FAST_INDEXING_MAX,
628 TrieType::Small => SMALL_TYPE_FAST_INDEXING_MAX,
629 }
630 );
631 self.data
632 .get(self.small_index(code_point) as usize)
633 .unwrap_or(self.error_value)
634 }
635
636 #[inline(always)] pub fn get32(&self, code_point: u32) -> T {
650 if let Some(v) = self.get32_by_fast_index(code_point) {
651 v
652 } else if code_point <= CODE_POINT_MAX {
653 self.get32_by_small_index_cold(code_point)
654 } else {
655 self.error_value
656 }
657 }
658
659 #[inline(always)]
672 pub fn get(&self, c: char) -> T {
673 let code_point = u32::from(c);
677 if let Some(v) = self.get32_by_fast_index(code_point) {
678 v
679 } else {
680 self.get32_by_small_index_cold(code_point)
681 }
682 }
683
684 #[inline(always)]
686 pub fn get16(&self, bmp: u16) -> T {
687 let code_point = u32::from(bmp);
691 if let Some(v) = self.get32_by_fast_index(code_point) {
692 v
693 } else {
694 self.get32_by_small_index_cold(code_point)
695 }
696 }
697
698 #[inline(always)]
704 pub fn get32_supplementary(&self, supplementary: u32) -> T {
705 if true {
if !(supplementary > 0xFFFF) {
::core::panicking::panic("assertion failed: supplementary > 0xFFFF")
};
};debug_assert!(supplementary > 0xFFFF);
706 if true {
if !(supplementary <= CODE_POINT_MAX) {
::core::panicking::panic("assertion failed: supplementary <= CODE_POINT_MAX")
};
};debug_assert!(supplementary <= CODE_POINT_MAX);
707 self.get32_by_small_index(supplementary)
708 }
709
710 #[inline(always)] pub fn get32_ule(&self, code_point: u32) -> Option<&T::ULE> {
724 let fast_max = match self.header.trie_type {
729 TrieType::Fast => FAST_TYPE_FAST_INDEXING_MAX,
730 TrieType::Small => SMALL_TYPE_FAST_INDEXING_MAX,
731 };
732 let data_pos: u32 = if code_point <= fast_max {
733 Self::fast_index(self, code_point)
734 } else if code_point <= CODE_POINT_MAX {
735 Self::small_index(self, code_point)
736 } else {
737 self.trie_error_val_index()
738 };
739 self.data.as_ule_slice().get(data_pos as usize)
741 }
742
743 #[cfg(feature = "alloc")]
772 pub fn try_into_converted<P>(self) -> Result<CodePointTrie<'trie, P>, UleError>
773 where
774 P: TrieValue,
775 {
776 let converted_data = self.data.try_into_converted()?;
777 let error_ule = self.error_value.to_unaligned();
778 let slice = &[error_ule];
779 let error_vec = ZeroVec::<T>::new_borrowed(slice);
780 let error_converted = error_vec.try_into_converted::<P>()?;
781 #[expect(clippy::expect_used)] Ok(CodePointTrie {
783 header: self.header,
784 index: self.index,
785 data: converted_data,
786 error_value: error_converted
787 .get(0)
788 .expect("vector known to have one element"),
789 })
790 }
791
792 #[cfg(feature = "alloc")]
815 pub fn try_alloc_map_value<P, E>(
816 &self,
817 mut f: impl FnMut(T) -> Result<P, E>,
818 ) -> Result<CodePointTrie<'trie, P>, E>
819 where
820 P: TrieValue,
821 {
822 let error_converted = f(self.error_value)?;
823 let converted_data = self.data.iter().map(f).collect::<Result<ZeroVec<P>, E>>()?;
824 Ok(CodePointTrie {
825 header: self.header,
826 index: self.index.clone(),
827 data: converted_data,
828 error_value: error_converted,
829 })
830 }
831
832 pub fn get_range(&self, start: u32) -> Option<CodePointMapRange<T>> {
886 if CODE_POINT_MAX < start {
890 return None;
891 }
892 if start >= self.header.high_start {
893 let di: usize = self.data.len() - (HIGH_VALUE_NEG_DATA_OFFSET as usize);
894 let value: T = self.data.get(di)?;
895 return Some(CodePointMapRange {
896 range: start..=CODE_POINT_MAX,
897 value,
898 });
899 }
900
901 let null_value: T = T::try_from_u32(self.header.null_value).ok()?;
902
903 let mut prev_i3_block: u32 = u32::MAX; let mut prev_block: u32 = u32::MAX; let mut c: u32 = start;
906 let mut trie_value: T = self.error_value();
907 let mut value: T = self.error_value();
908 let mut have_value: bool = false;
909
910 loop {
911 let i3_block: u32;
912 let mut i3: u32;
913 let i3_block_length: u32;
914 let data_block_length: u32;
915
916 if c <= 0xffff
929 && (self.header.trie_type == TrieType::Fast || c <= SMALL_TYPE_FAST_INDEXING_MAX)
930 {
931 i3_block = 0;
932 i3 = c >> FAST_TYPE_SHIFT;
933 i3_block_length = if self.header.trie_type == TrieType::Fast {
934 BMP_INDEX_LENGTH
935 } else {
936 SMALL_INDEX_LENGTH
937 };
938 data_block_length = FAST_TYPE_DATA_BLOCK_LENGTH;
939 } else {
940 let mut i1: u32 = c >> SHIFT_1;
942 if self.header.trie_type == TrieType::Fast {
943 if true {
if !(0xffff < c && c < self.header.high_start) {
::core::panicking::panic("assertion failed: 0xffff < c && c < self.header.high_start")
};
};debug_assert!(0xffff < c && c < self.header.high_start);
944 i1 = i1 + BMP_INDEX_LENGTH - OMITTED_BMP_INDEX_1_LENGTH;
945 } else {
946 if true {
if !(c < self.header.high_start && self.header.high_start > SMALL_LIMIT) {
::core::panicking::panic("assertion failed: c < self.header.high_start && self.header.high_start > SMALL_LIMIT")
};
};debug_assert!(
947 c < self.header.high_start && self.header.high_start > SMALL_LIMIT
948 );
949 i1 += SMALL_INDEX_LENGTH;
950 }
951 let i2: u16 = self.index.get(i1 as usize)?;
952 let i3_block_idx: u32 = (i2 as u32) + ((c >> SHIFT_2) & INDEX_2_MASK);
953 i3_block = if let Some(i3b) = self.index.get(i3_block_idx as usize) {
954 i3b as u32
955 } else {
956 return None;
957 };
958 if i3_block == prev_i3_block && (c - start) >= CP_PER_INDEX_2_ENTRY {
959 if true {
if !((c & (CP_PER_INDEX_2_ENTRY - 1)) == 0) {
::core::panicking::panic("assertion failed: (c & (CP_PER_INDEX_2_ENTRY - 1)) == 0")
};
};debug_assert!((c & (CP_PER_INDEX_2_ENTRY - 1)) == 0);
961 c += CP_PER_INDEX_2_ENTRY;
962
963 if c >= self.header.high_start {
964 break;
965 } else {
966 continue;
967 }
968 }
969 prev_i3_block = i3_block;
970 if i3_block == self.header.index3_null_offset as u32 {
971 if have_value {
978 if null_value != value {
979 return Some(CodePointMapRange {
980 range: start..=(c - 1),
981 value,
982 });
983 }
984 } else {
985 trie_value = T::try_from_u32(self.header.null_value).ok()?;
986 value = null_value;
987 have_value = true;
988 }
989 prev_block = self.header.data_null_offset;
990 c = (c + CP_PER_INDEX_2_ENTRY) & !(CP_PER_INDEX_2_ENTRY - 1);
991
992 if c >= self.header.high_start {
993 break;
994 } else {
995 continue;
996 }
997 }
998 i3 = (c >> SHIFT_3) & INDEX_3_MASK;
999 i3_block_length = INDEX_3_BLOCK_LENGTH;
1000 data_block_length = SMALL_DATA_BLOCK_LENGTH;
1001 }
1002
1003 loop {
1005 let mut block: u32;
1006 if (i3_block & 0x8000) == 0 {
1007 block = if let Some(b) = self.index.get((i3_block + i3) as usize) {
1008 b as u32
1009 } else {
1010 return None;
1011 };
1012 } else {
1013 let mut group: u32 = (i3_block & 0x7fff) + (i3 & !7) + (i3 >> 3);
1015 let gi: u32 = i3 & 7;
1016 let gi_val: u32 = if let Some(giv) = self.index.get(group as usize) {
1017 giv.into()
1018 } else {
1019 return None;
1020 };
1021 block = (gi_val << (2 + (2 * gi))) & 0x30000;
1022 group += 1;
1023 let ggi_val: u32 = if let Some(ggiv) = self.index.get((group + gi) as usize) {
1024 ggiv as u32
1025 } else {
1026 return None;
1027 };
1028 block |= ggi_val;
1029 }
1030
1031 if block == prev_block && (c - start) >= data_block_length {
1039 if true {
if !((c & (data_block_length - 1)) == 0) {
::core::panicking::panic("assertion failed: (c & (data_block_length - 1)) == 0")
};
};debug_assert!((c & (data_block_length - 1)) == 0);
1041 c += data_block_length;
1042 } else {
1043 let data_mask: u32 = data_block_length - 1;
1044 prev_block = block;
1045 if block == self.header.data_null_offset {
1046 if have_value {
1051 if null_value != value {
1052 return Some(CodePointMapRange {
1053 range: start..=(c - 1),
1054 value,
1055 });
1056 }
1057 } else {
1058 trie_value = T::try_from_u32(self.header.null_value).ok()?;
1059 value = null_value;
1060 have_value = true;
1061 }
1062 c = (c + data_block_length) & !data_mask;
1063 } else {
1064 let mut di: u32 = block + (c & data_mask);
1065 let mut trie_value_2: T = self.data.get(di as usize)?;
1066 if have_value {
1067 if trie_value_2 != trie_value {
1068 if maybe_filter_value(
1069 trie_value_2,
1070 T::try_from_u32(self.header.null_value).ok()?,
1071 null_value,
1072 ) != value
1073 {
1074 return Some(CodePointMapRange {
1075 range: start..=(c - 1),
1076 value,
1077 });
1078 }
1079 trie_value = trie_value_2; }
1098 } else {
1099 trie_value = trie_value_2;
1100 value = maybe_filter_value(
1101 trie_value_2,
1102 T::try_from_u32(self.header.null_value).ok()?,
1103 null_value,
1104 );
1105 have_value = true;
1106 }
1107
1108 c += 1;
1109 while (c & data_mask) != 0 {
1110 di += 1;
1111 trie_value_2 = self.data.get(di as usize)?;
1112 if trie_value_2 != trie_value {
1113 if maybe_filter_value(
1114 trie_value_2,
1115 T::try_from_u32(self.header.null_value).ok()?,
1116 null_value,
1117 ) != value
1118 {
1119 return Some(CodePointMapRange {
1120 range: start..=(c - 1),
1121 value,
1122 });
1123 }
1124 trie_value = trie_value_2; }
1143
1144 c += 1;
1145 }
1146 }
1147 }
1148
1149 i3 += 1;
1150 if i3 >= i3_block_length {
1151 break;
1152 }
1153 }
1154
1155 if c >= self.header.high_start {
1156 break;
1157 }
1158 }
1159
1160 if true {
if !have_value {
::core::panicking::panic("assertion failed: have_value")
};
};debug_assert!(have_value);
1161
1162 let di: u32 = self.data.len() as u32 - HIGH_VALUE_NEG_DATA_OFFSET;
1167 let high_value: T = self.data.get(di as usize)?;
1168 if maybe_filter_value(
1169 high_value,
1170 T::try_from_u32(self.header.null_value).ok()?,
1171 null_value,
1172 ) != value
1173 {
1174 c -= 1;
1175 } else {
1176 c = CODE_POINT_MAX;
1177 }
1178 Some(CodePointMapRange {
1179 range: start..=c,
1180 value,
1181 })
1182 }
1183
1184 pub fn iter_ranges(&self) -> CodePointMapRangeIterator<'_, T> {
1217 let init_range = Some(CodePointMapRange {
1218 range: u32::MAX..=u32::MAX,
1219 value: self.error_value(),
1220 });
1221 CodePointMapRangeIterator::<T> {
1222 cpt: self,
1223 cpm_range: init_range,
1224 }
1225 }
1226
1227 pub fn iter_ranges_for_value(
1249 &self,
1250 value: T,
1251 ) -> impl Iterator<Item = RangeInclusive<u32>> + '_ {
1252 self.iter_ranges()
1253 .filter(move |cpm_range| cpm_range.value == value)
1254 .map(|cpm_range| cpm_range.range)
1255 }
1256
1257 pub fn iter_ranges_mapped<'a, U: Eq + 'a>(
1279 &'a self,
1280 mut map: impl FnMut(T) -> U + Copy + 'a,
1281 ) -> impl Iterator<Item = CodePointMapRange<U>> + 'a {
1282 crate::iterator_utils::RangeListIteratorCoalescer::new(self.iter_ranges().map(
1283 move |range| CodePointMapRange {
1284 range: range.range,
1285 value: map(range.value),
1286 },
1287 ))
1288 }
1289
1290 #[cfg(feature = "alloc")]
1314 pub fn get_set_for_value(&self, value: T) -> CodePointInversionList<'static> {
1315 let value_ranges = self.iter_ranges_for_value(value);
1316 CodePointInversionList::from_iter(value_ranges)
1317 }
1318
1319 #[inline]
1321 pub fn error_value(&self) -> T {
1322 self.error_value
1323 }
1324}
1325
1326#[cfg(feature = "databake")]
1327impl<T: TrieValue + databake::Bake> databake::Bake for CodePointTrie<'_, T> {
1328 fn bake(&self, env: &databake::CrateEnv) -> databake::TokenStream {
1329 let header = self.header.bake(env);
1330 let index = self.index.bake(env);
1331 let data = self.data.bake(env);
1332 let error_value = self.error_value.bake(env);
1333 databake::quote! { unsafe { icu_collections::codepointtrie::CodePointTrie::from_parts_unstable_unchecked_v1(#header, #index, #data, #error_value) } }
1334 }
1335}
1336
1337#[cfg(feature = "databake")]
1338impl<T: TrieValue + databake::Bake> databake::BakeSize for CodePointTrie<'_, T> {
1339 fn borrows_size(&self) -> usize {
1340 self.header.borrows_size() + self.index.borrows_size() + self.data.borrows_size()
1341 }
1342}
1343
1344impl<T: TrieValue + Into<u32>> CodePointTrie<'_, T> {
1345 pub fn get32_u32(&self, code_point: u32) -> u32 {
1363 self.get32(code_point).into()
1364 }
1365}
1366
1367impl<T: TrieValue> Clone for CodePointTrie<'_, T>
1368where
1369 <T as AsULE>::ULE: Clone,
1370{
1371 fn clone(&self) -> Self {
1372 CodePointTrie {
1373 header: self.header,
1374 index: self.index.clone(),
1375 data: self.data.clone(),
1376 error_value: self.error_value,
1377 }
1378 }
1379}
1380
1381#[derive(#[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<T: ::core::cmp::PartialEq> ::core::cmp::PartialEq for
CodePointMapRange<T> {
#[inline]
fn eq(&self, other: &CodePointMapRange<T>) -> bool {
self.range == other.range && self.value == other.value
}
}PartialEq, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<T: ::core::cmp::Eq> ::core::cmp::Eq for CodePointMapRange<T> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<RangeInclusive<u32>>;
let _: ::core::cmp::AssertParamIsEq<T>;
}
}Eq, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<T: ::core::fmt::Debug> ::core::fmt::Debug for CodePointMapRange<T> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"CodePointMapRange", "range", &self.range, "value", &&self.value)
}
}Debug, #[automatically_derived]
#[allow(clippy::exhaustive_structs)]
impl<T: ::core::clone::Clone> ::core::clone::Clone for CodePointMapRange<T> {
#[inline]
fn clone(&self) -> CodePointMapRange<T> {
CodePointMapRange {
range: ::core::clone::Clone::clone(&self.range),
value: ::core::clone::Clone::clone(&self.value),
}
}
}Clone)]
1387#[allow(clippy::exhaustive_structs)] pub struct CodePointMapRange<T> {
1389 pub range: RangeInclusive<u32>,
1391 pub value: T,
1393}
1394
1395#[derive(#[automatically_derived]
impl<'a, T: ::core::fmt::Debug + TrieValue> ::core::fmt::Debug for
CodePointMapRangeIterator<'a, T> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"CodePointMapRangeIterator", "cpt", &self.cpt, "cpm_range",
&&self.cpm_range)
}
}Debug)]
1398pub struct CodePointMapRangeIterator<'a, T: TrieValue> {
1399 cpt: &'a CodePointTrie<'a, T>,
1400 cpm_range: Option<CodePointMapRange<T>>,
1407}
1408
1409impl<T: TrieValue> Iterator for CodePointMapRangeIterator<'_, T> {
1410 type Item = CodePointMapRange<T>;
1411
1412 fn next(&mut self) -> Option<Self::Item> {
1413 self.cpm_range = match &self.cpm_range {
1414 Some(cpmr) => {
1415 if *cpmr.range.start() == u32::MAX {
1416 self.cpt.get_range(0)
1417 } else {
1418 self.cpt.get_range(cpmr.range.end() + 1)
1419 }
1420 }
1421 None => None,
1422 };
1423 self.cpm_range.clone()
1425 }
1426}
1427
1428trait Seal {}
1434
1435#[allow(private_bounds)] pub trait TypedCodePointTrie<'trie, T: TrieValue>: Seal {
1439 const TRIE_TYPE: TrieType;
1445
1446 #[inline(always)]
1448 fn get32_u32(&self, code_point: u32) -> u32 {
1449 self.get32(code_point).to_u32()
1450 }
1451
1452 #[inline(always)]
1454 fn get16(&self, bmp: u16) -> T {
1455 let code_point = u32::from(bmp);
1459 if let Some(v) = self.get32_by_fast_index(code_point) {
1460 v
1461 } else {
1462 self.as_untyped_ref().get32_by_small_index_cold(code_point)
1463 }
1464 }
1465
1466 #[inline(always)]
1468 fn get32_supplementary(&self, supplementary: u32) -> T {
1469 self.as_untyped_ref().get32_supplementary(supplementary)
1470 }
1471
1472 #[inline(always)]
1474 fn get(&self, c: char) -> T {
1475 let code_point = u32::from(c);
1479 if let Some(v) = self.get32_by_fast_index(code_point) {
1480 v
1481 } else {
1482 self.as_untyped_ref().get32_by_small_index_cold(code_point)
1483 }
1484 }
1485
1486 #[inline(always)]
1488 fn get32(&self, code_point: u32) -> T {
1489 if let Some(v) = self.get32_by_fast_index(code_point) {
1490 v
1491 } else if code_point <= CODE_POINT_MAX {
1492 self.as_untyped_ref().get32_by_small_index_cold(code_point)
1493 } else {
1494 self.as_untyped_ref().error_value
1495 }
1496 }
1497
1498 #[inline(always)] fn get32_by_fast_index(&self, code_point: u32) -> Option<T> {
1503 if true {
match (&Self::TRIE_TYPE, &self.as_untyped_ref().header.trie_type) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
};
};debug_assert_eq!(Self::TRIE_TYPE, self.as_untyped_ref().header.trie_type);
1504 let fast_max = match Self::TRIE_TYPE {
1505 TrieType::Fast => FAST_TYPE_FAST_INDEXING_MAX,
1506 TrieType::Small => SMALL_TYPE_FAST_INDEXING_MAX,
1507 };
1508 if code_point <= fast_max {
1509 Some(unsafe { self.as_untyped_ref().get32_assuming_fast_index(code_point) })
1520 } else {
1521 None
1524 }
1525 }
1526
1527 fn as_untyped_ref(&self) -> &CodePointTrie<'trie, T>;
1529
1530 fn to_untyped(self) -> CodePointTrie<'trie, T>;
1532}
1533
1534#[derive(#[automatically_derived]
impl<'trie, T: ::core::fmt::Debug + TrieValue> ::core::fmt::Debug for
FastCodePointTrie<'trie, T> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"FastCodePointTrie", "inner", &&self.inner)
}
}Debug)]
1539#[repr(transparent)]
1540pub struct FastCodePointTrie<'trie, T: TrieValue> {
1541 inner: CodePointTrie<'trie, T>,
1542}
1543
1544impl<'trie, T: TrieValue> TypedCodePointTrie<'trie, T> for FastCodePointTrie<'trie, T> {
1545 const TRIE_TYPE: TrieType = TrieType::Fast;
1546
1547 #[inline(always)]
1549 fn as_untyped_ref(&self) -> &CodePointTrie<'trie, T> {
1550 &self.inner
1551 }
1552
1553 #[inline(always)]
1555 fn to_untyped(self) -> CodePointTrie<'trie, T> {
1556 self.inner
1557 }
1558
1559 #[inline(always)]
1561 fn get16(&self, bmp: u16) -> T {
1562 if true {
if !(u32::from(u16::MAX) <= FAST_TYPE_FAST_INDEXING_MAX) {
::core::panicking::panic("assertion failed: u32::from(u16::MAX) <= FAST_TYPE_FAST_INDEXING_MAX")
};
};debug_assert!(u32::from(u16::MAX) <= FAST_TYPE_FAST_INDEXING_MAX);
1563 if true {
match (&Self::TRIE_TYPE, &TrieType::Fast) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
};
};debug_assert_eq!(Self::TRIE_TYPE, TrieType::Fast);
1564 if true {
match (&self.as_untyped_ref().header.trie_type, &TrieType::Fast) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
};
};debug_assert_eq!(self.as_untyped_ref().header.trie_type, TrieType::Fast);
1565 let code_point = u32::from(bmp);
1566 unsafe { self.as_untyped_ref().get32_assuming_fast_index(code_point) }
1575 }
1576}
1577
1578impl<'trie, T: TrieValue> Seal for FastCodePointTrie<'trie, T> {}
1579
1580impl<'trie, T: TrieValue> TryFrom<&'trie CodePointTrie<'trie, T>>
1581 for &'trie FastCodePointTrie<'trie, T>
1582{
1583 type Error = TypedCodePointTrieError;
1584
1585 fn try_from(
1586 reference: &'trie CodePointTrie<'trie, T>,
1587 ) -> Result<&'trie FastCodePointTrie<'trie, T>, TypedCodePointTrieError> {
1588 match reference.as_typed_ref() {
1589 Typed::Fast(trie) => Ok(trie),
1590 Typed::Small(_) => Err(TypedCodePointTrieError),
1591 }
1592 }
1593}
1594
1595impl<'trie, T: TrieValue> TryFrom<CodePointTrie<'trie, T>> for FastCodePointTrie<'trie, T> {
1596 type Error = TypedCodePointTrieError;
1597
1598 fn try_from(
1599 value: CodePointTrie<'trie, T>,
1600 ) -> Result<FastCodePointTrie<'trie, T>, TypedCodePointTrieError> {
1601 match value.to_typed() {
1602 Typed::Fast(trie) => Ok(trie),
1603 Typed::Small(_) => Err(TypedCodePointTrieError),
1604 }
1605 }
1606}
1607
1608#[derive(#[automatically_derived]
impl<'trie, T: ::core::fmt::Debug + TrieValue> ::core::fmt::Debug for
SmallCodePointTrie<'trie, T> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"SmallCodePointTrie", "inner", &&self.inner)
}
}Debug)]
1611#[repr(transparent)]
1612pub struct SmallCodePointTrie<'trie, T: TrieValue> {
1613 inner: CodePointTrie<'trie, T>,
1614}
1615
1616impl<'trie, T: TrieValue> TypedCodePointTrie<'trie, T> for SmallCodePointTrie<'trie, T> {
1617 const TRIE_TYPE: TrieType = TrieType::Small;
1618
1619 #[inline(always)]
1621 fn as_untyped_ref(&self) -> &CodePointTrie<'trie, T> {
1622 &self.inner
1623 }
1624
1625 #[inline(always)]
1627 fn to_untyped(self) -> CodePointTrie<'trie, T> {
1628 self.inner
1629 }
1630}
1631
1632impl<'trie, T: TrieValue> Seal for SmallCodePointTrie<'trie, T> {}
1633
1634impl<'trie, T: TrieValue> TryFrom<&'trie CodePointTrie<'trie, T>>
1635 for &'trie SmallCodePointTrie<'trie, T>
1636{
1637 type Error = TypedCodePointTrieError;
1638
1639 fn try_from(
1640 reference: &'trie CodePointTrie<'trie, T>,
1641 ) -> Result<&'trie SmallCodePointTrie<'trie, T>, TypedCodePointTrieError> {
1642 match reference.as_typed_ref() {
1643 Typed::Fast(_) => Err(TypedCodePointTrieError),
1644 Typed::Small(trie) => Ok(trie),
1645 }
1646 }
1647}
1648
1649impl<'trie, T: TrieValue> TryFrom<CodePointTrie<'trie, T>> for SmallCodePointTrie<'trie, T> {
1650 type Error = TypedCodePointTrieError;
1651
1652 fn try_from(
1653 value: CodePointTrie<'trie, T>,
1654 ) -> Result<SmallCodePointTrie<'trie, T>, TypedCodePointTrieError> {
1655 match value.to_typed() {
1656 Typed::Fast(_) => Err(TypedCodePointTrieError),
1657 Typed::Small(trie) => Ok(trie),
1658 }
1659 }
1660}
1661
1662#[derive(#[automatically_derived]
impl ::core::fmt::Debug for TypedCodePointTrieError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "TypedCodePointTrieError")
}
}Debug)]
1665#[non_exhaustive]
1666pub struct TypedCodePointTrieError;
1667
1668#[allow(clippy::exhaustive_enums)]
1671#[derive(#[automatically_derived]
#[allow(clippy::exhaustive_enums)]
impl<F: ::core::fmt::Debug, S: ::core::fmt::Debug> ::core::fmt::Debug for
Typed<F, S> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Typed::Fast(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Fast",
&__self_0),
Typed::Small(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Small",
&__self_0),
}
}
}Debug)]
1672pub enum Typed<F, S> {
1673 Fast(F),
1675 Small(S),
1677}
1678
1679#[cfg(test)]
1680mod tests {
1681 use super::*;
1682 use crate::codepointtrie::planes;
1683 use alloc::vec::Vec;
1684
1685 #[test]
1686 #[cfg(feature = "serde")]
1687 fn test_serde_with_postcard_roundtrip() -> Result<(), postcard::Error> {
1688 let trie = planes::get_planes_trie();
1689 let trie_serialized: Vec<u8> = postcard::to_allocvec(&trie).unwrap();
1690
1691 const EXP_TRIE_SERIALIZED: &[u8] = &[
1693 128, 128, 64, 128, 2, 2, 0, 0, 1, 160, 18, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1694 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1695 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1696 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1697 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136,
1698 2, 144, 2, 144, 2, 144, 2, 176, 2, 176, 2, 176, 2, 176, 2, 208, 2, 208, 2, 208, 2, 208,
1699 2, 240, 2, 240, 2, 240, 2, 240, 2, 16, 3, 16, 3, 16, 3, 16, 3, 48, 3, 48, 3, 48, 3, 48,
1700 3, 80, 3, 80, 3, 80, 3, 80, 3, 112, 3, 112, 3, 112, 3, 112, 3, 144, 3, 144, 3, 144, 3,
1701 144, 3, 176, 3, 176, 3, 176, 3, 176, 3, 208, 3, 208, 3, 208, 3, 208, 3, 240, 3, 240, 3,
1702 240, 3, 240, 3, 16, 4, 16, 4, 16, 4, 16, 4, 48, 4, 48, 4, 48, 4, 48, 4, 80, 4, 80, 4,
1703 80, 4, 80, 4, 112, 4, 112, 4, 112, 4, 112, 4, 0, 0, 16, 0, 32, 0, 48, 0, 64, 0, 80, 0,
1704 96, 0, 112, 0, 0, 0, 16, 0, 32, 0, 48, 0, 0, 0, 16, 0, 32, 0, 48, 0, 0, 0, 16, 0, 32,
1705 0, 48, 0, 0, 0, 16, 0, 32, 0, 48, 0, 0, 0, 16, 0, 32, 0, 48, 0, 0, 0, 16, 0, 32, 0, 48,
1706 0, 0, 0, 16, 0, 32, 0, 48, 0, 0, 0, 16, 0, 32, 0, 48, 0, 128, 0, 128, 0, 128, 0, 128,
1707 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128,
1708 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128,
1709 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 144, 0, 144, 0, 144, 0, 144, 0, 144,
1710 0, 144, 0, 144, 0, 144, 0, 144, 0, 144, 0, 144, 0, 144, 0, 144, 0, 144, 0, 144, 0, 144,
1711 0, 144, 0, 144, 0, 144, 0, 144, 0, 144, 0, 144, 0, 144, 0, 144, 0, 144, 0, 144, 0, 144,
1712 0, 144, 0, 144, 0, 144, 0, 144, 0, 144, 0, 160, 0, 160, 0, 160, 0, 160, 0, 160, 0, 160,
1713 0, 160, 0, 160, 0, 160, 0, 160, 0, 160, 0, 160, 0, 160, 0, 160, 0, 160, 0, 160, 0, 160,
1714 0, 160, 0, 160, 0, 160, 0, 160, 0, 160, 0, 160, 0, 160, 0, 160, 0, 160, 0, 160, 0, 160,
1715 0, 160, 0, 160, 0, 160, 0, 160, 0, 176, 0, 176, 0, 176, 0, 176, 0, 176, 0, 176, 0, 176,
1716 0, 176, 0, 176, 0, 176, 0, 176, 0, 176, 0, 176, 0, 176, 0, 176, 0, 176, 0, 176, 0, 176,
1717 0, 176, 0, 176, 0, 176, 0, 176, 0, 176, 0, 176, 0, 176, 0, 176, 0, 176, 0, 176, 0, 176,
1718 0, 176, 0, 176, 0, 176, 0, 192, 0, 192, 0, 192, 0, 192, 0, 192, 0, 192, 0, 192, 0, 192,
1719 0, 192, 0, 192, 0, 192, 0, 192, 0, 192, 0, 192, 0, 192, 0, 192, 0, 192, 0, 192, 0, 192,
1720 0, 192, 0, 192, 0, 192, 0, 192, 0, 192, 0, 192, 0, 192, 0, 192, 0, 192, 0, 192, 0, 192,
1721 0, 192, 0, 192, 0, 208, 0, 208, 0, 208, 0, 208, 0, 208, 0, 208, 0, 208, 0, 208, 0, 208,
1722 0, 208, 0, 208, 0, 208, 0, 208, 0, 208, 0, 208, 0, 208, 0, 208, 0, 208, 0, 208, 0, 208,
1723 0, 208, 0, 208, 0, 208, 0, 208, 0, 208, 0, 208, 0, 208, 0, 208, 0, 208, 0, 208, 0, 208,
1724 0, 208, 0, 224, 0, 224, 0, 224, 0, 224, 0, 224, 0, 224, 0, 224, 0, 224, 0, 224, 0, 224,
1725 0, 224, 0, 224, 0, 224, 0, 224, 0, 224, 0, 224, 0, 224, 0, 224, 0, 224, 0, 224, 0, 224,
1726 0, 224, 0, 224, 0, 224, 0, 224, 0, 224, 0, 224, 0, 224, 0, 224, 0, 224, 0, 224, 0, 224,
1727 0, 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 240,
1728 0, 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 240,
1729 0, 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 240, 0, 0,
1730 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1731 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1732 1, 0, 1, 0, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1,
1733 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16,
1734 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 32, 1, 32, 1, 32, 1,
1735 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32,
1736 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1,
1737 32, 1, 32, 1, 32, 1, 32, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48,
1738 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1,
1739 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 64, 1, 64,
1740 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1,
1741 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64,
1742 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1,
1743 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80,
1744 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1,
1745 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96,
1746 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1,
1747 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 128, 0, 136, 0, 136, 0, 136, 0, 136,
1748 0, 136, 0, 136, 0, 136, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0,
1749 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2,
1750 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 168, 0, 168, 0, 168, 0, 168, 0, 168, 0,
1751 168, 0, 168, 0, 168, 0, 168, 0, 168, 0, 168, 0, 168, 0, 168, 0, 168, 0, 168, 0, 168, 0,
1752 168, 0, 168, 0, 168, 0, 168, 0, 168, 0, 168, 0, 168, 0, 168, 0, 168, 0, 168, 0, 168, 0,
1753 168, 0, 168, 0, 168, 0, 168, 0, 168, 0, 200, 0, 200, 0, 200, 0, 200, 0, 200, 0, 200, 0,
1754 200, 0, 200, 0, 200, 0, 200, 0, 200, 0, 200, 0, 200, 0, 200, 0, 200, 0, 200, 0, 200, 0,
1755 200, 0, 200, 0, 200, 0, 200, 0, 200, 0, 200, 0, 200, 0, 200, 0, 200, 0, 200, 0, 200, 0,
1756 200, 0, 200, 0, 200, 0, 200, 0, 232, 0, 232, 0, 232, 0, 232, 0, 232, 0, 232, 0, 232, 0,
1757 232, 0, 232, 0, 232, 0, 232, 0, 232, 0, 232, 0, 232, 0, 232, 0, 232, 0, 232, 0, 232, 0,
1758 232, 0, 232, 0, 232, 0, 232, 0, 232, 0, 232, 0, 232, 0, 232, 0, 232, 0, 232, 0, 232, 0,
1759 232, 0, 232, 0, 232, 0, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8,
1760 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1,
1761 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40,
1762 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1,
1763 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40,
1764 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1,
1765 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72,
1766 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 104, 1, 104, 1, 104, 1, 104, 1,
1767 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1,
1768 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1,
1769 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 136, 1, 136, 1, 136, 1, 136, 1, 136, 1,
1770 136, 1, 136, 1, 136, 1, 136, 1, 136, 1, 136, 1, 136, 1, 136, 1, 136, 1, 136, 1, 136, 1,
1771 136, 1, 136, 1, 136, 1, 136, 1, 136, 1, 136, 1, 136, 1, 136, 1, 136, 1, 136, 1, 136, 1,
1772 136, 1, 136, 1, 136, 1, 136, 1, 136, 1, 168, 1, 168, 1, 168, 1, 168, 1, 168, 1, 168, 1,
1773 168, 1, 168, 1, 168, 1, 168, 1, 168, 1, 168, 1, 168, 1, 168, 1, 168, 1, 168, 1, 168, 1,
1774 168, 1, 168, 1, 168, 1, 168, 1, 168, 1, 168, 1, 168, 1, 168, 1, 168, 1, 168, 1, 168, 1,
1775 168, 1, 168, 1, 168, 1, 168, 1, 200, 1, 200, 1, 200, 1, 200, 1, 200, 1, 200, 1, 200, 1,
1776 200, 1, 200, 1, 200, 1, 200, 1, 200, 1, 200, 1, 200, 1, 200, 1, 200, 1, 200, 1, 200, 1,
1777 200, 1, 200, 1, 200, 1, 200, 1, 200, 1, 200, 1, 200, 1, 200, 1, 200, 1, 200, 1, 200, 1,
1778 200, 1, 200, 1, 200, 1, 232, 1, 232, 1, 232, 1, 232, 1, 232, 1, 232, 1, 232, 1, 232, 1,
1779 232, 1, 232, 1, 232, 1, 232, 1, 232, 1, 232, 1, 232, 1, 232, 1, 232, 1, 232, 1, 232, 1,
1780 232, 1, 232, 1, 232, 1, 232, 1, 232, 1, 232, 1, 232, 1, 232, 1, 232, 1, 232, 1, 232, 1,
1781 232, 1, 232, 1, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2,
1782 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 8,
1783 2, 8, 2, 8, 2, 8, 2, 8, 2, 8, 2, 40, 2, 40, 2, 40, 2, 40, 2, 40, 2, 40, 2, 40, 2, 40,
1784 2, 40, 2, 40, 2, 40, 2, 40, 2, 40, 2, 40, 2, 40, 2, 40, 2, 40, 2, 40, 2, 40, 2, 40, 2,
1785 40, 2, 40, 2, 40, 2, 40, 2, 40, 2, 40, 2, 40, 2, 40, 2, 40, 2, 40, 2, 40, 2, 40, 2, 72,
1786 2, 72, 2, 72, 2, 72, 2, 72, 2, 72, 2, 72, 2, 72, 2, 72, 2, 72, 2, 72, 2, 72, 2, 72, 2,
1787 72, 2, 72, 2, 72, 2, 72, 2, 72, 2, 72, 2, 72, 2, 72, 2, 72, 2, 72, 2, 72, 2, 72, 2, 72,
1788 2, 72, 2, 72, 2, 72, 2, 72, 2, 72, 2, 72, 2, 104, 2, 104, 2, 104, 2, 104, 2, 104, 2,
1789 104, 2, 104, 2, 104, 2, 104, 2, 104, 2, 104, 2, 104, 2, 104, 2, 104, 2, 104, 2, 104, 2,
1790 104, 2, 104, 2, 104, 2, 104, 2, 104, 2, 104, 2, 104, 2, 104, 2, 104, 2, 104, 2, 104, 2,
1791 104, 2, 104, 2, 104, 2, 104, 2, 104, 2, 244, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1792 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1793 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1794 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1795 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1796 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1797 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
1798 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6,
1799 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
1800 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10,
1801 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11,
1802 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
1803 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14,
1804 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15,
1805 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 0,
1806 ];
1807 assert_eq!(trie_serialized, EXP_TRIE_SERIALIZED);
1808
1809 let trie_deserialized = postcard::from_bytes::<CodePointTrie<u8>>(&trie_serialized)?;
1810
1811 assert_eq!(&trie.index, &trie_deserialized.index);
1812 assert_eq!(&trie.data, &trie_deserialized.data);
1813
1814 assert!(!trie_deserialized.index.is_owned());
1815 assert!(!trie_deserialized.data.is_owned());
1816
1817 Ok(())
1818 }
1819
1820 #[test]
1821 fn test_typed() {
1822 let untyped = planes::get_planes_trie();
1823 assert_eq!(untyped.get('\u{10000}'), 1);
1824 let small_ref = <&SmallCodePointTrie<_>>::try_from(&untyped).unwrap();
1825 assert_eq!(small_ref.get('\u{10000}'), 1);
1826 let _ = <&FastCodePointTrie<_>>::try_from(&untyped).is_err();
1827 let small = <SmallCodePointTrie<_>>::try_from(untyped).unwrap();
1828 assert_eq!(small.get('\u{10000}'), 1);
1829 }
1830
1831 #[test]
1832 fn test_get_range() {
1833 let planes_trie = planes::get_planes_trie();
1834
1835 let first_range: Option<CodePointMapRange<u8>> = planes_trie.get_range(0x0);
1836 assert_eq!(
1837 first_range,
1838 Some(CodePointMapRange {
1839 range: 0x0..=0xffff,
1840 value: 0
1841 })
1842 );
1843
1844 let second_range: Option<CodePointMapRange<u8>> = planes_trie.get_range(0x1_0000);
1845 assert_eq!(
1846 second_range,
1847 Some(CodePointMapRange {
1848 range: 0x10000..=0x1ffff,
1849 value: 1
1850 })
1851 );
1852
1853 let penultimate_range: Option<CodePointMapRange<u8>> = planes_trie.get_range(0xf_0000);
1854 assert_eq!(
1855 penultimate_range,
1856 Some(CodePointMapRange {
1857 range: 0xf_0000..=0xf_ffff,
1858 value: 15
1859 })
1860 );
1861
1862 let last_range: Option<CodePointMapRange<u8>> = planes_trie.get_range(0x10_0000);
1863 assert_eq!(
1864 last_range,
1865 Some(CodePointMapRange {
1866 range: 0x10_0000..=0x10_ffff,
1867 value: 16
1868 })
1869 );
1870 }
1871
1872 #[test]
1873 #[allow(unused_unsafe)] fn databake() {
1875 databake::test_bake!(
1876 CodePointTrie<'static, u32>,
1877 const,
1878 unsafe {
1879 crate::codepointtrie::CodePointTrie::from_parts_unstable_unchecked_v1(
1880 crate::codepointtrie::CodePointTrieHeader {
1881 high_start: 1u32,
1882 shifted12_high_start: 2u16,
1883 index3_null_offset: 3u16,
1884 data_null_offset: 4u32,
1885 null_value: 5u32,
1886 trie_type: crate::codepointtrie::TrieType::Small,
1887 },
1888 zerovec::ZeroVec::new(),
1889 zerovec::ZeroVec::new(),
1890 0u32,
1891 )
1892 },
1893 icu_collections,
1894 [zerovec],
1895 );
1896 }
1897}