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 this: &mut core::mem::ManuallyDrop<Self>,
246 drop: unsafe extern "C" fn(AnonymRefMut<'_>),
247 ) {
248 unsafe {
250 drop(Self::as_mut(this));
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 pub const fn as_slice(&self) -> &[T] {
306 unsafe { core::slice::from_raw_parts(self.slice.start.ptr.as_ptr(), self.len()) }
308 }
309 #[rustversion::attr(since(1.86), const)]
311 pub fn as_slice_mut(&mut self) -> &mut [T] {
312 unsafe { core::slice::from_raw_parts_mut(self.slice.start.ptr.as_ptr(), self.len()) }
314 }
315 pub fn try_push(&mut self, value: T) -> Result<(), T> {
319 if self.slice.len()
321 >= unsafe { self.slice.start.prefix() }
322 .capacity
323 .load(core::sync::atomic::Ordering::Relaxed)
324 {
325 return Err(value);
326 }
327 unsafe {
329 core::ptr::write(self.slice.end.as_ptr(), value);
330 self.slice.end = NonNull::new_unchecked(self.slice.end.as_ptr().add(1));
331 }
332 Ok(())
333 }
334 pub(crate) fn into_raw_components(self) -> (AllocSlice<T, Alloc>, usize, Alloc) {
335 let slice = self.slice;
336 let alloc = unsafe { core::ptr::read(&self.alloc) };
338 core::mem::forget(self);
339 let capacity = if core::mem::size_of::<T>() == 0 || slice.is_empty() {
340 0
341 } else {
342 unsafe {
344 slice
345 .start
346 .prefix()
347 .capacity
348 .load(core::sync::atomic::Ordering::Relaxed)
349 }
350 };
351 (slice, capacity, alloc)
352 }
353}
354impl<T, Alloc: IAlloc> core::ops::Deref for BoxedSlice<T, Alloc> {
355 type Target = [T];
356 fn deref(&self) -> &Self::Target {
357 self.as_slice()
358 }
359}
360
361impl<T, Alloc: IAlloc> core::ops::DerefMut for BoxedSlice<T, Alloc> {
362 fn deref_mut(&mut self) -> &mut Self::Target {
363 self.as_slice_mut()
364 }
365}
366impl<T: Eq, Alloc: IAlloc> Eq for BoxedSlice<T, Alloc> {}
367impl<T: PartialEq, Alloc: IAlloc> PartialEq for BoxedSlice<T, Alloc> {
368 fn eq(&self, other: &Self) -> bool {
369 self.as_slice() == other.as_slice()
370 }
371}
372impl<T: Ord, Alloc: IAlloc> Ord for BoxedSlice<T, Alloc> {
373 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
374 self.as_slice().cmp(other.as_slice())
375 }
376}
377impl<T: PartialOrd, Alloc: IAlloc> PartialOrd for BoxedSlice<T, Alloc> {
378 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
379 self.as_slice().partial_cmp(other.as_slice())
380 }
381}
382impl<T: core::hash::Hash, Alloc: IAlloc> core::hash::Hash for BoxedSlice<T, Alloc> {
383 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
384 self.as_slice().hash(state)
385 }
386}
387impl<T, Alloc: IAlloc> From<Vec<T, Alloc>> for BoxedSlice<T, Alloc> {
388 fn from(value: Vec<T, Alloc>) -> Self {
389 let (mut slice, capacity, alloc) = value.into_raw_components();
390 if capacity != 0 {
391 unsafe {
393 slice.start.prefix_mut().capacity = core::sync::atomic::AtomicUsize::new(capacity);
394 }
395 Self {
396 slice: AllocSlice {
397 start: slice.start,
398 end: slice.end,
399 },
400 alloc,
401 }
402 } else {
403 Self { slice, alloc }
404 }
405 }
406}
407impl<T, Alloc: IAlloc> From<BoxedSlice<T, Alloc>> for Vec<T, Alloc> {
408 fn from(value: BoxedSlice<T, Alloc>) -> Self {
409 let (slice, capacity, alloc) = value.into_raw_components();
410 if capacity != 0 {
411 Vec {
412 inner: VecInner {
413 start: slice.start,
414 end: slice.end,
415 capacity: ptr_add(slice.start.ptr, capacity),
416 alloc,
417 },
418 }
419 } else {
420 Vec {
421 inner: VecInner {
422 start: slice.start,
423 end: slice.end,
424 capacity: if core::mem::size_of::<T>() == 0 {
425 unsafe { core::mem::transmute::<usize, NonNull<T>>(usize::MAX) }
426 } else {
427 slice.start.ptr
428 },
429 alloc,
430 },
431 }
432 }
433 }
434}
435impl<T: Copy, Alloc: IAlloc + Default> From<&[T]> for BoxedSlice<T, Alloc> {
436 fn from(value: &[T]) -> Self {
437 Vec::from(value).into()
438 }
439}
440impl<T, Alloc: IAlloc + Default> FromIterator<T> for BoxedSlice<T, Alloc> {
441 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
442 Vec::from_iter(iter).into()
443 }
444}
445
446impl<T, Alloc: IAlloc> Drop for BoxedSlice<T, Alloc> {
447 fn drop(&mut self) {
448 unsafe { core::ptr::drop_in_place(self.as_slice_mut()) }
449 if core::mem::size_of::<T>() != 0 && !self.is_empty() {
450 unsafe { self.slice.start.free(&mut self.alloc) }
451 }
452 }
453}
454
455impl<T: Debug, Alloc: IAlloc> Debug for BoxedSlice<T, Alloc> {
456 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
457 self.as_slice().fmt(f)
458 }
459}
460impl<T: core::fmt::LowerHex, Alloc: IAlloc> core::fmt::LowerHex for BoxedSlice<T, Alloc> {
461 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
462 let mut first = true;
463 for item in self {
464 if !first {
465 f.write_str(":")?;
466 }
467 first = false;
468 core::fmt::LowerHex::fmt(item, f)?;
469 }
470 Ok(())
471 }
472}
473impl<T: core::fmt::UpperHex, Alloc: IAlloc> core::fmt::UpperHex for BoxedSlice<T, Alloc> {
474 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
475 let mut first = true;
476 for item in self {
477 if !first {
478 f.write_str(":")?;
479 }
480 first = false;
481 core::fmt::UpperHex::fmt(item, f)?;
482 }
483 Ok(())
484 }
485}
486impl<'a, T, Alloc: IAlloc> IntoIterator for &'a BoxedSlice<T, Alloc> {
487 type Item = &'a T;
488 type IntoIter = core::slice::Iter<'a, T>;
489 fn into_iter(self) -> Self::IntoIter {
490 self.as_slice().iter()
491 }
492}
493impl<'a, T, Alloc: IAlloc> IntoIterator for &'a mut BoxedSlice<T, Alloc> {
494 type Item = &'a mut T;
495 type IntoIter = core::slice::IterMut<'a, T>;
496 fn into_iter(self) -> Self::IntoIter {
497 self.as_slice_mut().iter_mut()
498 }
499}
500impl<T, Alloc: IAlloc> IntoIterator for BoxedSlice<T, Alloc> {
501 type Item = T;
502 type IntoIter = super::vec::IntoIter<T, Alloc>;
503 fn into_iter(self) -> Self::IntoIter {
504 let this: super::vec::Vec<T, Alloc> = self.into();
505 this.into_iter()
506 }
507}
508pub use super::string::BoxedStr;
509
510#[cfg(feature = "serde")]
511mod serde_impl {
512 use super::*;
513 use crate::alloc::IAlloc;
514 use serde::{Deserialize, Serialize};
515 impl<T: Serialize, Alloc: IAlloc> Serialize for BoxedSlice<T, Alloc> {
516 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
517 where
518 S: serde::Serializer,
519 {
520 let slice: &[T] = self;
521 slice.serialize(serializer)
522 }
523 }
524 impl<'a, T: Deserialize<'a>, Alloc: IAlloc + Default> Deserialize<'a> for BoxedSlice<T, Alloc> {
525 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
526 where
527 D: serde::Deserializer<'a>,
528 {
529 crate::alloc::vec::Vec::deserialize(deserializer).map(Into::into)
530 }
531 }
532 impl<Alloc: IAlloc> Serialize for BoxedStr<Alloc> {
533 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
534 where
535 S: serde::Serializer,
536 {
537 let slice: &str = self;
538 slice.serialize(serializer)
539 }
540 }
541 impl<'a, Alloc: IAlloc + Default> Deserialize<'a> for BoxedStr<Alloc> {
542 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
543 where
544 D: serde::Deserializer<'a>,
545 {
546 crate::alloc::string::String::deserialize(deserializer).map(Into::into)
547 }
548 }
549}