1#![expect(clippy::allow_attributes, reason = "required attributes may depend on architecture specific implementation")]
4
5#[cfg(target_arch = "x86_64")]
6mod x86;
7
8#[cfg(target_arch = "x86_64")]
9#[doc(hidden)]
10pub use x86::*;
11
12mod cache;
13
14macro_rules! features_macro {
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;)*
21 $(@FEATURE: $feature:ident: $feature_lit:tt: $feature_doc:tt;)*
22 ) => {
23 #[macro_export]
24 $(#[$macro_attrs])*
25 #[doc = "Returns a bool if the current system supports the requested feature"]
26 #[doc = "\n\nThe features available to test are:"]
27 $(#[doc = concat!("- `", $feature_lit, "` - ", $feature_doc, "\n")])*
28 macro_rules! $macro_name {
29 $(
30 ($feature_lit) => {
31 $crate::detect::__detected::$feature()
32 };
33 )*
34 $(
35 ($bind_feature) => {
36 $crate::detect::__detected::$feature_impl()
37 };
38 )*
39 ($t:tt,) => {
40 $crate::$macro_name!($t);
41 };
42 ($t:tt) => {
43 compile_error!(
44 concat!(
45 concat!("unknown ", stringify!($target)),
46 concat!(" target feature: ", $t)
47 )
48 )
49 };
50 }
51
52 #[doc(hidden)]
53 #[allow(non_camel_case_types, reason = "feature names may not be camel case")]
54 #[derive(Copy, Clone, Debug)]
55 #[repr(u32)]
56 #[cfg($cfg)]
57 pub enum Feature {
58 $(
59 $feature,
60 )*
61 _last
62 }
63
64 #[cfg($cfg)]
65 impl Feature {
66 pub(crate) fn to_str(self) -> &'static str {
67 match self {
68 $(Feature::$feature => $feature_lit,)*
69 Feature::_last => unreachable!(),
70 }
71 }
72 }
73
74 #[doc(hidden)]
75 #[cfg($cfg)]
76 pub mod __detected {
77 $(
78 #[inline]
79 #[doc(hidden)]
80 pub fn $feature() -> bool {
81 $crate::detect::cache::test($crate::detect::Feature::$feature)
82 }
83 )*
84 }
85 };
86}
87
88pub(crate) use features_macro;
89
90pub fn features() -> impl Iterator<Item = (&'static str, bool)> {
92 (0u32..Feature::_last as u32).map(|discriminant: u32| {
93 let f: Feature = unsafe { core::mem::transmute::<u32, Feature>(discriminant) };
96 let name = f.to_str();
97 let enabled = cache::test(f);
98 (name, enabled)
99 })
100}