Skip to main content

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}