stabby_abi/alloc/
single_or_vec.rs

1use super::vec::Vec;
2use crate::alloc::{AllocationError, DefaultAllocator, IAlloc};
3use crate::num::NonMaxUsize;
4use crate::result::OkGuard;
5use crate::{IDeterminantProvider, IStable};
6mod seal {
7    #[crate::stabby]
8    pub struct Single<T, Alloc> {
9        pub value: T,
10        pub alloc: Alloc,
11    }
12}
13pub(crate) use seal::*;
14/// A vector that doesn't need to allocate for its first value.
15///
16/// Once a second value is pushed, or if greater capacity is reserved,
17/// the allocated vector will be used regardless of how the vector's
18/// number of elements evolves.
19#[crate::stabby]
20pub struct SingleOrVec<T: IStable, Alloc: IAlloc + IStable = DefaultAllocator>
21where
22    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
23    Vec<T, Alloc>: IStable,
24    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
25{
26    inner: crate::Result<Single<T, Alloc>, Vec<T, Alloc>>,
27}
28
29#[cfg(not(stabby_default_alloc = "disabled"))]
30impl<T: IStable> SingleOrVec<T>
31where
32    Single<T, DefaultAllocator>: IDeterminantProvider<Vec<T, DefaultAllocator>>,
33    Vec<T, DefaultAllocator>: IStable,
34    crate::Result<Single<T, DefaultAllocator>, Vec<T, DefaultAllocator>>: IStable,
35{
36    /// Constructs a new vector. This doesn't actually allocate.
37    pub fn new() -> Self {
38        Self::new_in(DefaultAllocator::new())
39    }
40}
41
42impl<T: IStable, Alloc: IAlloc + IStable + Default> Default for SingleOrVec<T, Alloc>
43where
44    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
45    Vec<T, Alloc>: IStable,
46    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
47{
48    fn default() -> Self {
49        Self::new_in(Alloc::default())
50    }
51}
52impl<T: IStable, Alloc: IAlloc + IStable> SingleOrVec<T, Alloc>
53where
54    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
55    Vec<T, Alloc>: IStable,
56    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
57{
58    /// Constructs a new vector in `alloc`. This doesn't actually allocate.
59    pub fn new_in(alloc: Alloc) -> Self {
60        Self {
61            inner: crate::Result::Err(Vec::new_in(alloc)),
62        }
63    }
64    /// Constructs a new vector in `alloc`, allocating sufficient space for `capacity` elements.
65    ///
66    /// # Panics
67    /// If the allocator failed to provide a large enough allocation.
68    pub fn with_capacity_in(capacity: usize, alloc: Alloc) -> Self {
69        let mut this = Self::new_in(alloc);
70        this.reserve(capacity);
71        this
72    }
73    /// Constructs a new vector, allocating sufficient space for `capacity` elements.
74    ///
75    /// # Panics
76    /// If the allocator failed to provide a large enough allocation.
77    pub fn with_capacity(capacity: usize) -> Self
78    where
79        Alloc: Default,
80    {
81        Self::with_capacity_in(capacity, Alloc::default())
82    }
83    /// Constructs a new vector in `alloc`, allocating sufficient space for `capacity` elements.
84    ///
85    /// # Errors
86    /// Returns an [`AllocationError`] if the allocator couldn't provide a sufficient allocation.
87    pub fn try_with_capacity_in(capacity: usize, alloc: Alloc) -> Result<Self, Alloc> {
88        Vec::try_with_capacity_in(capacity, alloc).map(|vec| Self {
89            inner: crate::Result::Err(vec),
90        })
91    }
92    /// Constructs a new vector, allocating sufficient space for `capacity` elements.
93    ///
94    /// # Errors
95    /// Returns an [`AllocationError`] if the allocator couldn't provide a sufficient allocation.
96    pub fn try_with_capacity(capacity: usize) -> Result<Self, Alloc>
97    where
98        Alloc: Default,
99        Self: IDeterminantProvider<AllocationError>,
100    {
101        Self::try_with_capacity_in(capacity, Alloc::default())
102    }
103    /// Returns the number of elements in the vector.
104    pub fn len(&self) -> usize {
105        self.inner.match_ref(|_| 1, |vec| vec.len())
106    }
107    /// Returns `true` if the vector is empty.
108    pub fn is_empty(&self) -> bool {
109        self.inner.match_ref(|_| false, |vec| vec.is_empty())
110    }
111    /// Adds `value` at the end of `self`.
112    ///
113    /// # Panics
114    /// This function panics if the vector tried to grow due to
115    /// being full, and the allocator failed to provide a new allocation.
116    pub fn push(&mut self, value: T) {
117        if self.try_push(value).is_err() {
118            panic!("Failed to push because reallocation failed.")
119        }
120    }
121    /// Adds `value` at the end of `self`.
122    ///
123    /// # Errors
124    /// This function gives back the `value` if the vector tried to grow due to
125    /// being full, and the allocator failed to provide a new allocation.
126    ///
127    /// `self` is still valid should that happen.
128    pub fn try_push(&mut self, item: T) -> Result<(), T> {
129        // Safety: either `this` or `*self` MUST be leaked to prevent double-frees.
130        let this = unsafe { core::ptr::read(self) };
131        // Safety: Any path that returns `Err` MUST leak the contents of the second argument.
132        let this = this.inner.match_owned_ctx(
133            item,
134            |item, single| {
135                // either `inner` must be leaked and overwritten by the new owner of `value` and `alloc`,
136                // or these two must be leaked to prevent double frees.
137                let Single { value, alloc } = single;
138                match Vec::try_with_capacity_in(8, alloc) {
139                    Ok(mut vec) => {
140                        vec.push(value);
141                        vec.push(item);
142                        Ok(crate::Result::Err(vec))
143                    }
144                    Err(alloc) => {
145                        // Safety: leak both `value` and `alloc` since `*self` won't be leaked
146                        core::mem::forget((value, alloc));
147                        Err(item)
148                    }
149                }
150            },
151            |item, mut vec| {
152                if vec.capacity() == 0 {
153                    unsafe {
154                        let alloc = core::ptr::read(&vec.inner.alloc);
155                        core::mem::forget(vec);
156                        Ok(crate::Result::Ok(Single { value: item, alloc }))
157                    }
158                } else {
159                    match vec.try_push(item) {
160                        Ok(()) => Ok(crate::Result::Err(vec)),
161                        Err(item) => {
162                            // Safety: `vec` since `*self` won't be leaked
163                            core::mem::forget(vec);
164                            Err(item)
165                        }
166                    }
167                }
168            },
169        );
170        match this {
171            Ok(inner) => unsafe {
172                // Safety: this leaks `*self`, preventing it from being unduely destroyed
173                core::ptr::write(self, Self { inner });
174                Ok(())
175            },
176            Err(item) => Err(item),
177        }
178    }
179    /// The total capacity of the vector.
180    pub fn capacity(&self) -> usize {
181        self.inner.match_ref(|_| 1, |vec| vec.capacity())
182    }
183    /// The remaining number of elements that can be pushed before reallocating.
184    pub fn remaining_capacity(&self) -> usize {
185        self.inner.match_ref(|_| 0, |vec| vec.remaining_capacity())
186    }
187    /// Ensures that `additional` more elements can be pushed on `self` without reallocating.
188    ///
189    /// This may reallocate once to provide this guarantee.
190    ///
191    /// # Panics
192    /// This function panics if the allocator failed to provide an appropriate allocation.
193    pub fn reserve(&mut self, additional: usize) {
194        self.try_reserve(additional).unwrap();
195    }
196    /// Ensures that `additional` more elements can be pushed on `self` without reallocating.
197    ///
198    /// This may reallocate once to provide this guarantee.
199    ///
200    /// # Errors
201    /// Returns Ok(new_capacity) if succesful (including if no reallocation was needed),
202    /// otherwise returns Err(AllocationError)
203    pub fn try_reserve(&mut self, additional: usize) -> Result<NonMaxUsize, AllocationError> {
204        let inner = &mut self.inner as *mut _;
205        self.inner.match_mut(
206            |value| unsafe {
207                let new_capacity = 1 + additional;
208                // either `inner` must be leaked and overwritten by the new owner of `value` and `alloc`,
209                // or these two must be leaked to prevent double frees.
210                let Single { value, alloc } = core::ptr::read(&*value);
211                match Vec::try_with_capacity_in(new_capacity, alloc) {
212                    Ok(mut vec) => {
213                        vec.push(value);
214                        // overwrite `inner` with `value` and `alloc` with their new owner without freeing `inner`.
215                        core::ptr::write(inner, crate::Result::Err(vec));
216                        NonMaxUsize::new(new_capacity).ok_or(AllocationError())
217                    }
218                    Err(alloc) => {
219                        // leak both `value` and `alloc` since `inner` can't be overwritten
220                        core::mem::drop((value, alloc));
221                        Err(AllocationError())
222                    }
223                }
224            },
225            |mut vec| vec.try_reserve(additional),
226        )
227    }
228    /// Removes all elements from `self` from the `len`th onward.
229    ///
230    /// Does nothing if `self.len() <= len`
231    pub fn truncate(&mut self, len: usize) {
232        if self.len() <= len {
233            return;
234        }
235        let inner = &mut self.inner as *mut _;
236        self.inner.match_mut(
237            |value| unsafe {
238                let Single { value, alloc } = core::ptr::read(&*value);
239                core::mem::drop(value); // drop `value` to prevent leaking it since we'll overwrite `inner` with something that doesn't own it
240                                        // overwrite `inner` with the new owner of `alloc`
241                core::ptr::write(inner, crate::Result::Err(Vec::new_in(alloc)))
242            },
243            |mut vec| vec.truncate(len),
244        )
245    }
246    /// Returns a slice of the elements in the vector.
247    pub fn as_slice(&self) -> &[T] {
248        self.inner.match_ref(
249            |value| core::slice::from_ref(&value.value),
250            |vec| vec.as_slice(),
251        )
252    }
253    /// Returns a mutable slice of the elements in the vector.
254    pub fn as_slice_mut(&mut self) -> SliceGuardMut<T, Alloc> {
255        self.inner.match_mut(
256            |value| SliceGuardMut { inner: Ok(value) },
257            |mut vec| SliceGuardMut {
258                inner: Err(unsafe {
259                    core::mem::transmute::<&mut [T], &mut [T]>(vec.as_slice_mut())
260                }),
261            },
262        )
263    }
264    // pub fn iter(&self) -> core::slice::Iter<'_, T> {
265    //     self.into_iter()
266    // }
267    // pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, T> {
268    //     self.into_iter()
269    // }
270}
271
272/// A mutable accessor to [`SingleOrVec`]'s inner slice.
273///
274/// Failing to drop this guard may cause Undefined Behaviour
275pub struct SliceGuardMut<'a, T, Alloc>
276where
277    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
278    Vec<T, Alloc>: IStable,
279    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
280    Alloc: IAlloc,
281{
282    #[allow(clippy::type_complexity)]
283    inner: Result<OkGuard<'a, Single<T, Alloc>, Vec<T, Alloc>>, &'a mut [T]>,
284}
285impl<T, Alloc> core::ops::Deref for SliceGuardMut<'_, T, Alloc>
286where
287    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
288    Vec<T, Alloc>: IStable,
289    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
290    Alloc: IAlloc,
291{
292    type Target = [T];
293    fn deref(&self) -> &Self::Target {
294        match &self.inner {
295            Ok(v) => core::slice::from_ref(&v.value),
296            Err(v) => v,
297        }
298    }
299}
300impl<T, Alloc> core::ops::DerefMut for SliceGuardMut<'_, T, Alloc>
301where
302    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
303    Vec<T, Alloc>: IStable,
304    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
305    Alloc: IAlloc,
306{
307    fn deref_mut(&mut self) -> &mut Self::Target {
308        match &mut self.inner {
309            Ok(v) => core::slice::from_mut(&mut v.value),
310            Err(v) => v,
311        }
312    }
313}
314
315impl<T: Clone, Alloc: IAlloc + Clone> Clone for SingleOrVec<T, Alloc>
316where
317    T: IStable,
318    Alloc: IStable,
319    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
320    Vec<T, Alloc>: IStable,
321    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
322{
323    fn clone(&self) -> Self {
324        self.inner.match_ref(
325            |Single { value, alloc }| Self {
326                inner: crate::Result::Ok(Single {
327                    value: value.clone(),
328                    alloc: alloc.clone(),
329                }),
330            },
331            |vec| Self {
332                inner: crate::Result::Err(vec.clone()),
333            },
334        )
335    }
336}
337impl<T: PartialEq, Alloc: IAlloc, Rhs: AsRef<[T]>> PartialEq<Rhs> for SingleOrVec<T, Alloc>
338where
339    T: IStable,
340    Alloc: IStable,
341    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
342    Vec<T, Alloc>: IStable,
343    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
344{
345    fn eq(&self, other: &Rhs) -> bool {
346        self.as_slice() == other.as_ref()
347    }
348}
349impl<T: Eq, Alloc: IAlloc> Eq for SingleOrVec<T, Alloc>
350where
351    T: IStable,
352    Alloc: IStable,
353    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
354    Vec<T, Alloc>: IStable,
355    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
356{
357}
358impl<T: PartialOrd, Alloc: IAlloc, Rhs: AsRef<[T]>> PartialOrd<Rhs> for SingleOrVec<T, Alloc>
359where
360    T: IStable,
361    Alloc: IStable,
362    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
363    Vec<T, Alloc>: IStable,
364    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
365{
366    fn partial_cmp(&self, other: &Rhs) -> Option<core::cmp::Ordering> {
367        self.as_slice().partial_cmp(other.as_ref())
368    }
369}
370impl<T: Ord, Alloc: IAlloc> Ord for SingleOrVec<T, Alloc>
371where
372    T: IStable,
373    Alloc: IStable,
374    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
375    Vec<T, Alloc>: IStable,
376    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
377{
378    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
379        self.as_slice().cmp(other.as_slice())
380    }
381}
382impl<T, Alloc: IAlloc> core::ops::Deref for SingleOrVec<T, Alloc>
383where
384    T: IStable,
385    Alloc: IStable,
386    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
387    Vec<T, Alloc>: IStable,
388    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
389{
390    type Target = [T];
391    fn deref(&self) -> &Self::Target {
392        self.as_slice()
393    }
394}
395impl<T, Alloc: IAlloc> core::convert::AsRef<[T]> for SingleOrVec<T, Alloc>
396where
397    T: IStable,
398    Alloc: IStable,
399    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
400    Vec<T, Alloc>: IStable,
401    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
402{
403    fn as_ref(&self) -> &[T] {
404        self.as_slice()
405    }
406}
407impl<T, Alloc: IAlloc> core::iter::Extend<T> for SingleOrVec<T, Alloc>
408where
409    T: IStable,
410    Alloc: IStable,
411    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
412    Vec<T, Alloc>: IStable,
413    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
414{
415    fn extend<Iter: IntoIterator<Item = T>>(&mut self, iter: Iter) {
416        let iter = iter.into_iter();
417        let min = iter.size_hint().0;
418        self.reserve(min);
419        for item in iter {
420            self.push(item);
421        }
422    }
423}
424
425impl<'a, T, Alloc: IAlloc> IntoIterator for &'a SingleOrVec<T, Alloc>
426where
427    T: IStable + 'a,
428    Alloc: IStable,
429    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
430    Vec<T, Alloc>: IStable,
431    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
432{
433    type Item = &'a T;
434    type IntoIter = core::slice::Iter<'a, T>;
435    fn into_iter(self) -> Self::IntoIter {
436        self.as_slice().iter()
437    }
438}
439impl<'a, T, Alloc: IAlloc> IntoIterator for &'a mut SingleOrVec<T, Alloc>
440where
441    T: IStable + 'a,
442    Alloc: IStable,
443    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
444    Vec<T, Alloc>: IStable,
445    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
446{
447    type Item = &'a mut T;
448    type IntoIter = IterMut<'a, T, Alloc>;
449    fn into_iter(self) -> Self::IntoIter {
450        let inner = self.as_slice_mut();
451        IterMut {
452            start: 0,
453            end: inner.len(),
454            inner,
455        }
456    }
457}
458
459/// An iterator over a [`SliceGuardMut`].
460pub struct IterMut<'a, T, Alloc>
461where
462    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
463    Vec<T, Alloc>: IStable,
464    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
465    Alloc: IAlloc,
466{
467    inner: SliceGuardMut<'a, T, Alloc>,
468    start: usize,
469    end: usize,
470}
471
472impl<'a, T, Alloc> Iterator for IterMut<'a, T, Alloc>
473where
474    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
475    Vec<T, Alloc>: IStable,
476    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
477    Alloc: IAlloc,
478{
479    type Item = &'a mut T;
480    fn next(&mut self) -> Option<Self::Item> {
481        if self.start < self.end {
482            let r = unsafe {
483                core::mem::transmute::<&mut T, &mut T>(self.inner.get_unchecked_mut(self.start))
484            };
485            self.start += 1;
486            Some(r)
487        } else {
488            None
489        }
490    }
491    fn size_hint(&self) -> (usize, Option<usize>) {
492        let len = self.len();
493        (len, Some(len))
494    }
495
496    fn count(self) -> usize
497    where
498        Self: Sized,
499    {
500        self.len()
501    }
502
503    fn last(mut self) -> Option<Self::Item>
504    where
505        Self: Sized,
506    {
507        self.next_back()
508    }
509
510    fn nth(&mut self, n: usize) -> Option<Self::Item> {
511        self.start += n;
512        self.next()
513    }
514}
515
516impl<T, Alloc> DoubleEndedIterator for IterMut<'_, T, Alloc>
517where
518    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
519    Vec<T, Alloc>: IStable,
520    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
521    Alloc: IAlloc,
522{
523    fn next_back(&mut self) -> Option<Self::Item> {
524        if self.start < self.end {
525            self.end -= 1;
526            let r = unsafe {
527                core::mem::transmute::<&mut T, &mut T>(self.inner.get_unchecked_mut(self.end))
528            };
529            Some(r)
530        } else {
531            None
532        }
533    }
534    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
535        self.end = self.end.saturating_sub(n);
536        self.next_back()
537    }
538}
539impl<T, Alloc> ExactSizeIterator for IterMut<'_, T, Alloc>
540where
541    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
542    Vec<T, Alloc>: IStable,
543    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
544    Alloc: IAlloc,
545{
546    fn len(&self) -> usize {
547        self.end.saturating_sub(self.start)
548    }
549}
550
551impl<T, Alloc: IAlloc> From<Vec<T, Alloc>> for SingleOrVec<T, Alloc>
552where
553    T: IStable,
554    Alloc: IStable,
555    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
556    Vec<T, Alloc>: IStable,
557    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
558{
559    fn from(value: Vec<T, Alloc>) -> Self {
560        Self {
561            inner: crate::Result::Err(value),
562        }
563    }
564}
565
566impl<T, Alloc: IAlloc> From<SingleOrVec<T, Alloc>> for Vec<T, Alloc>
567where
568    T: IStable,
569    Alloc: IStable,
570    Single<T, Alloc>: IDeterminantProvider<Vec<T, Alloc>>,
571    Vec<T, Alloc>: IStable,
572    crate::Result<Single<T, Alloc>, Vec<T, Alloc>>: IStable,
573{
574    fn from(value: SingleOrVec<T, Alloc>) -> Self {
575        value.inner.match_owned(
576            |Single { value, alloc }| {
577                let mut vec = Vec::new_in(alloc);
578                vec.push(value);
579                vec
580            },
581            |vec| vec,
582        )
583    }
584}
585
586#[test]
587fn test() {
588    use rand::Rng;
589    const LEN: usize = 20;
590    let mut std = std::vec::Vec::with_capacity(LEN);
591    let mut new: SingleOrVec<u8> = SingleOrVec::new();
592    let mut capacity: SingleOrVec<u8> = SingleOrVec::with_capacity(LEN);
593    let mut rng = rand::thread_rng();
594    let n: u8 = rng.gen();
595    new.push(n);
596    capacity.push(n);
597    std.push(n);
598    assert!(new.inner.is_ok());
599    assert!(capacity.inner.is_err());
600    for _ in 0..LEN {
601        let n: u8 = rng.gen();
602        new.push(n);
603        capacity.push(n);
604        std.push(n);
605    }
606    assert_eq!(new.as_slice(), std.as_slice());
607    assert_eq!(new.as_slice(), capacity.as_slice());
608    let clone = new.clone();
609    assert_eq!(new.as_slice(), clone.as_slice());
610}