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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//! Utility
//!
//! **This module is exempt from [the API stability guarantee][1]** unless
//! specified otherwise. It's exposed mostly because it's needed by macros.
//!
//! # Re-exports
//!
//! - [`Zeroable`], [`ZeroableInOption`]: Re-exported from [`bytemuck`]` ^1`.
//!   `Zeroable` is a marker trait used in [`HunkDefiner::zeroed`][2] and
//!   suchlike. It can be derived for struct types.
//!   These re-exports are subject to the application-side API stability
//!   guarantee.
//!
//! [1]: crate#stability
//! [2]: crate::hunk::HunkDefiner::zeroed
use core::marker::PhantomData;

/// Conditional type
macro_rules! If {
    ( if ($cond:expr) { $t:ty } else { $f:ty } ) => {
        <crate::utils::Conditional<$t, $f, {$cond}> as crate::utils::TypeFn>::Output
    };
    (
        |$($cap:ident: $cap_ty:ty),* $(,)*|
        if ($cond:expr) { $t:ty } else { $f:ty }
    ) => {
        <crate::utils::Conditional<$t, $f, {
            // "Complex" expressions are not allowed in [generic constants][1],
            // but function calls are okay for some reasons
            //
            // [1]: https://github.com/rust-lang/rust/issues/76560
            #[allow(unused_variables, non_snake_case)]
            #[doc(hidden)]
            pub const fn __evaluate_condition($($cap: $cap_ty),*) -> bool {
                $cond
            }

            __evaluate_condition($($cap),*)
        }> as crate::utils::TypeFn>::Output
    };

    (
        $( |$($cap:ident: $cap_ty:ty),* $(,)*| )?
        if ($cond:expr) { $t:ty } else if $($rest:tt)* ) => {
        If! {
            $( |$($cap: $cap_ty),*| )?
            if ($cond) {
                $t
            } else {
                If!{ $( |$($cap: $cap_ty),*| )? if $($rest)* }
            }
        }
    };
}

#[macro_use]
mod binary_search;
#[macro_use]
mod sort;
pub(crate) use sort::*;
#[macro_use]
mod vec;
pub use vec::*;
mod freeze;
pub use freeze::*;
mod alloc;
pub use alloc::*;
#[macro_use]
pub mod for_times;

mod aligned_storage;
pub(crate) mod binary_heap;
mod init;
pub mod mem;
mod rawcell;
pub(crate) mod refcell;
pub use aligned_storage::*;
pub use init::*;
pub use rawcell::*;

pub use bytemuck::{Zeroable, ZeroableInOption};

/// A phantom type that is invariant over `T`.
pub type PhantomInvariant<T> = core::marker::PhantomData<fn(T) -> T>;

/// A "type function" producing a type.
#[doc(hidden)]
pub trait TypeFn {
    type Output;
}

#[doc(hidden)]
pub struct Conditional<T, F, const B: bool>(PhantomData<(T, F)>);

impl<T, F> TypeFn for Conditional<T, F, false> {
    type Output = F;
}
impl<T, F> TypeFn for Conditional<T, F, true> {
    type Output = T;
}

/// Unwrap `#[doc = ...]`.
pub(crate) macro undoc(
    #[doc = $p0:expr]
    $( #[doc = $pN:expr] )*
) {
    concat!($p0, $( "\n", $pN, )*)
}