//! Provides helpful configuration macros, allowing detection of platform features such as1//! [`alloc`](crate::cfg::alloc) or [`std`](crate::cfg::std) without explicit features.23/// Provides a `match`-like expression similar to [`cfg_if`] and based on the experimental4/// [`cfg_match`].5/// The name `switch` is used to avoid conflict with the `match` keyword.6/// Arms are evaluated top to bottom, and an optional wildcard arm can be provided if no match7/// can be made.8///9/// An arm can either be:10/// - a `cfg(...)` pattern (e.g., `feature = "foo"`)11/// - a wildcard `_`12/// - an alias defined using [`define_alias`]13///14/// Common aliases are provided by [`cfg`](crate::cfg).15/// Note that aliases are evaluated from the context of the defining crate, not the consumer.16///17/// # Examples18///19/// ```20/// # use bevy_platform::cfg;21/// # fn log(_: &str) {}22/// # fn foo(_: &str) {}23/// #24/// cfg::switch! {25/// #[cfg(feature = "foo")] => {26/// foo("We have the `foo` feature!")27/// }28/// cfg::std => {29/// extern crate std;30/// std::println!("No `foo`, but we have `std`!");31/// }32/// _ => {33/// log("Don't have `std` or `foo`");34/// }35/// }36/// ```37///38/// [`cfg_if`]: https://crates.io/crates/cfg-if39/// [`cfg_match`]: https://github.com/rust-lang/rust/issues/11558540#[doc(inline)]41pub use crate::switch;4243/// Defines an alias for a particular configuration.44/// This has two advantages over directly using `#[cfg(...)]`:45///46/// 1. Complex configurations can be abbreviated to more meaningful shorthand.47/// 2. Features are evaluated in the context of the _defining_ crate, not the consuming.48///49/// The second advantage is a particularly powerful tool, as it allows consuming crates to use50/// functionality in a defining crate regardless of what crate in the dependency graph enabled the51/// relevant feature.52///53/// For example, consider a crate `foo` that depends on another crate `bar`.54/// `bar` has a feature "`faster_algorithms`".55/// If `bar` defines a "`faster_algorithms`" alias:56///57/// ```ignore58/// define_alias! {59/// #[cfg(feature = "faster_algorithms")] => { faster_algorithms }60/// }61/// ```62///63/// Now, `foo` can gate its usage of those faster algorithms on the alias, avoiding the need to64/// expose its own "`faster_algorithms`" feature.65/// This also avoids the unfortunate situation where one crate activates "`faster_algorithms`" on66/// `bar` without activating that same feature on `foo`.67///68/// Once an alias is defined, there are 4 ways you can use it:69///70/// 1. Evaluate with no contents to return a `bool` indicating if the alias is active.71/// ```72/// # use bevy_platform::cfg;73/// if cfg::std!() {74/// // Have `std`!75/// } else {76/// // No `std`...77/// }78/// ```79/// 2. Pass a single code block which will only be compiled if the alias is active.80/// ```81/// # use bevy_platform::cfg;82/// cfg::std! {83/// // Have `std`!84/// # ()85/// }86/// ```87/// 3. Pass a single `if { ... } else { ... }` expression to conditionally compile either the first88/// or the second code block.89/// ```90/// # use bevy_platform::cfg;91/// cfg::std! {92/// if {93/// // Have `std`!94/// } else {95/// // No `std`...96/// }97/// }98/// ```99/// 4. Use in a [`switch`] arm for more complex conditional compilation.100/// ```101/// # use bevy_platform::cfg;102/// cfg::switch! {103/// cfg::std => {104/// // Have `std`!105/// }106/// cfg::alloc => {107/// // No `std`, but do have `alloc`!108/// }109/// _ => {110/// // No `std` or `alloc`...111/// }112/// }113/// ```114#[doc(inline)]115pub use crate::define_alias;116117/// Macro which represents an enabled compilation condition.118#[doc(inline)]119pub use crate::enabled;120121/// Macro which represents a disabled compilation condition.122#[doc(inline)]123pub use crate::disabled;124125#[doc(hidden)]126#[macro_export]127macro_rules! switch {128({ $($tt:tt)* }) => {{129$crate::switch! { $($tt)* }130}};131(_ => { $($output:tt)* }) => {132$($output)*133};134(135$cond:path => $output:tt136$($( $rest:tt )+)?137) => {138$cond! {139if {140$crate::switch! { _ => $output }141} else {142$(143$crate::switch! { $($rest)+ }144)?145}146}147};148(149#[cfg($cfg:meta)] => $output:tt150$($( $rest:tt )+)?151) => {152#[cfg($cfg)]153$crate::switch! { _ => $output }154$(155#[cfg(not($cfg))]156$crate::switch! { $($rest)+ }157)?158};159}160161#[doc(hidden)]162#[macro_export]163macro_rules! disabled {164() => { false };165(if { $($p:tt)* } else { $($n:tt)* }) => { $($n)* };166($($p:tt)*) => {};167}168169#[doc(hidden)]170#[macro_export]171macro_rules! enabled {172() => { true };173(if { $($p:tt)* } else { $($n:tt)* }) => { $($p)* };174($($p:tt)*) => { $($p)* };175}176177#[doc(hidden)]178#[macro_export]179macro_rules! define_alias {180(181#[cfg($meta:meta)] => $p:ident182$(, $( $rest:tt )+)?183) => {184$crate::define_alias! {185#[cfg($meta)] => { $p }186$(187$($rest)+188)?189}190};191(192#[cfg($meta:meta)] => $p:ident,193$($( $rest:tt )+)?194) => {195$crate::define_alias! {196#[cfg($meta)] => { $p }197$(198$($rest)+199)?200}201};202(203#[cfg($meta:meta)] => {204$(#[$p_meta:meta])*205$p:ident206}207$($( $rest:tt )+)?208) => {209$crate::switch! {210#[cfg($meta)] => {211$(#[$p_meta])*212#[doc(inline)]213///214#[doc = concat!("This macro passes the provided code because `#[cfg(", stringify!($meta), ")]` is currently active.")]215pub use $crate::enabled as $p;216}217_ => {218$(#[$p_meta])*219#[doc(inline)]220///221#[doc = concat!("This macro suppresses the provided code because `#[cfg(", stringify!($meta), ")]` is _not_ currently active.")]222pub use $crate::disabled as $p;223}224}225226$(227$crate::define_alias! {228$($rest)+229}230)?231}232}233234define_alias! {235#[cfg(feature = "alloc")] => {236/// Indicates the `alloc` crate is available and can be used.237alloc238}239#[cfg(feature = "std")] => {240/// Indicates the `std` crate is available and can be used.241std242}243#[cfg(panic = "unwind")] => {244/// Indicates that a [`panic`] will be unwound, and can be potentially caught.245panic_unwind246}247#[cfg(panic = "abort")] => {248/// Indicates that a [`panic`] will lead to an abort, and cannot be caught.249panic_abort250}251#[cfg(all(target_arch = "wasm32", feature = "web"))] => {252/// Indicates that this target has access to browser APIs.253web254}255#[cfg(all(feature = "alloc", target_has_atomic = "ptr"))] => {256/// Indicates that this target has access to a native implementation of `Arc`.257arc258}259#[cfg(feature = "critical-section")] => {260/// Indicates `critical-section` is available.261critical_section262}263}264265266