Skip to main content

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