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