1#![doc(html_root_url = "http://docs.rs/const-default/1.0.0")]
2#![cfg_attr(not(feature = "std"), no_std)]
3#![cfg_attr(feature = "unstable-docs", feature(doc_cfg))]
4#![cfg_attr(
5 all(feature = "unstable", feature = "alloc"),
6 feature(const_btree_new)
7)]
8#![cfg_attr(feature = "unstable", feature(const_fn_trait_bound))]
9#![cfg_attr(
10 all(feature = "unstable", feature = "enable-atomics"),
11 feature(cfg_target_has_atomic)
12)]
13#![cfg_attr(
14 feature = "enable-atomics",
15 allow(clippy::declare_interior_mutable_const)
16)]
17
18#[cfg(feature = "alloc")]
19extern crate alloc;
20
21#[cfg(feature = "derive")]
22#[cfg_attr(feature = "unstable-docs", doc(cfg(feature = "derive")))]
23pub use const_default_derive::ConstDefault;
24
25pub trait ConstDefault: Sized {
48 const DEFAULT: Self;
50}
51
52#[inline]
54#[cfg(feature = "unstable")]
55#[cfg_attr(feature = "unstable-docs", doc(cfg(feature = "unstable")))]
56pub const fn const_default<T: ConstDefault>() -> T {
57 T::DEFAULT
58}
59
60impl<T> ConstDefault for Option<T> {
61 const DEFAULT: Self = None;
62}
63
64#[cfg(feature = "alloc")]
65#[cfg_attr(
66 feature = "unstable-docs",
67 doc(cfg(any(feature = "std", feature = "alloc")))
68)]
69impl<'a, T> ConstDefault for alloc::borrow::Cow<'a, T>
70where
71 T: alloc::borrow::ToOwned + ?Sized + 'a,
72 <T as alloc::borrow::ToOwned>::Owned: ConstDefault,
73{
74 const DEFAULT: Self = Self::Owned(
75 <<T as alloc::borrow::ToOwned>::Owned as ConstDefault>::DEFAULT,
76 );
77}
78
79impl<T: ConstDefault> ConstDefault for core::cell::Cell<T> {
80 const DEFAULT: Self = Self::new(T::DEFAULT);
81}
82
83impl<T: ConstDefault> ConstDefault for core::cell::UnsafeCell<T> {
84 const DEFAULT: Self = Self::new(T::DEFAULT);
85}
86
87impl<T: ConstDefault> ConstDefault for core::cell::RefCell<T> {
88 const DEFAULT: Self = Self::new(T::DEFAULT);
89}
90
91impl<T: ConstDefault> ConstDefault for core::mem::MaybeUninit<T> {
93 const DEFAULT: Self = Self::new(T::DEFAULT);
94}
95
96#[cfg(feature = "alloc")]
97#[cfg_attr(
98 feature = "unstable-docs",
99 doc(cfg(any(feature = "std", feature = "alloc")))
100)]
101impl<T> ConstDefault for alloc::vec::Vec<T> {
102 const DEFAULT: Self = Self::new();
103}
104
105#[cfg(feature = "alloc")]
106#[cfg_attr(
107 feature = "unstable-docs",
108 doc(cfg(any(feature = "std", feature = "alloc")))
109)]
110impl ConstDefault for alloc::string::String {
111 const DEFAULT: Self = Self::new();
112}
113
114#[cfg(all(feature = "alloc", feature = "unstable"))]
115#[cfg_attr(
116 feature = "unstable-docs",
117 doc(
118 cfg(any(feature = "std", feature = "alloc")),
119 cfg(feature = "unstable")
120 )
121)]
122impl<K: Ord, V> ConstDefault for alloc::collections::BTreeMap<K, V> {
123 const DEFAULT: Self = Self::new();
124}
125
126#[cfg(all(feature = "alloc", feature = "unstable"))]
127#[cfg_attr(
128 feature = "unstable-docs",
129 doc(
130 cfg(any(feature = "std", feature = "alloc")),
131 cfg(feature = "unstable")
132 )
133)]
134impl<T: Ord> ConstDefault for alloc::collections::BTreeSet<T> {
135 const DEFAULT: Self = Self::new();
136}
137
138#[cfg(feature = "alloc")]
139#[cfg_attr(
140 feature = "unstable-docs",
141 doc(cfg(any(feature = "std", feature = "alloc")))
142)]
143impl<T> ConstDefault for alloc::collections::LinkedList<T> {
144 const DEFAULT: Self = Self::new();
145}
146
147impl<'a, T: 'a> ConstDefault for &'a [T] {
148 const DEFAULT: Self = &[];
149}
150
151impl<T> ConstDefault for *const T {
152 const DEFAULT: Self = core::ptr::null();
153}
154
155impl<T> ConstDefault for *mut T {
156 const DEFAULT: Self = core::ptr::null_mut();
157}
158
159impl<T: ConstDefault> ConstDefault for core::mem::ManuallyDrop<T> {
160 const DEFAULT: Self = Self::new(T::DEFAULT);
161}
162
163impl<T: ?Sized> ConstDefault for core::marker::PhantomData<T> {
164 const DEFAULT: Self = Self;
165}
166
167impl ConstDefault for core::marker::PhantomPinned {
168 const DEFAULT: Self = Self;
169}
170
171impl<T> ConstDefault for core::iter::Empty<T> {
172 const DEFAULT: Self = core::iter::empty();
173}
174
175impl<T: ConstDefault> ConstDefault for core::num::Wrapping<T> {
176 const DEFAULT: Self = Self(T::DEFAULT);
177}
178
179impl ConstDefault for core::time::Duration {
180 const DEFAULT: Self = core::time::Duration::from_secs(0);
181}
182
183#[cfg(feature = "std")]
184#[cfg_attr(feature = "unstable-docs", doc(cfg(feature = "std")))]
185impl ConstDefault for std::sync::Once {
186 const DEFAULT: Self = Self::new();
187}
188
189macro_rules! impl_num {
190 ($($ty:ty=$d:expr$(;$name:ident=$width:literal)?),*) => {
191 $(
192 impl ConstDefault for $ty {
193 const DEFAULT: Self = $d;
194 }
195
196 impl ConstDefault for &$ty {
197 const DEFAULT: Self = &<$ty as ConstDefault>::DEFAULT;
198 }
199
200 $(
201 #[cfg(feature = "enable-atomics")]
202 #[cfg_attr(feature = "unstable-docs", doc(cfg(any(feature = "default", feature = "enable-atomics"))))]
203 #[cfg_attr(feature = "unstable", cfg(target_has_atomic = $width))]
204 impl ConstDefault for core::sync::atomic::$name {
205 const DEFAULT: Self = Self::new(ConstDefault::DEFAULT);
206 }
207 )?
208 )*
209 };
210}
211
212impl_num! {
213 ()=(), bool=false, f32=0.0, f64=0.0, char='\x00', &str="",
214 u8=0;AtomicU8="8", u16=0;AtomicU16="16", u32=0;AtomicU32="32", u64=0;AtomicU64="64", usize=0;AtomicUsize="ptr",
215 i8=0;AtomicI8="8", i16=0;AtomicI16="16", i32=0;AtomicI32="32", i64=0;AtomicI64="64", isize=0;AtomicIsize="ptr",
216 i128=0, u128=0
217}
218
219#[cfg(feature = "enable-atomics")]
220#[cfg_attr(
221 feature = "unstable-docs",
222 doc(cfg(any(feature = "default", feature = "enable-atomics")))
223)]
224#[cfg_attr(feature = "unstable", cfg(target_has_atomic = "8"))]
225impl ConstDefault for core::sync::atomic::AtomicBool {
226 const DEFAULT: Self = Self::new(ConstDefault::DEFAULT);
227}
228
229#[cfg(feature = "enable-atomics")]
230#[cfg_attr(
231 feature = "unstable-docs",
232 doc(cfg(any(feature = "default", feature = "enable-atomics")))
233)]
234#[cfg_attr(feature = "unstable", cfg(target_has_atomic = "ptr"))]
235impl<T> ConstDefault for core::sync::atomic::AtomicPtr<T> {
236 const DEFAULT: Self = Self::new(core::ptr::null_mut());
237}
238
239macro_rules! impl_tuple {
240 (@rec $t:ident) => { };
241 (@rec $_:ident $($t:ident)+) => {
242 impl_tuple! { @impl $($t)* }
243 impl_tuple! { @rec $($t)* }
244 };
245 (@impl $($t:ident)*) => {
246 impl<$($t: ConstDefault,)*> ConstDefault for ($($t,)*) {
247 const DEFAULT: Self = ($($t::DEFAULT,)*);
248 }
249 };
250 ($($t:ident)*) => {
251 impl_tuple! { @rec _t $($t)* }
252 };
253}
254
255impl_tuple! {
256 A B C D E F G H I J K L
257}
258
259impl<T: ConstDefault, const N: usize> ConstDefault for [T; N] {
260 const DEFAULT: Self = [T::DEFAULT; N];
261}