1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use crate::boxed::ABox;
use crate::fat::{Alloc, Free};
use crate::meta::*;
use core::ffi::CStr;
// Allocating traits, falliable counterparts
#[cfg(global_oom_handling)] impl<T: Default, A: Alloc + Free + Default> Default for ABox<T, A> {
/// Allocate a new box containing `T::default()` using `A::default()`.
///
/// ## Failure Modes
/// * Fails to compile on impossible alignments (e.g. attempting to allocate 4 KiB alignment pages via 8/16 byte aligned malloc)
/// * [`panic!`]s or [`handle_alloc_error`](alloc::alloc::handle_alloc_error)s when out of memory
fn default() -> Self {
let _ = Self::ASSERT_A_CAN_ALLOC_T;
Self::new(T::default())
}
}
impl<T, A: Alloc + Free + Default + ZstInfalliableOrGlobalOomHandling> Default for ABox<[T], A> { fn default() -> Self { ABox::<[T], A>::try_from_array([]).unwrap() } }
impl< A: Alloc + Free + Default + ZstInfalliableOrGlobalOomHandling> Default for ABox<str, A> { fn default() -> Self { ABox::<str, A>::try_from_str("").unwrap() } }
#[cfg(feature = "std")] impl<A: Alloc + Free + Default + ZstInfalliableOrGlobalOomHandling> Default for ABox<std::ffi::OsStr, A> { fn default() -> Self { Self::try_from_osstr(std::ffi::OsStr::new("")).unwrap() } }
#[cfg(feature = "std")] impl<A: Alloc + Free + Default + ZstInfalliableOrGlobalOomHandling> Default for ABox<std::path::Path, A> { fn default() -> Self { Self::try_from_path(std::path::Path::new("")).unwrap() } }
// TODO: remove A : ZstSupported bound? CStr is never a ZST as it always has at least a `\0`
#[cfg(global_oom_handling)] impl<A: Alloc + Free + Default + ZstSupported> Default for ABox<CStr, A> {
fn default() -> Self { ABox::<CStr,A>::try_from_cstr(CStr::from_bytes_with_nul(b"\0").unwrap()).unwrap() }
}
// TODO: Non-panic alternatives to [`Default`] / support for alternative allocators for slice, str, CStr
/// Non-panicing alternatives to [`Default`] / support for alternative allocators.
impl<T: Default, A: Free> ABox<T, A> {
/// Allocate a new box containing `T::default()` using `A::default()`.
///
/// ## Failure Modes
/// * Fails to compile on impossible alignments (e.g. attempting to allocate 4 KiB alignment pages via 8/16 byte aligned malloc)
/// * Returns <code>[Err]\(...\)</code> when out of memory
///
/// ## Examples
/// ```
/// use ialloc::{allocator::{c::Malloc, debug::Null}, boxed::ABox};
/// let err = ABox::<u32, Null>::try_default().unwrap_err();
/// let b = ABox::<u32, Malloc>::try_default().unwrap();
/// assert_eq!(*b, 0);
/// ```
///
/// ```compile_fail,E0080
/// # use ialloc::{allocator::{c::Malloc, debug::Null}, boxed::ABox};
/// // won't compile - requires too much alignment for Malloc
/// #[repr(C, align(4096))] pub struct Page([u8; 4096]);
/// impl Default for Page { fn default() -> Self { Self([0u8; 4096]) } }
/// let b = ABox::<Page, Malloc>::try_default().unwrap();
/// ```
pub fn try_default() -> Result<ABox<T, A>, A::Error> where T : Default, A : Alloc + Default {
let _ = Self::ASSERT_A_CAN_ALLOC_T;
ABox::try_new_in(T::default(), A::default())
}
/// Allocate a new box containing `T::default()` using `allocator`.
///
/// ## Failure Modes
/// * Fails to compile on impossible alignments (e.g. attempting to allocate 4 KiB alignment pages via 8/16 byte aligned malloc)
/// * Returns <code>[Err]\(...\)</code> when out of memory
///
/// ## Examples
/// ```
/// use ialloc::{allocator::{c::Malloc, debug::Null}, boxed::ABox};
/// let err = ABox::<u32, _>::try_default_in(Null).unwrap_err();
/// let b = ABox::<u32, _>::try_default_in(Malloc).unwrap();
/// assert_eq!(*b, 0);
/// ```
///
/// ```compile_fail,E0080
/// # use ialloc::{allocator::{c::Malloc, debug::Null}, boxed::ABox};
/// // won't compile - requires too much alignment for Malloc
/// #[repr(C, align(4096))] pub struct Page([u8; 4096]);
/// impl Default for Page { fn default() -> Self { Self([0u8; 4096]) } }
/// let b = ABox::<Page, _>::try_default_in(Malloc).unwrap();
/// ```
pub fn try_default_in(allocator: A) -> Result<ABox<T, A>, A::Error> where T : Default, A: Alloc {
let _ = Self::ASSERT_A_CAN_ALLOC_T;
ABox::try_new_in(T::default(), allocator)
}
/// Allocate a new box containing `T::default()` using `allocator`.
///
/// ## Failure Modes
/// * Fails to compile on impossible alignments (e.g. attempting to allocate 4 KiB alignment pages via 8/16 byte aligned malloc)
/// * [`panic!`]s or [`handle_alloc_error`](alloc::alloc::handle_alloc_error)s when out of memory
///
/// ## Examples
/// ```
/// use ialloc::{allocator::{c::Malloc, debug::Null}, boxed::ABox};
/// let b = ABox::<u32, _>::default_in(Malloc);
/// assert_eq!(*b, 0);
/// ```
///
/// ```should_panic
/// # use ialloc::{allocator::{c::Malloc, debug::Null}, boxed::ABox};
/// // will panic - Null can't allocate anything
/// let b = ABox::<u32, _>::default_in(Null);
/// ```
///
/// ```compile_fail,E0080
/// # use ialloc::{allocator::{c::Malloc, debug::Null}, boxed::ABox};
/// // won't compile - requires too much alignment for Malloc
/// #[repr(C, align(4096))] pub struct Page([u8; 4096]);
/// impl Default for Page { fn default() -> Self { Self([0u8; 4096]) } }
/// let b = ABox::<Page, _>::default_in(Malloc);
/// ```
#[cfg(global_oom_handling)] pub fn default_in(allocator: A) -> ABox<T, A> where T : Default, A : Alloc {
let _ = Self::ASSERT_A_CAN_ALLOC_T;
ABox::new_in(T::default(), allocator)
}
}