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