#[doc = crate::_tags!(init)]
#[doc = crate::_doc_location!("code")]
pub trait ConstInit {
const INIT: Self;
}
#[doc(hidden)]
#[macro_export]
#[allow(clippy::crate_in_macro_def, reason = "uses $trait relative to the call-site crate")]
macro_rules! _impl_init {
($trait:ident: <$A:ident> $def:expr => $($t:ty),+) => {
$( $crate::_impl_init![$trait:@<$A> $def => $t]; )+
};
($trait:ident: @<$A:ident> $def:expr => $t:ty) => {
impl<$A> crate::$trait for $t {
#[allow(clippy::declare_interior_mutable_const)]
const INIT: Self = $def;
}
};
($trait:ident: <$A:ident:$A_:ident> $def:expr => $($t:ty),+) => {
$( $crate::_impl_init![$trait:@<$A:$A_> $def => $t]; )+
};
($trait:ident: @<$A:ident:$A_:ident> $def:expr => $t:ty) => {
impl<$A: crate::$trait> crate::$trait for $t {
#[allow(clippy::declare_interior_mutable_const, reason = "FIXME?")]
const INIT: Self = $def;
}
};
($trait:ident: <$A:ident, $B:ident> $def:expr => $($t:ty),+) => {
$( $crate::_impl_init![$trait:@<$A, $B> $def => $t]; )+
};
($trait:ident: @<$A:ident, $B:ident> $def:expr => $t:ty) => {
impl<$A, $B> crate::$trait for $t {
#[allow(clippy::declare_interior_mutable_const)] const INIT: Self = $def;
}
};
($trait:ident: <$A:ident:$A_:ident, $B:ident:$B_:ident> $def:expr => $($t:ty),+) => {
$( $crate::_impl_init![$trait:@<$A:$A_, $B:$B_> $def => $t]; )+ };
($trait:ident: @<$A:ident:$A_:ident, $B:ident:$B_:ident> $def:expr => $t:ty) => {
impl<$A:$A_, $B:$B_> crate::$trait for $t {
#[allow(clippy::declare_interior_mutable_const)] const INIT: Self = $def;
}
};
($trait:ident: <$A:ident, $B:ident, $C:ident> $def:expr => $($t:ty),+) => {
$( $crate::_impl_init![$trait:@<$A, $B, $C> $def => $t]; )+
};
($trait:ident: @<$A:ident, $B:ident, $C:ident> $def:expr => $t:ty) => {
impl<$A, $B, $C> crate::$trait for $t {
#[allow(clippy::declare_interior_mutable_const)] const INIT: Self = $def;
}
};
($trait:ident: $def:expr => $( $(#[$attr:meta])* $t:ty ),+ $(,)?) => {
$( $crate::_impl_init![$trait:@$def => $(#[$attr])* $t]; )+
};
($trait:ident: @$def:expr => $(#[$attr:meta])* $t:ty) => {
$(#[$attr])*
impl crate::$trait for $t {
#[allow(clippy::declare_interior_mutable_const)]
const INIT: Self = $def;
}
};
($trait:ident: arrays <$A:ident:$BOUND:ident> $($LEN:literal),+) => {
$( $crate::_impl_init![$trait:@array:$LEN <$A:$BOUND>]; )+
};
($trait:ident: @array:$LEN:literal <$A:ident:$BOUND:ident>) => {
impl<$A: crate::$trait> crate::$trait for [$A; $LEN] {
#[allow(clippy::declare_interior_mutable_const)] const INIT: Self = [$A::INIT; $LEN];
}
};
($trait:ident: tuples <$A:ident:$BOUND:ident>) => {
$crate::_impl_init![$trait:@tuple <$A:$BOUND> ($A,) => ($A::INIT,)];
$crate::_impl_init![$trait:@tuple <$A:$BOUND> ($A,$A,) => ($A::INIT, $A::INIT)];
$crate::_impl_init![$trait:@tuple <$A:$BOUND> ($A,$A,$A) => ($A::INIT, $A::INIT, $A::INIT)];
$crate::_impl_init![$trait:@tuple <$A:$BOUND> ($A,$A,$A,$A) => ($A::INIT, $A::INIT, $A::INIT, $A::INIT)];
$crate::_impl_init![$trait:@tuple <$A:$BOUND> ($A,$A,$A,$A,$A) => ($A::INIT, $A::INIT, $A::INIT, $A::INIT, $A::INIT)];
$crate::_impl_init![$trait:@tuple <$A:$BOUND> ($A,$A,$A,$A,$A,$A) => ($A::INIT, $A::INIT, $A::INIT, $A::INIT, $A::INIT, $A::INIT)];
$crate::_impl_init![$trait:@tuple <$A:$BOUND> ($A,$A,$A,$A,$A,$A,$A) => ($A::INIT, $A::INIT, $A::INIT, $A::INIT, $A::INIT, $A::INIT,
$A::INIT)];
$crate::_impl_init![$trait:@tuple <$A:$BOUND> ($A,$A,$A,$A,$A,$A,$A,$A) => ($A::INIT, $A::INIT, $A::INIT, $A::INIT, $A::INIT, $A::INIT,
$A::INIT, $A::INIT)];
$crate::_impl_init![$trait:@tuple <$A:$BOUND> ($A,$A,$A,$A,$A,$A,$A,$A,$A) => ($A::INIT, $A::INIT, $A::INIT, $A::INIT, $A::INIT, $A::INIT,
$A::INIT, $A::INIT, $A::INIT)];
$crate::_impl_init![$trait:@tuple <$A:$BOUND> ($A,$A,$A,$A,$A,$A,$A,$A,$A,$A) => ($A::INIT, $A::INIT, $A::INIT, $A::INIT, $A::INIT, $A::INIT,
$A::INIT, $A::INIT, $A::INIT, $A::INIT)];
$crate::_impl_init![$trait:@tuple <$A:$BOUND> ($A,$A,$A,$A,$A,$A,$A,$A,$A,$A,$A) => ($A::INIT, $A::INIT, $A::INIT, $A::INIT, $A::INIT, $A::INIT,
$A::INIT, $A::INIT, $A::INIT, $A::INIT, $A::INIT)];
$crate::_impl_init![$trait:@tuple <$A:$BOUND> ($A,$A,$A,$A,$A,$A,$A,$A,$A,$A,$A,$A) => ($A::INIT, $A::INIT, $A::INIT, $A::INIT, $A::INIT, $A::INIT,
$A::INIT, $A::INIT, $A::INIT, $A::INIT, $A::INIT, $A::INIT)];
};
($trait:ident: @tuple <$A:ident:$BOUND:ident> $type:ty => $value:expr) => {
impl<$A: crate::$trait> crate::$trait for $type {
const INIT: Self = $value;
}
};
}
#[doc(hidden)]
pub use _impl_init;
#[rustfmt::skip]
mod impl_core {
use super::ConstInit;
use crate::{
NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize,
NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize,
Cell, OnceCell, RefCell, UnsafeCell,
PhantomData, PhantomPinned, ManuallyDrop,
Reverse, Saturating, Wrapping,
Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive,
PanicAssertUnwindSafe,
};
use ::core::time::Duration;
use ::core::ffi::CStr;
_impl_init![ConstInit: tuples <T: ConstInit>];
_impl_init![ConstInit: arrays <T: ConstInit>
0, 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];
_impl_init![ConstInit: () => ()];
_impl_init![ConstInit: false => bool];
_impl_init![ConstInit: '\x00' => char];
_impl_init![ConstInit: 0 =>
i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize];
_impl_init![ConstInit: 0.0 => f32, f64];
crate::CONST! { _NZ = "This implementation returns the same as [`Self::MIN`]."; }
_impl_init![ConstInit: Self::MIN =>
#[doc=_NZ!()]NonZeroU8, #[doc=_NZ!()]NonZeroU16, #[doc=_NZ!()]NonZeroU32,
#[doc=_NZ!()]NonZeroU64, #[doc=_NZ!()]NonZeroU128, #[doc=_NZ!()]NonZeroUsize,
#[doc=_NZ!()]NonZeroI8, #[doc=_NZ!()]NonZeroI16, #[doc=_NZ!()]NonZeroI32,
#[doc=_NZ!()]NonZeroI64, #[doc=_NZ!()]NonZeroI128, #[doc=_NZ!()]NonZeroIsize
];
_impl_init![ConstInit: Duration::new(0, 0) => Duration];
_impl_init![ConstInit: Self => RangeFull];
_impl_init![ConstInit: Self => PhantomPinned];
impl ConstInit for &CStr {
const INIT: Self = {
if let Ok(s) = CStr::from_bytes_until_nul(&[0]) { s } else { unreachable![]; } }; }
_impl_init![ConstInit: "" => &str];
#[cfg(all(not(feature = "safe_text"), feature = "unsafe_str"))]
#[cfg_attr(nightly_doc, doc(cfg(feature = "unsafe_str")))]
impl crate::ConstInit for &mut str {
const INIT: Self = unsafe { ::core::str::from_utf8_unchecked_mut(&mut []) };
}
_impl_init![ConstInit: <T> core::ptr::null() => *const T];
_impl_init![ConstInit: <T> core::ptr::null_mut() => *mut T];
_impl_init![ConstInit: <T> &[] => &[T]];
_impl_init![ConstInit: <T: ConstInit>
Self { start: T::INIT } => RangeFrom<T>];
_impl_init![ConstInit: <T: ConstInit>
Self { end: T::INIT } => RangeTo<T>, RangeToInclusive<T>];
_impl_init![ConstInit: <T: ConstInit>
Self { start: T::INIT, end: T::INIT } => Range<T>];
_impl_init![ConstInit: <T: ConstInit>
Self::new(T::INIT, T::INIT) => RangeInclusive<T>];
_impl_init![ConstInit: <T: ConstInit> Self::new() => OnceCell<T>];
_impl_init![ConstInit: <T: ConstInit> Self::new(T::INIT) =>
Cell<T>, ManuallyDrop<T>, RefCell<T>, UnsafeCell<T>
];
_impl_init![ConstInit: <T: ConstInit> Self(T::INIT) =>
PanicAssertUnwindSafe<T>, Reverse<T>, Saturating<T>, Wrapping<T>
];
_impl_init![ConstInit: <T> Self => PhantomData<T>]; _impl_init![ConstInit: <T: ConstInit> Some(T::INIT) => Option<T>];
impl<T: ConstInit, E> ConstInit for Result<T, E> {
const INIT: Self = { Ok(T::INIT) };
}
}
#[rustfmt::skip]
#[cfg(feature = "alloc")]
#[cfg_attr(nightly_doc, doc(cfg(feature = "alloc")))]
mod impl_alloc {
use super::ConstInit;
use crate::{
BTreeSet, BTreeMap,
LinkedList,
Vec,
BinaryHeap, VecDeque,
RcWeak,
String,
};
_impl_init![ConstInit: <T> Self::new() => BTreeSet<T>, LinkedList<T>, Vec<T>, VecDeque<T>];
impl<T: Ord> ConstInit for BinaryHeap<T> { const INIT: Self = Self::new(); }
_impl_init![ConstInit: <K, V> Self::new() => BTreeMap<K, V>];
_impl_init![ConstInit: <T: ConstInit> Self::new() => RcWeak<T>];
_impl_init![ConstInit: Self::new() => String];
}
#[cfg(feature = "std")]
#[cfg_attr(nightly_doc, doc(cfg(feature = "std")))]
mod impl_std {
use std::{
cell::LazyCell,
process::ExitCode,
sync::{Condvar, LazyLock, Mutex, Once, OnceLock, RwLock, Weak as ArcWeak},
};
_impl_init![ConstInit: Self::SUCCESS => ExitCode];
_impl_init![ConstInit: Self::new() => Condvar, Once];
_impl_init![ConstInit: <T: ConstInit>
Self::new() => ArcWeak<T>, OnceLock<T>];
_impl_init![ConstInit: <T: ConstInit>
Self::new(T::INIT) => Mutex<T>, RwLock<T>];
_impl_init![ConstInit: <T: ConstInit>
Self::new(|| T::INIT) => LazyCell<T>, LazyLock<T>];
}