slice_cell/
lib.rs

1#![no_std]
2
3#[cfg(feature = "alloc")]
4extern crate alloc;
5#[cfg(feature = "std")]
6extern crate std;
7
8#[cfg(feature = "rc")]
9use alloc::rc::Rc;
10#[cfg(feature = "alloc")]
11use alloc::{boxed::Box, vec::Vec};
12use core::cell::Cell;
13use core::cell::UnsafeCell;
14use core::ops::Index;
15use core::ops::IndexMut;
16use index::SliceCellIndex;
17
18// TODO: decide whether &mut apis should in general return `&mut T` or `&mut Cell<T>`
19// (or whether we need &mut apis at all, other than `as_mut(&mut self) -> &mut [T]`).
20//
21// Note: `Cell::get_mut` exists to go from `&mut Cell<T>` to `&mut T`.
22//
23// Currently, `split_first`/`split_last` return `&mut T`, but
24// `get_mut(usize)` returns `&mut Cell<T>`.
25
26// TODO: #[cfg_attr(doc_cfg, doc(cfg(feature = ...)))]
27// see: https://github.com/rust-random/rand/pull/1019/files
28
29mod index;
30#[cfg(feature = "std")]
31pub mod io;
32
33/// A [`Cell<[T; N]>`](core::cell::Cell)-like type that has some additional slice-like API.
34///
35/// This type dereferences to [`SliceCell<T>`](SliceCell).
36///
37/// This type can be converted to and from `Cell<[T; N]>` and `[Cell<T>; N]` in several ways.
38#[repr(transparent)]
39pub struct ArrayCell<T, const N: usize> {
40    inner: UnsafeCell<[T; N]>,
41}
42
43// SAFETY: `Cell`-like types are safe to *send* between threads, but not to *share* between threads
44// (so no `Sync` impl).
45unsafe impl<T: Send, const N: usize> Send for ArrayCell<T, N> {}
46
47/// A [`Cell<[T]>`](core::cell::Cell)-like type that has some additional slice-like API.
48///
49/// References to this type can be gotten from dereferencing an [`ArrayCell<T, N>`](ArrayCell), or using [`from_mut`](SliceCell::from_mut).
50///
51/// This type can be converted to and from `Cell<[T]>` and `[Cell<T>]` in several ways.
52#[repr(transparent)]
53pub struct SliceCell<T> {
54    inner: UnsafeCell<[T]>,
55}
56
57// SAFETY: `Cell`-like types are safe to *send* between threads, but not to *share* between threads
58// (so no `Sync` impl).
59unsafe impl<T: Send> Send for SliceCell<T> {}
60
61impl<T, const N: usize> ArrayCell<T, N> {
62    /// View this [`ArrayCell`] as a [`Cell`] of an [array] of `N` elements.
63    pub const fn as_std_ref(&self) -> &Cell<[T; N]> {
64        // SAFETY: `Cell` upholds the same invariants that we do:
65        // 1a. `Cell<T>` has the same layout as `T`.
66        // 1b. `ArrayCell<T, N>` has the same layout as `[T; N]`.
67        // 1c. `SliceCell<T>` has the same layout as `[T]`.
68        // 2. `&Cell<T>` does not allow arbitrary user code to access `T` by reference directly.
69        // Additional assumptions:
70        // 3. `Cell<[T; N]>` has the same layout as `[Cell<T>; N]` (implied by 1).
71        // This safety comment applies to the bodies of all `as_std_*`/`into_std_*` and `from_std_*` methods
72        // on `SliceCell` and `ArrayCell`.
73        unsafe { &*(self as *const Self).cast() }
74    }
75    /// View this [`ArrayCell`] as an [array] of `N` [`Cell`]s.
76    pub const fn as_std_transposed_ref(&self) -> &[Cell<T>; N] {
77        // See `ArrayCell::as_std_ref` for safety.
78        unsafe { &*(self as *const Self).cast() }
79    }
80    /// View a [`Cell`] of an [array] of `N` elements as an [`ArrayCell`].
81    pub const fn from_std_ref(std: &Cell<[T; N]>) -> &Self {
82        // See `ArrayCell::as_std_ref` for safety.
83        unsafe { &*(std as *const Cell<[T; N]>).cast() }
84    }
85    /// View an [array] of `N` [`Cell`]s as an [`ArrayCell`].
86    pub const fn from_std_transposed_ref(std: &[Cell<T>; N]) -> &Self {
87        // See `ArrayCell::as_std_ref` for safety.
88        unsafe { &*(std as *const [Cell<T>; N]).cast() }
89    }
90    /// View this [`ArrayCell`] as a [`Cell`] of an [array] of `N` elements.
91    pub fn as_std_mut(&mut self) -> &mut Cell<[T; N]> {
92        // See `ArrayCell::as_std_ref` for safety.
93        unsafe { &mut *(self as *mut Self).cast() }
94    }
95    /// View this [`ArrayCell`] as an [array] of `N` [`Cell`]s.
96    pub fn as_std_transposed_mut(&mut self) -> &mut [Cell<T>; N] {
97        // See `ArrayCell::as_std_ref` for safety.
98        unsafe { &mut *(self as *mut Self).cast() }
99    }
100    /// View a [`Cell`] of an [array] of `N` elements as an [`ArrayCell`].
101    pub fn from_std_mut(std: &mut Cell<[T; N]>) -> &mut Self {
102        // See `ArrayCell::as_std_ref` for safety.
103        unsafe { &mut *(std as *mut Cell<[T; N]>).cast() }
104    }
105    /// View an [array] of `N` [`Cell`]s as an [`ArrayCell`].
106    pub fn from_std_transposed_mut(std: &mut [Cell<T>; N]) -> &mut Self {
107        // See `ArrayCell::as_std_ref` for safety.
108        unsafe { &mut *(std as *mut [Cell<T>; N]).cast() }
109    }
110}
111
112#[cfg(feature = "alloc")]
113impl<T, const N: usize> ArrayCell<T, N> {
114    /// View this [`ArrayCell`] as a [`Cell`] of an [array] of `N` elements.
115    pub fn into_std_boxed(self: Box<Self>) -> Box<Cell<[T; N]>> {
116        // See `ArrayCell::as_std_ref` for safety.
117        unsafe { Box::from_raw(Box::into_raw(self).cast()) }
118    }
119    /// View this [`ArrayCell`] as an [array] of `N` [`Cell`]s.
120    pub fn into_std_transposed_boxed(self: Box<Self>) -> Box<[Cell<T>; N]> {
121        // See `ArrayCell::as_std_ref` for safety.
122        unsafe { Box::from_raw(Box::into_raw(self).cast()) }
123    }
124    /// View a [`Cell`] of an [array] of `N` elements as an [`ArrayCell`].
125    pub fn from_std_boxed(std: Box<Cell<[T; N]>>) -> Box<Self> {
126        // See `ArrayCell::as_std_ref` for safety.
127        unsafe { Box::from_raw(Box::into_raw(std).cast()) }
128    }
129    /// View an [array] of `N` [`Cell`]s as an [`ArrayCell`].
130    pub fn from_std_transposed_boxed(std: Box<[Cell<T>; N]>) -> Box<Self> {
131        // See `ArrayCell::as_std_ref` for safety.
132        unsafe { Box::from_raw(Box::into_raw(std).cast()) }
133    }
134}
135
136#[cfg(feature = "rc")]
137impl<T, const N: usize> ArrayCell<T, N> {
138    /// View this [`ArrayCell`] as a [`Cell`] of an [array] of `N` elements.
139    pub fn into_std_rc(self: Rc<Self>) -> Rc<Cell<[T; N]>> {
140        // See `ArrayCell::as_std_ref` for safety.
141        unsafe { Rc::from_raw(Rc::into_raw(self).cast()) }
142    }
143    /// View this [`ArrayCell`] as an [array] of `N` [`Cell`]s.
144    pub fn into_std_transposed_rc(self: Rc<Self>) -> Rc<[Cell<T>; N]> {
145        // See `ArrayCell::as_std_ref` for safety.
146        unsafe { Rc::from_raw(Rc::into_raw(self).cast()) }
147    }
148    /// View a [`Cell`] of an [array] of `N` elements as an [`ArrayCell`].
149    pub fn from_std_rc(std: Rc<Cell<[T; N]>>) -> Rc<Self> {
150        // See `ArrayCell::as_std_ref` for safety.
151        unsafe { Rc::from_raw(Rc::into_raw(std).cast()) }
152    }
153    /// View an [array] of `N` [`Cell`]s as an [`ArrayCell`].
154    pub fn from_std_transposed_rc(std: Rc<[Cell<T>; N]>) -> Rc<Self> {
155        // See `ArrayCell::as_std_ref` for safety.
156        unsafe { Rc::from_raw(Rc::into_raw(std).cast()) }
157    }
158}
159
160impl<T, const N: usize> ArrayCell<T, N> {
161    /// Returns a raw pointer to the underlying data in this [`ArrayCell`].
162    pub fn as_ptr(&self) -> *mut [T; N] {
163        UnsafeCell::raw_get(&self.inner).cast()
164    }
165
166    /// Consumes the [`ArrayCell`], returning the wrapped [array].
167    pub fn into_inner(self) -> [T; N] {
168        self.inner.into_inner()
169    }
170
171    /// Wraps an [array] in an [`ArrayCell`].
172    pub fn new(inner: [T; N]) -> Self {
173        Self {
174            inner: UnsafeCell::new(inner),
175        }
176    }
177
178    /// Wraps a [boxed](alloc::boxed::Box) [array] in an [`ArrayCell`].
179    #[cfg(feature = "alloc")]
180    pub fn new_boxed(inner: Box<[T; N]>) -> Box<Self> {
181        // SAFETY: `ArrayCell<T, N>` has the same layout as `[T; N]`.
182        unsafe { Box::from_raw(Box::into_raw(inner).cast()) }
183    }
184
185    /// Unwaps a [boxed](alloc::boxed::Box) [ArrayCell] into an [array].
186    #[cfg(feature = "alloc")]
187    pub fn into_inner_boxed(self: Box<Self>) -> Box<[T; N]> {
188        // SAFETY: `ArrayCell<T, N>` has the same layout as `[T; N]`.
189        unsafe { Box::from_raw(Box::into_raw(self).cast()) }
190    }
191
192    /// Wraps a [reference-counted](alloc::rc::Rc) [array] in an `ArrayCell`, if it is uniquely owned.
193    #[cfg(feature = "rc")]
194    pub fn try_new_rc(mut inner: Rc<[T; N]>) -> Result<Rc<Self>, Rc<[T; N]>> {
195        match Rc::get_mut(&mut inner) {
196            // SAFETY: `ArrayCell<T, N>` has the same layout as `[T; N]`.
197            // And: there are no other `Rc` or `Weak` pointers to this allocation, so it is sound
198            // to "add" interior mutability to it
199            Some(_unique) => Ok(unsafe { Rc::from_raw(Rc::into_raw(inner).cast()) }),
200            None => Err(inner),
201        }
202    }
203
204    /// Unwraps a [reference-counted](alloc::rc::Rc) [`ArrayCell`] into an [array], if it is uniquely owned.
205    #[cfg(feature = "rc")]
206    pub fn try_into_inner_rc(mut self: Rc<Self>) -> Result<Rc<[T; N]>, Rc<Self>> {
207        match Rc::get_mut(&mut self) {
208            // SAFETY: `ArrayCell<T, N>` has the same layout as `[T; N]`.
209            // And: there are no other `Rc` or `Weak` pointers to this allocation, so it is sound
210            // to "remove" interior mutability from it
211            Some(_unique) => Ok(unsafe { Rc::from_raw(Rc::into_raw(self).cast()) }),
212            None => Err(self),
213        }
214    }
215
216    #[cfg(feature = "rc")]
217    /// Replacement for `From` impl, since `Rc` is not fundamental.
218    // TODO: If manual coercion is added, just make ArrayCell<T, N> coerce to SliceCell<T>
219    // and deprecate `ArrayCell::unsize_rc` (but not `SliceCell::try_size_rc`).
220    pub fn unsize_rc(self: Rc<Self>) -> Rc<SliceCell<T>> {
221        SliceCell::from_std_transposed_rc(ArrayCell::into_std_transposed_rc(self))
222    }
223
224    /// Unwraps a uniquely borrowed [`ArrayCell`] into an array.
225    #[doc(alias = "get_mut")]
226    pub fn as_mut(&mut self) -> &mut [T; N] {
227        self.inner.get_mut()
228    }
229
230    /// Wraps a uniquely borrowed array in an [`ArrayCell`].
231    pub fn from_mut(inner: &mut [T; N]) -> &mut Self {
232        unsafe { &mut *(inner as *mut [T; N]).cast() }
233    }
234
235    /// Returns a reference to an element or subslice depending on the type of index.
236    ///
237    /// See [`slice::get`].
238    pub fn get<I: SliceCellIndex<Self>>(&self, idx: I) -> Option<&I::Output> {
239        idx.get(self)
240    }
241
242    /// Returns a mutable reference to an element or subslice depending on the type of index.
243    ///
244    /// See also [`slice::get_mut`].
245    pub fn get_mut<I: SliceCellIndex<Self>>(&mut self, idx: I) -> Option<&mut I::Output> {
246        idx.get_mut(self)
247    }
248
249    /// Returns the length of the [`ArrayCell`].
250    pub const fn len(&self) -> usize {
251        N
252    }
253}
254
255impl<T, const N: usize> AsRef<SliceCell<T>> for ArrayCell<T, N> {
256    fn as_ref(&self) -> &SliceCell<T> {
257        SliceCell::from_std_ref(self.as_std_ref())
258    }
259}
260
261impl<T, const N: usize> AsMut<SliceCell<T>> for ArrayCell<T, N> {
262    fn as_mut(&mut self) -> &mut SliceCell<T> {
263        SliceCell::from_mut(self.as_mut())
264    }
265}
266
267impl<T> AsRef<SliceCell<T>> for SliceCell<T> {
268    fn as_ref(&self) -> &SliceCell<T> {
269        self
270    }
271}
272
273impl<T> AsMut<SliceCell<T>> for SliceCell<T> {
274    fn as_mut(&mut self) -> &mut SliceCell<T> {
275        self
276    }
277}
278
279impl<T> SliceCell<T> {
280    /// View this [`SliceCell`] as a [`Cell`] of a [slice].
281    pub const fn as_std_ref(&self) -> &Cell<[T]> {
282        // See `ArrayCell::as_std_ref` for safety.
283        unsafe { &*(self as *const Self as *const _) }
284    }
285    /// View this [`SliceCell`] as a [slice] of [`Cell`]s.
286    pub const fn as_std_transposed_ref(&self) -> &[Cell<T>] {
287        // See `ArrayCell::as_std_ref` for safety.
288        unsafe { &*(self as *const Self as *const _) }
289    }
290    /// View a [`Cell`] of a [slice] as a [`SliceCell`].
291    pub const fn from_std_ref(std: &Cell<[T]>) -> &Self {
292        // See `ArrayCell::as_std_ref` for safety.
293        unsafe { &*(std as *const Cell<[T]> as *const _) }
294    }
295    /// View a [slice] of [`Cell`]s as a [`SliceCell`].
296    pub const fn from_std_transposed_ref(std: &[Cell<T>]) -> &Self {
297        // See `ArrayCell::as_std_ref` for safety.
298        unsafe { &*(std as *const [Cell<T>] as *const _) }
299    }
300    /// View this [`SliceCell`] as a [`Cell`] of a [slice].
301    pub fn as_std_mut(&mut self) -> &mut Cell<[T]> {
302        // See `ArrayCell::as_std_ref` for safety.
303        unsafe { &mut *(self as *mut Self as *mut _) }
304    }
305    /// View this [`SliceCell`] as a [slice] of [`Cell`]s.
306    pub fn as_std_transposed_mut(&mut self) -> &mut [Cell<T>] {
307        // See `ArrayCell::as_std_ref` for safety.
308        unsafe { &mut *(self as *mut Self as *mut _) }
309    }
310    /// View a [`Cell`] of a [slice] as a [`SliceCell`].
311    pub fn from_std_mut(std: &mut Cell<[T]>) -> &mut Self {
312        // See `ArrayCell::as_std_ref` for safety.
313        unsafe { &mut *(std as *mut Cell<[T]> as *mut _) }
314    }
315    /// View a [slice] of [`Cell`] as a [`SliceCell`].
316    pub fn from_std_transposed_mut(std: &mut [Cell<T>]) -> &mut Self {
317        // See `ArrayCell::as_std_ref` for safety.
318        unsafe { &mut *(std as *mut [Cell<T>] as *mut _) }
319    }
320}
321
322#[cfg(feature = "alloc")]
323impl<T> SliceCell<T> {
324    /// View this [`SliceCell`] as a [`Cell`] of a [slice].
325    pub fn into_std_boxed(self: Box<Self>) -> Box<Cell<[T]>> {
326        // See `ArrayCell::as_std_ref` for safety.
327        unsafe { Box::from_raw(Box::into_raw(self) as *mut _) }
328    }
329    /// View this [`SliceCell`] as a [slice] of [`Cell`]s.
330    pub fn into_std_transposed_boxed(self: Box<Self>) -> Box<[Cell<T>]> {
331        // See `ArrayCell::as_std_ref` for safety.
332        unsafe { Box::from_raw(Box::into_raw(self) as *mut _) }
333    }
334    /// View a [`Cell`] of a [slice] as a [`SliceCell`].
335    pub fn from_std_boxed(std: Box<Cell<[T]>>) -> Box<Self> {
336        // See `ArrayCell::as_std_ref` for safety.
337        unsafe { Box::from_raw(Box::into_raw(std) as *mut _) }
338    }
339    /// View a [slice] of [`Cell`]s as a [`SliceCell`].
340    pub fn from_std_transposed_boxed(std: Box<[Cell<T>]>) -> Box<Self> {
341        // See `ArrayCell::as_std_ref` for safety.
342        unsafe { Box::from_raw(Box::into_raw(std) as *mut _) }
343    }
344
345    /// Unwraps an owned [boxed](alloc::boxed::Box) [`SliceCell`] into a slice.
346    pub fn into_inner_boxed(self: Box<Self>) -> Box<[T]> {
347        // SAFETY: `ArrayCell<T, N>` has the same layout as `[T; N]`.
348        unsafe { Box::from_raw(Box::into_raw(self) as *mut _) }
349    }
350
351    /// Wraps an owned [boxed](alloc::boxed::Box) [slice] in a [`SliceCell`].
352    pub fn new_boxed(inner: Box<[T]>) -> Box<Self> {
353        unsafe { Box::from_raw(Box::into_raw(inner) as *mut _) }
354    }
355}
356
357#[cfg(feature = "rc")]
358impl<T> SliceCell<T> {
359    /// View this [`SliceCell`] as a [`Cell`] of a [slice].
360    pub fn into_std_rc(self: Rc<Self>) -> Rc<Cell<[T]>> {
361        // See `ArrayCell::as_std_ref` for safety.
362        unsafe { Rc::from_raw(Rc::into_raw(self) as *const _) }
363    }
364    /// View this [`SliceCell`] as a [slice] of [`Cell`]s.
365    pub fn into_std_transposed_rc(self: Rc<Self>) -> Rc<[Cell<T>]> {
366        // See `ArrayCell::as_std_ref` for safety.
367        unsafe { Rc::from_raw(Rc::into_raw(self) as *const _) }
368    }
369    /// View a [`Cell`] of a [slice] as a [`SliceCell`].
370    pub fn from_std_rc(std: Rc<Cell<[T]>>) -> Rc<Self> {
371        // See `ArrayCell::as_std_ref` for safety.
372        unsafe { Rc::from_raw(Rc::into_raw(std) as *const _) }
373    }
374    pub fn from_std_transposed_rc(std: Rc<[Cell<T>]>) -> Rc<Self> {
375        // See `ArrayCell::as_std_ref` for safety.
376        unsafe { Rc::from_raw(Rc::into_raw(std) as *const _) }
377    }
378
379    /// Wraps a [reference-counted](alloc::rc::Rc) [slice] in a `SliceCell`, if it is uniquely owned.
380    pub fn try_new_rc(mut inner: Rc<[T]>) -> Result<Rc<Self>, Rc<[T]>> {
381        match Rc::get_mut(&mut inner) {
382            // SAFETY: `SliceCell<T>` has the same layout as `[T]`.
383            // And: there are no other `Rc` or `Weak` pointers to this allocation, so it is sound
384            // to "add" interior mutability to it
385            Some(_unique) => Ok(unsafe { Rc::from_raw(Rc::into_raw(inner) as *const _) }),
386            None => Err(inner),
387        }
388    }
389
390    /// Unwraps a [reference-counted](alloc::rc::Rc) [`SliceCell`] into an [slice], if it is uniquely owned.
391    pub fn try_into_inner_rc(mut self: Rc<Self>) -> Result<Rc<[T]>, Rc<Self>> {
392        match Rc::get_mut(&mut self) {
393            // SAFETY: `SliceCell<T>` has the same layout as `[T]`.
394            // And: there are no other `Rc` or `Weak` pointers to this allocation, so it is sound
395            // to "remove" interior mutability from it
396            Some(_unique) => Ok(unsafe { Rc::from_raw(Rc::into_raw(self) as *const _) }),
397            None => Err(self),
398        }
399    }
400
401    /// Replacement for `TryFrom` impl, since `Rc` is not fundamental
402    pub fn try_size_rc<const N: usize>(self: Rc<Self>) -> Result<Rc<ArrayCell<T, N>>, Rc<Self>> {
403        if self.len() == N {
404            Ok({
405                let the_rc = self
406                    .into_std_transposed_rc()
407                    .try_into()
408                    .ok()
409                    .expect("already checked the length");
410                ArrayCell::from_std_transposed_rc(the_rc)
411            })
412        } else {
413            Err(self)
414        }
415    }
416}
417
418impl<T> SliceCell<T> {
419    /// Returns a raw pointer to the underlying data in this `SliceCell`.
420    pub fn as_ptr(&self) -> *mut [T] {
421        UnsafeCell::raw_get(&self.inner)
422    }
423
424    /// Unwraps a uniquely borrowed [`SliceCell`] into a slice.
425    #[doc(alias = "get_mut")]
426    pub fn as_mut(&mut self) -> &mut [T] {
427        self.inner.get_mut()
428    }
429
430    /// Wraps a uniquely borrowed slice in a [`SliceCell`].
431    pub fn from_mut(inner: &mut [T]) -> &mut Self {
432        // SAFETY: `SliceCell<T>` has the same layout as `[T]`.
433        // And: the slice is uniquely borrowed, so it is sound to "add" interior mutability for the
434        // length of the borrow.
435        unsafe { &mut *(inner as *mut [T] as *mut _) }
436    }
437
438    /// Returns a reference to an element or subslice depending on the type of index.
439    ///
440    /// See [`slice::get`].
441    pub fn get<I: SliceCellIndex<Self>>(&self, idx: I) -> Option<&I::Output> {
442        idx.get(self)
443    }
444
445    /// Returns a mutable reference to an element or subslice depending on the type of index.
446    ///
447    /// See also [`slice::get_mut`].
448    pub fn get_mut<I: SliceCellIndex<Self>>(&mut self, idx: I) -> Option<&mut I::Output> {
449        idx.get_mut(self)
450    }
451
452    /// Returns the length of the [`SliceCell`].
453    pub const fn len(&self) -> usize {
454        self.as_std_transposed_ref().len()
455    }
456
457    /// Divide one `SliceCell` into two at an index.
458    ///
459    /// Panics if `mid > self.len()`.
460    ///
461    /// See [slice::split_at]
462    pub fn split_at(&self, mid: usize) -> (&SliceCell<T>, &SliceCell<T>) {
463        let (start, end) = self.as_std_transposed_ref().split_at(mid);
464        (
465            Self::from_std_transposed_ref(start),
466            Self::from_std_transposed_ref(end),
467        )
468    }
469
470    /// Divide one mutable `SliceCell` into two at an index.
471    ///
472    /// Panics if `mid > self.len()`.
473    ///
474    /// See [slice::split_at_mut]
475    pub fn split_at_mut(&mut self, mid: usize) -> (&mut SliceCell<T>, &mut SliceCell<T>) {
476        let (start, end) = self.as_mut().split_at_mut(mid);
477        (Self::from_mut(start), Self::from_mut(end))
478    }
479
480    /// Returns the first and all the rest of the elements of the `SliceCell`, or None if it is empty.
481    ///
482    /// See [slice::split_first]
483    pub fn split_first(&self) -> Option<(&Cell<T>, &SliceCell<T>)> {
484        let (first, end) = self.as_std_transposed_ref().split_first()?;
485        Some((first, Self::from_std_transposed_ref(end)))
486    }
487
488    /// Returns the first and all the rest of the elements of the `SliceCell`, or None if it is empty.
489    ///
490    /// See [slice::split_first_mut]
491    pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut SliceCell<T>)> {
492        let (first, end) = self.as_mut().split_first_mut()?;
493        Some((first, Self::from_mut(end)))
494    }
495
496    /// Returns the last and all the rest of the elements of the `SliceCell`, or None if it is empty.
497    ///
498    /// See [slice::split_last]
499    pub fn split_last(&self) -> Option<(&Cell<T>, &SliceCell<T>)> {
500        let (last, start) = self.as_std_transposed_ref().split_last()?;
501        Some((last, Self::from_std_transposed_ref(start)))
502    }
503
504    /// Returns the last and all the rest of the elements of the `SliceCell`, or None if it is empty.
505    ///
506    /// See [slice::split_last_mut]
507    pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut SliceCell<T>)> {
508        let (last, start) = self.as_mut().split_last_mut()?;
509        Some((last, Self::from_mut(start)))
510    }
511
512    /// Copies all elements from src into self, likely using a memcpy.
513    ///
514    /// The length of src must be the same as self.
515    ///
516    /// See [slice::copy_from_slice].
517    pub fn copy_from_slice(&self, src: &[T])
518    where
519        T: Copy,
520    {
521        assert!(self.len() == src.len());
522        // Compiles down to a memcpy in release mode, at least on 1.66.0
523        self.iter().zip(src.iter()).for_each(|(dst, src)| {
524            dst.set(*src);
525        });
526    }
527
528    /// Copies all elements from src into self, likely using a memmove.
529    ///
530    /// The length of src must be the same as self.
531    ///
532    /// `self` and `src` may overlap.
533    pub fn copy_from(&self, src: &SliceCell<T>)
534    where
535        T: Copy,
536    {
537        assert!(self.len() == src.len());
538        // SAFETY: *src and *self may overlap, but that's fine since std::ptr::copy is
539        // a memmove, not a memcpy. Both are valid for `self.len() * size_of::<T>()` bytes
540        // for read/write, since their lengths are the same.
541        unsafe {
542            std::ptr::copy(
543                src.as_ptr() as *const T,
544                self.as_ptr() as *mut T,
545                self.len(),
546            );
547        }
548    }
549
550    /// Clones all elements from src into self.
551    ///
552    /// The length of src must be the same as self.
553    ///
554    /// See [slice::copy_from_slice].
555    pub fn clone_from_slice(&self, src: &[T])
556    where
557        T: Clone,
558    {
559        assert!(self.len() == src.len());
560        // T::clone and T::drop are arbitrary user code, so we can't use `self.inner.get().clone_from_slice()`
561        for (dst, val) in self.iter().zip(src.iter().cloned()) {
562            dst.set(val);
563        }
564    }
565
566    /// Take all elements from this `SliceCell` into a mutable slice, leaving `T::default()` in each cell
567    pub fn take_into_slice(&self, dst: &mut [T])
568    where
569        T: Default,
570    {
571        assert!(self.len() == dst.len());
572        // T::default and T::drop are arbitrary user code, so we can't hold a reference into self while it runs.
573        for (src, dst) in self.iter().zip(dst.iter_mut()) {
574            let val = src.take();
575            *dst = val;
576        }
577    }
578
579    /// Take all elements from this `SliceCell` into a newly allocated `Vec<T>`, leaving `T::default()` in each cell.
580    #[cfg(feature = "alloc")]
581    pub fn take_into_vec(&self) -> Vec<T>
582    where
583        T: Default,
584    {
585        self.iter().map(Cell::take).collect()
586    }
587
588    /// Copy all elements from this `SliceCell` into a mutable slice.
589    pub fn copy_into_slice(&self, dst: &mut [T])
590    where
591        T: Copy,
592    {
593        assert!(self.len() == dst.len());
594        // Compiles down to a memcpy in release mode, at least on 1.66.0
595        self.iter().zip(dst.iter_mut()).for_each(|(src, dst)| {
596            *dst = src.get();
597        });
598    }
599
600    /// Copy all elements from this `SliceCell` into a newly allocated `Vec<T>`.
601    #[cfg(feature = "alloc")]
602    pub fn copy_into_vec(&self) -> Vec<T>
603    where
604        T: Copy,
605    {
606        // Compiles down to a memcpy in release mode, at least on 1.66.0
607        self.iter().map(Cell::get).collect()
608    }
609
610    #[cfg(feature = "alloc")]
611    pub fn replace_with_vec(&self, mut src: Vec<T>) {
612        self.swap_with_slice(&mut src);
613    }
614
615    pub fn swap_with_slice(&self, val: &mut [T]) {
616        assert_eq!(self.len(), val.len());
617        // SAFETY: (assumes that) `slice::swap_with_slice` uses memcpy-like operations,
618        // and does not run arbitrary user code that could access `*self` racily
619        unsafe { &mut *self.inner.get() }.swap_with_slice(val);
620    }
621
622    #[cfg(any())]
623    pub fn swap_with_slicecell(&self, other: &Self) -> Result {
624        todo!("decide what to do with overlapping slices. Probably just return an error?")
625    }
626
627    /// Swaps two elements in the slice.
628    ///
629    /// See [`<[T]>::swap`](slice::swap).
630    pub fn swap(&self, a: usize, b: usize) {
631        if a == b {
632            return;
633        }
634        let a = &self[a];
635        let b = &self[b];
636        Cell::swap(a, b)
637    }
638
639    /// See [`<[T]>::rotate_left`](slice::rotate_left)
640    pub fn rotate_left(&self, mid: usize) {
641        // SAFETY: (assumes that) `slice::rotate_right` uses memcpy-like operations,
642        // and does not run arbitrary user code that could access `*self` racily
643        unsafe { &mut *self.inner.get() }.rotate_left(mid)
644    }
645
646    /// See [`<[T]>::rotate_right`](slice::rotate_right)
647    pub fn rotate_right(&self, mid: usize) {
648        // SAFETY: (assumes that) `slice::rotate_right` uses memcpy-like operations,
649        // and does not run arbitrary user code that could access `*self` racily
650        unsafe { &mut *self.inner.get() }.rotate_right(mid)
651    }
652
653    /// Fills self with elements by cloning value.
654    ///
655    /// See also: [`<[T]>::fill`](slice::fill).
656    pub fn fill(&self, val: T)
657    where
658        T: Clone,
659    {
660        for dst in self {
661            dst.set(val.clone());
662        }
663    }
664
665    /// Fills self with elements returned by calling a closure repeatedly.
666    ///
667    /// See also: [`<[T]>::fill_with`](slice::fill_with).
668    pub fn fill_with<F>(&self, mut f: F)
669    where
670        F: FnMut() -> T,
671    {
672        for dst in self {
673            dst.set(f());
674        }
675    }
676
677    /// N should not be 0.
678    ///
679    /// Splits the slice into a slice of N-element arrays, starting at the beginning of the slice, and a remainder slice with length strictly less than N.
680    pub fn as_chunks<const N: usize>(&self) -> (&SliceCell<[T; N]>, &Self) {
681        if N == 0 {
682            (Default::default(), self)
683        } else {
684            let chunk_count = self.len() / N;
685            let remainder = self.len() % N;
686            let (chunks, remainder) = self.split_at(self.len() - remainder);
687            let chunks: &[Cell<T>] = chunks.as_std_transposed_ref();
688            // SAFETY: [[T; N]] has the same layout as [T], Cell<T> has the same layout as T
689            // (so [Cell<T>] => [[Cell<T>; N]] => [Cell<[T; N]>]),
690            // and we calculated the correct length.
691            let chunks: &[Cell<[T; N]>] =
692                unsafe { core::slice::from_raw_parts(chunks.as_ptr().cast(), chunk_count) };
693            let chunks: &SliceCell<[T; N]> = SliceCell::from_std_transposed_ref(chunks);
694            (chunks, remainder)
695        }
696    }
697
698    /// N should not be 0.
699    ///
700    /// Splits the slice into a slice of N-element arrays, starting at the end of the slice, and a remainder slice with length strictly less than N.
701    pub fn as_rchunks<const N: usize>(&self) -> (&Self, &SliceCell<[T; N]>) {
702        if N == 0 {
703            (self, Default::default())
704        } else {
705            let chunk_count = self.len() / N;
706            let remainder = self.len() % N;
707            let (remainder, chunks) = self.split_at(remainder);
708            let chunks: &[Cell<T>] = chunks.as_std_transposed_ref();
709            // SAFETY: [[T; N]] has the same layout as [T], Cell<T> has the same layout as T
710            // (so [Cell<T>] => [[Cell<T>; N]] => [Cell<[T; N]>]),
711            // and we calculated the correct length.
712            let chunks: &[Cell<[T; N]>] =
713                unsafe { core::slice::from_raw_parts(chunks.as_ptr().cast(), chunk_count) };
714            let chunks: &SliceCell<[T; N]> = SliceCell::from_std_transposed_ref(chunks);
715            (remainder, chunks)
716        }
717    }
718
719    /// N should not be 0.
720    ///
721    /// Splits the slice into a slice of N-element arrays, starting at the beginning of the slice, and a remainder slice with length strictly less than N.
722    pub fn as_chunks_mut<const N: usize>(&mut self) -> (&mut SliceCell<[T; N]>, &mut Self) {
723        if N == 0 {
724            (Default::default(), self)
725        } else {
726            let chunk_count = self.len() / N;
727            let remainder = self.len() % N;
728            let (chunks, remainder) = self.split_at_mut(self.len() - remainder);
729            let chunks: &mut [T] = chunks.as_mut();
730            // SAFETY: [[T; N]] has the same layout as [T], and we calculated the correct length.
731            let chunks: &mut [[T; N]] =
732                unsafe { core::slice::from_raw_parts_mut(chunks.as_mut_ptr().cast(), chunk_count) };
733            let chunks: &mut SliceCell<[T; N]> = SliceCell::from_mut(chunks);
734            (chunks, remainder)
735        }
736    }
737
738    /// N should not be 0.
739    ///
740    /// Splits the slice into a slice of N-element arrays, starting at the end of the slice, and a remainder slice with length strictly less than N.
741    pub fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut Self, &mut SliceCell<[T; N]>) {
742        if N == 0 {
743            (self, Default::default())
744        } else {
745            let chunk_count = self.len() / N;
746            let remainder = self.len() % N;
747            let (remainder, chunks) = self.split_at_mut(remainder);
748            let chunks: &mut [T] = chunks.as_mut();
749            // SAFETY: [[T; N]] has the same layout as [T], and we calculated the correct length.
750            let chunks: &mut [[T; N]] =
751                unsafe { core::slice::from_raw_parts_mut(chunks.as_mut_ptr().cast(), chunk_count) };
752            let chunks: &mut SliceCell<[T; N]> = SliceCell::from_mut(chunks);
753            (remainder, chunks)
754        }
755    }
756
757    pub fn iter(&self) -> core::slice::Iter<'_, Cell<T>> {
758        IntoIterator::into_iter(self)
759    }
760
761    pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, T> {
762        self.as_mut().iter_mut()
763    }
764}
765
766impl<T, const N: usize> SliceCell<[T; N]> {
767    /// Flattens a `&SliceCell<[T; N]>` into a `&SliceCell<T>`.
768    ///
769    /// # Panics
770    ///
771    /// Panics if the length of the resulting `SliceCell` would overflow a `usize`.
772    ///
773    /// See also [`slice::flatten`].
774    pub fn flatten(&self) -> &SliceCell<T> {
775        let new_len = self.len().checked_mul(N).expect("length overflow");
776        let this: &[Cell<[T; N]>] = self.as_std_transposed_ref();
777        // SAFETY: [[T; N]] has the same layout as [T], Cell<T> has the same layout as T
778        // (so [Cell<[T; N]>] => [[Cell<T>; N]] => [Cell<T>]),
779        // and we calculated the correct length.
780        let this: &[Cell<T>] =
781            unsafe { core::slice::from_raw_parts(this.as_ptr().cast(), new_len) };
782        let this: &SliceCell<T> = SliceCell::from_std_transposed_ref(this);
783        this
784    }
785
786    /// Flattens a `&mut SliceCell<[T; N]>` into a `&mut SliceCell<T>`.
787    ///
788    /// # Panics
789    ///
790    /// Panics if the length of the resulting `SliceCell` would overflow a `usize`.
791    ///
792    /// See also [`slice::flatten_mut`].
793    pub fn flatten_mut(&mut self) -> &mut SliceCell<T> {
794        let new_len = self.len().checked_mul(N).expect("length overflow");
795        let this: &mut [[T; N]] = self.as_mut();
796        // SAFETY: [[T; N]] has the same layout as [T], and we calculated the correct length.
797        let this: &mut [T] =
798            unsafe { core::slice::from_raw_parts_mut(this.as_mut_ptr().cast(), new_len) };
799        let this: &mut SliceCell<T> = SliceCell::from_mut(this);
800        this
801    }
802
803    /// Access this `SliceCell` of [array]s as a [slice] of [`ArrayCell`]s.
804    #[cfg(any())]
805    pub fn as_slice_of_arraycells(&self) -> &[ArrayCell<T, N>] {
806        todo!()
807    }
808}
809
810impl<T, I: SliceCellIndex<Self>> Index<I> for SliceCell<T> {
811    type Output = <I as SliceCellIndex<Self>>::Output;
812
813    fn index(&self, index: I) -> &Self::Output {
814        index.get(self).unwrap()
815    }
816}
817
818impl<T, I: SliceCellIndex<Self>> IndexMut<I> for SliceCell<T> {
819    fn index_mut(&mut self, index: I) -> &mut Self::Output {
820        index.get_mut(self).unwrap()
821    }
822}
823
824impl<'a, T: 'a> Default for &'a mut ArrayCell<T, 0> {
825    fn default() -> Self {
826        ArrayCell::from_mut(&mut [])
827    }
828}
829
830impl<'a, T: 'a> Default for &'a ArrayCell<T, 0> {
831    fn default() -> Self {
832        ArrayCell::from_mut(&mut [])
833    }
834}
835
836impl<'a, T: 'a> Default for &'a mut SliceCell<T> {
837    fn default() -> Self {
838        SliceCell::from_mut(&mut [])
839    }
840}
841
842impl<'a, T: 'a> Default for &'a SliceCell<T> {
843    fn default() -> Self {
844        SliceCell::from_mut(&mut [])
845    }
846}
847
848impl<'a, T, const N: usize> From<&'a ArrayCell<T, N>> for &'a SliceCell<T> {
849    fn from(value: &'a ArrayCell<T, N>) -> Self {
850        SliceCell::from_std_ref(value.as_std_ref())
851    }
852}
853
854impl<'a, T, const N: usize> From<&'a mut ArrayCell<T, N>> for &'a mut SliceCell<T> {
855    fn from(value: &'a mut ArrayCell<T, N>) -> Self {
856        SliceCell::from_mut(value.as_mut())
857    }
858}
859
860#[cfg(feature = "alloc")]
861impl<'a, T, const N: usize> From<Box<ArrayCell<T, N>>> for Box<SliceCell<T>> {
862    fn from(value: Box<ArrayCell<T, N>>) -> Self {
863        SliceCell::from_std_boxed(value.into_std_boxed())
864    }
865}
866
867impl<'a, T, const N: usize> TryFrom<&'a SliceCell<T>> for &'a ArrayCell<T, N> {
868    type Error = &'a SliceCell<T>;
869
870    fn try_from(value: &'a SliceCell<T>) -> Result<Self, Self::Error> {
871        if value.len() == N {
872            Ok({
873                let the_ref = value
874                    .as_std_transposed_ref()
875                    .try_into()
876                    .expect("already checked the length");
877                ArrayCell::from_std_transposed_ref(the_ref)
878            })
879        } else {
880            Err(value)
881        }
882    }
883}
884
885impl<'a, T, const N: usize> TryFrom<&'a mut SliceCell<T>> for &'a mut ArrayCell<T, N> {
886    type Error = &'a mut SliceCell<T>;
887
888    fn try_from(value: &'a mut SliceCell<T>) -> Result<Self, Self::Error> {
889        if value.len() == N {
890            Ok({
891                let the_mut = value
892                    .as_mut()
893                    .try_into()
894                    .expect("already checked the length");
895                ArrayCell::from_mut(the_mut)
896            })
897        } else {
898            Err(value)
899        }
900    }
901}
902
903#[cfg(feature = "alloc")]
904impl<'a, T, const N: usize> TryFrom<Box<SliceCell<T>>> for Box<ArrayCell<T, N>> {
905    type Error = Box<SliceCell<T>>;
906
907    fn try_from(value: Box<SliceCell<T>>) -> Result<Self, Self::Error> {
908        if value.len() == N {
909            Ok({
910                let the_box = value
911                    .into_std_transposed_boxed()
912                    .try_into()
913                    .ok()
914                    .expect("already checked the length");
915                ArrayCell::from_std_transposed_boxed(the_box)
916            })
917        } else {
918            Err(value)
919        }
920    }
921}
922
923impl<'a, T> IntoIterator for &'a SliceCell<T> {
924    type Item = &'a Cell<T>;
925
926    type IntoIter = core::slice::Iter<'a, Cell<T>>;
927
928    fn into_iter(self) -> Self::IntoIter {
929        self.as_std_transposed_ref().iter()
930    }
931}
932
933impl<'a, T, const N: usize> IntoIterator for &'a ArrayCell<T, N> {
934    type Item = &'a Cell<T>;
935
936    type IntoIter = core::slice::Iter<'a, Cell<T>>;
937
938    fn into_iter(self) -> Self::IntoIter {
939        self.as_std_transposed_ref().iter()
940    }
941}
942
943impl<'a, T> IntoIterator for &'a mut SliceCell<T> {
944    type Item = &'a mut T;
945
946    type IntoIter = core::slice::IterMut<'a, T>;
947
948    fn into_iter(self) -> Self::IntoIter {
949        self.as_mut().iter_mut()
950    }
951}
952
953impl<'a, T, const N: usize> IntoIterator for &'a mut ArrayCell<T, N> {
954    type Item = &'a mut T;
955
956    type IntoIter = core::slice::IterMut<'a, T>;
957
958    fn into_iter(self) -> Self::IntoIter {
959        self.as_mut().iter_mut()
960    }
961}