@@ -635,6 +635,89 @@ macro_rules! uninitialized_array {
635635 } ) ;
636636}
637637
638+ /// A macro for defining `#[cfg]` if-else statements.
639+ ///
640+ /// The macro provided by this crate, `cfg_if`, is similar to the `if/elif` C
641+ /// preprocessor macro by allowing definition of a cascade of `#[cfg]` cases,
642+ /// emitting the implementation which matches first.
643+ ///
644+ /// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
645+ /// without having to rewrite each clause multiple times.
646+ ///
647+ /// # Example
648+ ///
649+ /// ```
650+ /// #[macro_use]
651+ /// extern crate cfg_if;
652+ ///
653+ /// cfg_if! {
654+ /// if #[cfg(unix)] {
655+ /// fn foo() { /* unix specific functionality */ }
656+ /// } else if #[cfg(target_pointer_width = "32")] {
657+ /// fn foo() { /* non-unix, 32-bit functionality */ }
658+ /// } else {
659+ /// fn foo() { /* fallback implementation */ }
660+ /// }
661+ /// }
662+ ///
663+ /// # fn main() {}
664+ /// ```
665+ #[ macro_export( local_inner_macros) ]
666+ #[ unstable( feature = "cfg_if" , issue = "59442" ) ]
667+ macro_rules! cfg_if {
668+ // match if/else chains with a final `else`
669+ ( $(
670+ if #[ cfg( $( $meta: meta) ,* ) ] { $( $it: item) * }
671+ ) else * else {
672+ $( $it2: item) *
673+ } ) => {
674+ cfg_if! {
675+ @__items
676+ ( ) ;
677+ $( ( ( $( $meta) ,* ) ( $( $it) * ) ) , ) *
678+ ( ( ) ( $( $it2) * ) ) ,
679+ }
680+ } ;
681+
682+ // match if/else chains lacking a final `else`
683+ (
684+ if #[ cfg( $( $i_met: meta) ,* ) ] { $( $i_it: item) * }
685+ $(
686+ else if #[ cfg( $( $e_met: meta) ,* ) ] { $( $e_it: item) * }
687+ ) *
688+ ) => {
689+ cfg_if! {
690+ @__items
691+ ( ) ;
692+ ( ( $( $i_met) ,* ) ( $( $i_it) * ) ) ,
693+ $( ( ( $( $e_met) ,* ) ( $( $e_it) * ) ) , ) *
694+ ( ( ) ( ) ) ,
695+ }
696+ } ;
697+
698+ // Internal and recursive macro to emit all the items
699+ //
700+ // Collects all the negated cfgs in a list at the beginning and after the
701+ // semicolon is all the remaining items
702+ ( @__items ( $( $not: meta, ) * ) ; ) => { } ;
703+ ( @__items ( $( $not: meta, ) * ) ; ( ( $( $m: meta) ,* ) ( $( $it: item) * ) ) , $( $rest: tt) * ) => {
704+ // Emit all items within one block, applying an approprate #[cfg]. The
705+ // #[cfg] will require all `$m` matchers specified and must also negate
706+ // all previous matchers.
707+ cfg_if! { @__apply cfg( all( $( $m, ) * not( any( $( $not) ,* ) ) ) ) , $( $it) * }
708+
709+ // Recurse to emit all other items in `$rest`, and when we do so add all
710+ // our `$m` matchers to the list of `$not` matchers as future emissions
711+ // will have to negate everything we just matched as well.
712+ cfg_if! { @__items ( $( $not, ) * $( $m, ) * ) ; $( $rest) * }
713+ } ;
714+
715+ // Internal macro to Apply a cfg attribute to a list of items
716+ ( @__apply $m: meta, $( $it: item) * ) => {
717+ $( #[ $m] $it) *
718+ } ;
719+ }
720+
638721/// Built-in macros to the compiler itself.
639722///
640723/// These macros do not have any corresponding definition with a `macro_rules!`
0 commit comments