typed_index_collections/slice/mod.rs
1#[cfg(feature = "alloc")]
2mod boxed;
3
4#[cfg(feature = "alloc")]
5mod concat;
6
7#[cfg(feature = "alloc")]
8mod join;
9
10mod slice_index;
11
12#[cfg(feature = "alloc")]
13use alloc::borrow::{Cow, ToOwned};
14#[cfg(feature = "alloc")]
15use alloc::boxed::Box;
16#[cfg(feature = "std")]
17use alloc::string::String;
18#[cfg(feature = "std")]
19use alloc::vec::Vec;
20use core::cmp::Ordering;
21use core::fmt;
22use core::hash::{Hash, Hasher};
23use core::marker::PhantomData;
24use core::ops::{Index, IndexMut, Range};
25use core::slice::{
26 ChunkBy, ChunkByMut, Chunks, ChunksExact, ChunksExactMut, ChunksMut, EscapeAscii, Iter,
27 IterMut, RChunks, RChunksExact, RChunksExactMut, RChunksMut, RSplit, RSplitMut, RSplitN,
28 RSplitNMut, Split, SplitInclusive, SplitInclusiveMut, SplitMut, SplitN, SplitNMut, Windows,
29};
30use core::str::Utf8Chunks;
31#[cfg(feature = "std")]
32use std::io::{BufRead, IoSlice, IoSliceMut, Read, Result as IoResult, Write};
33
34#[cfg(feature = "bincode")]
35use bincode::enc::{Encode, Encoder};
36#[cfg(feature = "bincode")]
37use bincode::error::EncodeError;
38#[cfg(feature = "alloc")]
39pub use concat::Concat;
40#[cfg(feature = "alloc")]
41pub use join::Join;
42#[cfg(feature = "serde")]
43use serde::ser::{Serialize, Serializer};
44pub use slice_index::TiSliceIndex;
45
46#[cfg(feature = "alloc")]
47use crate::TiVec;
48use crate::{TiEnumerated, TiRangeBounds, TiSliceKeys, TiSliceMutMap, TiSliceRefMap};
49
50/// A dynamically-sized view into a contiguous sequence of `T`
51/// that only accepts keys of the type `K`.
52///
53/// `TiSlice<K, V>` is a wrapper around Rust primitive type [`slice`].
54/// The struct mirrors the stable API of Rust [`slice`]
55/// and forwards to it as much as possible.
56///
57/// `TiSlice<K, V>` uses `K` instead of `usize` for element indices.
58/// It also uses [`Range`], [`RangeTo`], [`RangeFrom`], [`RangeInclusive`] and
59/// [`RangeToInclusive`] range types with `K` indices for `get`-methods and
60/// index expressions. The [`RangeFull`] trait is not currently supported.
61///
62/// `TiSlice<K, V>` require the index to implement
63/// [`From<usize>`][`From`] and [`Into<usize>`][`Into`] traits.
64/// Their implementation can be easily done
65/// with [`derive_more`] crate and `#[derive(From, Into)]`.
66///
67/// There are zero-cost conversions available between types and references:
68/// - [`&[V]`][`slice`] and `&TiSlice<K, V>` with [`AsRef`],
69/// - [`&mut [V]`][`slice`] and `&mut TiSlice<K, V>` with [`AsMut`],
70/// - [`Box<[V]>`][`Box`] and `Box<TiSlice<K, V>>` with [`From`] and [`Into`].
71///
72/// Added methods:
73/// - [`from_ref`] - Converts a [`&[V]`][`slice`] into a `&TiSlice<K, V>`.
74/// - [`from_mut`] - Converts a [`&mut [V]`][`slice`] into a `&mut TiSlice<K,
75/// V>`.
76/// - [`keys`] - Returns an iterator over all keys.
77/// - [`next_key`] - Returns the index of the next slice element to be appended
78/// and at the same time number of elements in the slice of type `K`.
79/// - [`first_key`] - Returns the first slice element index of type `K`, or
80/// `None` if the slice is empty.
81/// - [`first_key_value`] - Returns the first slice element index of type `K`
82/// and the element itself, or `None` if the slice is empty.
83/// - [`first_key_value_mut`] - Returns the first slice element index of type
84/// `K` and a mutable reference to the element itself, or `None` if the slice
85/// is empty.
86/// - [`last_key`] - Returns the last slice element index of type `K`, or `None`
87/// if the slice is empty.
88/// - [`last_key_value`] - Returns the last slice element index of type `K` and
89/// the element itself, or `None` if the slice is empty.
90/// - [`last_key_value_mut`] - Returns the last slice element index of type `K`
91/// and a mutable reference to the element itself, or `None` if the slice is
92/// empty.
93/// - [`iter_enumerated`] - Returns an iterator over all key-value pairs. It
94/// acts like `self.iter().enumerate()`, but use `K` instead of `usize` for
95/// iteration indices.
96/// - [`iter_mut_enumerated`] - Returns an iterator over all key-value pairs,
97/// with mutable references to the values. It acts like
98/// `self.iter_mut().enumerate()`, but use `K` instead of `usize` for
99/// iteration indices.
100/// - [`position`] - Searches for an element in an iterator, returning its index
101/// of type `K`. It acts like `self.iter().position(...)`, but instead of
102/// `usize` it returns index of type `K`.
103/// - [`rposition`] - Searches for an element in an iterator from the right,
104/// returning its index of type `K`. It acts like
105/// `self.iter().rposition(...)`, but instead of `usize` it returns index of
106/// type `K`.
107///
108/// # Example
109///
110/// ```
111/// use derive_more::{From, Into};
112/// use typed_index_collections::TiSlice;
113///
114/// #[derive(From, Into)]
115/// struct FooId(usize);
116///
117/// let mut foos_raw = [1, 2, 5, 8];
118/// let foos: &mut TiSlice<FooId, usize> = TiSlice::from_mut(&mut foos_raw);
119/// foos[FooId(2)] = 4;
120/// assert_eq!(foos[FooId(2)], 4);
121/// ```
122///
123/// [`from_ref`]: #method.from_ref
124/// [`from_mut`]: #method.from_mut
125/// [`keys`]: #method.keys
126/// [`next_key`]: #method.next_key
127/// [`first_key`]: #method.first_key
128/// [`first_key_value`]: #method.first_key_value
129/// [`first_key_value_mut`]: #method.first_key_value_mut
130/// [`last_key`]: #method.last_key
131/// [`last_key_value`]: #method.last_key_value
132/// [`last_key_value_mut`]: #method.last_key_value_mut
133/// [`iter_enumerated`]: #method.iter_enumerated
134/// [`iter_mut_enumerated`]: #method.iter_mut_enumerated
135/// [`position`]: #method.position
136/// [`rposition`]: #method.rposition
137/// [`slice`]: https://doc.rust-lang.org/std/primitive.slice.html
138/// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
139/// [`Into`]: https://doc.rust-lang.org/std/convert/trait.Into.html
140/// [`AsRef`]: https://doc.rust-lang.org/std/convert/trait.AsRef.html
141/// [`AsMut`]: https://doc.rust-lang.org/std/convert/trait.AsMut.html
142/// [`Box`]: https://doc.rust-lang.org/std/boxed/struct.Box.html
143/// [`Range`]: https://doc.rust-lang.org/std/ops/struct.Range.html
144/// [`RangeTo`]: https://doc.rust-lang.org/std/ops/struct.RangeTo.html
145/// [`RangeFrom`]: https://doc.rust-lang.org/std/ops/struct.RangeFrom.html
146/// [`RangeInclusive`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html
147/// [`RangeToInclusive`]: https://doc.rust-lang.org/std/ops/struct.RangeToInclusive.html
148/// [`RangeFull`]: https://doc.rust-lang.org/std/ops/struct.RangeFull.html
149/// [`derive_more`]: https://crates.io/crates/derive_more
150#[repr(transparent)]
151pub struct TiSlice<K, V> {
152 /// Tied slice index type
153 ///
154 /// `fn(T) -> T` is *[PhantomData pattern][phantomdata patterns]*
155 /// used to relax auto trait implementations bounds for
156 /// [`Send`], [`Sync`], [`Unpin`], [`UnwindSafe`] and [`RefUnwindSafe`].
157 ///
158 /// Derive attribute is not used for trait implementations because it also
159 /// requires the same trait implemented for K that is an unnecessary
160 /// requirement.
161 ///
162 /// [phantomdata patterns]: https://doc.rust-lang.org/nomicon/phantom-data.html#table-of-phantomdata-patterns
163 /// [`Send`]: https://doc.rust-lang.org/core/marker/trait.Send.html
164 /// [`Sync`]: https://doc.rust-lang.org/core/marker/trait.Sync.html
165 /// [`Unpin`]: https://doc.rust-lang.org/core/marker/trait.Unpin.html
166 /// [`UnwindSafe`]: https://doc.rust-lang.org/core/std/panic/trait.UnwindSafe.html
167 /// [`RefUnwindSafe`]: https://doc.rust-lang.org/core/std/panic/trait.RefUnwindSafe.html
168 _marker: PhantomData<fn(K) -> K>,
169
170 /// Raw slice property
171 pub raw: [V],
172}
173
174impl<K, V> TiSlice<K, V> {
175 /// Converts a `&[V]` into a `&TiSlice<K, V>`.
176 ///
177 /// # Example
178 ///
179 /// ```
180 /// # use typed_index_collections::TiSlice;
181 /// pub struct Id(usize);
182 /// let slice: &TiSlice<Id, usize> = TiSlice::from_ref(&[1, 2, 4]);
183 /// ```
184 #[expect(clippy::as_conversions, reason = "transparent over a `[V]` type")]
185 #[inline]
186 pub const fn from_ref(raw: &[V]) -> &Self {
187 // SAFETY: `TiSlice<K, V>` is `repr(transparent)` over a `[V]` type.
188 unsafe { &*(core::ptr::from_ref::<[V]>(raw) as *const Self) }
189 }
190
191 /// Converts a `&mut [V]` into a `&mut TiSlice<K, V>`.
192 ///
193 /// # Example
194 ///
195 /// ```
196 /// # use typed_index_collections::TiSlice;
197 /// pub struct Id(usize);
198 /// let slice: &mut TiSlice<Id, usize> = TiSlice::from_mut(&mut [1, 2, 4]);
199 /// ```
200 #[expect(clippy::as_conversions, reason = "transparent over a `[V]` type")]
201 #[inline]
202 pub const fn from_mut(raw: &mut [V]) -> &mut Self {
203 // SAFETY: `TiSlice<K, V>` is `repr(transparent)` over a `[V]` type.
204 unsafe { &mut *(core::ptr::from_mut::<[V]>(raw) as *mut Self) }
205 }
206
207 /// Returns the number of elements in the slice.
208 ///
209 /// See [`slice::len`] for more details.
210 ///
211 /// [`slice::len`]: https://doc.rust-lang.org/std/primitive.slice.html#method.len
212 #[inline]
213 pub const fn len(&self) -> usize {
214 self.raw.len()
215 }
216
217 /// Returns the index of the next slice element to be appended
218 /// and at the same time number of elements in the slice of type `K`.
219 ///
220 /// # Example
221 ///
222 /// ```
223 /// # use derive_more::{From, Into};
224 /// # use typed_index_collections::TiSlice;
225 /// #[derive(Eq, Debug, From, Into, PartialEq)]
226 /// pub struct Id(usize);
227 /// let slice: &TiSlice<Id, usize> = TiSlice::from_ref(&[1, 2, 4]);
228 /// assert_eq!(slice.next_key(), Id(3));
229 /// ```
230 #[inline]
231 pub fn next_key(&self) -> K
232 where
233 usize: Into<K>,
234 {
235 self.raw.len().into()
236 }
237
238 /// Returns `true` if the slice has a length of 0.
239 ///
240 /// See [`slice::is_empty`] for more details.
241 ///
242 /// [`slice::is_empty`]: https://doc.rust-lang.org/std/primitive.slice.html#method.is_empty
243 #[inline]
244 pub const fn is_empty(&self) -> bool {
245 self.raw.is_empty()
246 }
247
248 /// Returns an iterator over all keys.
249 ///
250 /// # Example
251 ///
252 /// ```
253 /// # use derive_more::{From, Into};
254 /// # use typed_index_collections::TiSlice;
255 /// #[derive(Debug, Eq, From, Into, PartialEq)]
256 /// pub struct Id(usize);
257 /// let slice: &TiSlice<Id, usize> = TiSlice::from_ref(&[1, 2, 4]);
258 /// let mut iterator = slice.keys();
259 /// assert_eq!(iterator.next(), Some(Id(0)));
260 /// assert_eq!(iterator.next(), Some(Id(1)));
261 /// assert_eq!(iterator.next(), Some(Id(2)));
262 /// assert_eq!(iterator.next(), None);
263 /// ```
264 #[inline]
265 pub fn keys(&self) -> TiSliceKeys<K>
266 where
267 usize: Into<K>,
268 {
269 (0..self.len()).map(Into::into)
270 }
271
272 /// Returns the first element of the slice, or `None` if it is empty.
273 ///
274 /// See [`slice::first`] for more details.
275 ///
276 /// [`slice::first`]: https://doc.rust-lang.org/std/primitive.slice.html#method.first
277 #[inline]
278 pub const fn first(&self) -> Option<&V> {
279 self.raw.first()
280 }
281
282 /// Returns a mutable reference to the first element of the slice, or `None`
283 /// if it is empty.
284 ///
285 /// See [`slice::first_mut`] for more details.
286 ///
287 /// [`slice::first_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.first_mut
288 #[inline]
289 pub const fn first_mut(&mut self) -> Option<&mut V> {
290 self.raw.first_mut()
291 }
292
293 /// Returns the first slice element index of type `K`, or `None` if the
294 /// slice is empty.
295 ///
296 /// # Example
297 ///
298 /// ```
299 /// # use derive_more::{From, Into};
300 /// # use typed_index_collections::TiSlice;
301 /// #[derive(Debug, Eq, From, Into, PartialEq)]
302 /// pub struct Id(usize);
303 /// let empty_slice: &TiSlice<Id, usize> = TiSlice::from_ref(&[]);
304 /// let slice: &TiSlice<Id, usize> = TiSlice::from_ref(&[1, 2, 4]);
305 /// assert_eq!(empty_slice.first_key(), None);
306 /// assert_eq!(slice.first_key(), Some(Id(0)));
307 /// ```
308 #[inline]
309 pub fn first_key(&self) -> Option<K>
310 where
311 usize: Into<K>,
312 {
313 if self.is_empty() {
314 None
315 } else {
316 Some(0.into())
317 }
318 }
319
320 /// Returns the first slice element index of type `K` and the element
321 /// itself, or `None` if the slice is empty.
322 ///
323 /// See [`slice::first`] for more details.
324 ///
325 /// # Example
326 ///
327 /// ```
328 /// # use derive_more::{From, Into};
329 /// # use typed_index_collections::TiSlice;
330 /// #[derive(Debug, Eq, From, Into, PartialEq)]
331 /// pub struct Id(usize);
332 /// let empty_slice: &TiSlice<Id, usize> = TiSlice::from_ref(&[]);
333 /// let slice: &TiSlice<Id, usize> = TiSlice::from_ref(&[1, 2, 4]);
334 /// assert_eq!(empty_slice.first_key_value(), None);
335 /// assert_eq!(slice.first_key_value(), Some((Id(0), &1)));
336 /// ```
337 ///
338 /// [`slice::first`]: https://doc.rust-lang.org/std/primitive.slice.html#method.first
339 #[inline]
340 pub fn first_key_value(&self) -> Option<(K, &V)>
341 where
342 usize: Into<K>,
343 {
344 self.raw.first().map(|first| (0.into(), first))
345 }
346
347 /// Returns the first slice element index of type `K` and a mutable
348 /// reference to the element itself, or `None` if the slice is empty.
349 ///
350 /// See [`slice::first_mut`] for more details.
351 ///
352 /// # Example
353 ///
354 /// ```
355 /// # use derive_more::{From, Into};
356 /// # use typed_index_collections::TiSlice;
357 /// #[derive(Debug, Eq, From, Into, PartialEq)]
358 /// pub struct Id(usize);
359 /// let empty_slice: &mut TiSlice<Id, usize> = TiSlice::from_mut(&mut []);
360 /// let mut array = [1, 2, 4];
361 /// let slice: &mut TiSlice<Id, usize> = TiSlice::from_mut(&mut array);
362 /// assert_eq!(empty_slice.first_key_value_mut(), None);
363 /// assert_eq!(slice.first_key_value_mut(), Some((Id(0), &mut 1)));
364 /// *slice.first_key_value_mut().unwrap().1 = 123;
365 /// assert_eq!(slice.raw, [123, 2, 4]);
366 /// ```
367 ///
368 /// [`slice::first_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.first_mut
369 #[inline]
370 pub fn first_key_value_mut(&mut self) -> Option<(K, &mut V)>
371 where
372 usize: Into<K>,
373 {
374 self.raw.first_mut().map(|first| (0.into(), first))
375 }
376
377 /// Returns the first and all the rest of the elements of the slice, or
378 /// `None` if it is empty.
379 ///
380 /// See [`slice::split_first`] for more details.
381 ///
382 /// [`slice::split_first`]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_first
383 #[inline]
384 pub const fn split_first(&self) -> Option<(&V, &Self)> {
385 match self.raw.split_first() {
386 Some((first, rest)) => Some((first, Self::from_ref(rest))),
387 None => None,
388 }
389 }
390
391 /// Returns the first and all the rest of the elements of the slice, or
392 /// `None` if it is empty.
393 ///
394 /// See [`slice::split_first_mut`] for more details.
395 ///
396 /// [`slice::split_first_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_first_mut
397 #[inline]
398 pub const fn split_first_mut(&mut self) -> Option<(&mut V, &mut Self)> {
399 match self.raw.split_first_mut() {
400 Some((first, rest)) => Some((first, Self::from_mut(rest))),
401 None => None,
402 }
403 }
404
405 /// Returns the last and all the rest of the elements of the slice, or
406 /// `None` if it is empty.
407 ///
408 /// See [`slice::split_last`] for more details.
409 ///
410 /// [`slice::split_last`]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_last
411 #[inline]
412 pub const fn split_last(&self) -> Option<(&V, &Self)> {
413 match self.raw.split_last() {
414 Some((last, rest)) => Some((last, Self::from_ref(rest))),
415 None => None,
416 }
417 }
418
419 /// Returns the last and all the rest of the elements of the slice, or
420 /// `None` if it is empty.
421 ///
422 /// See [`slice::split_last_mut`] for more details.
423 ///
424 /// [`slice::split_last_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_last_mut
425 #[inline]
426 pub const fn split_last_mut(&mut self) -> Option<(&mut V, &mut Self)> {
427 match self.raw.split_last_mut() {
428 Some((first, rest)) => Some((first, Self::from_mut(rest))),
429 None => None,
430 }
431 }
432
433 /// Returns the last element of the slice of type `K`, or `None` if it is
434 /// empty.
435 ///
436 /// See [`slice::last`] for more details.
437 ///
438 /// [`slice::last`]: https://doc.rust-lang.org/std/primitive.slice.html#method.last
439 #[inline]
440 pub const fn last(&self) -> Option<&V> {
441 self.raw.last()
442 }
443
444 /// Returns a mutable reference to the last item in the slice.
445 ///
446 /// See [`slice::last_mut`] for more details.
447 ///
448 /// [`slice::last_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.last_mut
449 #[inline]
450 pub const fn last_mut(&mut self) -> Option<&mut V> {
451 self.raw.last_mut()
452 }
453
454 /// Returns the last slice element index of type `K`, or `None` if the slice
455 /// is empty.
456 ///
457 /// # Example
458 ///
459 /// ```
460 /// # use derive_more::{From, Into};
461 /// # use typed_index_collections::TiSlice;
462 /// #[derive(Debug, Eq, From, Into, PartialEq)]
463 /// pub struct Id(usize);
464 /// let empty_slice: &TiSlice<Id, usize> = TiSlice::from_ref(&[]);
465 /// let slice: &TiSlice<Id, usize> = TiSlice::from_ref(&[1, 2, 4]);
466 /// assert_eq!(empty_slice.last_key(), None);
467 /// assert_eq!(slice.last_key(), Some(Id(2)));
468 /// ```
469 #[inline]
470 pub fn last_key(&self) -> Option<K>
471 where
472 usize: Into<K>,
473 {
474 Some(self.len().checked_sub(1)?.into())
475 }
476
477 /// Returns the last slice element index of type `K` and the element itself,
478 /// or `None` if the slice is empty.
479 ///
480 /// See [`slice::last`] for more details.
481 ///
482 /// # Example
483 ///
484 /// ```
485 /// # use derive_more::{From, Into};
486 /// # use typed_index_collections::TiSlice;
487 /// #[derive(Debug, Eq, From, Into, PartialEq)]
488 /// pub struct Id(usize);
489 /// let empty_slice: &TiSlice<Id, usize> = TiSlice::from_ref(&[]);
490 /// let slice: &TiSlice<Id, usize> = TiSlice::from_ref(&[1, 2, 4]);
491 /// assert_eq!(empty_slice.last_key_value(), None);
492 /// assert_eq!(slice.last_key_value(), Some((Id(2), &4)));
493 /// ```
494 ///
495 /// [`slice::last`]: https://doc.rust-lang.org/std/primitive.slice.html#method.last
496 #[expect(clippy::missing_panics_doc, reason = "should not panic")]
497 #[inline]
498 pub fn last_key_value(&self) -> Option<(K, &V)>
499 where
500 usize: Into<K>,
501 {
502 let len = self.len();
503 self.raw.last().map(|last| {
504 (
505 len.checked_sub(1).expect("unexpected overflow").into(),
506 last,
507 )
508 })
509 }
510
511 /// Returns the last slice element index of type `K` and a mutable reference
512 /// to the element itself, or `None` if the slice is empty.
513 ///
514 /// See [`slice::last_mut`] for more details.
515 ///
516 /// # Example
517 ///
518 /// ```
519 /// # use derive_more::{From, Into};
520 /// # use typed_index_collections::TiSlice;
521 /// #[derive(Debug, Eq, From, Into, PartialEq)]
522 /// pub struct Id(usize);
523 /// let empty_slice: &mut TiSlice<Id, usize> = TiSlice::from_mut(&mut []);
524 /// let mut array = [1, 2, 4];
525 /// let slice: &mut TiSlice<Id, usize> = TiSlice::from_mut(&mut array);
526 /// assert_eq!(empty_slice.last_key_value_mut(), None);
527 /// assert_eq!(slice.last_key_value_mut(), Some((Id(2), &mut 4)));
528 /// *slice.last_key_value_mut().unwrap().1 = 123;
529 /// assert_eq!(slice.raw, [1, 2, 123]);
530 /// ```
531 ///
532 /// [`slice::last_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.last_mut
533 #[expect(clippy::missing_panics_doc, reason = "should not panic")]
534 #[inline]
535 pub fn last_key_value_mut(&mut self) -> Option<(K, &mut V)>
536 where
537 usize: Into<K>,
538 {
539 let len = self.len();
540 self.raw.last_mut().map(|last| {
541 (
542 len.checked_sub(1).expect("unexpected overflow").into(),
543 last,
544 )
545 })
546 }
547
548 /// Returns a reference to an element or subslice
549 /// depending on the type of index or `None` if the index is out of bounds.
550 ///
551 /// See [`slice::get`] for more details.
552 ///
553 /// [`slice::get`]: https://doc.rust-lang.org/std/primitive.slice.html#method.get
554 #[inline]
555 pub fn get<I>(&self, index: I) -> Option<&I::Output>
556 where
557 I: TiSliceIndex<K, V>,
558 {
559 index.get(self)
560 }
561
562 /// Returns a mutable reference to an element or subslice
563 /// depending on the type of index or `None` if the index is out of bounds.
564 ///
565 /// See [`slice::get_mut`] for more details.
566 ///
567 /// [`slice::get_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.get_mut
568 #[inline]
569 pub fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
570 where
571 I: TiSliceIndex<K, V>,
572 {
573 index.get_mut(self)
574 }
575
576 /// Returns a reference to an element or subslice
577 /// depending on the type of index, without doing bounds checking.
578 ///
579 /// See [`slice::get_unchecked`] for more details.
580 ///
581 /// # Safety
582 ///
583 /// Calling this method with an out-of-bounds index is
584 /// *[undefined behavior]* even if the resulting reference is not used.
585 /// For a safe alternative see [`get`].
586 ///
587 /// [`get`]: #method.get
588 /// [`slice::get_unchecked`]: https://doc.rust-lang.org/std/primitive.slice.html#method.get_unchecked
589 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
590 #[inline]
591 pub unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
592 where
593 I: TiSliceIndex<K, V>,
594 {
595 // SAFETY: Guaranteed by the caller.
596 unsafe { index.get_unchecked(self) }
597 }
598
599 /// Returns a mutable reference to an element or subslice
600 /// depending on the type of index, without doing bounds checking.
601 ///
602 /// See [`slice::get_unchecked_mut`] for more details.
603 ///
604 /// # Safety
605 ///
606 /// Calling this method with an out-of-bounds index is
607 /// *[undefined behavior]* even if the resulting reference is not used.
608 /// For a safe alternative see [`get_mut`].
609 ///
610 /// [`get_mut`]: #method.get_mut
611 /// [`slice::get_unchecked_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.get_unchecked_mut
612 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
613 #[inline]
614 pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
615 where
616 I: TiSliceIndex<K, V>,
617 {
618 // SAFETY: Guaranteed by the caller.
619 unsafe { index.get_unchecked_mut(self) }
620 }
621
622 /// Returns a raw pointer to the slice's buffer.
623 ///
624 /// See [`slice::as_ptr`] for more details.
625 ///
626 /// [`slice::as_ptr`]: https://doc.rust-lang.org/std/primitive.slice.html#method.as_ptr
627 #[inline]
628 pub const fn as_ptr(&self) -> *const V {
629 self.raw.as_ptr()
630 }
631
632 /// Returns an unsafe mutable reference to the slice's buffer.
633 ///
634 /// See [`slice::as_mut_ptr`] for more details.
635 ///
636 /// [`slice::as_mut_ptr`]: https://doc.rust-lang.org/std/primitive.slice.html#method.as_mut_ptr
637 #[inline]
638 pub const fn as_mut_ptr(&mut self) -> *mut V {
639 self.raw.as_mut_ptr()
640 }
641
642 /// Returns the two raw pointers spanning the slice.
643 ///
644 /// See [`slice::as_ptr_range`] for more details.
645 ///
646 /// [`slice::as_ptr_range`]: https://doc.rust-lang.org/std/primitive.slice.html#method.as_ptr_range
647 #[inline]
648 #[must_use]
649 pub const fn as_ptr_range(&self) -> Range<*const V> {
650 self.raw.as_ptr_range()
651 }
652
653 /// Returns the two unsafe mutable pointers spanning the slice.
654 ///
655 /// See [`slice::as_mut_ptr_range`] for more details.
656 ///
657 /// [`slice::as_mut_ptr_range`]: https://doc.rust-lang.org/std/primitive.slice.html#method.as_mut_ptr_range
658 #[inline]
659 #[must_use]
660 pub const fn as_mut_ptr_range(&mut self) -> Range<*mut V> {
661 self.raw.as_mut_ptr_range()
662 }
663
664 /// Swaps two elements in the slice.
665 ///
666 /// See [`slice::swap`] for more details.
667 ///
668 /// [`slice::swap`]: https://doc.rust-lang.org/std/primitive.slice.html#method.swap
669 #[inline]
670 pub fn swap(&mut self, a: K, b: K)
671 where
672 K: Into<usize>,
673 {
674 self.raw.swap(a.into(), b.into());
675 }
676
677 /// Reverses the order of elements in the slice, in place.
678 ///
679 /// See [`slice::reverse`] for more details.
680 ///
681 /// [`slice::reverse`]: https://doc.rust-lang.org/std/primitive.slice.html#method.reverse
682 #[inline]
683 pub const fn reverse(&mut self) {
684 self.raw.reverse();
685 }
686
687 /// Returns an iterator over the slice.
688 ///
689 /// See [`slice::iter`] for more details.
690 ///
691 /// [`slice::iter`]: https://doc.rust-lang.org/std/primitive.slice.html#method.iter
692 #[inline]
693 pub fn iter(&self) -> Iter<'_, V> {
694 self.raw.iter()
695 }
696
697 /// Returns an iterator over all key-value pairs.
698 ///
699 /// It acts like `self.iter().enumerate()`,
700 /// but use `K` instead of `usize` for iteration indices.
701 ///
702 /// See [`slice::iter`] for more details.
703 ///
704 /// # Example
705 ///
706 /// ```
707 /// # use derive_more::{From, Into};
708 /// # use typed_index_collections::TiSlice;
709 /// #[derive(Debug, Eq, From, Into, PartialEq)]
710 /// pub struct Id(usize);
711 /// let slice: &TiSlice<Id, usize> = TiSlice::from_ref(&[1, 2, 4]);
712 /// let mut iterator = slice.iter_enumerated();
713 /// assert_eq!(iterator.next(), Some((Id(0), &1)));
714 /// assert_eq!(iterator.next(), Some((Id(1), &2)));
715 /// assert_eq!(iterator.next(), Some((Id(2), &4)));
716 /// assert_eq!(iterator.next(), None);
717 /// ```
718 ///
719 /// [`slice::iter`]: https://doc.rust-lang.org/std/primitive.slice.html#method.iter
720 #[inline]
721 pub fn iter_enumerated(&self) -> TiEnumerated<Iter<'_, V>, K, &V>
722 where
723 usize: Into<K>,
724 {
725 self.raw
726 .iter()
727 .enumerate()
728 .map(|(key, value)| (key.into(), value))
729 }
730
731 /// Returns an iterator that allows modifying each value.
732 ///
733 /// See [`slice::iter_mut`] for more details.
734 ///
735 /// [`slice::iter_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.iter_mut
736 #[inline]
737 pub fn iter_mut(&mut self) -> IterMut<'_, V> {
738 self.raw.iter_mut()
739 }
740
741 /// Returns an iterator over all key-value pairs, with mutable references to
742 /// the values.
743 ///
744 /// It acts like `self.iter_mut().enumerate()`,
745 /// but use `K` instead of `usize` for iteration indices.
746 ///
747 /// # Example
748 ///
749 /// ```
750 /// # use derive_more::{From, Into};
751 /// # use typed_index_collections::TiSlice;
752 /// #[derive(Debug, Eq, From, Into, PartialEq)]
753 /// pub struct Id(usize);
754 /// let mut array = [1, 2, 4];
755 /// let slice: &mut TiSlice<Id, usize> = TiSlice::from_mut(&mut array);
756 /// for (key, value) in slice.iter_mut_enumerated() {
757 /// *value += key.0;
758 /// }
759 /// assert_eq!(array, [1, 3, 6]);
760 /// ```
761 ///
762 /// [`slice::iter_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.iter_mut
763 #[inline]
764 pub fn iter_mut_enumerated(&mut self) -> TiEnumerated<IterMut<'_, V>, K, &mut V>
765 where
766 usize: Into<K>,
767 {
768 self.raw
769 .iter_mut()
770 .enumerate()
771 .map(|(key, value)| (key.into(), value))
772 }
773
774 /// Searches for an element in an iterator, returning its index of type `K`.
775 ///
776 /// It acts like `self.iter().position(...)`,
777 /// but instead of `usize` it returns index of type `K`.
778 ///
779 /// See [`slice::iter`] and [`Iterator::position`] for more details.
780 ///
781 /// # Example
782 ///
783 /// ```
784 /// # use derive_more::{From, Into};
785 /// # use typed_index_collections::TiSlice;
786 /// #[derive(Debug, Eq, From, Into, PartialEq)]
787 /// pub struct Id(usize);
788 /// let slice: &TiSlice<Id, usize> = TiSlice::from_ref(&[1, 2, 4, 2, 1]);
789 /// assert_eq!(slice.position(|&value| value == 1), Some(Id(0)));
790 /// assert_eq!(slice.position(|&value| value == 2), Some(Id(1)));
791 /// assert_eq!(slice.position(|&value| value == 3), None);
792 /// assert_eq!(slice.position(|&value| value == 4), Some(Id(2)));
793 /// ```
794 ///
795 /// [`slice::iter`]: https://doc.rust-lang.org/std/primitive.slice.html#method.iter
796 /// [`Iterator::position`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.position
797 #[inline]
798 pub fn position<P>(&self, predicate: P) -> Option<K>
799 where
800 usize: Into<K>,
801 P: FnMut(&V) -> bool,
802 {
803 self.raw.iter().position(predicate).map(Into::into)
804 }
805
806 /// Searches for an element in an iterator from the right, returning its
807 /// index of type `K`.
808 ///
809 /// It acts like `self.iter().rposition(...)`,
810 /// but instead of `usize` it returns index of type `K`.
811 ///
812 /// See [`slice::iter`] and [`Iterator::rposition`] for more details.
813 ///
814 /// # Example
815 ///
816 /// ```
817 /// # use derive_more::{From, Into};
818 /// # use typed_index_collections::TiSlice;
819 /// #[derive(Debug, Eq, From, Into, PartialEq)]
820 /// pub struct Id(usize);
821 /// let slice: &TiSlice<Id, usize> = TiSlice::from_ref(&[1, 2, 4, 2, 1]);
822 /// assert_eq!(slice.rposition(|&value| value == 1), Some(Id(4)));
823 /// assert_eq!(slice.rposition(|&value| value == 2), Some(Id(3)));
824 /// assert_eq!(slice.rposition(|&value| value == 3), None);
825 /// assert_eq!(slice.rposition(|&value| value == 4), Some(Id(2)));
826 /// ```
827 ///
828 /// [`slice::iter`]: https://doc.rust-lang.org/std/primitive.slice.html#method.iter
829 /// [`Iterator::rposition`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.rposition
830 #[inline]
831 pub fn rposition<P>(&self, predicate: P) -> Option<K>
832 where
833 usize: Into<K>,
834 P: FnMut(&V) -> bool,
835 {
836 self.raw.iter().rposition(predicate).map(Into::into)
837 }
838
839 /// Returns an iterator over all contiguous windows of length
840 /// `size`. The windows overlap. If the slice is shorter than
841 /// `size`, the iterator returns no values.
842 ///
843 /// See [`slice::windows`] for more details.
844 ///
845 /// [`slice::windows`]: https://doc.rust-lang.org/std/primitive.slice.html#method.windows
846 #[inline]
847 pub fn windows(&self, size: usize) -> TiSliceRefMap<Windows<'_, V>, K, V> {
848 self.raw.windows(size).map(Self::from_ref)
849 }
850
851 /// Returns an iterator over `chunk_size` elements of the slice at a time,
852 /// starting at the beginning of the slice.
853 ///
854 /// See [`slice::chunks`] for more details.
855 ///
856 /// [`slice::chunks`]: https://doc.rust-lang.org/std/primitive.slice.html#method.chunks
857 #[inline]
858 pub fn chunks(&self, chunk_size: usize) -> TiSliceRefMap<Chunks<'_, V>, K, V> {
859 self.raw.chunks(chunk_size).map(Self::from_ref)
860 }
861
862 /// Returns an iterator over `chunk_size` elements of the slice at a time,
863 /// starting at the beginning of the slice.
864 ///
865 /// See [`slice::chunks_mut`] for more details.
866 ///
867 /// [`slice::chunks_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.chunks_mut
868 #[inline]
869 pub fn chunks_mut(&mut self, chunk_size: usize) -> TiSliceMutMap<ChunksMut<'_, V>, K, V> {
870 self.raw.chunks_mut(chunk_size).map(Self::from_mut)
871 }
872
873 /// Returns an iterator over `chunk_size` elements of the slice at a time,
874 /// starting at the beginning of the slice.
875 ///
876 /// See [`slice::chunks_exact`] for more details.
877 ///
878 /// [`slice::chunks_exact`]: https://doc.rust-lang.org/std/primitive.slice.html#method.chunks_exact
879 #[inline]
880 pub fn chunks_exact(&self, chunk_size: usize) -> TiSliceRefMap<ChunksExact<'_, V>, K, V> {
881 self.raw.chunks_exact(chunk_size).map(Self::from_ref)
882 }
883
884 /// Returns an iterator over `chunk_size` elements of the slice at a time,
885 /// starting at the beginning of the slice.
886 ///
887 /// See [`slice::chunks_exact_mut`] for more details.
888 ///
889 /// [`slice::chunks_exact_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.chunks_exact_mut
890 #[inline]
891 pub fn chunks_exact_mut(
892 &mut self,
893 chunk_size: usize,
894 ) -> TiSliceMutMap<ChunksExactMut<'_, V>, K, V> {
895 self.raw.chunks_exact_mut(chunk_size).map(Self::from_mut)
896 }
897
898 /// Returns an iterator over `chunk_size` elements of the slice at a time,
899 /// starting at the end of the slice.
900 ///
901 /// See [`slice::rchunks`] for more details.
902 ///
903 /// [`slice::rchunks`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rchunks
904 #[inline]
905 pub fn rchunks(&self, chunk_size: usize) -> TiSliceRefMap<RChunks<'_, V>, K, V> {
906 self.raw.rchunks(chunk_size).map(Self::from_ref)
907 }
908
909 /// Returns an iterator over `chunk_size` elements of the slice at a time,
910 /// starting at the end of the slice.
911 ///
912 /// See [`slice::rchunks_mut`] for more details.
913 ///
914 /// [`slice::rchunks_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rchunks_mut
915 #[inline]
916 pub fn rchunks_mut(&mut self, chunk_size: usize) -> TiSliceMutMap<RChunksMut<'_, V>, K, V> {
917 self.raw.rchunks_mut(chunk_size).map(Self::from_mut)
918 }
919
920 /// Returns an iterator over `chunk_size` elements of the slice at a time,
921 /// starting at the end of the slice.
922 ///
923 /// See [`slice::rchunks_exact`] for more details.
924 ///
925 /// [`slice::rchunks_exact`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rchunks_exact
926 #[inline]
927 pub fn rchunks_exact(&self, chunk_size: usize) -> TiSliceRefMap<RChunksExact<'_, V>, K, V> {
928 self.raw.rchunks_exact(chunk_size).map(Self::from_ref)
929 }
930
931 /// Returns an iterator over `chunk_size` elements of the slice at a time,
932 /// starting at the end of the slice.
933 ///
934 /// See [`slice::rchunks_exact_mut`] for more details.
935 ///
936 /// [`slice::rchunks_exact_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rchunks_exact_mut
937 #[inline]
938 pub fn rchunks_exact_mut(
939 &mut self,
940 chunk_size: usize,
941 ) -> TiSliceMutMap<RChunksExactMut<'_, V>, K, V> {
942 self.raw.rchunks_exact_mut(chunk_size).map(Self::from_mut)
943 }
944
945 /// Returns an iterator over the slice producing non-overlapping runs
946 /// of elements using the predicate to separate them.
947 ///
948 /// See [`slice::chunk_by`] for more details.
949 ///
950 /// [`slice::chunk_by`]: https://doc.rust-lang.org/std/primitive.slice.html#method.chunk_by
951 #[inline]
952 pub fn chunk_by<F>(&self, pred: F) -> TiSliceRefMap<ChunkBy<'_, V, F>, K, V>
953 where
954 F: FnMut(&V, &V) -> bool,
955 {
956 self.raw.chunk_by(pred).map(Self::from_ref)
957 }
958
959 /// Returns an iterator over the slice producing non-overlapping mutable
960 /// runs of elements using the predicate to separate them.
961 ///
962 /// See [`slice::chunk_by_mut`] for more details.
963 ///
964 /// [`slice::chunk_by_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.chunk_by_mut
965 #[inline]
966 pub fn chunk_by_mut<F>(&mut self, pred: F) -> TiSliceMutMap<ChunkByMut<'_, V, F>, K, V>
967 where
968 F: FnMut(&V, &V) -> bool,
969 {
970 self.raw.chunk_by_mut(pred).map(Self::from_mut)
971 }
972
973 /// Divides one slice into two at an index.
974 ///
975 /// See [`slice::split_at`] for more details.
976 ///
977 /// [`slice::split_at`]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_at
978 #[inline]
979 pub fn split_at(&self, mid: K) -> (&Self, &Self)
980 where
981 K: Into<usize>,
982 {
983 let (left, right) = self.raw.split_at(mid.into());
984 (left.as_ref(), right.as_ref())
985 }
986
987 /// Divides one mutable slice into two at an index.
988 ///
989 /// See [`slice::split_at_mut`] for more details.
990 ///
991 /// [`slice::split_at_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_at_mut
992 #[inline]
993 pub fn split_at_mut(&mut self, mid: K) -> (&mut Self, &mut Self)
994 where
995 K: Into<usize>,
996 {
997 let (left, right) = self.raw.split_at_mut(mid.into());
998 (left.as_mut(), right.as_mut())
999 }
1000
1001 /// Divides one slice into two at an index, without doing bounds checking.
1002 ///
1003 /// See [`slice::split_at_unchecked`] for more details.
1004 ///
1005 /// # Safety
1006 ///
1007 /// Calling this method with an out-of-bounds index is
1008 /// *[undefined behavior]* even if the resulting reference is not used. The
1009 /// caller has to ensure that `0 <= mid <= self.len()`.
1010 ///
1011 /// [`slice::split_at_unchecked`]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_at_unchecked
1012 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1013 #[inline]
1014 #[must_use]
1015 pub unsafe fn split_at_unchecked(&self, mid: K) -> (&Self, &Self)
1016 where
1017 K: Into<usize>,
1018 {
1019 // SAFETY: Guaranteed by the caller.
1020 let (left, right) = unsafe { self.raw.split_at_unchecked(mid.into()) };
1021 (left.as_ref(), right.as_ref())
1022 }
1023
1024 /// Divides one mutable slice into two at an index, without doing bounds
1025 /// checking.
1026 ///
1027 /// See [`slice::split_at_mut_unchecked`] for more details.
1028 ///
1029 /// # Safety
1030 ///
1031 /// Calling this method with an out-of-bounds index is
1032 /// *[undefined behavior]* even if the resulting reference is not used. The
1033 /// caller has to ensure that `0 <= mid <= self.len()`.
1034 ///
1035 /// [`slice::split_at_mut_unchecked`]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_at_mut_unchecked
1036 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1037 #[inline]
1038 #[must_use]
1039 pub unsafe fn split_at_mut_unchecked(&mut self, mid: K) -> (&mut Self, &mut Self)
1040 where
1041 K: Into<usize>,
1042 {
1043 // SAFETY: Guaranteed by the caller.
1044 let (left, right) = unsafe { self.raw.split_at_mut_unchecked(mid.into()) };
1045 (left.as_mut(), right.as_mut())
1046 }
1047
1048 /// Divides one slice into two at an index, returning `None` if the slice is
1049 /// too short.
1050 ///
1051 /// See [`slice::split_at_checked`] for more details.
1052 ///
1053 /// [`slice::split_at_checked`]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_at_checked
1054 #[inline]
1055 #[must_use]
1056 pub fn split_at_checked(&self, mid: K) -> Option<(&Self, &Self)>
1057 where
1058 K: Into<usize>,
1059 {
1060 let (left, right) = self.raw.split_at_checked(mid.into())?;
1061 Some((left.as_ref(), right.as_ref()))
1062 }
1063
1064 /// Divides one mutable slice into two at an index, returning `None` if the
1065 /// slice is too short.
1066 ///
1067 /// See [`slice::split_at_mut_checked`] for more details.
1068 ///
1069 /// [`slice::split_at_mut_checked`]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_at_mut_checked
1070 #[inline]
1071 #[must_use]
1072 pub fn split_at_mut_checked(&mut self, mid: K) -> Option<(&mut Self, &mut Self)>
1073 where
1074 K: Into<usize>,
1075 {
1076 let (left, right) = self.raw.split_at_mut_checked(mid.into())?;
1077 Some((left.as_mut(), right.as_mut()))
1078 }
1079
1080 /// Returns an iterator over subslices separated by elements that match
1081 /// `pred`. The matched element is not contained in the subslices.
1082 ///
1083 /// See [`slice::split`] for more details.
1084 ///
1085 /// [`slice::split`]: https://doc.rust-lang.org/std/primitive.slice.html#method.split
1086 #[inline]
1087 pub fn split<F>(&self, pred: F) -> TiSliceRefMap<Split<'_, V, F>, K, V>
1088 where
1089 F: FnMut(&V) -> bool,
1090 {
1091 self.raw.split(pred).map(Self::from_ref)
1092 }
1093
1094 /// Returns an iterator over mutable subslices separated by elements that
1095 /// match `pred`. The matched element is not contained in the subslices.
1096 ///
1097 /// See [`slice::split_mut`] for more details.
1098 ///
1099 /// [`slice::split_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_mut
1100 #[inline]
1101 pub fn split_mut<F>(&mut self, pred: F) -> TiSliceMutMap<SplitMut<'_, V, F>, K, V>
1102 where
1103 F: FnMut(&V) -> bool,
1104 {
1105 self.raw.split_mut(pred).map(Self::from_mut)
1106 }
1107
1108 /// Returns an iterator over subslices separated by elements that match
1109 /// `pred`. The matched element is contained in the end of the previous
1110 /// subslice as a terminator.
1111 ///
1112 /// See [`slice::split_inclusive`] for more details.
1113 ///
1114 /// [`slice::split_inclusive`]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_inclusive
1115 #[inline]
1116 pub fn split_inclusive<F>(&self, pred: F) -> TiSliceRefMap<SplitInclusive<'_, V, F>, K, V>
1117 where
1118 F: FnMut(&V) -> bool,
1119 {
1120 self.raw.split_inclusive(pred).map(Self::from_ref)
1121 }
1122
1123 /// Returns an iterator over mutable subslices separated by elements that
1124 /// match `pred`. The matched element is contained in the previous
1125 /// subslice as a terminator.
1126 ///
1127 /// See [`slice::split_inclusive_mut`] for more details.
1128 ///
1129 /// [`slice::split_inclusive_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_inclusive_mut
1130 #[inline]
1131 pub fn split_inclusive_mut<F>(
1132 &mut self,
1133 pred: F,
1134 ) -> TiSliceMutMap<SplitInclusiveMut<'_, V, F>, K, V>
1135 where
1136 F: FnMut(&V) -> bool,
1137 {
1138 self.raw.split_inclusive_mut(pred).map(Self::from_mut)
1139 }
1140
1141 /// Returns an iterator over subslices separated by elements that match
1142 /// `pred`, starting at the end of the slice and working backwards.
1143 /// The matched element is not contained in the subslices.
1144 ///
1145 /// See [`slice::rsplit`] for more details.
1146 ///
1147 /// [`slice::rsplit`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rsplit
1148 #[inline]
1149 pub fn rsplit<F>(&self, pred: F) -> TiSliceRefMap<RSplit<'_, V, F>, K, V>
1150 where
1151 F: FnMut(&V) -> bool,
1152 {
1153 self.raw.rsplit(pred).map(Self::from_ref)
1154 }
1155
1156 /// Returns an iterator over mutable subslices separated by elements that
1157 /// match `pred`, starting at the end of the slice and working
1158 /// backwards. The matched element is not contained in the subslices.
1159 ///
1160 /// See [`slice::rsplit_mut`] for more details.
1161 ///
1162 /// [`slice::rsplit_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rsplit_mut
1163 #[inline]
1164 pub fn rsplit_mut<F>(&mut self, pred: F) -> TiSliceMutMap<RSplitMut<'_, V, F>, K, V>
1165 where
1166 F: FnMut(&V) -> bool,
1167 {
1168 self.raw.rsplit_mut(pred).map(Self::from_mut)
1169 }
1170
1171 /// Returns an iterator over subslices separated by elements that match
1172 /// `pred`, limited to returning at most `n` items. The matched element is
1173 /// not contained in the subslices.
1174 ///
1175 /// See [`slice::splitn`] for more details.
1176 ///
1177 /// [`slice::splitn`]: https://doc.rust-lang.org/std/primitive.slice.html#method.splitn
1178 #[inline]
1179 pub fn splitn<F>(&self, n: usize, pred: F) -> TiSliceRefMap<SplitN<'_, V, F>, K, V>
1180 where
1181 F: FnMut(&V) -> bool,
1182 {
1183 self.raw.splitn(n, pred).map(Self::from_ref)
1184 }
1185
1186 /// Returns an iterator over subslices separated by elements that match
1187 /// `pred`, limited to returning at most `n` items. The matched element is
1188 /// not contained in the subslices.
1189 ///
1190 /// See [`slice::splitn_mut`] for more details.
1191 ///
1192 /// [`slice::splitn_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.splitn_mut
1193 #[inline]
1194 pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> TiSliceMutMap<SplitNMut<'_, V, F>, K, V>
1195 where
1196 F: FnMut(&V) -> bool,
1197 {
1198 self.raw.splitn_mut(n, pred).map(Self::from_mut)
1199 }
1200
1201 /// Returns an iterator over subslices separated by elements that match
1202 /// `pred` limited to returning at most `n` items. This starts at the end of
1203 /// the slice and works backwards. The matched element is not contained in
1204 /// the subslices.
1205 ///
1206 /// See [`slice::rsplitn`] for more details.
1207 ///
1208 /// [`slice::rsplitn`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rsplitn
1209 #[inline]
1210 pub fn rsplitn<F>(&self, n: usize, pred: F) -> TiSliceRefMap<RSplitN<'_, V, F>, K, V>
1211 where
1212 F: FnMut(&V) -> bool,
1213 {
1214 self.raw.rsplitn(n, pred).map(Self::from_ref)
1215 }
1216
1217 /// Returns an iterator over subslices separated by elements that match
1218 /// `pred` limited to returning at most `n` items. This starts at the end of
1219 /// the slice and works backwards. The matched element is not contained in
1220 /// the subslices.
1221 ///
1222 /// See [`slice::rsplitn_mut`] for more details.
1223 ///
1224 /// [`slice::rsplitn_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rsplitn_mut
1225 #[inline]
1226 pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> TiSliceMutMap<RSplitNMut<'_, V, F>, K, V>
1227 where
1228 F: FnMut(&V) -> bool,
1229 {
1230 self.raw.rsplitn_mut(n, pred).map(Self::from_mut)
1231 }
1232
1233 /// Returns `true` if the slice contains an element with the given value.
1234 ///
1235 /// See [`slice::contains`] for more details.
1236 ///
1237 /// [`slice::contains`]: https://doc.rust-lang.org/std/primitive.slice.html#method.contains
1238 #[inline]
1239 pub fn contains(&self, x: &V) -> bool
1240 where
1241 V: PartialEq,
1242 {
1243 self.raw.contains(x)
1244 }
1245
1246 /// Returns `true` if `needle` is a prefix of the slice.
1247 ///
1248 /// See [`slice::starts_with`] for more details.
1249 ///
1250 /// [`slice::starts_with`]: https://doc.rust-lang.org/std/primitive.slice.html#method.starts_with
1251 #[inline]
1252 pub fn starts_with(&self, needle: &Self) -> bool
1253 where
1254 V: PartialEq,
1255 {
1256 self.raw.starts_with(needle.as_ref())
1257 }
1258
1259 /// Returns `true` if `needle` is a suffix of the slice.
1260 ///
1261 /// See [`slice::ends_with`] for more details.
1262 ///
1263 /// [`slice::ends_with`]: https://doc.rust-lang.org/std/primitive.slice.html#method.ends_with
1264 #[inline]
1265 pub fn ends_with(&self, needle: &Self) -> bool
1266 where
1267 V: PartialEq,
1268 {
1269 self.raw.ends_with(needle.as_ref())
1270 }
1271
1272 /// Binary searches this sorted slice for a given element.
1273 ///
1274 /// See [`slice::binary_search`] for more details.
1275 ///
1276 /// [`slice::binary_search`]: https://doc.rust-lang.org/std/primitive.slice.html#method.binary_search
1277 #[expect(clippy::missing_errors_doc, reason = "missed in std docs")]
1278 #[inline]
1279 pub fn binary_search(&self, x: &V) -> Result<K, K>
1280 where
1281 V: Ord,
1282 usize: Into<K>,
1283 {
1284 self.raw
1285 .binary_search(x)
1286 .map(Into::into)
1287 .map_err(Into::into)
1288 }
1289
1290 /// Binary searches this sorted slice with a comparator function.
1291 ///
1292 /// See [`slice::binary_search_by`] for more details.
1293 ///
1294 /// [`slice::binary_search_by`]: https://doc.rust-lang.org/std/primitive.slice.html#method.binary_search_by
1295 #[expect(clippy::missing_errors_doc, reason = "missed in std docs")]
1296 #[inline]
1297 pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<K, K>
1298 where
1299 F: FnMut(&'a V) -> Ordering,
1300 usize: Into<K>,
1301 {
1302 self.raw
1303 .binary_search_by(f)
1304 .map(Into::into)
1305 .map_err(Into::into)
1306 }
1307
1308 /// Binary searches this sorted slice with a key extraction function.
1309 ///
1310 /// See [`slice::binary_search_by_key`] for more details.
1311 ///
1312 /// [`slice::binary_search_by_key`]: https://doc.rust-lang.org/std/primitive.slice.html#method.binary_search_by_key
1313 #[expect(clippy::missing_errors_doc, reason = "missed in std docs")]
1314 #[inline]
1315 pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, f: F) -> Result<K, K>
1316 where
1317 F: FnMut(&'a V) -> B,
1318 B: Ord,
1319 usize: Into<K>,
1320 {
1321 self.raw
1322 .binary_search_by_key(b, f)
1323 .map(Into::into)
1324 .map_err(Into::into)
1325 }
1326
1327 /// Sorts the slice, but may not preserve the order of equal elements.
1328 ///
1329 /// See [`slice::sort_unstable`] for more details.
1330 ///
1331 /// [`slice::sort_unstable`]: https://doc.rust-lang.org/std/primitive.slice.html#method.sort_unstable
1332 #[inline]
1333 pub fn sort_unstable(&mut self)
1334 where
1335 V: Ord,
1336 {
1337 self.raw.sort_unstable();
1338 }
1339
1340 /// Sorts the slice with a comparator function, but may not preserve the
1341 /// order of equal elements.
1342 ///
1343 /// See [`slice::sort_unstable_by`] for more details.
1344 ///
1345 /// [`slice::sort_unstable_by`]: https://doc.rust-lang.org/std/primitive.slice.html#method.sort_unstable_by
1346 #[inline]
1347 pub fn sort_unstable_by<F>(&mut self, compare: F)
1348 where
1349 F: FnMut(&V, &V) -> Ordering,
1350 {
1351 self.raw.sort_unstable_by(compare);
1352 }
1353
1354 /// Sorts the slice with a key extraction function, but may not preserve the
1355 /// order of equal elements.
1356 ///
1357 /// See [`slice::sort_unstable_by_key`] for more details.
1358 ///
1359 /// [`slice::sort_unstable_by_key`]: https://doc.rust-lang.org/std/primitive.slice.html#method.sort_unstable_by_key
1360 #[inline]
1361 pub fn sort_unstable_by_key<K2, F>(&mut self, f: F)
1362 where
1363 F: FnMut(&V) -> K2,
1364 K2: Ord,
1365 {
1366 self.raw.sort_unstable_by_key(f);
1367 }
1368
1369 /// Reorder the slice such that the element at `index` after the reordering
1370 /// is at its final sorted position.
1371 ///
1372 /// See [`slice::select_nth_unstable`] for more details.
1373 ///
1374 /// # Panics
1375 ///
1376 /// Panics when `index >= len()`, meaning it always panics on empty slices.
1377 ///
1378 /// May panic if the implementation of [`Ord`] for `T` does not implement a
1379 /// [total order].
1380 ///
1381 /// [`slice::select_nth_unstable`]: https://doc.rust-lang.org/std/primitive.slice.html#method.select_nth_unstable
1382 #[inline]
1383 pub fn select_nth_unstable(&mut self, index: K) -> (&mut Self, &mut V, &mut Self)
1384 where
1385 K: Into<usize>,
1386 V: Ord,
1387 {
1388 let (left, nth, right) = self.raw.select_nth_unstable(index.into());
1389 (Self::from_mut(left), nth, Self::from_mut(right))
1390 }
1391
1392 /// Reorder the slice with a comparator function such that the element at
1393 /// `index` after the reordering is at its final sorted position.
1394 ///
1395 /// See [`slice::select_nth_unstable_by`] for more details.
1396 ///
1397 /// # Panics
1398 ///
1399 /// Panics when `index >= len()`, meaning it always panics on empty slices.
1400 ///
1401 /// May panic if `compare` does not implement a [total order].
1402 ///
1403 /// [`slice::select_nth_unstable_by`]: https://doc.rust-lang.org/std/primitive.slice.html#method.select_nth_unstable_by
1404 #[inline]
1405 pub fn select_nth_unstable_by<F>(
1406 &mut self,
1407 index: K,
1408 compare: F,
1409 ) -> (&mut Self, &mut V, &mut Self)
1410 where
1411 K: Into<usize>,
1412 F: FnMut(&V, &V) -> Ordering,
1413 {
1414 let (left, nth, right) = self.raw.select_nth_unstable_by(index.into(), compare);
1415 (Self::from_mut(left), nth, Self::from_mut(right))
1416 }
1417
1418 /// Reorder the slice with a key extraction function such that the element
1419 /// at `index` after the reordering is at its final sorted position.
1420 ///
1421 /// See [`slice::select_nth_unstable_by_key`] for more details.
1422 ///
1423 /// # Panics
1424 ///
1425 /// Panics when `index >= len()`, meaning it always panics on empty slices.
1426 ///
1427 /// May panic if `K: Ord` does not implement a total order.
1428 ///
1429 /// [`slice::select_nth_unstable_by_key`]: https://doc.rust-lang.org/std/primitive.slice.html#method.select_nth_unstable_by_key
1430 #[inline]
1431 pub fn select_nth_unstable_by_key<Key, F>(
1432 &mut self,
1433 index: K,
1434 f: F,
1435 ) -> (&mut Self, &mut V, &mut Self)
1436 where
1437 K: Into<usize>,
1438 F: FnMut(&V) -> Key,
1439 Key: Ord,
1440 {
1441 let (left, nth, right) = self.raw.select_nth_unstable_by_key(index.into(), f);
1442 (Self::from_mut(left), nth, Self::from_mut(right))
1443 }
1444
1445 /// Rotates the slice in-place such that the first `mid` elements of the
1446 /// slice move to the end while the last `self.next_key() - mid` elements
1447 /// move to the front. After calling `rotate_left`, the element
1448 /// previously at index `mid` will become the first element in the
1449 /// slice.
1450 ///
1451 /// See [`slice::rotate_left`] for more details.
1452 ///
1453 /// [`slice::rotate_left`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rotate_left
1454 #[inline]
1455 pub fn rotate_left(&mut self, mid: K)
1456 where
1457 K: Into<usize>,
1458 {
1459 self.raw.rotate_left(mid.into());
1460 }
1461
1462 /// Rotates the slice in-place such that the first `self.next_key() - k`
1463 /// elements of the slice move to the end while the last `k` elements move
1464 /// to the front. After calling `rotate_right`, the element previously at
1465 /// index `self.next_key() - k` will become the first element in the slice.
1466 ///
1467 /// See [`slice::rotate_right`] for more details.
1468 ///
1469 /// [`slice::rotate_right`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rotate_right
1470 #[inline]
1471 pub fn rotate_right(&mut self, k: K)
1472 where
1473 K: Into<usize>,
1474 {
1475 self.raw.rotate_right(k.into());
1476 }
1477
1478 /// Fills `self` with elements by cloning `value`.
1479 ///
1480 /// See [`slice::fill`] for more details.
1481 ///
1482 /// [`slice::fill`]: https://doc.rust-lang.org/std/primitive.slice.html#method.fill
1483 #[inline]
1484 pub fn fill(&mut self, value: V)
1485 where
1486 V: Clone,
1487 {
1488 self.raw.fill(value);
1489 }
1490
1491 /// Fills `self` with elements returned by calling a closure repeatedly.
1492 ///
1493 /// See [`slice::fill_with`] for more details.
1494 ///
1495 /// [`slice::fill_with`]: https://doc.rust-lang.org/std/primitive.slice.html#method.fill_with
1496 #[inline]
1497 pub fn fill_with<F>(&mut self, f: F)
1498 where
1499 F: FnMut() -> V,
1500 {
1501 self.raw.fill_with(f);
1502 }
1503
1504 /// Copies the elements from `src` into `self`.
1505 ///
1506 /// See [`slice::clone_from_slice`] for more details.
1507 ///
1508 /// [`slice::clone_from_slice`]: https://doc.rust-lang.org/std/primitive.slice.html#method.clone_from_slice
1509 #[inline]
1510 pub fn clone_from_slice(&mut self, src: &Self)
1511 where
1512 V: Clone,
1513 {
1514 self.raw.clone_from_slice(&src.raw);
1515 }
1516
1517 /// Copies all elements from `src` into `self`, using a memcpy.
1518 ///
1519 /// See [`slice::copy_from_slice`] for more details.
1520 ///
1521 /// [`slice::copy_from_slice`]: https://doc.rust-lang.org/std/primitive.slice.html#method.copy_from_slice
1522 #[inline]
1523 pub const fn copy_from_slice(&mut self, src: &Self)
1524 where
1525 V: Copy,
1526 {
1527 self.raw.copy_from_slice(&src.raw);
1528 }
1529
1530 /// Copies elements from one part of the slice to another part of itself,
1531 /// using a memmove.
1532 ///
1533 /// See [`slice::copy_within`] for more details.
1534 ///
1535 /// [`slice::copy_within`]: https://doc.rust-lang.org/std/primitive.slice.html#method.copy_within
1536 #[inline]
1537 pub fn copy_within<R>(&mut self, src: R, dest: K)
1538 where
1539 R: TiRangeBounds<K>,
1540 V: Copy,
1541 K: Into<usize>,
1542 {
1543 self.raw.copy_within(src.into_range(), dest.into());
1544 }
1545
1546 /// Swaps all elements in `self` with those in `other`.
1547 ///
1548 ///
1549 /// See [`slice::swap_with_slice`] for more details.
1550 ///
1551 /// [`slice::swap_with_slice`]: https://doc.rust-lang.org/std/primitive.slice.html#method.swap_with_slice
1552 #[inline]
1553 pub fn swap_with_slice(&mut self, other: &mut Self) {
1554 self.raw.swap_with_slice(other.as_mut());
1555 }
1556
1557 /// Transmute the slice to a slice of another type, ensuring alignment of
1558 /// the types is maintained.
1559 ///
1560 /// See [`slice::align_to`] for more details.
1561 ///
1562 /// # Safety
1563 ///
1564 /// This method is essentially a `transmute` with respect to the elements in
1565 /// the returned middle slice, so all the usual caveats pertaining to
1566 /// `transmute::<T, U>` also apply here.
1567 ///
1568 /// [`slice::align_to`]: https://doc.rust-lang.org/std/primitive.slice.html#method.align_to
1569 #[inline]
1570 pub unsafe fn align_to<U>(&self) -> (&Self, &TiSlice<K, U>, &Self) {
1571 // SAFETY: Guaranteed by the caller.
1572 let (first, mid, last) = unsafe { self.raw.align_to() };
1573 (first.as_ref(), mid.as_ref(), last.as_ref())
1574 }
1575
1576 /// Transmute the slice to a slice of another type, ensuring alignment of
1577 /// the types is maintained.
1578 ///
1579 /// See [`slice::align_to_mut`] for more details.
1580 ///
1581 /// # Safety
1582 ///
1583 /// This method is essentially a `transmute` with respect to the elements in
1584 /// the returned middle slice, so all the usual caveats pertaining to
1585 /// `transmute::<T, U>` also apply here.
1586 ///
1587 /// [`slice::align_to_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.align_to_mut
1588 #[inline]
1589 pub unsafe fn align_to_mut<U>(&mut self) -> (&mut Self, &mut TiSlice<K, U>, &mut Self) {
1590 // SAFETY: Guaranteed by the caller.
1591 let (first, mid, last) = unsafe { self.raw.align_to_mut() };
1592 (first.as_mut(), mid.as_mut(), last.as_mut())
1593 }
1594
1595 /// Checks if the elements of this slice are sorted.
1596 ///
1597 /// See [`slice::is_sorted`] for more details.
1598 ///
1599 /// [`slice::is_sorted`]: https://doc.rust-lang.org/std/primitive.slice.html#method.is_sorted
1600 #[inline]
1601 #[must_use]
1602 pub fn is_sorted(&self) -> bool
1603 where
1604 V: PartialOrd,
1605 {
1606 self.raw.is_sorted()
1607 }
1608
1609 /// Checks if the elements of this slice are sorted using the given
1610 /// comparator function.
1611 ///
1612 /// See [`slice::is_sorted_by`] for more details.
1613 ///
1614 /// [`slice::is_sorted_by`]: https://doc.rust-lang.org/std/primitive.slice.html#method.is_sorted_by
1615 #[inline]
1616 #[must_use]
1617 pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> bool
1618 where
1619 F: FnMut(&'a V, &'a V) -> bool,
1620 {
1621 self.raw.is_sorted_by(compare)
1622 }
1623
1624 /// Checks if the elements of this slice are sorted using the given key
1625 /// extraction function.
1626 ///
1627 /// See [`slice::is_sorted_by_key`] for more details.
1628 ///
1629 /// [`slice::is_sorted_by_key`]: https://doc.rust-lang.org/std/primitive.slice.html#method.is_sorted_by_key
1630 #[inline]
1631 #[must_use]
1632 pub fn is_sorted_by_key<'a, F, T>(&'a self, f: F) -> bool
1633 where
1634 F: FnMut(&'a V) -> T,
1635 T: PartialOrd,
1636 {
1637 self.raw.is_sorted_by_key(f)
1638 }
1639
1640 /// Returns the index of the partition point according to the given
1641 /// predicate (the index of the first element of the second partition).
1642 ///
1643 /// See [`slice::partition_point`] for more details.
1644 ///
1645 /// [`slice::partition_point`]: https://doc.rust-lang.org/std/primitive.slice.html#method.partition_point
1646 #[inline]
1647 #[must_use]
1648 pub fn partition_point<P>(&self, pred: P) -> K
1649 where
1650 usize: Into<K>,
1651 P: FnMut(&V) -> bool,
1652 {
1653 self.raw.partition_point(pred).into()
1654 }
1655
1656 /// Removes the first element of the slice and returns a reference
1657 /// to it.
1658 ///
1659 /// Returns `None` if the slice is empty.
1660 ///
1661 /// See [`slice::split_off_first`] for more details.
1662 ///
1663 /// [`slice::split_off_first`]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_off_first
1664 #[inline]
1665 pub const fn split_off_first<'a>(self: &mut &'a Self) -> Option<&'a V> {
1666 let Some((first, rem)) = self.split_first() else {
1667 return None;
1668 };
1669 *self = rem;
1670 Some(first)
1671 }
1672
1673 /// Removes the first element of the slice and returns a mutable
1674 ///
1675 /// See [`slice::split_off_first_mut`] for more details.
1676 ///
1677 /// [`slice::split_off_first_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_off_first_mut
1678 /// reference to it.
1679 #[expect(clippy::mut_mut, reason = "used in original slice API")]
1680 #[inline]
1681 pub const fn split_off_first_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut V> {
1682 let Some((first, rem)) =
1683 core::mem::replace(self, Self::from_mut(&mut [])).split_first_mut()
1684 else {
1685 return None;
1686 };
1687 *self = rem;
1688 Some(first)
1689 }
1690
1691 /// Removes the last element of the slice and returns a reference
1692 /// to it.
1693 ///
1694 /// Returns `None` if the slice is empty.
1695 ///
1696 /// See [`slice::split_off_last`] for more details.
1697 ///
1698 /// [`slice::split_off_last`]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_off_last
1699 #[inline]
1700 pub const fn split_off_last<'a>(self: &mut &'a Self) -> Option<&'a V> {
1701 let Some((last, rem)) = self.split_last() else {
1702 return None;
1703 };
1704 *self = rem;
1705 Some(last)
1706 }
1707
1708 /// Removes the last element of the slice and returns a mutable
1709 /// reference to it.
1710 ///
1711 /// Returns `None` if the slice is empty.
1712 ///
1713 /// See [`slice::split_off_last_mut`] for more details.
1714 ///
1715 /// [`slice::split_off_last_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.split_off_last_mut
1716 #[expect(clippy::mut_mut, reason = "used in original slice API")]
1717 #[inline]
1718 pub const fn split_off_last_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut V> {
1719 let Some((last, rem)) = core::mem::replace(self, Self::from_mut(&mut [])).split_last_mut()
1720 else {
1721 return None;
1722 };
1723 *self = rem;
1724 Some(last)
1725 }
1726}
1727
1728impl<K> TiSlice<K, u8> {
1729 /// Checks if all bytes in this slice are within the ASCII range.
1730 ///
1731 /// See [`slice::is_ascii`] for more details.
1732 ///
1733 /// [`slice::is_ascii`]: https://doc.rust-lang.org/std/primitive.slice.html#method.is_ascii
1734 #[inline]
1735 #[must_use]
1736 pub const fn is_ascii(&self) -> bool {
1737 self.raw.is_ascii()
1738 }
1739
1740 /// Checks that two slices are an ASCII case-insensitive match.
1741 ///
1742 /// See [`slice::eq_ignore_ascii_case`] for more details.
1743 ///
1744 /// [`slice::eq_ignore_ascii_case`]: https://doc.rust-lang.org/std/primitive.slice.html#method.eq_ignore_ascii_case
1745 #[inline]
1746 #[must_use]
1747 pub const fn eq_ignore_ascii_case(&self, other: &Self) -> bool {
1748 self.raw.eq_ignore_ascii_case(&other.raw)
1749 }
1750
1751 /// Converts this slice to its ASCII upper case equivalent in-place.
1752 ///
1753 /// See [`slice::make_ascii_uppercase`] for more details.
1754 ///
1755 /// [`slice::make_ascii_uppercase`]: https://doc.rust-lang.org/std/primitive.slice.html#method.make_ascii_uppercase
1756 #[inline]
1757 pub const fn make_ascii_uppercase(&mut self) {
1758 self.raw.make_ascii_uppercase();
1759 }
1760
1761 /// Converts this slice to its ASCII lower case equivalent in-place.
1762 ///
1763 /// See [`slice::make_ascii_lowercase`] for more details.
1764 ///
1765 /// [`slice::make_ascii_lowercase`]: https://doc.rust-lang.org/std/primitive.slice.html#method.make_ascii_lowercase
1766 #[inline]
1767 pub const fn make_ascii_lowercase(&mut self) {
1768 self.raw.make_ascii_lowercase();
1769 }
1770
1771 /// Returns an iterator that produces an escaped version of this slice,
1772 /// treating it as an ASCII string.
1773 ///
1774 /// See [`slice::escape_ascii`] for more details.
1775 ///
1776 /// [`slice::escape_ascii`]: https://doc.rust-lang.org/std/primitive.slice.html#method.escape_ascii
1777 #[must_use = "this returns the escaped bytes as an iterator, without modifying the original"]
1778 #[inline]
1779 pub fn escape_ascii(&self) -> EscapeAscii<'_> {
1780 self.raw.escape_ascii()
1781 }
1782
1783 /// Returns a byte slice with leading ASCII whitespace bytes removed.
1784 ///
1785 /// See [`slice::trim_ascii_start`] for more details.
1786 ///
1787 /// [`slice::trim_ascii_start`]: https://doc.rust-lang.org/std/primitive.slice.html#method.trim_ascii_start
1788 #[inline]
1789 #[must_use]
1790 pub const fn trim_ascii_start(&self) -> &Self {
1791 Self::from_ref(self.raw.trim_ascii_start())
1792 }
1793
1794 /// Returns a byte slice with trailing ASCII whitespace bytes removed.
1795 ///
1796 /// See [`slice::trim_ascii_end`] for more details.
1797 ///
1798 /// [`slice::trim_ascii_end`]: https://doc.rust-lang.org/std/primitive.slice.html#method.trim_ascii_end
1799 #[inline]
1800 #[must_use]
1801 pub const fn trim_ascii_end(&self) -> &Self {
1802 Self::from_ref(self.raw.trim_ascii_end())
1803 }
1804
1805 /// Returns a byte slice with leading and trailing ASCII whitespace bytes
1806 /// removed.
1807 ///
1808 /// See [`slice::trim_ascii`] for more details.
1809 ///
1810 /// [`slice::trim_ascii`]: https://doc.rust-lang.org/std/primitive.slice.html#method.trim_ascii
1811 #[inline]
1812 #[must_use]
1813 pub const fn trim_ascii(&self) -> &Self {
1814 Self::from_ref(self.raw.trim_ascii())
1815 }
1816
1817 /// Creates an iterator over the contiguous valid UTF-8 ranges of this
1818 /// slice, and the non-UTF-8 fragments in between.
1819 ///
1820 /// See [`slice::utf8_chunks`] for more details.
1821 ///
1822 /// [`slice::utf8_chunks`]: https://doc.rust-lang.org/std/primitive.slice.html#method.utf8_chunks
1823 #[inline]
1824 pub fn utf8_chunks(&self) -> Utf8Chunks<'_> {
1825 self.raw.utf8_chunks()
1826 }
1827}
1828
1829#[cfg(feature = "alloc")]
1830#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
1831impl<K, V> TiSlice<K, V> {
1832 /// Sorts the slice.
1833 ///
1834 /// See [`slice::sort`] for more details.
1835 ///
1836 /// [`slice::sort`]: https://doc.rust-lang.org/std/primitive.slice.html#method.sort
1837 #[inline]
1838 pub fn sort(&mut self)
1839 where
1840 V: Ord,
1841 {
1842 self.raw.sort();
1843 }
1844
1845 /// Sorts the slice with a comparator function.
1846 ///
1847 /// See [`slice::sort_by`] for more details.
1848 ///
1849 /// [`slice::sort_by`]: https://doc.rust-lang.org/std/primitive.slice.html#method.sort_by
1850 #[inline]
1851 pub fn sort_by<F>(&mut self, compare: F)
1852 where
1853 F: FnMut(&V, &V) -> Ordering,
1854 {
1855 self.raw.sort_by(compare);
1856 }
1857
1858 /// Sorts the slice with a key extraction function.
1859 ///
1860 /// See [`slice::sort_by_key`] for more details.
1861 ///
1862 /// [`slice::sort_by_key`]: https://doc.rust-lang.org/std/primitive.slice.html#method.sort_by_key
1863 #[inline]
1864 pub fn sort_by_key<K2, F>(&mut self, f: F)
1865 where
1866 F: FnMut(&V) -> K2,
1867 K2: Ord,
1868 {
1869 self.raw.sort_by_key(f);
1870 }
1871
1872 /// Sorts the slice with a key extraction function.
1873 ///
1874 /// See [`slice::sort_by_cached_key`] for more details.
1875 ///
1876 /// [`slice::sort_by_cached_key`]: https://doc.rust-lang.org/std/primitive.slice.html#method.sort_by_cached_key
1877 #[inline]
1878 pub fn sort_by_cached_key<K2, F>(&mut self, f: F)
1879 where
1880 F: FnMut(&V) -> K2,
1881 K2: Ord,
1882 {
1883 self.raw.sort_by_cached_key(f);
1884 }
1885
1886 /// Copies `self` into a new `TiVec`.
1887 ///
1888 /// See [`slice::to_vec`] for more details.
1889 ///
1890 /// [`slice::to_vec`]: https://doc.rust-lang.org/std/primitive.slice.html#method.to_vec
1891 #[inline]
1892 pub fn to_vec(&self) -> TiVec<K, V>
1893 where
1894 V: Clone,
1895 {
1896 self.raw.to_vec().into()
1897 }
1898
1899 /// Converts `self` into a vector without clones or allocation.
1900 ///
1901 /// See [`slice::into_vec`] for more details.
1902 ///
1903 /// [`slice::into_vec`]: https://doc.rust-lang.org/std/primitive.slice.html#method.into_vec
1904 #[inline]
1905 #[must_use]
1906 pub fn into_vec(self: Box<Self>) -> TiVec<K, V> {
1907 Box::<[V]>::from(self).into_vec().into()
1908 }
1909
1910 /// Creates a vector by repeating a slice `n` times.
1911 ///
1912 /// See [`slice::repeat`] for more details.
1913 ///
1914 /// [`slice::repeat`]: https://doc.rust-lang.org/std/primitive.slice.html#method.repeat
1915 #[inline]
1916 pub fn repeat(&self, n: usize) -> TiVec<K, V>
1917 where
1918 V: Copy,
1919 {
1920 self.raw.repeat(n).into()
1921 }
1922
1923 /// Flattens a slice of `T` into a single value `Self::Output`.
1924 ///
1925 /// See [`slice::concat`] for more details.
1926 ///
1927 /// [`slice::concat`]: https://doc.rust-lang.org/std/primitive.slice.html#method.concat
1928 #[inline]
1929 pub fn concat<Item: ?Sized>(&self) -> <Self as Concat<Item>>::Output
1930 where
1931 Self: Concat<Item>,
1932 {
1933 Concat::concat(self)
1934 }
1935
1936 /// Flattens a slice of `T` into a single value `Self::Output`, placing a
1937 /// given separator between each.
1938 ///
1939 /// See [`slice::join`] for more details.
1940 ///
1941 /// [`slice::join`]: https://doc.rust-lang.org/std/primitive.slice.html#method.join
1942 #[inline]
1943 pub fn join<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
1944 where
1945 Self: Join<Separator>,
1946 {
1947 Join::join(self, sep)
1948 }
1949}
1950
1951#[cfg(feature = "alloc")]
1952#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
1953impl<K> TiSlice<K, u8> {
1954 /// Returns a vector containing a copy of this slice where each byte
1955 /// is mapped to its ASCII upper case equivalent.
1956 ///
1957 /// See [`slice::to_ascii_uppercase`] for more details.
1958 ///
1959 /// [`slice::to_ascii_uppercase`]: https://doc.rust-lang.org/std/primitive.slice.html#method.to_ascii_uppercase
1960 #[inline]
1961 #[must_use]
1962 pub fn to_ascii_uppercase(&self) -> TiVec<K, u8> {
1963 self.raw.to_ascii_uppercase().into()
1964 }
1965
1966 /// Returns a vector containing a copy of this slice where each byte
1967 /// is mapped to its ASCII lower case equivalent.
1968 ///
1969 /// See [`slice::to_ascii_lowercase`] for more details.
1970 ///
1971 /// [`slice::to_ascii_lowercase`]: https://doc.rust-lang.org/std/primitive.slice.html#method.to_ascii_lowercase
1972 #[inline]
1973 #[must_use]
1974 pub fn to_ascii_lowercase(&self) -> TiVec<K, u8> {
1975 self.raw.to_ascii_lowercase().into()
1976 }
1977}
1978
1979impl<K, V> fmt::Debug for TiSlice<K, V>
1980where
1981 K: fmt::Debug,
1982 V: fmt::Debug,
1983 usize: Into<K>,
1984{
1985 #[allow(clippy::allow_attributes, reason = "rust-lang/rust#130021")]
1986 #[allow(
1987 clippy::missing_inline_in_public_items,
1988 reason = "use default inlining behavior"
1989 )]
1990 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1991 f.debug_map().entries(self.iter_enumerated()).finish()
1992 }
1993}
1994
1995impl<K, V> AsRef<Self> for TiSlice<K, V> {
1996 #[inline]
1997 fn as_ref(&self) -> &Self {
1998 self
1999 }
2000}
2001
2002impl<K, V> AsMut<Self> for TiSlice<K, V> {
2003 #[inline]
2004 fn as_mut(&mut self) -> &mut Self {
2005 self
2006 }
2007}
2008
2009impl<K, V> AsRef<[V]> for TiSlice<K, V> {
2010 #[inline]
2011 fn as_ref(&self) -> &[V] {
2012 &self.raw
2013 }
2014}
2015
2016impl<K, V> AsMut<[V]> for TiSlice<K, V> {
2017 #[inline]
2018 fn as_mut(&mut self) -> &mut [V] {
2019 &mut self.raw
2020 }
2021}
2022
2023impl<K, V> AsRef<TiSlice<K, V>> for [V] {
2024 #[inline]
2025 fn as_ref(&self) -> &TiSlice<K, V> {
2026 TiSlice::from_ref(self)
2027 }
2028}
2029
2030impl<K, V> AsMut<TiSlice<K, V>> for [V] {
2031 #[inline]
2032 fn as_mut(&mut self) -> &mut TiSlice<K, V> {
2033 TiSlice::from_mut(self)
2034 }
2035}
2036
2037#[cfg(feature = "alloc")]
2038#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
2039impl<'a, K, V: Clone> From<&'a TiSlice<K, V>> for Cow<'a, TiSlice<K, V>> {
2040 #[inline]
2041 fn from(value: &'a TiSlice<K, V>) -> Self {
2042 Cow::Borrowed(value)
2043 }
2044}
2045
2046impl<K, V> Eq for TiSlice<K, V> where V: Eq {}
2047
2048impl<K, A, B> PartialEq<TiSlice<K, B>> for TiSlice<K, A>
2049where
2050 A: PartialEq<B>,
2051{
2052 #[inline]
2053 fn eq(&self, other: &TiSlice<K, B>) -> bool {
2054 self.raw == other.raw
2055 }
2056}
2057
2058impl<K, V> Ord for TiSlice<K, V>
2059where
2060 V: Ord,
2061{
2062 #[inline]
2063 fn cmp(&self, other: &Self) -> Ordering {
2064 self.raw.cmp(&other.raw)
2065 }
2066}
2067
2068impl<K, V> PartialOrd<Self> for TiSlice<K, V>
2069where
2070 V: PartialOrd<V>,
2071{
2072 #[inline]
2073 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
2074 self.raw.partial_cmp(&other.raw)
2075 }
2076}
2077
2078impl<K, V> Hash for TiSlice<K, V>
2079where
2080 V: Hash,
2081{
2082 #[inline]
2083 fn hash<H: Hasher>(&self, state: &mut H) {
2084 self.raw.hash(state);
2085 }
2086}
2087
2088impl<K, V> Default for &TiSlice<K, V> {
2089 #[inline]
2090 fn default() -> Self {
2091 TiSlice::from_ref(&[])
2092 }
2093}
2094
2095impl<K, V> Default for &mut TiSlice<K, V> {
2096 #[inline]
2097 fn default() -> Self {
2098 TiSlice::from_mut(&mut [])
2099 }
2100}
2101
2102impl<I, K, V> Index<I> for TiSlice<K, V>
2103where
2104 I: TiSliceIndex<K, V>,
2105{
2106 type Output = I::Output;
2107
2108 #[inline]
2109 fn index(&self, index: I) -> &Self::Output {
2110 index.index(self)
2111 }
2112}
2113
2114impl<I, K, V> IndexMut<I> for TiSlice<K, V>
2115where
2116 I: TiSliceIndex<K, V>,
2117{
2118 #[inline]
2119 fn index_mut(&mut self, index: I) -> &mut Self::Output {
2120 index.index_mut(self)
2121 }
2122}
2123
2124impl<'a, K, V> IntoIterator for &'a TiSlice<K, V> {
2125 type Item = &'a V;
2126 type IntoIter = Iter<'a, V>;
2127
2128 #[inline]
2129 fn into_iter(self) -> Iter<'a, V> {
2130 self.raw.iter()
2131 }
2132}
2133
2134impl<'a, K, V> IntoIterator for &'a mut TiSlice<K, V> {
2135 type Item = &'a mut V;
2136 type IntoIter = IterMut<'a, V>;
2137
2138 #[inline]
2139 fn into_iter(self) -> IterMut<'a, V> {
2140 self.raw.iter_mut()
2141 }
2142}
2143
2144/// Read is implemented for `&TiSlice<K, u8>` by copying from the slice.
2145///
2146/// Note that reading updates the slice to point to the yet unread part.
2147/// The slice will be empty when EOF is reached.
2148#[cfg(feature = "std")]
2149#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
2150impl<K> Read for &TiSlice<K, u8> {
2151 #[inline]
2152 fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
2153 as_readable_byte_slice(self).read(buf)
2154 }
2155
2156 #[inline]
2157 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> IoResult<usize> {
2158 as_readable_byte_slice(self).read_vectored(bufs)
2159 }
2160
2161 #[inline]
2162 fn read_exact(&mut self, buf: &mut [u8]) -> IoResult<()> {
2163 as_readable_byte_slice(self).read_exact(buf)
2164 }
2165
2166 #[inline]
2167 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> IoResult<usize> {
2168 as_readable_byte_slice(self).read_to_end(buf)
2169 }
2170
2171 #[inline]
2172 fn read_to_string(&mut self, buf: &mut String) -> IoResult<usize> {
2173 as_readable_byte_slice(self).read_to_string(buf)
2174 }
2175}
2176
2177#[cfg(feature = "std")]
2178#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
2179impl<K> BufRead for &TiSlice<K, u8> {
2180 #[inline]
2181 fn fill_buf(&mut self) -> IoResult<&[u8]> {
2182 as_readable_byte_slice(self).fill_buf()
2183 }
2184
2185 #[inline]
2186 fn consume(&mut self, amt: usize) {
2187 as_readable_byte_slice(self).consume(amt);
2188 }
2189}
2190
2191/// Write is implemented for `&mut TiSlice<K, u8>` by copying into the slice,
2192/// overwriting its data.
2193///
2194/// Note that writing updates the slice to point to the yet unwritten part.
2195/// The slice will be empty when it has been completely overwritten.
2196///
2197/// If the number of bytes to be written exceeds the size of the slice, write
2198/// operations will return short writes: ultimately, `Ok(0)`; in this situation,
2199/// `write_all` returns an error of kind `ErrorKind::WriteZero`.
2200#[cfg(feature = "std")]
2201#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
2202impl<K> Write for &mut TiSlice<K, u8> {
2203 #[inline]
2204 fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
2205 as_writable_byte_slice(self).write(buf)
2206 }
2207
2208 #[inline]
2209 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> IoResult<usize> {
2210 as_writable_byte_slice(self).write_vectored(bufs)
2211 }
2212
2213 #[inline]
2214 fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
2215 as_writable_byte_slice(self).write_all(buf)
2216 }
2217
2218 #[inline]
2219 fn flush(&mut self) -> IoResult<()> {
2220 as_writable_byte_slice(self).flush()
2221 }
2222}
2223
2224#[cfg(feature = "std")]
2225#[inline]
2226fn as_readable_byte_slice<'a, 'b, K>(value: &'a mut &'b TiSlice<K, u8>) -> &'a mut &'b [u8] {
2227 let ptr: *mut &TiSlice<K, u8> = core::ptr::from_mut::<&TiSlice<K, u8>>(value);
2228 let ptr: *mut &[u8] = ptr.cast();
2229 // SAFETY: `TiSlice<K, V>` is `repr(transparent)` over a `[V]` type.
2230 unsafe { &mut *ptr }
2231}
2232
2233#[expect(clippy::mut_mut, reason = "can not avoid this cast")]
2234#[cfg(feature = "std")]
2235#[inline]
2236fn as_writable_byte_slice<'a, 'b, K>(
2237 value: &'a mut &'b mut TiSlice<K, u8>,
2238) -> &'a mut &'b mut [u8] {
2239 let ptr: *mut &mut TiSlice<K, u8> = core::ptr::from_mut::<&mut TiSlice<K, u8>>(value);
2240 let ptr: *mut &mut [u8] = ptr.cast();
2241 // SAFETY: `TiSlice<K, V>` is `repr(transparent)` over a `[V]` type.
2242 unsafe { &mut *ptr }
2243}
2244
2245#[cfg(feature = "alloc")]
2246#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
2247impl<K, V: Clone> ToOwned for TiSlice<K, V> {
2248 type Owned = TiVec<K, V>;
2249
2250 #[inline]
2251 fn to_owned(&self) -> TiVec<K, V> {
2252 self.raw.to_owned().into()
2253 }
2254}
2255
2256#[cfg(feature = "serde")]
2257#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
2258impl<K, V> Serialize for TiSlice<K, V>
2259where
2260 V: Serialize,
2261{
2262 #[inline]
2263 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2264 where
2265 S: Serializer,
2266 {
2267 self.raw.serialize(serializer)
2268 }
2269}
2270
2271#[cfg(feature = "bincode")]
2272#[cfg_attr(docsrs, doc(cfg(feature = "bincode")))]
2273impl<K, V> Encode for TiSlice<K, V>
2274where
2275 V: Encode,
2276{
2277 #[inline]
2278 fn encode<E>(&self, encoder: &mut E) -> Result<(), EncodeError>
2279 where
2280 E: Encoder,
2281 {
2282 self.raw.encode(encoder)
2283 }
2284}
2285
2286#[expect(
2287 dead_code,
2288 unused_imports,
2289 unused_mut,
2290 clippy::fallible_impl_from,
2291 clippy::into_iter_on_ref,
2292 clippy::too_many_lines,
2293 clippy::undocumented_unsafe_blocks,
2294 clippy::unwrap_used,
2295 reason = "okay in tests"
2296)]
2297#[rustversion::attr(
2298 before(1.92.0),
2299 expect(clippy::zero_repeat_side_effects, reason = "okay in tests"),
2300)]
2301#[cfg(test)]
2302mod test {
2303 #[cfg(feature = "alloc")]
2304 use alloc::borrow::{Cow, ToOwned};
2305 #[cfg(feature = "alloc")]
2306 use alloc::boxed::Box;
2307 #[cfg(feature = "std")]
2308 use alloc::string::{String, ToString};
2309 #[cfg(feature = "alloc")]
2310 use alloc::vec::Vec;
2311 use core::borrow::{Borrow, BorrowMut};
2312 use core::hash::{Hash, Hasher};
2313 use core::ops::Bound;
2314 #[cfg(feature = "std")]
2315 use std::hash::DefaultHasher;
2316 #[cfg(feature = "std")]
2317 use std::io::{BufRead, IoSlice, IoSliceMut, Read, Write};
2318
2319 use crate::test_util::{CollectToVec, Id};
2320 use crate::TiSlice;
2321
2322 #[derive(Clone, Debug, Eq, PartialEq)]
2323 struct NonCopy<T>(pub T);
2324
2325 #[test]
2326 fn test_slice_read_core_api_compatibility() {
2327 for v in [
2328 &[0_u32; 0][..],
2329 &[1],
2330 &[1, 1234],
2331 &[1, 2, 4],
2332 &[1, 5, 3, 2],
2333 &[1, 1, 9, 2, 4, 1, 12345, 12],
2334 ] {
2335 let mut cv = (v, TiSlice::from_ref(v));
2336
2337 let mut mv = (v.to_vec(), v.to_vec());
2338 let mut mv = (mv.0.as_mut_slice(), TiSlice::from_mut(mv.1.as_mut_slice()));
2339
2340 assert_eq_api!(cv, v => AsRef::<[_]>::as_ref(v));
2341 assert_eq_api!(mv, v => AsMut::<[_]>::as_mut(v));
2342 assert_eq_api!(cv, v => AsRef::<TiSlice<_, _>>::as_ref(v));
2343 assert_eq_api!(mv, v => AsMut::<TiSlice<_, _>>::as_mut(v));
2344
2345 assert_eq_api!(cv, v => v.len());
2346 assert_eq_api!(cv, v => v.is_empty());
2347 assert_eq_api!(cv, v => v.is_sorted());
2348 assert_eq_api!(cv, v => v.is_sorted_by(|a, b| a >= b));
2349 assert_eq_api!(cv, v => v.is_sorted_by_key(core::cmp::Reverse));
2350 assert_eq_api!(cv, v => v.first());
2351 assert_eq_api!(mv, v => v.first_mut());
2352 assert_eq_api!(cv, v => v.last());
2353 assert_eq_api!(mv, v => v.last_mut());
2354 assert_eq_api!(cv, v => v.split_first().into_std());
2355 assert_eq_api!(mv, v => v.split_first_mut().into_std());
2356 assert_eq_api!(cv, v => v.split_last().into_std());
2357 assert_eq_api!(mv, v => v.split_last_mut().into_std());
2358 assert_eq_api!(cv, v => v.split_off_first());
2359 assert_eq_api!(mv, v => v.split_off_first_mut());
2360 assert_eq_api!(cv, v => v.split_off_last());
2361 assert_eq_api!(mv, v => v.split_off_last_mut());
2362
2363 assert_eq_api!(cv, v => { let _ = v.split_off_first(); v.into_std() });
2364 assert_eq_api!(mv, v => { let _ = v.split_off_first_mut(); v.into_std() });
2365 assert_eq_api!(cv, v => { let _ = v.split_off_last(); v.into_std() });
2366 assert_eq_api!(mv, v => { let _ = v.split_off_last_mut(); v.into_std() });
2367
2368 assert_eq_api!(cv, v => v.as_ptr());
2369 assert_eq_api!(cv, v => v.as_ptr_range());
2370 if !v.is_empty() {
2371 assert_ne!(mv.0.as_mut_ptr(), mv.1.as_mut_ptr());
2372 assert_ne!(mv.0.as_mut_ptr_range(), mv.1.as_mut_ptr_range());
2373 }
2374 assert_eq!(
2375 mv.0.as_mut_ptr(),
2376 TiSlice::<Id, _>::from_mut(mv.0).as_mut_ptr()
2377 );
2378 assert_eq!(
2379 mv.0.as_mut_ptr_range(),
2380 TiSlice::<Id, _>::from_mut(mv.0).as_mut_ptr_range()
2381 );
2382
2383 assert_eq_api!(cv, v => v == <&TheSlice<u32>>::default());
2384 assert_eq_api!(cv, v => v == <&mut TheSlice<u32>>::default());
2385 assert_eq_api!(cv, v => v.cmp([1, 1234][..].into_tic()));
2386 assert_eq_api!(cv, v => v.partial_cmp([1, 1234][..].into_tic()));
2387
2388 assert_eq_api!(cv, v => v.get((Bound::Unbounded, Bound::Unbounded)).into_std());
2389 assert_eq_api!(mv, v => v.get_mut((Bound::Unbounded, Bound::Unbounded)).into_std());
2390
2391 for i in 0..5_usize {
2392 assert_eq_api!(cv, v => v.get(i.into_tic()));
2393 assert_eq_api!(mv, v => v.get_mut(i.into_tic()));
2394
2395 assert_eq_api!(cv, v => v.get(i.into_tic()..).into_std());
2396 assert_eq_api!(mv, v => v.get_mut(i.into_tic()..).into_std());
2397
2398 assert_eq_api!(cv, v => v.get(..i.into_tic()).into_std());
2399 assert_eq_api!(mv, v => v.get_mut(..i.into_tic()).into_std());
2400
2401 assert_eq_api!(cv, v => v.get(..=i.into_tic()).into_std());
2402 assert_eq_api!(mv, v => v.get_mut(..=i.into_tic()).into_std());
2403
2404 let r = (Bound::Included(i), Bound::Unbounded);
2405 assert_eq_api!(cv, v => v.get(r.into_tic()).into_std());
2406 assert_eq_api!(mv, v => v.get_mut(r.into_tic()).into_std());
2407
2408 let r = (Bound::Unbounded, Bound::Excluded(i));
2409 assert_eq_api!(cv, v => v.get(r.into_tic()).into_std());
2410 assert_eq_api!(mv, v => v.get_mut(r.into_tic()).into_std());
2411
2412 let r = (Bound::Excluded(i), Bound::Unbounded);
2413 assert_eq_api!(cv, v => v.get(r.into_tic()).into_std());
2414 assert_eq_api!(mv, v => v.get_mut(r.into_tic()).into_std());
2415
2416 let r = (Bound::Unbounded, Bound::Included(i));
2417 assert_eq_api!(cv, v => v.get(r.into_tic()).into_std());
2418 assert_eq_api!(mv, v => v.get_mut(r.into_tic()).into_std());
2419 }
2420
2421 for i in 0..=v.len() {
2422 unsafe {
2423 if i < v.len() {
2424 assert_eq_api!(cv, v => v.get_unchecked(i.into_tic()));
2425 assert_eq_api!(mv, v => v.get_unchecked_mut(i.into_tic()));
2426 assert_eq_api!(cv, v => v[i.into_tic()]);
2427 assert_eq_api!(mv, v => v[i.into_tic()] = v[i.into_tic()]);
2428 }
2429
2430 assert_eq_api!(cv, v => v[i.into_tic()..].into_std());
2431 assert_eq_api!(cv, v => v.get_unchecked(i.into_tic()..).into_std());
2432 assert_eq_api!(mv, v => v.get_unchecked_mut(i.into_tic()..).into_std());
2433
2434 assert_eq_api!(cv, v => v[..i.into_tic()].into_std());
2435 assert_eq_api!(cv, v => v.get_unchecked(..i.into_tic()).into_std());
2436 assert_eq_api!(mv, v => v.get_unchecked_mut(..i.into_tic()).into_std());
2437
2438 if i < v.len() {
2439 assert_eq_api!(cv, v => v[..=i.into_tic()].into_std());
2440 assert_eq_api!(cv, v => v.get_unchecked(..=i.into_tic()).into_std());
2441 assert_eq_api!(mv, v => v.get_unchecked_mut(..=i.into_tic()).into_std());
2442 }
2443
2444 let r = (Bound::Included(i), Bound::Unbounded);
2445 assert_eq_api!(cv, v => v.get_unchecked(r.into_tic()).into_std());
2446 assert_eq_api!(mv, v => v.get_unchecked_mut(r.into_tic()).into_std());
2447
2448 let r = (Bound::Unbounded, Bound::Excluded(i));
2449 assert_eq_api!(cv, v => v.get_unchecked(r.into_tic()).into_std());
2450 assert_eq_api!(mv, v => v.get_unchecked_mut(r.into_tic()).into_std());
2451
2452 if i < v.len() {
2453 let r = (Bound::Excluded(i), Bound::Unbounded);
2454 assert_eq_api!(cv, v => v.get_unchecked(r.into_tic()).into_std());
2455 assert_eq_api!(mv, v => v.get_unchecked_mut(r.into_tic()).into_std());
2456
2457 let r = (Bound::Unbounded, Bound::Included(i));
2458 assert_eq_api!(cv, v => v.get_unchecked(r.into_tic()).into_std());
2459 assert_eq_api!(mv, v => v.get_unchecked_mut(r.into_tic()).into_std());
2460 }
2461 }
2462 }
2463
2464 for a in 0..5usize {
2465 for b in 0..5usize {
2466 assert_eq_api!(cv, v => v.get((a..b).into_tic()).into_std());
2467 assert_eq_api!(mv, v => v.get_mut((a..b).into_tic()).into_std());
2468
2469 assert_eq_api!(cv, v => v.get((a..=b).into_tic()).into_std());
2470 assert_eq_api!(mv, v => v.get_mut((a..=b).into_tic()).into_std());
2471
2472 let r = (Bound::Included(a), Bound::Excluded(b));
2473 assert_eq_api!(cv, v => v.get(r.into_tic()).into_std());
2474 assert_eq_api!(mv, v => v.get_mut(r.into_tic()).into_std());
2475
2476 let r = (Bound::Included(a), Bound::Included(b));
2477 assert_eq_api!(cv, v => v.get(r.into_tic()).into_std());
2478 assert_eq_api!(mv, v => v.get_mut(r.into_tic()).into_std());
2479
2480 let r = (Bound::Excluded(a), Bound::Excluded(b));
2481 assert_eq_api!(cv, v => v.get(r.into_tic()).into_std());
2482 assert_eq_api!(mv, v => v.get_mut(r.into_tic()).into_std());
2483
2484 let r = (Bound::Excluded(a), Bound::Included(b));
2485 assert_eq_api!(cv, v => v.get(r.into_tic()).into_std());
2486 assert_eq_api!(mv, v => v.get_mut(r.into_tic()).into_std());
2487 }
2488 }
2489
2490 for a in 0..=v.len() {
2491 for b in a..=v.len() {
2492 unsafe {
2493 assert_eq_api!(cv, v => v[(a..b).into_tic()].into_std());
2494 assert_eq_api!(cv, v => v.get_unchecked((a..b).into_tic()).into_std());
2495 assert_eq_api!(mv, v => v.get_unchecked_mut((a..b).into_tic()).into_std());
2496
2497 if a < v.len() && b < v.len() {
2498 assert_eq_api!(cv, v => v[(a..=b).into_tic()].into_std());
2499 assert_eq_api!(cv, v => v.get_unchecked((a..=b).into_tic()).into_std());
2500 assert_eq_api!(mv, v => v.get_unchecked_mut((a..=b).into_tic()).into_std());
2501 }
2502
2503 let r = (Bound::Included(a), Bound::Excluded(b));
2504 assert_eq_api!(cv, v => v.get_unchecked(r.into_tic()).into_std());
2505 assert_eq_api!(mv, v => v.get_unchecked_mut(r.into_tic()).into_std());
2506
2507 if a < v.len() && b < v.len() {
2508 let r = (Bound::Included(a), Bound::Included(b));
2509 assert_eq_api!(cv, v => v.get_unchecked(r.into_tic()).into_std());
2510 assert_eq_api!(mv, v => v.get_unchecked_mut(r.into_tic()).into_std());
2511 }
2512
2513 if a < b {
2514 let r = (Bound::Excluded(a), Bound::Excluded(b));
2515 assert_eq_api!(cv, v => v.get_unchecked(r.into_tic()).into_std());
2516 assert_eq_api!(mv, v => v.get_unchecked_mut(r.into_tic()).into_std());
2517 }
2518
2519 if a < v.len() && b < v.len() {
2520 let r = (Bound::Excluded(a), Bound::Included(b));
2521 assert_eq_api!(cv, v => v.get_unchecked(r.into_tic()).into_std());
2522 assert_eq_api!(mv, v => v.get_unchecked_mut(r.into_tic()).into_std());
2523 }
2524 }
2525 }
2526 }
2527
2528 assert_eq_api!(cv, v => v.iter().collect_to_vec());
2529 assert_eq_api!(cv, v => v.into_iter().collect_to_vec());
2530
2531 assert_eq_api!(mv, v => v.iter().collect_to_vec());
2532 assert_eq_api!(mv, v => v.iter_mut().collect_to_vec());
2533 assert_eq_api!(mv, v => v.into_iter().collect_to_vec());
2534
2535 for l in 1..5 {
2536 assert_eq_api!(cv, v => v.windows(l).map_into_std().collect_to_vec());
2537 assert_eq_api!(cv, v => v.chunks(l).map_into_std().collect_to_vec());
2538 assert_eq_api!(mv, v => v.chunks_mut(l).map_into_std().collect_to_vec());
2539 assert_eq_api!(cv, v => v.chunks_exact(l).map_into_std().collect_to_vec());
2540 assert_eq_api!(mv, v => v.chunks_exact_mut(l).map_into_std().collect_to_vec());
2541 assert_eq_api!(cv, v => v.rchunks(l).map_into_std().collect_to_vec());
2542 assert_eq_api!(mv, v => v.rchunks_mut(l).map_into_std().collect_to_vec());
2543 assert_eq_api!(cv, v => v.rchunks(l).map_into_std().collect_to_vec());
2544 assert_eq_api!(mv, v => v.rchunks_mut(l).map_into_std().collect_to_vec());
2545 assert_eq_api!(cv, v => v.rchunks(l).map_into_std().collect_to_vec());
2546 assert_eq_api!(mv, v => v.rchunks_mut(l).map_into_std().collect_to_vec());
2547 assert_eq_api!(cv, v => v.rchunks_exact(l).map_into_std().collect_to_vec());
2548 assert_eq_api!(mv, v => v.rchunks_exact_mut(l).map_into_std().collect_to_vec());
2549
2550 assert_eq_api!(
2551 cv, v => v.chunk_by(|a, b| a.abs_diff(*b) < 2)
2552 .map_into_std().collect_to_vec()
2553 );
2554 assert_eq_api!(
2555 mv, v => v.chunk_by_mut(|a, b| a.abs_diff(*b) < 2)
2556 .map_into_std().collect_to_vec()
2557 );
2558 }
2559
2560 for i in 0..5 {
2561 assert_eq_api!(cv, v => v.split_at_checked(i.into_tic()).into_std());
2562 assert_eq_api!(mv, v => v.split_at_mut_checked(i.into_tic()).into_std());
2563 }
2564
2565 for i in 0..v.len() {
2566 assert_eq_api!(cv, v => v.split_at(i.into_tic()).into_std());
2567 assert_eq_api!(mv, v => v.split_at_mut(i.into_tic()).into_std());
2568 unsafe {
2569 assert_eq_api!(cv, v => v.split_at_unchecked(i.into_tic()).into_std());
2570 assert_eq_api!(mv, v => v.split_at_mut_unchecked(i.into_tic()).into_std());
2571 }
2572 }
2573
2574 for d in 1..5 {
2575 assert_eq_api!(
2576 cv, v => v.split(|v| v % d == 0)
2577 .map_into_std().collect_to_vec()
2578 );
2579 assert_eq_api!(
2580 mv, v => v.split_mut(|v| v % d == 0)
2581 .map_into_std().collect_to_vec()
2582 );
2583 assert_eq_api!(
2584 cv, v => v.rsplit(|v| v % d == 0)
2585 .map_into_std().collect_to_vec()
2586 );
2587 assert_eq_api!(
2588 mv, v => v.rsplit_mut(|v| v % d == 0)
2589 .map_into_std().collect_to_vec()
2590 );
2591 assert_eq_api!(
2592 cv, v => v.split_inclusive(|v| v % d == 0)
2593 .map_into_std().collect_to_vec()
2594 );
2595 assert_eq_api!(
2596 mv, v => v.split_inclusive_mut(|v| v % d == 0)
2597 .map_into_std().collect_to_vec()
2598 );
2599 for n in 0..5 {
2600 assert_eq_api!(
2601 cv, v => v.splitn(n, |v| v % d == 0)
2602 .map_into_std().collect_to_vec()
2603 );
2604 assert_eq_api!(
2605 mv, v => v.splitn_mut(n, |v| v % d == 0)
2606 .map_into_std().collect_to_vec()
2607 );
2608 assert_eq_api!(
2609 cv, v => v.rsplitn(n, |v| v % d == 0)
2610 .map_into_std().collect_to_vec()
2611 );
2612 assert_eq_api!(
2613 mv, v => v.rsplitn_mut(n, |v| v % d == 0)
2614 .map_into_std().collect_to_vec()
2615 );
2616 }
2617 }
2618
2619 for a in 1..5 {
2620 assert_eq_api!(cv, v => v.contains(&a));
2621 assert_eq_api!(cv, v => v.binary_search(&a).into_std());
2622 assert_eq_api!(cv, v => v.binary_search_by(|b| b.cmp(&a).reverse()).into_std());
2623 assert_eq_api!(
2624 cv, v => v.binary_search_by_key(&a, |b| 10_u32.wrapping_sub(*b)).into_std()
2625 );
2626 }
2627
2628 for a in &[&[][..], &[0], &[1, 2], &[3, 4], &[1, 3], &[3, 5]] {
2629 assert_eq_api!(cv, v => v.starts_with(a.into_tic()));
2630 assert_eq_api!(cv, v => v.ends_with(a.into_tic()));
2631 }
2632
2633 for i in 0..v.len() {
2634 unsafe {
2635 assert_eq_api!(cv, v => v[i.into_tic()..].align_to::<u64>().into_std());
2636 let mv = &mut *mv.0;
2637 let slices = mv.align_to_mut::<u64>();
2638 let ptrs1 = (
2639 slices.0.as_ptr_range(),
2640 slices.1.as_ptr_range(),
2641 slices.2.as_ptr_range(),
2642 );
2643 let slices = TiSlice::<Id, _>::from_mut(mv).align_to_mut::<u64>();
2644 let ptrs2 = (
2645 slices.0.as_ptr_range(),
2646 slices.1.as_ptr_range(),
2647 slices.2.as_ptr_range(),
2648 );
2649 assert_eq!(ptrs1, ptrs2);
2650 }
2651 }
2652
2653 for a in 1..5 {
2654 assert_eq_api!(cv, v => v.partition_point(|b| *b < a).into_std());
2655 }
2656 }
2657 }
2658
2659 #[rustversion::attr(
2660 since(1.94.0),
2661 expect(clippy::needless_for_each, reason = "intentionally tested"),
2662 )]
2663 #[test]
2664 fn test_slice_write_core_api_compatibility() {
2665 for v in [
2666 &[0_u32; 0][..],
2667 &[1],
2668 &[1, 1234],
2669 &[1, 2, 4],
2670 &[1, 5, 3, 2],
2671 &[1, 1, 9, 2, 4, 1, 12345, 12],
2672 ] {
2673 let mut mv = (v.to_vec(), v.to_vec());
2674 let mut mv = (mv.0.as_mut_slice(), TiSlice::from_mut(mv.1.as_mut_slice()));
2675 let restore = |mv: &mut (&mut [u32], &mut TiSlice<Id, u32>)| {
2676 mv.0.copy_from_slice(v);
2677 mv.1.raw.copy_from_slice(v);
2678 };
2679
2680 restore(&mut mv);
2681 assert_eq_api!(mv, v => v.into_iter().for_each(|item| *item += 1));
2682
2683 restore(&mut mv);
2684 for i in 0..v.len() {
2685 for j in 0..v.len() {
2686 assert_eq_api!(mv, v => v.swap(i.into_tic(), j.into_tic()));
2687 }
2688 }
2689
2690 restore(&mut mv);
2691 assert_eq_api!(mv, v => v.reverse());
2692
2693 restore(&mut mv);
2694 assert_eq_api!(mv, v => v.sort_unstable());
2695
2696 restore(&mut mv);
2697 assert_eq_api!(mv, v => v.sort_unstable_by(|a, b| b.cmp(a)));
2698
2699 restore(&mut mv);
2700 assert_eq_api!(mv, v => v.sort_unstable_by_key(|a| a * (a % 3)));
2701
2702 for i in 0..v.len() {
2703 restore(&mut mv);
2704 assert_eq_api!(mv, v => v.select_nth_unstable(i.into_tic()).into_std());
2705 }
2706
2707 for i in 0..v.len() {
2708 restore(&mut mv);
2709 assert_eq_api!(mv, v => v.select_nth_unstable_by(
2710 i.into_tic(), |a, b| b.cmp(a)
2711 ).into_std());
2712 }
2713
2714 for i in 0..v.len() {
2715 restore(&mut mv);
2716 assert_eq_api!(mv, v => v.select_nth_unstable_by_key(
2717 i.into_tic(), |a| a * (a % 3)
2718 ).into_std());
2719 }
2720
2721 for a in 0..v.len() {
2722 restore(&mut mv);
2723 assert_eq_api!(mv, v => v.rotate_left(a.into_tic()));
2724 restore(&mut mv);
2725 assert_eq_api!(mv, v => v.rotate_right(a.into_tic()));
2726 }
2727
2728 restore(&mut mv);
2729 assert_eq_api!(mv, v => v.fill(123));
2730
2731 restore(&mut mv);
2732 assert_eq_api!(mv, v => { let mut a = 1; v.fill_with(|| { a *= 2; a }) });
2733
2734 for a in 0..v.len() {
2735 for b in a..v.len() {
2736 for c in 0..v.len() - (b - a) {
2737 restore(&mut mv);
2738 assert_eq_api!(mv, v => v.copy_within((a..b).into_tic(), c.into_tic()));
2739 }
2740 }
2741 }
2742
2743 restore(&mut mv);
2744 let mut w = [0; 8];
2745 w[0..v.len()].copy_from_slice(v);
2746 for w in &mut w {
2747 *w ^= 0b1010_1010;
2748 }
2749
2750 let mut mw = (w, w);
2751 let mut mw = (
2752 &mut mw.0[0..v.len()],
2753 TiSlice::from_mut(&mut mw.1[0..v.len()]),
2754 );
2755 mv.0.swap_with_slice(mw.0);
2756 mv.1.swap_with_slice(mw.1);
2757 assert_eq_api!(mv, v => (*v).into_std());
2758 assert_eq_api!(mw, w => (*w).into_std());
2759 }
2760
2761 let vs = [&[0; 0][..], &[1], &[1, 2], &[1, 2, 4], &[1, 2, 3, 5]];
2762 for v in vs {
2763 let mut mv = (v.to_vec(), v.to_vec());
2764 let mut mv = (mv.0.as_mut_slice(), TiSlice::from_mut(mv.1.as_mut_slice()));
2765
2766 for w in vs {
2767 let l = v.len().min(w.len());
2768 assert_eq_api!(
2769 mv,
2770 v => v[..l.into_tic()].copy_from_slice(w[..l].into_tic())
2771 );
2772 }
2773 }
2774
2775 let vs = [
2776 &[NonCopy(0); 0][..],
2777 &[NonCopy(1)],
2778 &[NonCopy(1), NonCopy(2)],
2779 &[NonCopy(1), NonCopy(2), NonCopy(4)],
2780 &[NonCopy(1), NonCopy(2), NonCopy(3), NonCopy(5)],
2781 ];
2782 for v in vs {
2783 let mut mv = (v.to_vec(), v.to_vec());
2784 let mut mv = (mv.0.as_mut_slice(), TiSlice::from_mut(mv.1.as_mut_slice()));
2785
2786 for w in vs {
2787 let l = v.len().min(w.len());
2788 assert_eq_api!(
2789 mv,
2790 v => v[..l.into_tic()].clone_from_slice(w[..l].into_tic())
2791 );
2792 }
2793 }
2794 }
2795
2796 #[cfg(feature = "std")]
2797 #[test]
2798 fn test_slice_hash_compatibility() {
2799 for v in [
2800 &[0_u32; 0][..],
2801 &[1],
2802 &[1, 1234],
2803 &[1, 2, 4],
2804 &[1, 5, 3, 2],
2805 &[1, 1, 9, 2, 4, 1, 12345, 12],
2806 ] {
2807 let mut cv = (v, TiSlice::<Id, _>::from_ref(v));
2808 assert_eq_api!(cv, v => {
2809 let mut hasher = DefaultHasher::new();
2810 v.hash(&mut hasher);
2811 hasher.finish()
2812 });
2813 }
2814 }
2815
2816 #[cfg(feature = "alloc")]
2817 #[test]
2818 fn test_slice_read_alloc_api_compatibility() {
2819 for v in [
2820 &[0_u32; 0][..],
2821 &[1],
2822 &[1, 1234],
2823 &[1, 2, 4],
2824 &[1, 5, 3, 2],
2825 &[1, 1, 9, 2, 4, 1, 12345, 12],
2826 ] {
2827 let mut cv = (v, TiSlice::from_ref(v));
2828
2829 assert_eq_api!(cv, v => Cow::from(v).into_std());
2830 assert_eq_api!(cv, v => matches!(Cow::from(v), Cow::Borrowed(_)));
2831 assert_eq_api!(cv, v => Cow::from(v).into_owned().into_std());
2832 assert_eq_api!(cv, v => v.to_vec().into_std());
2833 assert_eq_api!(cv, v => v.to_vec().into_boxed_slice().into_std());
2834 assert_eq_api!(cv, v => v.to_vec().into_boxed_slice().into_vec().into_std());
2835 assert_eq_api!(cv, v => v.to_owned().into_std());
2836 assert_eq_api!(cv, v => v.repeat(5).into_std());
2837 }
2838
2839 for v in [
2840 &[&[1, 2][..], &[3, 4]][..],
2841 &[&[1, 2], &[]],
2842 &[&[], &[3, 4]],
2843 ] {
2844 let mut cv = (v, TiSlice::from_ref(v));
2845
2846 assert_eq_api!(cv, v => v.concat().into_std());
2847 assert_eq_api!(cv, v => v.join(&0).into_std());
2848 assert_eq_api!(cv, v => v.join(&[1, 2, 3][..]).into_std());
2849 }
2850 }
2851
2852 #[cfg(feature = "alloc")]
2853 #[expect(clippy::stable_sort_primitive, reason = "okay in tests")]
2854 #[test]
2855 fn test_slice_write_alloc_api_compatibility() {
2856 for v in [
2857 &[0_u32; 0][..],
2858 &[1],
2859 &[1, 1234],
2860 &[1, 2, 4],
2861 &[1, 5, 3, 2],
2862 &[1, 1, 9, 2, 4, 1, 12345, 12],
2863 ] {
2864 let mut mv = (v.to_vec(), v.to_vec());
2865 let mut mv = (mv.0.as_mut_slice(), TiSlice::from_mut(mv.1.as_mut_slice()));
2866
2867 let re = |mv: &mut (&mut [u32], &mut TiSlice<Id, u32>)| {
2868 mv.0.copy_from_slice(v);
2869 mv.1.raw.copy_from_slice(v);
2870 };
2871
2872 re(&mut mv);
2873 assert_eq_api!(mv, v => v.sort());
2874 re(&mut mv);
2875 assert_eq_api!(mv, v => v.sort_by(|a, b| b.cmp(a)));
2876 re(&mut mv);
2877 assert_eq_api!(mv, v => v.sort_by_key(|a| a * (a % 3)));
2878 re(&mut mv);
2879 assert_eq_api!(mv, v => v.sort_by_cached_key(|a| a * (a % 3)));
2880 }
2881 }
2882
2883 #[test]
2884 fn test_u8_slice_read_core_api_compatibility() {
2885 for v in [&b"abc"[..], b"aBc", b"ABC", b"abd", b"a\x80\x81b"] {
2886 let mut cv = (v, TiSlice::from_ref(v));
2887 assert_eq_api!(cv, v => v.is_ascii());
2888 assert_eq_api!(cv, v => v.trim_ascii_start().into_std());
2889 assert_eq_api!(cv, v => v.trim_ascii_end().into_std());
2890 assert_eq_api!(cv, v => v.trim_ascii().into_std());
2891 assert_eq_api!(cv, v => v.eq_ignore_ascii_case(b"aBc".into_tic()));
2892 assert_eq_api!(cv, v => v.escape_ascii().collect_to_vec());
2893 assert_eq_api!(cv, v => v.utf8_chunks().collect_to_vec());
2894 }
2895 }
2896
2897 #[cfg(feature = "alloc")]
2898 #[test]
2899 fn test_str_slice_read_alloc_api_compatibility() {
2900 let v = &["abc", "aBc", "ABC", "abd"][..];
2901 let mut cv = (v, TiSlice::<Id, _>::from_ref(v));
2902 assert_eq_api!(cv, v => v.concat());
2903 assert_eq_api!(cv, v => v.join("foo"));
2904 }
2905
2906 #[test]
2907 fn test_u8_slice_write_core_api_compatibility() {
2908 for v in [&b"abc"[..], b"aBc", b"ABC", b"abd", b"\x80\x81"] {
2909 let mut mv = (v.to_vec(), v.to_vec());
2910 let mut mv = (mv.0.as_mut_slice(), TiSlice::from_mut(mv.1.as_mut_slice()));
2911 assert_eq_api!(mv, v => v.make_ascii_uppercase());
2912 assert_eq_api!(mv, v => (*v).into_std());
2913 assert_eq_api!(mv, v => v.make_ascii_lowercase());
2914 assert_eq_api!(mv, v => (*v).into_std());
2915 }
2916 }
2917
2918 #[cfg(feature = "alloc")]
2919 #[test]
2920 fn test_u8_slice_read_alloc_api_compatibility() {
2921 for v in [&b"abc"[..], b"aBc", b"ABC", b"abd", b"\x80\x81"] {
2922 let mut cv = (v, TiSlice::from_ref(v));
2923 assert_eq_api!(cv, v => v.to_ascii_uppercase().into_std());
2924 assert_eq_api!(cv, v => v.to_ascii_lowercase().into_std());
2925 }
2926 }
2927
2928 #[test]
2929 fn test_slice_non_zero_indexes() {
2930 use core::mem::size_of;
2931 use core::num::NonZeroUsize;
2932
2933 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
2934 struct Id(NonZeroUsize);
2935
2936 impl From<usize> for Id {
2937 fn from(value: usize) -> Self {
2938 Self(NonZeroUsize::new(value + 1).unwrap())
2939 }
2940 }
2941
2942 assert_eq!(size_of::<Option<Id>>(), size_of::<Id>());
2943
2944 let slice: &TiSlice<Id, usize> = TiSlice::from_ref(&[1, 2, 4, 8, 16]);
2945 assert_eq!(
2946 slice.first_key_value(),
2947 Some((Id(NonZeroUsize::new(1).unwrap()), &1))
2948 );
2949 }
2950
2951 #[cfg(feature = "std")]
2952 #[test]
2953 fn test_slice_read() {
2954 let arr = core::array::from_fn::<_, 128, _>(|i| {
2955 let i = u8::try_from(i).unwrap();
2956 i % 2 + i % 3 + i % 5 + i % 7 + i % 11 + i % 13 + i % 17 + i % 19
2957 });
2958 for v in [
2959 &[0_u8; 0][..],
2960 &[1],
2961 &[1, 123],
2962 &[1, 2, 4, 3, 9, 27, 4, 16, 255],
2963 &[123; 31],
2964 b"abc",
2965 &arr,
2966 ] {
2967 let ov = (v, TiSlice::<Id, _>::from_ref(v));
2968
2969 for n in [0, 1, 2, 3, 4, 16, 256] {
2970 let mut cv = ov;
2971 assert_eq_api!(cv, v => {
2972 let mut buf = [0; 256];
2973 let slice = &mut buf[0..n];
2974 (v.read(slice).unwrap(), slice.len(), buf)
2975 });
2976 }
2977
2978 for n in [0, 1, 2, 3, 4, 16, 256] {
2979 for m in [0, 1, 2, 3, 4, 16, 256] {
2980 let mut cv = ov;
2981 assert_eq_api!(cv, v => {
2982 let mut buf1 = [0; 256];
2983 let mut buf2 = [0; 256];
2984 let ios1 = IoSliceMut::new(&mut buf1[0..n]);
2985 let ios2 = IoSliceMut::new(&mut buf2[0..m]);
2986 let ios3 = &mut [ios1, ios2];
2987 (
2988 v.read_vectored(ios3).unwrap(),
2989 ios3.len(),
2990 ios3[0].len(),
2991 ios3[1].len(),
2992 buf1,
2993 buf2,
2994 )
2995 });
2996 }
2997 }
2998
2999 for n in [0, 1, 2, 3, 4, 16, 256] {
3000 let mut cv = ov;
3001 assert_eq_api!(cv, v => {
3002 let mut buf = [0; 256];
3003 let slice = &mut buf[0..n];
3004 match v.read_exact(slice) {
3005 Ok(len) => Ok((len, slice.len(), buf)),
3006 Err(err) => Err(err.to_string()),
3007 }
3008 });
3009 }
3010
3011 let mut cv = ov;
3012 assert_eq_api!(cv, v => {
3013 let mut buf = Vec::new();
3014 (v.read_to_end(&mut buf).unwrap(), buf)
3015 });
3016
3017 let mut cv = ov;
3018 assert_eq_api!(cv, v => {
3019 let mut buf = String::new();
3020 match v.read_to_string(&mut buf) {
3021 Ok(len) => Ok((len, buf)),
3022 Err(err) => Err(err.to_string()),
3023 }
3024 });
3025 }
3026 }
3027
3028 #[cfg(feature = "std")]
3029 #[test]
3030 fn test_slice_buf_read() {
3031 let arr = core::array::from_fn::<_, 128, _>(|i| {
3032 let i = u8::try_from(i).unwrap();
3033 i % 2 + i % 3 + i % 5 + i % 7 + i % 11 + i % 13 + i % 17 + i % 19
3034 });
3035 for v in [
3036 &[0_u8; 0][..],
3037 &[1],
3038 &[1, 123],
3039 &[1, 2, 4, 3, 9, 27, 4, 16, 255],
3040 &[123; 31],
3041 &arr,
3042 ] {
3043 let ov = (v, TiSlice::<Id, _>::from_ref(v));
3044
3045 let mut cv = ov;
3046 assert_eq_api!(cv, v => v.fill_buf().unwrap());
3047
3048 for n in [0, 1, 2, 3, 4, 16, 256] {
3049 if n <= v.len() {
3050 let mut cv = ov;
3051 assert_eq_api!(cv, v => {
3052 v.consume(n);
3053 v.fill_buf().unwrap()
3054 });
3055 }
3056 }
3057 }
3058 }
3059
3060 #[cfg(feature = "std")]
3061 #[test]
3062 fn test_slice_write() {
3063 let ov = (&mut [0; 16][..], &mut [0; 16]);
3064 let ov = (ov.0, TiSlice::<Id, u8>::from_mut(ov.1));
3065 let mut mv = (&mut *ov.0, &mut *ov.1);
3066 let mut mv = (&mut mv.0, &mut mv.1);
3067
3068 assert_eq_api!(mv, v => v.write(&[1, 2, 3]).unwrap());
3069 assert_eq_api!(mv, v => v.write(&[]).unwrap());
3070 assert_eq_api!(mv, v => v.write(&[2, 3]).unwrap());
3071 assert_eq_api!(mv, v => v.write_vectored(
3072 &[IoSlice::new(&[3, 4, 5]), IoSlice::new(&[]), IoSlice::new(&[5, 6])]
3073 ).unwrap());
3074 assert_eq_api!(mv, v => v.write_all(&[7, 8, 9]).unwrap());
3075 assert_eq_api!(mv, v => v.flush().unwrap());
3076
3077 assert_eq!(*mv.0, &[0, 0, 0]);
3078 assert_eq!(&mv.1.raw, &[0, 0, 0]);
3079 assert_eq!(&ov.0, &[1, 2, 3, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 0, 0, 0]);
3080 assert_eq!(&ov.1.raw, &[1, 2, 3, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 0, 0, 0]);
3081
3082 let ov = (&mut [0; 4][..], &mut [0; 4]);
3083 let ov = (ov.0, TiSlice::<Id, u8>::from_mut(ov.1));
3084 let mut mv = (&mut *ov.0, &mut *ov.1);
3085 let mut mv = (&mut mv.0, &mut mv.1);
3086
3087 assert_eq_api!(mv, v => v.write_all(&[2, 3, 4, 5, 6, 7]).map_err(|err| err.to_string()));
3088
3089 assert_eq!(*mv.0, &[0_u8; 0][..]);
3090 assert_eq!(&mv.1.raw, &[0_u8; 0][..]);
3091 assert_eq!(&ov.0, &[2, 3, 4, 5]);
3092 assert_eq!(&ov.1.raw, &[2, 3, 4, 5]);
3093 }
3094
3095 #[cfg(feature = "alloc")]
3096 #[test]
3097 fn test_slice_debug() {
3098 let s0: &TiSlice<Id, u32> = TiSlice::from_ref(&[]);
3099 let s1: &TiSlice<Id, u32> = TiSlice::from_ref(&[12]);
3100 let s2: &TiSlice<Id, u32> = TiSlice::from_ref(&[23, 34]);
3101 assert_eq!(&alloc::format!("{s0:?}"), "{}");
3102 assert_eq!(&alloc::format!("{s1:?}"), "{Id(0): 12}");
3103 assert_eq!(&alloc::format!("{s2:?}"), "{Id(0): 23, Id(1): 34}");
3104 }
3105
3106 #[cfg(all(feature = "alloc", feature = "serde"))]
3107 #[test]
3108 fn test_slice_serialize() {
3109 let s0: &TiSlice<Id, u32> = TiSlice::from_ref(&[]);
3110 let s1: &TiSlice<Id, u32> = TiSlice::from_ref(&[12]);
3111 let s2: &TiSlice<Id, u32> = TiSlice::from_ref(&[23, 34]);
3112 assert_eq!(&serde_json::to_string(&s0).unwrap(), "[]");
3113 assert_eq!(&serde_json::to_string(&s1).unwrap(), "[12]");
3114 assert_eq!(&serde_json::to_string(&s2).unwrap(), "[23,34]");
3115 }
3116
3117 #[cfg(all(feature = "alloc", feature = "bincode"))]
3118 #[test]
3119 fn test_slice_encode() {
3120 let config = bincode::config::standard();
3121 let s0: &TiSlice<Id, u32> = TiSlice::from_ref(&[]);
3122 let s1: &TiSlice<Id, u32> = TiSlice::from_ref(&[12]);
3123 let s2: &TiSlice<Id, u32> = TiSlice::from_ref(&[23, 34]);
3124 let s3: &TiSlice<Id, u32> = TiSlice::from_ref(&[0x1234_5678, 0x2345_6789]);
3125 assert_eq!(&bincode::encode_to_vec(s0, config).unwrap(), &[0]);
3126 assert_eq!(&bincode::encode_to_vec(s1, config).unwrap(), &[1, 12]);
3127 assert_eq!(&bincode::encode_to_vec(s2, config).unwrap(), &[2, 23, 34]);
3128 assert_eq!(
3129 &bincode::encode_to_vec(s3, config).unwrap(),
3130 &[2, 252, 0x78, 0x56, 0x34, 0x12, 252, 0x89, 0x67, 0x45, 0x23]
3131 );
3132 }
3133
3134 #[should_panic(expected = "where expr: v.bad_return()")]
3135 #[test]
3136 fn test_api_compatibility_return_check_failure() {
3137 pub trait BadReturn {
3138 fn bad_return(&self) -> u32;
3139 }
3140
3141 impl<T> BadReturn for [T] {
3142 fn bad_return(&self) -> u32 {
3143 12
3144 }
3145 }
3146
3147 impl<K, V> BadReturn for TiSlice<K, V> {
3148 fn bad_return(&self) -> u32 {
3149 23
3150 }
3151 }
3152
3153 let v = &[1, 2, 3][..];
3154 let mut cv = (v, TiSlice::<Id, _>::from_ref(v));
3155 assert_eq_api!(cv, v => v.bad_return());
3156 }
3157
3158 #[should_panic(expected = "where expr: v.bad_modify()")]
3159 #[test]
3160 fn test_api_compatibility_modify_check_failure() {
3161 pub trait BadModify {
3162 fn bad_modify(&mut self);
3163 }
3164
3165 impl<T> BadModify for [T] {
3166 fn bad_modify(&mut self) {}
3167 }
3168
3169 impl<K, V> BadModify for TiSlice<K, V> {
3170 fn bad_modify(&mut self) {
3171 self.reverse();
3172 }
3173 }
3174
3175 let v = (&mut [1, 2, 3][..], &mut [1, 2, 3][..]);
3176 let mut mv = (v.0, TiSlice::<Id, _>::from_mut(v.1));
3177 assert_eq_api!(mv, v => v.bad_modify());
3178 }
3179}