1#[macro_export]
2#[allow_internal_unstable(stdsimd)]
3macro_rules! detect_feature {
4 ($feature:tt, $feature_lit:tt) => {
5 $crate::detect_feature!($feature, $feature_lit : $feature_lit)
6 };
7 ($feature:tt, $feature_lit:tt : $($target_feature_lit:tt),*) => {
8 $(cfg!(target_feature = $target_feature_lit) ||)*
9 $crate::detect::__is_feature_detected::$feature()
10 };
11}
12
13#[allow(unused)]
14macro_rules! features {
15 (
16 @TARGET: $target:ident;
17 @CFG: $cfg:meta;
18 @MACRO_NAME: $macro_name:ident;
19 @MACRO_ATTRS: $(#[$macro_attrs:meta])*
20 $(@BIND_FEATURE_NAME: $bind_feature:tt; $feature_impl:tt; $(#[$deprecate_attr:meta];)?)*
21 $(@NO_RUNTIME_DETECTION: $nort_feature:tt; )*
22 $(@FEATURE: #[$stability_attr:meta] $feature:ident: $feature_lit:tt;
23 $(implied by target_features: [$($target_feature_lit:tt),*];)?
24 $(#[$feature_comment:meta])*)*
25 ) => {
26 #[macro_export]
27 $(#[$macro_attrs])*
28 #[allow_internal_unstable(stdsimd_internal, stdsimd)]
29 #[cfg($cfg)]
30 #[doc(cfg($cfg))]
31 macro_rules! $macro_name {
32 $(
33 ($feature_lit) => {
34 $crate::detect_feature!($feature, $feature_lit $(: $($target_feature_lit),*)?)
35 };
36 )*
37 $(
38 ($bind_feature) => {
39 {
40 $(
41 #[$deprecate_attr] macro_rules! deprecated_feature { {} => {}; }
42 deprecated_feature! {};
43 )?
44 $crate::$macro_name!($feature_impl)
45 }
46 };
47 )*
48 $(
49 ($nort_feature) => {
50 compile_error!(
51 concat!(
52 stringify!($nort_feature),
53 " feature cannot be detected at run-time"
54 )
55 )
56 };
57 )*
58 ($t:tt,) => {
59 $crate::$macro_name!($t);
60 };
61 ($t:tt) => {
62 compile_error!(
63 concat!(
64 concat!("unknown ", stringify!($target)),
65 concat!(" target feature: ", $t)
66 )
67 )
68 };
69 }
70
71 $(#[$macro_attrs])*
72 #[macro_export]
73 #[cfg(not($cfg))]
74 #[doc(cfg($cfg))]
75 macro_rules! $macro_name {
76 $(
77 ($feature_lit) => {
78 compile_error!(
79 concat!(
80 r#"This macro cannot be used on the current target.
81 You can prevent it from being used in other architectures by
82 guarding it behind a cfg("#,
83 stringify!($cfg),
84 ")."
85 )
86 )
87 };
88 )*
89 $(
90 ($bind_feature) => { $crate::$macro_name!($feature_impl) };
91 )*
92 $(
93 ($nort_feature) => {
94 compile_error!(
95 concat!(
96 stringify!($nort_feature),
97 " feature cannot be detected at run-time"
98 )
99 )
100 };
101 )*
102 ($t:tt,) => {
103 $crate::$macro_name!($t);
104 };
105 ($t:tt) => {
106 compile_error!(
107 concat!(
108 concat!("unknown ", stringify!($target)),
109 concat!(" target feature: ", $t)
110 )
111 )
112 };
113 }
114
115 /// Each variant denotes a position in a bitset for a particular feature.
116 ///
117 /// PLEASE: do not use this, it is an implementation detail subject
118 /// to change.
119 #[doc(hidden)]
120 #[allow(non_camel_case_types)]
121 #[derive(Copy, Clone)]
122 #[repr(u8)]
123 #[unstable(feature = "stdsimd_internal", issue = "none")]
124 #[cfg($cfg)]
125 pub(crate) enum Feature {
126 $(
127 $(#[$feature_comment])*
128 $feature,
129 )*
130
131 // Do not add variants after last:
132 _last
133 }
134
135 #[cfg($cfg)]
136 impl Feature {
137 pub(crate) fn to_str(self) -> &'static str {
138 match self {
139 $(Feature::$feature => $feature_lit,)*
140 Feature::_last => unreachable!(),
141 }
142 }
143 #[cfg(feature = "std_detect_env_override")]
144 pub(crate) fn from_str(s: &str) -> Result<Feature, ()> {
145 match s {
146 $($feature_lit => Ok(Feature::$feature),)*
147 _ => Err(())
148 }
149 }
150 }
151
152 /// Each function performs run-time feature detection for a single
153 /// feature. This allow us to use stability attributes on a per feature
154 /// basis.
155 ///
156 /// PLEASE: do not use this, it is an implementation detail subject
157 /// to change.
158 #[doc(hidden)]
159 #[cfg($cfg)]
160 pub mod __is_feature_detected {
161 $(
162
163 /// PLEASE: do not use this, it is an implementation detail
164 /// subject to change.
165 #[inline]
166 #[doc(hidden)]
167 #[$stability_attr]
168 pub fn $feature() -> bool {
169 $crate::detect::check_for($crate::detect::Feature::$feature)
170 }
171 )*
172 }
173 };
174}
175