const_util/
lib.rs

1#![no_std]
2
3//! Provides stable const implementations for some things missing from the standard library.
4//!
5//! Currently implemented are
6//! - Functions in the [`concat`] module to concat const strings and byte slices.
7//! - [`destruct_tuple`] to destructure tuples with generic types or types with drop glue in them
8//! - [`mem::nonnull_from`] to create [`core::ptr::NonNull`]s from mutable and regular references
9//!   conveniently
10//! - [`mem::man_drop_ref`]/[`mem::man_drop_mut`] as a workaround for the lack of const
11//!   [`Deref`](core::ops::Deref) implementations
12
13/// A constant value
14pub trait Const {
15    /// The type of the constant
16    type Type;
17    /// The value of the constant
18    const VALUE: Self::Type;
19}
20/// Alias for [`Const::VALUE`].
21///
22/// Note that functions are evaluated more lazily than associated consts in const contexts by the
23/// current compiler.
24pub const fn value_of<C: Const>() -> C::Type {
25    C::VALUE
26}
27
28pub mod concat;
29pub mod mem;
30pub mod result;
31
32#[doc(hidden)]
33#[macro_export]
34macro_rules! __infer {
35    ($($_:tt)*) => {
36        _
37    };
38}
39
40/// Allows destructuring tuples in `const` contexts, regardless of items having drop glue.
41///
42/// This is mainly useful to allow generic functions to return tuples without being then stuck
43/// without a way to pull them back apart.
44///
45/// # Example
46/// ```
47/// use const_util::*;
48/// const fn pair_to_arr<T>(pair: (T, T)) -> [T; 2] {
49///     destruct_tuple! { a, b in pair }
50///     [a, b]
51/// }
52/// assert_eq!(
53///     pair_to_arr((String::from("ABC"), String::new())),
54///     ["ABC", ""],
55/// );
56/// ```
57#[macro_export]
58macro_rules! destruct_tuple {
59    ($($field:ident),* in $tup:expr) => {
60        let __tup: ($($crate::__infer!($field),)*) = $tup;
61        let __tup = $crate::__mac::core::mem::ManuallyDrop::new(__tup);
62        let ($($field),*) = $crate::mem::man_drop_ref(&__tup);
63        // SAFETY: The tuple is forgotten after this
64        $(let $field = unsafe { $crate::__mac::core::ptr::read($field) };)*
65    };
66}
67
68#[doc(hidden)]
69pub mod __mac {
70    pub use core;
71}