@@ -635,6 +635,89 @@ macro_rules! uninitialized_array {
635
635
} ) ;
636
636
}
637
637
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
+
638
721
/// Built-in macros to the compiler itself.
639
722
///
640
723
/// These macros do not have any corresponding definition with a `macro_rules!`
0 commit comments