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