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