1 | #[macro_export ] |
2 | #[allow_internal_unstable (stdsimd)] |
3 | macro_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)] |
14 | macro_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 | |