1 | #[cfg (feature = "alloc" )] |
2 | mod boxed; |
3 | |
4 | #[cfg (feature = "alloc" )] |
5 | mod concat; |
6 | |
7 | #[cfg (feature = "alloc" )] |
8 | mod join; |
9 | |
10 | mod slice_index; |
11 | |
12 | #[cfg (feature = "alloc" )] |
13 | use alloc::borrow::{Cow, ToOwned}; |
14 | #[cfg (feature = "alloc" )] |
15 | use alloc::boxed::Box; |
16 | #[cfg (feature = "std" )] |
17 | use alloc::string::String; |
18 | #[cfg (feature = "std" )] |
19 | use alloc::vec::Vec; |
20 | use core::cmp::Ordering; |
21 | use core::fmt; |
22 | use core::hash::{Hash, Hasher}; |
23 | use core::marker::PhantomData; |
24 | use core::ops::{Index, IndexMut, Range}; |
25 | use 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 | }; |
30 | use core::str::Utf8Chunks; |
31 | #[cfg (feature = "std" )] |
32 | use std::io::{BufRead, IoSlice, IoSliceMut, Read, Result as IoResult, Write}; |
33 | |
34 | #[cfg (feature = "alloc" )] |
35 | pub use concat::Concat; |
36 | #[cfg (feature = "alloc" )] |
37 | pub use join::Join; |
38 | #[cfg (feature = "serde" )] |
39 | use serde::ser::{Serialize, Serializer}; |
40 | pub use slice_index::TiSliceIndex; |
41 | |
42 | #[cfg (feature = "alloc" )] |
43 | use crate::TiVec; |
44 | use 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)] |
147 | pub 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 | |
170 | impl<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 | |
1598 | impl<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" )))] |
1701 | impl<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" )))] |
1823 | impl<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 | |
1849 | impl<K, V> fmt::Debug for TiSlice<K, V> |
1850 | where |
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 | |
1864 | impl<K, V> AsRef<Self> for TiSlice<K, V> { |
1865 | #[inline ] |
1866 | fn as_ref(&self) -> &Self { |
1867 | self |
1868 | } |
1869 | } |
1870 | |
1871 | impl<K, V> AsMut<Self> for TiSlice<K, V> { |
1872 | #[inline ] |
1873 | fn as_mut(&mut self) -> &mut Self { |
1874 | self |
1875 | } |
1876 | } |
1877 | |
1878 | impl<K, V> AsRef<[V]> for TiSlice<K, V> { |
1879 | #[inline ] |
1880 | fn as_ref(&self) -> &[V] { |
1881 | &self.raw |
1882 | } |
1883 | } |
1884 | |
1885 | impl<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 | |
1892 | impl<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 | |
1899 | impl<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" )))] |
1908 | impl<'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 | |
1915 | impl<K, V> Eq for TiSlice<K, V> where V: Eq {} |
1916 | |
1917 | impl<K, A, B> PartialEq<TiSlice<K, B>> for TiSlice<K, A> |
1918 | where |
1919 | A: PartialEq<B>, |
1920 | { |
1921 | #[inline ] |
1922 | fn eq(&self, other: &TiSlice<K, B>) -> bool { |
1923 | self.raw == other.raw |
1924 | } |
1925 | } |
1926 | |
1927 | impl<K, V> Ord for TiSlice<K, V> |
1928 | where |
1929 | V: Ord, |
1930 | { |
1931 | #[inline ] |
1932 | fn cmp(&self, other: &Self) -> Ordering { |
1933 | self.raw.cmp(&other.raw) |
1934 | } |
1935 | } |
1936 | |
1937 | impl<K, V> PartialOrd<Self> for TiSlice<K, V> |
1938 | where |
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 | |
1947 | impl<K, V> Hash for TiSlice<K, V> |
1948 | where |
1949 | V: Hash, |
1950 | { |
1951 | #[inline ] |
1952 | fn hash<H: Hasher>(&self, state: &mut H) { |
1953 | self.raw.hash(state); |
1954 | } |
1955 | } |
1956 | |
1957 | impl<K, V> Default for &TiSlice<K, V> { |
1958 | #[inline ] |
1959 | fn default() -> Self { |
1960 | TiSlice::from_ref(&[]) |
1961 | } |
1962 | } |
1963 | |
1964 | impl<K, V> Default for &mut TiSlice<K, V> { |
1965 | #[inline ] |
1966 | fn default() -> Self { |
1967 | TiSlice::from_mut(&mut []) |
1968 | } |
1969 | } |
1970 | |
1971 | impl<I, K, V> Index<I> for TiSlice<K, V> |
1972 | where |
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 | |
1983 | impl<I, K, V> IndexMut<I> for TiSlice<K, V> |
1984 | where |
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 | |
1993 | impl<'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 | |
2003 | impl<'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" )))] |
2019 | impl<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" )))] |
2048 | impl<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" )))] |
2071 | impl<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 ] |
2095 | fn 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 ] |
2105 | fn 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" )))] |
2116 | impl<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" )))] |
2127 | impl<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)] |
2147 | mod 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 | |