1use core::fmt::Debug;
4use core::marker::PhantomData;
5use core::mem::MaybeUninit;
6use core::ptr::{self, NonNull};
7
8use const_default::ConstDefault;
9
10use crate::alloc::{AllocateIn, Allocator, AllocatorDefault, Fixed, Global, Spill};
11use crate::capacity::{Grow, GrowDoubling, GrowExact, Index};
12use crate::error::StorageError;
13use crate::storage::{ArrayStorage, FatBuffer, Inline, InlineBuffer, SpillStorage, ThinBuffer};
14
15use super::buffer::{VecBuffer, VecHeader};
16
17pub trait VecConfig {
19 type Buffer<T>: VecBuffer<Item = T, Index = Self::Index>;
21
22 type Grow: Grow;
24
25 type Index: Index;
27}
28
29impl<A: Allocator> VecConfig for A {
30 type Buffer<T> = FatBuffer<T, VecHeader<usize>, A>;
31 type Grow = GrowDoubling;
32 type Index = usize;
33}
34
35pub trait VecConfigAlloc<T>: VecConfig {
37 type Alloc: Allocator;
39
40 fn allocator(buf: &Self::Buffer<T>) -> &Self::Alloc;
42
43 fn buffer_from_parts(
45 data: NonNull<T>,
46 length: Self::Index,
47 capacity: Self::Index,
48 alloc: Self::Alloc,
49 ) -> Self::Buffer<T>;
50
51 fn buffer_into_parts(
53 buffer: Self::Buffer<T>,
54 ) -> (NonNull<T>, Self::Index, Self::Index, Self::Alloc);
55}
56
57impl<T, A: Allocator> VecConfigAlloc<T> for A {
58 type Alloc = A;
59
60 #[inline]
61 fn allocator(buf: &Self::Buffer<T>) -> &Self::Alloc {
62 &buf.alloc
63 }
64
65 #[inline]
66 fn buffer_from_parts(
67 data: NonNull<T>,
68 length: Self::Index,
69 capacity: Self::Index,
70 alloc: Self::Alloc,
71 ) -> Self::Buffer<T> {
72 FatBuffer::from_parts(VecHeader { capacity, length }, data, alloc)
73 }
74
75 #[inline]
76 fn buffer_into_parts(
77 buffer: Self::Buffer<T>,
78 ) -> (NonNull<T>, Self::Index, Self::Index, Self::Alloc) {
79 let (header, data, alloc) = buffer.into_parts();
80 (data, header.length, header.capacity, alloc)
81 }
82}
83
84pub trait VecConfigNew<T>: VecConfigSpawn<T> {
86 const EMPTY_BUFFER: Self::Buffer<T>;
88
89 fn buffer_try_new(capacity: Self::Index, exact: bool) -> Result<Self::Buffer<T>, StorageError>;
91}
92
93impl<T, A: AllocatorDefault> VecConfigNew<T> for A {
94 const EMPTY_BUFFER: Self::Buffer<T> = FatBuffer::<T, VecHeader<usize>, A>::DEFAULT;
95
96 #[inline]
97 fn buffer_try_new(capacity: Self::Index, exact: bool) -> Result<Self::Buffer<T>, StorageError> {
98 FatBuffer::allocate_in(
99 VecHeader {
100 capacity,
101 length: Self::Index::ZERO,
102 },
103 A::DEFAULT,
104 exact,
105 )
106 }
107}
108
109pub trait VecConfigSpawn<T>: VecConfig {
111 fn buffer_try_spawn(
113 buf: &Self::Buffer<T>,
114 capacity: Self::Index,
115 exact: bool,
116 ) -> Result<Self::Buffer<T>, StorageError>;
117}
118
119impl<T, A: Allocator + Clone> VecConfigSpawn<T> for A {
120 #[inline]
121 fn buffer_try_spawn(
122 buf: &Self::Buffer<T>,
123 capacity: Self::Index,
124 exact: bool,
125 ) -> Result<Self::Buffer<T>, StorageError> {
126 FatBuffer::allocate_in(
127 VecHeader {
128 capacity,
129 length: Index::ZERO,
130 },
131 buf.alloc.clone(),
132 exact,
133 )
134 }
135}
136
137pub trait VecNewIn<T> {
139 type Config: VecConfig;
141
142 fn buffer_try_new_in(
144 self,
145 capacity: <Self::Config as VecConfig>::Index,
146 exact: bool,
147 ) -> Result<<Self::Config as VecConfig>::Buffer<T>, StorageError>;
148}
149
150#[derive(Debug, Default)]
152pub struct Custom<A: Allocator, I: Index = usize, G: Grow = GrowExact> {
153 alloc: A,
154 _pd: PhantomData<(I, G)>,
155}
156
157impl<A: AllocatorDefault, I: Index, G: Grow> ConstDefault for Custom<A, I, G> {
158 const DEFAULT: Self = Self {
160 alloc: A::DEFAULT,
161 _pd: PhantomData,
162 };
163}
164
165impl<A: Allocator, I: Index, G: Grow> VecConfig for Custom<A, I, G> {
166 type Buffer<T> = FatBuffer<T, VecHeader<I>, A>;
167 type Grow = G;
168 type Index = I;
169}
170
171impl<T, A: AllocatorDefault, I: Index, G: Grow> VecConfigNew<T> for Custom<A, I, G> {
172 const EMPTY_BUFFER: Self::Buffer<T> = FatBuffer::DEFAULT;
173
174 fn buffer_try_new(capacity: Self::Index, exact: bool) -> Result<Self::Buffer<T>, StorageError> {
175 FatBuffer::allocate_in(
176 VecHeader {
177 capacity,
178 length: Self::Index::ZERO,
179 },
180 A::DEFAULT,
181 exact,
182 )
183 }
184}
185
186impl<T, A: Allocator + Clone, I: Index, G: Grow> VecConfigSpawn<T> for Custom<A, I, G> {
187 #[inline]
188 fn buffer_try_spawn(
189 buf: &Self::Buffer<T>,
190 capacity: Self::Index,
191 exact: bool,
192 ) -> Result<Self::Buffer<T>, StorageError> {
193 FatBuffer::allocate_in(
194 VecHeader {
195 capacity,
196 length: Index::ZERO,
197 },
198 buf.alloc.clone(),
199 exact,
200 )
201 }
202}
203
204#[derive(Clone, Debug, Default, PartialEq, Eq)]
206pub struct Thin<A: Allocator = Global, I: Index = usize, G: Grow = GrowExact> {
207 alloc: A,
208 _pd: PhantomData<(I, G)>,
209}
210
211impl<A: Allocator, I: Index, G: Grow> VecConfig for Thin<A, I, G> {
212 type Buffer<T> = ThinBuffer<T, VecHeader<usize>, A>;
213 type Grow = GrowDoubling;
214 type Index = usize;
215}
216
217impl<A: AllocatorDefault, I: Index, G: Grow> ConstDefault for Thin<A, I, G> {
218 const DEFAULT: Self = Self {
219 alloc: A::DEFAULT,
220 _pd: PhantomData,
221 };
222}
223
224impl<T, A: Allocator, I: Index, G: Grow> VecConfigAlloc<T> for Thin<A, I, G> {
225 type Alloc = A;
226
227 #[inline]
228 fn allocator(buf: &Self::Buffer<T>) -> &Self::Alloc {
229 &buf.alloc
230 }
231
232 #[inline]
233 fn buffer_from_parts(
234 data: NonNull<T>,
235 length: Self::Index,
236 capacity: Self::Index,
237 alloc: Self::Alloc,
238 ) -> Self::Buffer<T> {
239 ThinBuffer::from_parts(VecHeader { capacity, length }, data, alloc)
240 }
241
242 #[inline]
243 fn buffer_into_parts(
244 buffer: Self::Buffer<T>,
245 ) -> (NonNull<T>, Self::Index, Self::Index, Self::Alloc) {
246 let (header, data, alloc) = buffer.into_parts();
247 (data, header.length, header.capacity, alloc)
248 }
249}
250
251impl<T, A: AllocatorDefault, I: Index, G: Grow> VecConfigNew<T> for Thin<A, I, G> {
252 const EMPTY_BUFFER: Self::Buffer<T> = ThinBuffer::<T, VecHeader<usize>, A>::DEFAULT;
253
254 #[inline]
255 fn buffer_try_new(capacity: Self::Index, exact: bool) -> Result<Self::Buffer<T>, StorageError> {
256 ThinBuffer::allocate_in(
257 VecHeader {
258 capacity,
259 length: Self::Index::ZERO,
260 },
261 A::DEFAULT,
262 exact,
263 )
264 }
265}
266
267impl<T, A: Allocator + Clone, I: Index, G: Grow> VecConfigSpawn<T> for Thin<A, I, G> {
268 #[inline]
269 fn buffer_try_spawn(
270 buf: &Self::Buffer<T>,
271 capacity: Self::Index,
272 exact: bool,
273 ) -> Result<Self::Buffer<T>, StorageError> {
274 ThinBuffer::allocate_in(
275 VecHeader {
276 capacity,
277 length: Index::ZERO,
278 },
279 buf.alloc.clone(),
280 exact,
281 )
282 }
283}
284
285impl<T, A: AllocatorDefault, I: Index, G: Grow> VecNewIn<T> for Thin<A, I, G> {
286 type Config = Thin<A, I, G>;
287
288 #[inline]
289 fn buffer_try_new_in(
290 self,
291 capacity: <Self::Config as VecConfig>::Index,
292 exact: bool,
293 ) -> Result<<Self::Config as VecConfig>::Buffer<T>, StorageError> {
294 ThinBuffer::allocate_in(
295 VecHeader {
296 capacity,
297 length: Index::ZERO,
298 },
299 A::DEFAULT,
300 exact,
301 )
302 }
303}
304
305impl<const N: usize> VecConfig for Inline<N> {
306 type Buffer<T> = InlineBuffer<T, N>;
307 type Index = usize;
308 type Grow = GrowExact;
309}
310
311impl<T, const N: usize> VecConfigNew<T> for Inline<N> {
312 const EMPTY_BUFFER: Self::Buffer<T> = InlineBuffer::<T, N>::DEFAULT;
313
314 fn buffer_try_new(capacity: Self::Index, exact: bool) -> Result<Self::Buffer<T>, StorageError> {
315 InlineBuffer::try_for_capacity(capacity, exact)
316 }
317}
318
319impl<T, const N: usize> VecConfigSpawn<T> for Inline<N> {
320 #[inline]
321 fn buffer_try_spawn(
322 _buf: &Self::Buffer<T>,
323 capacity: Self::Index,
324 exact: bool,
325 ) -> Result<Self::Buffer<T>, StorageError> {
326 InlineBuffer::try_for_capacity(capacity, exact)
327 }
328}
329
330impl<T, C: AllocateIn> VecNewIn<T> for C {
331 type Config = C::Alloc;
332
333 #[inline]
334 fn buffer_try_new_in(
335 self,
336 capacity: <Self::Config as VecConfig>::Index,
337 exact: bool,
338 ) -> Result<<Self::Config as VecConfig>::Buffer<T>, StorageError> {
339 FatBuffer::allocate_in(
340 VecHeader {
341 capacity,
342 length: Index::ZERO,
343 },
344 self,
345 exact,
346 )
347 }
348}
349
350impl<T, A: Allocator, I: Index, G: Grow> VecNewIn<T> for Custom<A, I, G> {
351 type Config = Self;
352
353 #[inline]
354 fn buffer_try_new_in(
355 self,
356 capacity: <Self::Config as VecConfig>::Index,
357 exact: bool,
358 ) -> Result<<Self::Config as VecConfig>::Buffer<T>, StorageError> {
359 FatBuffer::allocate_in(
360 VecHeader {
361 capacity,
362 length: Index::ZERO,
363 },
364 self.alloc,
365 exact,
366 )
367 }
368}
369
370impl<'a, T, const N: usize> VecNewIn<T> for &'a mut ArrayStorage<T, N> {
371 type Config = Fixed<'a>;
372
373 #[inline]
374 fn buffer_try_new_in(
375 self,
376 mut capacity: <Self::Config as VecConfig>::Index,
377 exact: bool,
378 ) -> Result<<Self::Config as VecConfig>::Buffer<T>, StorageError> {
379 if capacity > N {
380 return Err(StorageError::CapacityLimit);
381 }
382 if !exact {
383 capacity = N;
384 }
385 Ok(FatBuffer::from_parts(
386 VecHeader {
387 capacity,
388 length: Index::ZERO,
389 },
390 NonNull::from(&mut self.0).cast(),
391 Fixed::default(),
392 ))
393 }
394}
395
396impl<'a, T, A: Allocator> VecNewIn<T> for SpillStorage<'a, &'a mut [MaybeUninit<T>], A> {
397 type Config = Spill<'a, A>;
398
399 fn buffer_try_new_in(
400 self,
401 mut capacity: <Self::Config as VecConfig>::Index,
402 exact: bool,
403 ) -> Result<<Self::Config as VecConfig>::Buffer<T>, StorageError> {
404 if capacity > self.buffer.len() {
405 return FatBuffer::allocate_in(
406 VecHeader {
407 capacity,
408 length: Index::ZERO,
409 },
410 Spill::new(self.alloc, ptr::null(), Fixed::DEFAULT),
411 exact,
412 );
413 }
414 if !exact {
415 capacity = self.buffer.len();
416 }
417 let data = NonNull::from(self.buffer).cast::<T>();
418 Ok(FatBuffer::from_parts(
419 VecHeader {
420 capacity,
421 length: Index::ZERO,
422 },
423 data,
424 Spill::new(self.alloc, data.as_ptr().cast::<u8>(), Fixed::DEFAULT),
425 ))
426 }
427}
428
429impl<T, const N: usize> VecNewIn<T> for Inline<N> {
430 type Config = Inline<N>;
431
432 #[inline]
433 fn buffer_try_new_in(
434 self,
435 capacity: <Self::Config as VecConfig>::Index,
436 exact: bool,
437 ) -> Result<<Self::Config as VecConfig>::Buffer<T>, StorageError> {
438 if capacity > N || (capacity < N && exact) {
439 return Err(StorageError::CapacityLimit);
440 }
441 Ok(InlineBuffer::DEFAULT)
442 }
443}