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