Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ULE types Copy, add PairULE #1193

Merged
merged 7 commits into from
Oct 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions components/datetime/src/fields/ule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ impl AsULE for fields::Field {
type ULE = FieldULE;

#[inline]
fn as_unaligned(&self) -> Self::ULE {
fn as_unaligned(self) -> Self::ULE {
FieldULE([self.symbol.idx(), self.length.idx()])
}

#[inline]
fn from_unaligned(unaligned: &Self::ULE) -> Self {
fn from_unaligned(unaligned: Self::ULE) -> Self {
let value = unaligned.0;
let symbol = fields::FieldSymbol::from_idx(value[0]).unwrap();
let length = fields::FieldLength::from_idx(value[1]).unwrap();
Expand Down Expand Up @@ -119,7 +119,7 @@ mod test {
for (ref_field, ref_bytes) in samples {
let ule = ref_field.as_unaligned();
assert_eq!(ULE::as_byte_slice(&[ule]), *ref_bytes);
let field = Field::from_unaligned(&ule);
let field = Field::from_unaligned(ule);
assert_eq!(field, *ref_field);
}
}
Expand Down
18 changes: 9 additions & 9 deletions components/datetime/src/pattern/item/ule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,21 +107,21 @@ impl AsULE for PatternItem {
type ULE = PatternItemULE;

#[inline]
fn as_unaligned(&self) -> Self::ULE {
fn as_unaligned(self) -> Self::ULE {
match self {
Self::Field(field) => {
PatternItemULE([0b1000_0000, field.symbol.idx(), field.length.idx()])
}
Self::Literal(ch) => {
let u = *ch as u32;
let u = ch as u32;
let bytes = u.to_be_bytes();
PatternItemULE([bytes[1], bytes[2], bytes[3]])
}
}
}

#[inline]
fn from_unaligned(unaligned: &Self::ULE) -> Self {
fn from_unaligned(unaligned: Self::ULE) -> Self {
let value = unaligned.0;
match PatternItemULE::determine_field_from_u8(value[0]) {
false => {
Expand Down Expand Up @@ -238,19 +238,19 @@ impl AsULE for GenericPatternItem {
type ULE = GenericPatternItemULE;

#[inline]
fn as_unaligned(&self) -> Self::ULE {
fn as_unaligned(self) -> Self::ULE {
match self {
Self::Placeholder(idx) => GenericPatternItemULE([0b1000_0000, 0x00, *idx]),
Self::Placeholder(idx) => GenericPatternItemULE([0b1000_0000, 0x00, idx]),
Self::Literal(ch) => {
let u = *ch as u32;
let u = ch as u32;
let bytes = u.to_be_bytes();
GenericPatternItemULE([bytes[1], bytes[2], bytes[3]])
}
}
}

#[inline]
fn from_unaligned(unaligned: &Self::ULE) -> Self {
fn from_unaligned(unaligned: Self::ULE) -> Self {
let value = unaligned.0;
match GenericPatternItemULE::determine_field_from_u8(value[0]) {
false => {
Expand Down Expand Up @@ -305,7 +305,7 @@ mod test {
for (ref_pattern, ref_bytes) in samples {
let ule = ref_pattern.as_unaligned();
assert_eq!(ULE::as_byte_slice(&[ule]), *ref_bytes);
let pattern = PatternItem::from_unaligned(&ule);
let pattern = PatternItem::from_unaligned(ule);
assert_eq!(pattern, *ref_pattern);
}
}
Expand Down Expand Up @@ -361,7 +361,7 @@ mod test {
for (ref_pattern, ref_bytes) in samples {
let ule = ref_pattern.as_unaligned();
assert_eq!(ULE::as_byte_slice(&[ule]), *ref_bytes);
let pattern = GenericPatternItem::from_unaligned(&ule);
let pattern = GenericPatternItem::from_unaligned(ule);
assert_eq!(pattern, *ref_pattern);
}
}
Expand Down
10 changes: 5 additions & 5 deletions components/properties/src/ule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ impl AsULE for GeneralSubcategory {
type ULE = GeneralSubcategoryULE;

#[inline]
fn as_unaligned(&self) -> Self::ULE {
let u = *self as u8;
fn as_unaligned(self) -> Self::ULE {
let u = self as u8;
GeneralSubcategoryULE(u)
}

#[inline]
fn from_unaligned(unaligned: &Self::ULE) -> Self {
fn from_unaligned(unaligned: Self::ULE) -> Self {
// Safe because the contents of GeneralSubcategoryULE are required to be valid.
unsafe { Self::from_unchecked(unaligned.0) }
}
Expand Down Expand Up @@ -50,12 +50,12 @@ impl AsULE for Script {
type ULE = PlainOldULE<2>;

#[inline]
fn as_unaligned(&self) -> Self::ULE {
fn as_unaligned(self) -> Self::ULE {
PlainOldULE(self.0.to_le_bytes())
}

#[inline]
fn from_unaligned(unaligned: &Self::ULE) -> Self {
fn from_unaligned(unaligned: Self::ULE) -> Self {
Script(u16::from_le_bytes(unaligned.0))
}
}
15 changes: 8 additions & 7 deletions utils/uniset/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ impl UnicodeSetBuilder {
.chunks(2)
.for_each(|pair| {
self.add(
AsULE::from_unaligned(&pair[0]),
AsULE::from_unaligned(&pair[1]),
AsULE::from_unaligned(pair[0]),
AsULE::from_unaligned(pair[1]),
)
});
}
Expand Down Expand Up @@ -246,8 +246,8 @@ impl UnicodeSetBuilder {
.chunks(2)
.for_each(|pair| {
self.remove(
AsULE::from_unaligned(&pair[0]),
AsULE::from_unaligned(&pair[1]),
AsULE::from_unaligned(pair[0]),
AsULE::from_unaligned(pair[1]),
)
});
}
Expand Down Expand Up @@ -311,8 +311,8 @@ impl UnicodeSetBuilder {
pub fn retain_set(&mut self, set: &UnicodeSet) {
let mut prev = 0;
for pair in set.as_inversion_list().as_slice().chunks(2) {
let range_start = AsULE::from_unaligned(&pair[0]);
let range_limit = AsULE::from_unaligned(&pair[1]);
let range_start = AsULE::from_unaligned(pair[0]);
let range_limit = AsULE::from_unaligned(pair[1]);
self.remove(prev, range_start);
prev = range_limit;
}
Expand Down Expand Up @@ -449,7 +449,8 @@ impl UnicodeSetBuilder {
.as_inversion_list()
.as_slice()
.iter()
.map(|cp| <u32 as AsULE>::from_unaligned(cp));
.copied()
.map(<u32 as AsULE>::from_unaligned);
self.complement_list(inv_list_iter_owned);
}

Expand Down
10 changes: 5 additions & 5 deletions utils/uniset/src/uniset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ impl<'data> UnicodeSet<'data> {
.as_slice()
.chunks(2)
.map(|end_points| {
<u32 as AsULE>::from_unaligned(&end_points[1])
- <u32 as AsULE>::from_unaligned(&end_points[0])
<u32 as AsULE>::from_unaligned(end_points[1])
- <u32 as AsULE>::from_unaligned(end_points[0])
})
.sum::<u32>() as usize;
Ok(Self { inv_list, size })
Expand Down Expand Up @@ -264,7 +264,7 @@ impl<'data> UnicodeSet<'data> {
self.inv_list
.as_slice()
.chunks(2)
.flat_map(|pair| (AsULE::from_unaligned(&pair[0])..AsULE::from_unaligned(&pair[1])))
.flat_map(|pair| (AsULE::from_unaligned(pair[0])..AsULE::from_unaligned(pair[1])))
.filter_map(char::from_u32)
}

Expand All @@ -288,8 +288,8 @@ impl<'data> UnicodeSet<'data> {
/// ```
pub fn iter_ranges(&self) -> impl ExactSizeIterator<Item = RangeInclusive<u32>> + '_ {
self.inv_list.as_slice().chunks(2).map(|pair| {
let range_start: u32 = AsULE::from_unaligned(&pair[0]);
let range_limit: u32 = AsULE::from_unaligned(&pair[1]);
let range_start: u32 = AsULE::from_unaligned(pair[0]);
let range_limit: u32 = AsULE::from_unaligned(pair[1]);
RangeInclusive::new(range_start, range_limit - 1)
})
}
Expand Down
5 changes: 2 additions & 3 deletions utils/uniset/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ pub fn is_valid_zv(inv_list_zv: &ZeroVec<'_, u32>) -> bool {
slice.is_empty()
|| (slice.len() % 2 == 0
&& slice.windows(2).all(|chunk| {
<u32 as AsULE>::from_unaligned(&chunk[0])
< <u32 as AsULE>::from_unaligned(&chunk[1])
<u32 as AsULE>::from_unaligned(chunk[0]) < <u32 as AsULE>::from_unaligned(chunk[1])
})
&& slice.last().map_or(false, |e| {
<u32 as AsULE>::from_unaligned(e) <= ((char::MAX as u32) + 1)
<u32 as AsULE>::from_unaligned(*e) <= ((char::MAX as u32) + 1)
}))
}

Expand Down
4 changes: 2 additions & 2 deletions utils/zerovec/src/map/kv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ macro_rules! impl_sized_kv {

#[inline]
fn cmp_get(&self, g: &Self::GetType) -> Ordering {
self.cmp(&$ty::from_unaligned(g))
self.cmp(&$ty::from_unaligned(*g))
}

#[inline]
fn with_ser<R>(g: &Self::GetType, f: impl FnOnce(&Self) -> R) -> R {
f(&Self::from_unaligned(g))
f(&Self::from_unaligned(*g))
}

#[inline]
Expand Down
6 changes: 3 additions & 3 deletions utils/zerovec/src/map/vecs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ where
self.to_mut().insert(index, value.as_unaligned())
}
fn remove(&mut self, index: usize) -> T {
T::from_unaligned(&self.to_mut().remove(index))
T::from_unaligned(self.to_mut().remove(index))
}
fn replace(&mut self, index: usize, value: &T) -> T {
let vec = self.to_mut();
T::from_unaligned(&mem::replace(&mut vec[index], value.as_unaligned()))
T::from_unaligned(mem::replace(&mut vec[index], value.as_unaligned()))
}
fn push(&mut self, value: &T) {
self.to_mut().push(value.as_unaligned())
Expand All @@ -96,7 +96,7 @@ where
fn is_ascending(&self) -> bool {
self.as_slice()
.windows(2)
.all(|w| T::from_unaligned(&w[1]).cmp(&T::from_unaligned(&w[0])) == Ordering::Greater)
.all(|w| T::from_unaligned(w[1]).cmp(&T::from_unaligned(w[0])) == Ordering::Greater)
}
}

Expand Down
34 changes: 25 additions & 9 deletions utils/zerovec/src/ule/chars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use core::convert::TryFrom;
/// let c1 = '𑄃';
/// let ule = c1.as_unaligned();
/// assert_eq!(CharULE::as_byte_slice(&[ule]), &[0x03, 0x11, 0x01, 0x00]);
/// let c2 = char::from_unaligned(&ule);
/// let c2 = char::from_unaligned(ule);
/// assert_eq!(c1, c2);
/// ```
///
Expand Down Expand Up @@ -66,13 +66,13 @@ impl AsULE for char {
type ULE = CharULE;

#[inline]
fn as_unaligned(&self) -> Self::ULE {
let u = u32::from(*self);
fn as_unaligned(self) -> Self::ULE {
let u = u32::from(self);
CharULE(u.to_le_bytes())
}

#[inline]
fn from_unaligned(unaligned: &Self::ULE) -> Self {
fn from_unaligned(unaligned: Self::ULE) -> Self {
let u = u32::from_le_bytes(unaligned.0);
// Safe because the bytes of CharULE are defined to represent a valid Unicode code point.
// TODO: Use char::from_u32_unchecked() when stabilized
Expand All @@ -92,13 +92,17 @@ mod test {
fn test_parse() {
// 1-byte, 2-byte, 3-byte, and 4-byte character in UTF-8 (not as relevant in UTF-32)
let chars = ['w', 'ω', '文', '𑄃'];
let char_ules: Vec<CharULE> = chars.iter().map(char::as_unaligned).collect();
let char_ules: Vec<CharULE> = chars.iter().copied().map(char::as_unaligned).collect();
let char_bytes: &[u8] = CharULE::as_byte_slice(&char_ules);

// Check parsing
let parsed_ules: &[CharULE] = CharULE::parse_byte_slice(char_bytes).unwrap();
assert_eq!(char_ules, parsed_ules);
let parsed_chars: Vec<char> = parsed_ules.iter().map(char::from_unaligned).collect();
let parsed_chars: Vec<char> = parsed_ules
.iter()
.copied()
.map(char::from_unaligned)
.collect();
assert_eq!(&chars, parsed_chars.as_slice());

// Check EqULE
Expand All @@ -110,7 +114,11 @@ mod test {

// Compare to u32
let u32s: Vec<u32> = chars.iter().copied().map(u32::from).collect();
let u32_ules: Vec<PlainOldULE<4>> = u32s.iter().map(<u32 as AsULE>::as_unaligned).collect();
let u32_ules: Vec<PlainOldULE<4>> = u32s
.iter()
.copied()
.map(<u32 as AsULE>::as_unaligned)
.collect();
let u32_bytes: &[u8] = PlainOldULE::<4>::as_byte_slice(&u32_ules);
assert_eq!(char_bytes, u32_bytes);

Expand All @@ -125,14 +133,22 @@ mod test {
fn test_failures() {
// 119 and 120 are valid, but not 0xD800 (high surrogate)
let u32s = [119, 0xD800, 120];
let u32_ules: Vec<PlainOldULE<4>> = u32s.iter().map(<u32 as AsULE>::as_unaligned).collect();
let u32_ules: Vec<PlainOldULE<4>> = u32s
.iter()
.copied()
.map(<u32 as AsULE>::as_unaligned)
.collect();
let u32_bytes: &[u8] = PlainOldULE::<4>::as_byte_slice(&u32_ules);
let parsed_ules_result = CharULE::parse_byte_slice(u32_bytes);
assert!(matches!(parsed_ules_result, Err(_)));

// 0x20FFFF is out of range for a char
let u32s = [0x20FFFF];
let u32_ules: Vec<PlainOldULE<4>> = u32s.iter().map(<u32 as AsULE>::as_unaligned).collect();
let u32_ules: Vec<PlainOldULE<4>> = u32s
.iter()
.copied()
.map(<u32 as AsULE>::as_unaligned)
.collect();
let u32_bytes: &[u8] = PlainOldULE::<4>::as_byte_slice(&u32_ules);
let parsed_ules_result = CharULE::parse_byte_slice(u32_bytes);
assert!(matches!(parsed_ules_result, Err(_)));
Expand Down
8 changes: 4 additions & 4 deletions utils/zerovec/src/ule/custom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,12 @@
//!
//! let vzv = VarZeroVec::from(&*foos);
//!
//! assert_eq!(char::from_unaligned(&vzv.get(0).unwrap().field1), 'u');
//! assert_eq!(u32::from_unaligned(&vzv.get(0).unwrap().field2), 983);
//! assert_eq!(char::from_unaligned(vzv.get(0).unwrap().field1), 'u');
//! assert_eq!(u32::from_unaligned(vzv.get(0).unwrap().field2), 983);
//! assert_eq!(&vzv.get(0).unwrap().field3, ZeroVec::clone_from_slice(&[1212,2309,500,7000]).as_slice());
//!
//! assert_eq!(char::from_unaligned(&vzv.get(1).unwrap().field1), 'l');
//! assert_eq!(u32::from_unaligned(&vzv.get(1).unwrap().field2), 1010);
//! assert_eq!(char::from_unaligned(vzv.get(1).unwrap().field1), 'l');
//! assert_eq!(u32::from_unaligned(vzv.get(1).unwrap().field2), 1010);
//! assert_eq!(&vzv.get(1).unwrap().field3, ZeroVec::clone_from_slice(&[1932, 0, 8888, 91237]).as_slice());
//! }
//! ```
Expand Down
Loading