summaryrefslogtreecommitdiffstats
path: root/vendor/icu_locid/src/helpers.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /vendor/icu_locid/src/helpers.rs
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/icu_locid/src/helpers.rs')
-rw-r--r--vendor/icu_locid/src/helpers.rs131
1 files changed, 69 insertions, 62 deletions
diff --git a/vendor/icu_locid/src/helpers.rs b/vendor/icu_locid/src/helpers.rs
index e5889a7b0..42b2b7286 100644
--- a/vendor/icu_locid/src/helpers.rs
+++ b/vendor/icu_locid/src/helpers.rs
@@ -4,36 +4,40 @@
use core::iter::FromIterator;
+use alloc::boxed::Box;
use alloc::vec;
use alloc::vec::Vec;
use litemap::store::*;
/// Internal: A vector that supports no-allocation, constant values if length 0 or 1.
+/// Using ZeroOne(Option<T>) saves 8 bytes in ShortSlice via niche optimization.
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
-pub(crate) enum ShortVec<T> {
- Empty,
- Single(T),
- Multi(Vec<T>),
+pub(crate) enum ShortSlice<T> {
+ ZeroOne(Option<T>),
+ Multi(Box<[T]>),
}
-impl<T> ShortVec<T> {
+impl<T> ShortSlice<T> {
#[inline]
pub const fn new() -> Self {
- Self::Empty
+ Self::ZeroOne(None)
}
#[inline]
pub const fn new_single(item: T) -> Self {
- Self::Single(item)
+ Self::ZeroOne(Some(item))
}
pub fn push(&mut self, item: T) {
- *self = match core::mem::replace(self, Self::Empty) {
- ShortVec::Empty => ShortVec::Single(item),
- ShortVec::Single(prev_item) => ShortVec::Multi(vec![prev_item, item]),
- ShortVec::Multi(mut items) => {
+ *self = match core::mem::replace(self, Self::ZeroOne(None)) {
+ ShortSlice::ZeroOne(None) => ShortSlice::ZeroOne(Some(item)),
+ ShortSlice::ZeroOne(Some(prev_item)) => {
+ ShortSlice::Multi(vec![prev_item, item].into_boxed_slice())
+ }
+ ShortSlice::Multi(items) => {
+ let mut items = items.into_vec();
items.push(item);
- ShortVec::Multi(items)
+ ShortSlice::Multi(items.into_boxed_slice())
}
};
}
@@ -41,25 +45,25 @@ impl<T> ShortVec<T> {
#[inline]
pub fn as_slice(&self) -> &[T] {
match self {
- ShortVec::Empty => &[],
- ShortVec::Single(v) => core::slice::from_ref(v),
- ShortVec::Multi(v) => v.as_slice(),
+ ShortSlice::ZeroOne(None) => &[],
+ ShortSlice::ZeroOne(Some(v)) => core::slice::from_ref(v),
+ ShortSlice::Multi(v) => v,
}
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [T] {
match self {
- ShortVec::Empty => &mut [],
- ShortVec::Single(v) => core::slice::from_mut(v),
- ShortVec::Multi(v) => v.as_mut_slice(),
+ ShortSlice::ZeroOne(None) => &mut [],
+ ShortSlice::ZeroOne(Some(v)) => core::slice::from_mut(v),
+ ShortSlice::Multi(v) => v,
}
}
#[inline]
pub const fn single(&self) -> Option<&T> {
match self {
- ShortVec::Single(v) => Some(v),
+ ShortSlice::ZeroOne(Some(v)) => Some(v),
_ => None,
}
}
@@ -67,9 +71,9 @@ impl<T> ShortVec<T> {
#[inline]
pub fn len(&self) -> usize {
match self {
- ShortVec::Empty => 0,
- ShortVec::Single(_) => 1,
- ShortVec::Multi(ref v) => v.len(),
+ ShortSlice::ZeroOne(None) => 0,
+ ShortSlice::ZeroOne(_) => 1,
+ ShortSlice::Multi(ref v) => v.len(),
}
}
@@ -81,19 +85,20 @@ impl<T> ShortVec<T> {
self.len()
);
- *self = match core::mem::replace(self, ShortVec::Empty) {
- ShortVec::Empty => ShortVec::Single(elt),
- ShortVec::Single(item) => {
+ *self = match core::mem::replace(self, ShortSlice::ZeroOne(None)) {
+ ShortSlice::ZeroOne(None) => ShortSlice::ZeroOne(Some(elt)),
+ ShortSlice::ZeroOne(Some(item)) => {
let items = if index == 0 {
- vec![elt, item]
+ vec![elt, item].into_boxed_slice()
} else {
- vec![item, elt]
+ vec![item, elt].into_boxed_slice()
};
- ShortVec::Multi(items)
+ ShortSlice::Multi(items)
}
- ShortVec::Multi(mut items) => {
+ ShortSlice::Multi(items) => {
+ let mut items = items.into_vec();
items.insert(index, elt);
- ShortVec::Multi(items)
+ ShortSlice::Multi(items.into_boxed_slice())
}
}
}
@@ -106,17 +111,18 @@ impl<T> ShortVec<T> {
self.len()
);
- let (replaced, removed_item) = match core::mem::replace(self, ShortVec::Empty) {
- ShortVec::Empty => unreachable!(),
- ShortVec::Single(v) => (ShortVec::Empty, v),
- ShortVec::Multi(mut v) => {
+ let (replaced, removed_item) = match core::mem::replace(self, ShortSlice::ZeroOne(None)) {
+ ShortSlice::ZeroOne(None) => unreachable!(),
+ ShortSlice::ZeroOne(Some(v)) => (ShortSlice::ZeroOne(None), v),
+ ShortSlice::Multi(v) => {
+ let mut v = v.into_vec();
let removed_item = v.remove(index);
match v.len() {
#[allow(clippy::unwrap_used)]
// we know that the vec has exactly one element left
- 1 => (ShortVec::Single(v.pop().unwrap()), removed_item),
+ 1 => (ShortSlice::ZeroOne(Some(v.pop().unwrap())), removed_item),
// v has at least 2 elements, create a Multi variant
- _ => (ShortVec::Multi(v), removed_item),
+ _ => (ShortSlice::Multi(v.into_boxed_slice()), removed_item),
}
}
};
@@ -126,38 +132,38 @@ impl<T> ShortVec<T> {
#[inline]
pub fn clear(&mut self) {
- let _ = core::mem::replace(self, ShortVec::Empty);
+ let _ = core::mem::replace(self, ShortSlice::ZeroOne(None));
}
}
-impl<T> From<Vec<T>> for ShortVec<T> {
+impl<T> From<Vec<T>> for ShortSlice<T> {
fn from(v: Vec<T>) -> Self {
match v.len() {
- 0 => ShortVec::Empty,
+ 0 => ShortSlice::ZeroOne(None),
#[allow(clippy::unwrap_used)] // we know that the vec is not empty
- 1 => ShortVec::Single(v.into_iter().next().unwrap()),
- _ => ShortVec::Multi(v),
+ 1 => ShortSlice::ZeroOne(Some(v.into_iter().next().unwrap())),
+ _ => ShortSlice::Multi(v.into_boxed_slice()),
}
}
}
-impl<T> Default for ShortVec<T> {
+impl<T> Default for ShortSlice<T> {
fn default() -> Self {
- ShortVec::Empty
+ ShortSlice::ZeroOne(None)
}
}
-impl<T> FromIterator<T> for ShortVec<T> {
+impl<T> FromIterator<T> for ShortSlice<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
iter.into_iter().collect::<Vec<_>>().into()
}
}
-impl<K, V> StoreConstEmpty<K, V> for ShortVec<(K, V)> {
- const EMPTY: ShortVec<(K, V)> = ShortVec::Empty;
+impl<K, V> StoreConstEmpty<K, V> for ShortSlice<(K, V)> {
+ const EMPTY: ShortSlice<(K, V)> = ShortSlice::ZeroOne(None);
}
-impl<K, V> Store<K, V> for ShortVec<(K, V)> {
+impl<K, V> Store<K, V> for ShortSlice<(K, V)> {
#[inline]
fn lm_len(&self) -> usize {
self.len()
@@ -165,7 +171,7 @@ impl<K, V> Store<K, V> for ShortVec<(K, V)> {
#[inline]
fn lm_is_empty(&self) -> bool {
- matches!(self, ShortVec::Empty)
+ matches!(self, ShortSlice::ZeroOne(None))
}
#[inline]
@@ -176,9 +182,8 @@ impl<K, V> Store<K, V> for ShortVec<(K, V)> {
#[inline]
fn lm_last(&self) -> Option<(&K, &V)> {
match self {
- ShortVec::Empty => None,
- ShortVec::Single(v) => Some(v),
- ShortVec::Multi(v) => v.as_slice().last(),
+ ShortSlice::ZeroOne(v) => v.as_ref(),
+ ShortSlice::Multi(v) => v.last(),
}
.map(|elt| (&elt.0, &elt.1))
}
@@ -192,18 +197,20 @@ impl<K, V> Store<K, V> for ShortVec<(K, V)> {
}
}
-impl<K, V> StoreMut<K, V> for ShortVec<(K, V)> {
- fn lm_with_capacity(_capacity: usize) -> Self {
- ShortVec::Empty
+impl<K: Ord, V> StoreFromIterable<K, V> for ShortSlice<(K, V)> {
+ fn lm_sort_from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
+ let v: Vec<(K, V)> = Vec::lm_sort_from_iter(iter);
+ v.into()
}
+}
- // ShortVec supports reserving capacity for additional elements only if we have already allocated a vector
- fn lm_reserve(&mut self, additional: usize) {
- if let ShortVec::Multi(ref mut v) = self {
- v.reserve(additional)
- }
+impl<K, V> StoreMut<K, V> for ShortSlice<(K, V)> {
+ fn lm_with_capacity(_capacity: usize) -> Self {
+ ShortSlice::ZeroOne(None)
}
+ fn lm_reserve(&mut self, _additional: usize) {}
+
fn lm_get_mut(&mut self, index: usize) -> Option<(&K, &mut V)> {
self.as_mut_slice()
.get_mut(index)
@@ -227,7 +234,7 @@ impl<K, V> StoreMut<K, V> for ShortVec<(K, V)> {
}
}
-impl<'a, K: 'a, V: 'a> StoreIterable<'a, K, V> for ShortVec<(K, V)> {
+impl<'a, K: 'a, V: 'a> StoreIterable<'a, K, V> for ShortSlice<(K, V)> {
type KeyValueIter =
core::iter::Map<core::slice::Iter<'a, (K, V)>, for<'r> fn(&'r (K, V)) -> (&'r K, &'r V)>;
@@ -236,11 +243,11 @@ impl<'a, K: 'a, V: 'a> StoreIterable<'a, K, V> for ShortVec<(K, V)> {
}
}
-impl<K, V> StoreFromIterator<K, V> for ShortVec<(K, V)> {}
+impl<K, V> StoreFromIterator<K, V> for ShortSlice<(K, V)> {}
#[test]
fn test_shortvec_impl() {
- litemap::testing::check_store::<ShortVec<(u32, u64)>>();
+ litemap::testing::check_store::<ShortSlice<(u32, u64)>>();
}
macro_rules! impl_tinystr_subtag {