slice_cell/
lib.rs

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