musli/alloc/
default.rs

1use core::marker::PhantomData;
2
3use super::{Alloc, AllocError, Allocator};
4#[cfg(not(feature = "alloc"))]
5use super::{Slice, SliceAlloc};
6#[cfg(feature = "alloc")]
7use super::{System, SystemAlloc};
8
9/// The default stack buffer size for the default allocator provided through
10/// [`default()`].
11///
12/// [`default()`]: super::default()
13pub const DEFAULT_ARRAY_BUFFER: usize = 4096;
14
15macro_rules! implement {
16    ($id:ident, $ty:ty, $raw_vec:ty, $raw:ty) => {
17        /// The default allocator implementation.
18        ///
19        /// The exact implementation of this depends on if the `alloc` feature
20        /// is enabled.
21        ///
22        /// For more information, see [`default()`].
23        ///
24        /// [`default()`]: super::default()
25        #[repr(transparent)]
26        pub struct $id<'buf, const BUF: usize> {
27            inner: $ty,
28            _marker: PhantomData<&'buf mut [u8]>,
29        }
30
31        impl<'buf, const BUF: usize> $id<'buf, BUF> {
32            #[inline]
33            pub(super) fn new(inner: $ty) -> Self {
34                Self {
35                    inner,
36                    _marker: PhantomData,
37                }
38            }
39        }
40
41        /// The default raw allocation.
42        ///
43        /// The exact implementation of this depends on if the `alloc` feature
44        /// is enabled.
45        ///
46        /// For more information, see [`default()`].
47        ///
48        /// [`default()`]: super::default()
49        pub struct DefaultAlloc<'a, T, const BUF: usize> {
50            inner: $raw,
51            _marker: PhantomData<&'a ()>,
52        }
53    };
54}
55
56#[cfg(feature = "alloc")]
57implement!(DefaultAllocator, System, SystemAlloc<T>, SystemAlloc<T>);
58
59#[cfg(not(feature = "alloc"))]
60implement!(
61    DefaultAllocator,
62    Slice<'buf>,
63    SliceAlloc<'a, T>,
64    SliceAlloc<'a, T>
65);
66
67unsafe impl<'a, const BUF: usize> Allocator for &'a DefaultAllocator<'_, BUF> {
68    #[cfg(feature = "alloc")]
69    const IS_SYSTEM: bool = true;
70
71    #[cfg(not(feature = "alloc"))]
72    const IS_SYSTEM: bool = false;
73
74    type Alloc<T> = DefaultAlloc<'a, T, BUF>;
75
76    #[inline]
77    fn alloc<T>(self, value: T) -> Result<Self::Alloc<T>, AllocError> {
78        Ok(DefaultAlloc {
79            inner: self.inner.alloc(value)?,
80            _marker: PhantomData,
81        })
82    }
83
84    #[inline]
85    fn alloc_empty<T>(self) -> Self::Alloc<T> {
86        DefaultAlloc {
87            inner: self.inner.alloc_empty(),
88            _marker: PhantomData,
89        }
90    }
91}
92
93impl<T, const BUF: usize> Alloc<T> for DefaultAlloc<'_, T, BUF> {
94    #[inline]
95    fn as_ptr(&self) -> *const T {
96        Alloc::as_ptr(&self.inner)
97    }
98
99    #[inline]
100    fn as_mut_ptr(&mut self) -> *mut T {
101        Alloc::as_mut_ptr(&mut self.inner)
102    }
103
104    #[inline]
105    fn capacity(&self) -> usize {
106        self.inner.capacity()
107    }
108
109    #[inline]
110    fn resize(&mut self, len: usize, additional: usize) -> Result<(), AllocError> {
111        self.inner.resize(len, additional)
112    }
113
114    #[inline]
115    fn try_merge<B>(&mut self, this_len: usize, other: B, other_len: usize) -> Result<(), B>
116    where
117        B: Alloc<T>,
118    {
119        self.inner.try_merge(this_len, other, other_len)
120    }
121}