1use crate::{unreachable_unchecked, AnonymRef, AnonymRefMut, IPtrMut, IntoDyn};
16
17use super::{vec::*, AllocPtr, AllocSlice, IAlloc};
18use core::{
19 fmt::Debug,
20 marker::PhantomData,
21 mem::{ManuallyDrop, MaybeUninit},
22 ptr::NonNull,
23};
24
25#[crate::stabby]
27pub struct Box<T, Alloc: IAlloc = super::DefaultAllocator> {
28 ptr: AllocPtr<T, Alloc>,
29}
30unsafe impl<T: Send, Alloc: IAlloc + Send> Send for Box<T, Alloc> {}
32unsafe impl<T: Sync, Alloc: IAlloc> Sync for Box<T, Alloc> {}
34unsafe impl<T: Send, Alloc: IAlloc + Send> Send for BoxedSlice<T, Alloc> {}
36unsafe impl<T: Sync, Alloc: IAlloc> Sync for BoxedSlice<T, Alloc> {}
38
39#[cfg(not(stabby_default_alloc = "disabled"))]
40impl<T> Box<T> {
41 pub unsafe fn make<
56 F: for<'a> FnOnce(&'a mut core::mem::MaybeUninit<T>) -> Result<&'a mut T, ()>,
57 >(
58 constructor: F,
59 ) -> Result<Self, Box<MaybeUninit<T>>> {
60 unsafe { Self::make_in(constructor, super::DefaultAllocator::new()) }
62 }
63 pub fn new(value: T) -> Self {
68 Self::new_in(value, super::DefaultAllocator::new())
69 }
70}
71impl<T, Alloc: IAlloc> Box<T, Alloc> {
72 #[allow(clippy::type_complexity)]
88 pub unsafe fn try_make_in<
89 F: for<'a> FnOnce(&'a mut core::mem::MaybeUninit<T>) -> Result<&'a mut T, ()>,
90 >(
91 constructor: F,
92 mut alloc: Alloc,
93 ) -> Result<Self, Result<Box<MaybeUninit<T>, Alloc>, (F, Alloc)>> {
94 let mut ptr = match AllocPtr::alloc(&mut alloc) {
95 Some(mut ptr) => {
96 unsafe { ptr.prefix_mut() }.alloc.write(alloc);
98 ptr
99 }
100 None => return Err(Err((constructor, alloc))),
101 };
102 constructor(unsafe { ptr.as_mut() }).map_or_else(
104 |()| Err(Ok(Box { ptr })),
105 |_| {
106 Ok(Self {
107 ptr: unsafe { ptr.assume_init() },
109 })
110 },
111 )
112 }
113 pub fn try_new_in(value: T, alloc: Alloc) -> Result<Self, (T, Alloc)> {
117 let this = unsafe {
119 Self::try_make_in(
120 |slot: &mut core::mem::MaybeUninit<T>| {
121 Ok(slot.write(core::ptr::read(&value)))
123 },
124 alloc,
125 )
126 };
127 match this {
128 Ok(this) => {
129 core::mem::forget(value);
130 Ok(this)
131 }
132 Err(Err((_, a))) => Err((value, a)),
133 Err(Ok(_)) => unsafe { unreachable_unchecked!() },
135 }
136 }
137 pub unsafe fn make_in<
150 F: for<'a> FnOnce(&'a mut core::mem::MaybeUninit<T>) -> Result<&'a mut T, ()>,
151 >(
152 constructor: F,
153 alloc: Alloc,
154 ) -> Result<Self, Box<MaybeUninit<T>, Alloc>> {
155 Self::try_make_in(constructor, alloc).map_err(|e| match e {
156 Ok(uninit) => uninit,
157 Err(_) => panic!("Allocation failed"),
158 })
159 }
160 pub fn new_in(value: T, alloc: Alloc) -> Self {
165 let this = unsafe { Self::make_in(move |slot| Ok(slot.write(value)), alloc) };
167 unsafe { this.unwrap_unchecked() }
169 }
170 pub fn into_inner(this: Self) -> T {
172 let mut this = core::mem::ManuallyDrop::new(this);
173 let ret = ManuallyDrop::new(unsafe { core::ptr::read(&**this) });
175 unsafe { this.free() };
177 ManuallyDrop::into_inner(ret)
178 }
179 pub const fn into_raw(this: Self) -> AllocPtr<T, Alloc> {
183 let inner = this.ptr;
184 core::mem::forget(this);
185 inner
186 }
187 pub const unsafe fn from_raw(this: AllocPtr<T, Alloc>) -> Self {
191 Self { ptr: this }
192 }
193}
194
195impl<T, Alloc: IAlloc> Box<T, Alloc> {
196 unsafe fn free(&mut self) {
200 let mut alloc = unsafe { self.ptr.prefix().alloc.assume_init_read() };
202 unsafe { self.ptr.free(&mut alloc) }
204 }
205}
206
207impl<T: Clone, Alloc: IAlloc + Clone> Clone for Box<T, Alloc> {
208 fn clone(&self) -> Self {
209 Box::new_in(
210 T::clone(self),
211 unsafe { self.ptr.prefix().alloc.assume_init_ref() }.clone(),
212 )
213 }
214}
215impl<T, Alloc: IAlloc> core::ops::Deref for Box<T, Alloc> {
216 type Target = T;
217 fn deref(&self) -> &Self::Target {
218 unsafe { self.ptr.as_ref() }
219 }
220}
221
222impl<T, Alloc: IAlloc> core::ops::DerefMut for Box<T, Alloc> {
223 fn deref_mut(&mut self) -> &mut Self::Target {
224 unsafe { self.ptr.as_mut() }
225 }
226}
227impl<T, Alloc: IAlloc> crate::IPtr for Box<T, Alloc> {
228 unsafe fn as_ref(&self) -> AnonymRef<'_> {
229 AnonymRef {
230 ptr: self.ptr.ptr.cast(),
231 _marker: PhantomData,
232 }
233 }
234}
235impl<T, Alloc: IAlloc> crate::IPtrMut for Box<T, Alloc> {
236 unsafe fn as_mut(&mut self) -> AnonymRefMut<'_> {
237 AnonymRefMut {
238 ptr: self.ptr.ptr.cast(),
239 _marker: PhantomData,
240 }
241 }
242}
243impl<T, Alloc: IAlloc> crate::IPtrOwned for Box<T, Alloc> {
244 fn drop(
245 mut this: &mut core::mem::ManuallyDrop<Self>,
246 drop: unsafe extern "C" fn(AnonymRefMut<'_>),
247 ) {
248 unsafe {
250 drop(this.as_mut());
251 }
252 unsafe { this.free() }
254 }
255}
256impl<T, Alloc: IAlloc> Drop for Box<T, Alloc> {
257 fn drop(&mut self) {
258 unsafe {
260 core::ptr::drop_in_place(self.ptr.as_mut());
261 }
262 unsafe { self.free() }
264 }
265}
266impl<T, Alloc: IAlloc> IntoDyn for Box<T, Alloc> {
267 type Anonymized = Box<(), Alloc>;
268 type Target = T;
269 fn anonimize(self) -> Self::Anonymized {
270 let original_prefix = self.ptr.prefix_ptr();
271 let anonymized = unsafe { core::mem::transmute::<Self, Self::Anonymized>(self) };
273 let anonymized_prefix = anonymized.ptr.prefix_ptr();
274 assert_eq!(anonymized_prefix, original_prefix, "The allocation prefix was lost in anonimization, this is definitely a bug, please report it.");
275 anonymized
276 }
277}
278
279#[crate::stabby]
287pub struct BoxedSlice<T, Alloc: IAlloc = super::DefaultAllocator> {
288 pub(crate) slice: AllocSlice<T, Alloc>,
289 pub(crate) alloc: Alloc,
290}
291impl<T, Alloc: IAlloc> BoxedSlice<T, Alloc> {
292 pub fn with_capacity_in(capacity: usize, alloc: Alloc) -> Self {
294 Vec::with_capacity_in(capacity, alloc).into()
295 }
296 pub const fn len(&self) -> usize {
298 ptr_diff(self.slice.end, self.slice.start.ptr)
299 }
300 pub const fn is_empty(&self) -> bool {
302 self.len() == 0
303 }
304 #[rustversion::attr(since(1.86), const)]
306 pub fn as_slice(&self) -> &[T] {
307 unsafe { core::slice::from_raw_parts(self.slice.start.ptr.as_ptr(), self.len()) }
309 }
310 #[rustversion::attr(since(1.86), const)]
312 pub fn as_slice_mut(&mut self) -> &mut [T] {
313 unsafe { core::slice::from_raw_parts_mut(self.slice.start.ptr.as_ptr(), self.len()) }
315 }
316 pub fn try_push(&mut self, value: T) -> Result<(), T> {
320 if self.slice.len()
322 >= unsafe { self.slice.start.prefix() }
323 .capacity
324 .load(core::sync::atomic::Ordering::Relaxed)
325 {
326 return Err(value);
327 }
328 unsafe {
330 core::ptr::write(self.slice.end.as_ptr(), value);
331 self.slice.end = NonNull::new_unchecked(self.slice.end.as_ptr().add(1));
332 }
333 Ok(())
334 }
335 pub(crate) fn into_raw_components(self) -> (AllocSlice<T, Alloc>, usize, Alloc) {
336 let slice = self.slice;
337 let alloc = unsafe { core::ptr::read(&self.alloc) };
339 core::mem::forget(self);
340 let capacity = if core::mem::size_of::<T>() == 0 || slice.is_empty() {
341 0
342 } else {
343 unsafe {
345 slice
346 .start
347 .prefix()
348 .capacity
349 .load(core::sync::atomic::Ordering::Relaxed)
350 }
351 };
352 (slice, capacity, alloc)
353 }
354}
355impl<T, Alloc: IAlloc> core::ops::Deref for BoxedSlice<T, Alloc> {
356 type Target = [T];
357 fn deref(&self) -> &Self::Target {
358 self.as_slice()
359 }
360}
361
362impl<T, Alloc: IAlloc> core::ops::DerefMut for BoxedSlice<T, Alloc> {
363 fn deref_mut(&mut self) -> &mut Self::Target {
364 self.as_slice_mut()
365 }
366}
367impl<T: Eq, Alloc: IAlloc> Eq for BoxedSlice<T, Alloc> {}
368impl<T: PartialEq, Alloc: IAlloc> PartialEq for BoxedSlice<T, Alloc> {
369 fn eq(&self, other: &Self) -> bool {
370 self.as_slice() == other.as_slice()
371 }
372}
373impl<T: Ord, Alloc: IAlloc> Ord for BoxedSlice<T, Alloc> {
374 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
375 self.as_slice().cmp(other.as_slice())
376 }
377}
378impl<T: PartialOrd, Alloc: IAlloc> PartialOrd for BoxedSlice<T, Alloc> {
379 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
380 self.as_slice().partial_cmp(other.as_slice())
381 }
382}
383impl<T: core::hash::Hash, Alloc: IAlloc> core::hash::Hash for BoxedSlice<T, Alloc> {
384 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
385 self.as_slice().hash(state)
386 }
387}
388impl<T, Alloc: IAlloc> From<Vec<T, Alloc>> for BoxedSlice<T, Alloc> {
389 fn from(value: Vec<T, Alloc>) -> Self {
390 let (mut slice, capacity, alloc) = value.into_raw_components();
391 if capacity != 0 {
392 unsafe {
394 slice.start.prefix_mut().capacity = core::sync::atomic::AtomicUsize::new(capacity);
395 }
396 Self {
397 slice: AllocSlice {
398 start: slice.start,
399 end: slice.end,
400 },
401 alloc,
402 }
403 } else {
404 Self { slice, alloc }
405 }
406 }
407}
408impl<T, Alloc: IAlloc> From<BoxedSlice<T, Alloc>> for Vec<T, Alloc> {
409 fn from(value: BoxedSlice<T, Alloc>) -> Self {
410 let (slice, capacity, alloc) = value.into_raw_components();
411 if capacity != 0 {
412 Vec {
413 inner: VecInner {
414 start: slice.start,
415 end: slice.end,
416 capacity: ptr_add(slice.start.ptr, capacity),
417 alloc,
418 },
419 }
420 } else {
421 Vec {
422 inner: VecInner {
423 start: slice.start,
424 end: slice.end,
425 capacity: if core::mem::size_of::<T>() == 0 {
426 unsafe { core::mem::transmute::<usize, NonNull<T>>(usize::MAX) }
427 } else {
428 slice.start.ptr
429 },
430 alloc,
431 },
432 }
433 }
434 }
435}
436impl<T: Copy, Alloc: IAlloc + Default> From<&[T]> for BoxedSlice<T, Alloc> {
437 fn from(value: &[T]) -> Self {
438 Vec::from(value).into()
439 }
440}
441impl<T, Alloc: IAlloc + Default> FromIterator<T> for BoxedSlice<T, Alloc> {
442 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
443 Vec::from_iter(iter).into()
444 }
445}
446
447impl<T, Alloc: IAlloc> Drop for BoxedSlice<T, Alloc> {
448 fn drop(&mut self) {
449 unsafe { core::ptr::drop_in_place(self.as_slice_mut()) }
450 if core::mem::size_of::<T>() != 0 && !self.is_empty() {
451 unsafe { self.slice.start.free(&mut self.alloc) }
452 }
453 }
454}
455
456impl<T: Debug, Alloc: IAlloc> Debug for BoxedSlice<T, Alloc> {
457 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
458 self.as_slice().fmt(f)
459 }
460}
461impl<T: core::fmt::LowerHex, Alloc: IAlloc> core::fmt::LowerHex for BoxedSlice<T, Alloc> {
462 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
463 let mut first = true;
464 for item in self {
465 if !first {
466 f.write_str(":")?;
467 }
468 first = false;
469 core::fmt::LowerHex::fmt(item, f)?;
470 }
471 Ok(())
472 }
473}
474impl<T: core::fmt::UpperHex, Alloc: IAlloc> core::fmt::UpperHex for BoxedSlice<T, Alloc> {
475 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
476 let mut first = true;
477 for item in self {
478 if !first {
479 f.write_str(":")?;
480 }
481 first = false;
482 core::fmt::UpperHex::fmt(item, f)?;
483 }
484 Ok(())
485 }
486}
487impl<'a, T, Alloc: IAlloc> IntoIterator for &'a BoxedSlice<T, Alloc> {
488 type Item = &'a T;
489 type IntoIter = core::slice::Iter<'a, T>;
490 fn into_iter(self) -> Self::IntoIter {
491 self.as_slice().iter()
492 }
493}
494impl<'a, T, Alloc: IAlloc> IntoIterator for &'a mut BoxedSlice<T, Alloc> {
495 type Item = &'a mut T;
496 type IntoIter = core::slice::IterMut<'a, T>;
497 fn into_iter(self) -> Self::IntoIter {
498 self.as_slice_mut().iter_mut()
499 }
500}
501impl<T, Alloc: IAlloc> IntoIterator for BoxedSlice<T, Alloc> {
502 type Item = T;
503 type IntoIter = super::vec::IntoIter<T, Alloc>;
504 fn into_iter(self) -> Self::IntoIter {
505 let this: super::vec::Vec<T, Alloc> = self.into();
506 this.into_iter()
507 }
508}
509pub use super::string::BoxedStr;
510
511#[cfg(feature = "serde")]
512mod serde_impl {
513 use super::*;
514 use crate::alloc::IAlloc;
515 use serde::{Deserialize, Serialize};
516 impl<T: Serialize, Alloc: IAlloc> Serialize for BoxedSlice<T, Alloc> {
517 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
518 where
519 S: serde::Serializer,
520 {
521 let slice: &[T] = self;
522 slice.serialize(serializer)
523 }
524 }
525 impl<'a, T: Deserialize<'a>, Alloc: IAlloc + Default> Deserialize<'a> for BoxedSlice<T, Alloc> {
526 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
527 where
528 D: serde::Deserializer<'a>,
529 {
530 crate::alloc::vec::Vec::deserialize(deserializer).map(Into::into)
531 }
532 }
533 impl<Alloc: IAlloc> Serialize for BoxedStr<Alloc> {
534 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
535 where
536 S: serde::Serializer,
537 {
538 let slice: &str = self;
539 slice.serialize(serializer)
540 }
541 }
542 impl<'a, Alloc: IAlloc + Default> Deserialize<'a> for BoxedStr<Alloc> {
543 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
544 where
545 D: serde::Deserializer<'a>,
546 {
547 crate::alloc::string::String::deserialize(deserializer).map(Into::into)
548 }
549 }
550}