mirror of
https://gitee.com/openharmony/third_party_rust_bitflags
synced 2024-11-23 07:10:11 +00:00
const functions
This adds const functions for every non mutable function in the crate.
This commit is contained in:
parent
bb53c1999b
commit
d038a14537
@ -21,6 +21,7 @@ exclude = [
|
||||
"appveyor.yml",
|
||||
"bors.toml"
|
||||
]
|
||||
build = "build.rs"
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "bitflags/bitflags" }
|
||||
|
44
build.rs
Normal file
44
build.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use std::env;
|
||||
use std::process::Command;
|
||||
use std::str::{self, FromStr};
|
||||
|
||||
fn main(){
|
||||
let minor = match rustc_minor_version() {
|
||||
Some(minor) => minor,
|
||||
None => return,
|
||||
};
|
||||
|
||||
// const fn stabilized in Rust 1.31:
|
||||
if minor >= 31 {
|
||||
println!("cargo:rustc-cfg=bitflags_const_fn");
|
||||
}
|
||||
}
|
||||
|
||||
fn rustc_minor_version() -> Option<u32> {
|
||||
let rustc = match env::var_os("RUSTC") {
|
||||
Some(rustc) => rustc,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
let output = match Command::new(rustc).arg("--version").output() {
|
||||
Ok(output) => output,
|
||||
Err(_) => return None,
|
||||
};
|
||||
|
||||
let version = match str::from_utf8(&output.stdout) {
|
||||
Ok(version) => version,
|
||||
Err(_) => return None,
|
||||
};
|
||||
|
||||
let mut pieces = version.split('.');
|
||||
if pieces.next() != Some("rustc 1") {
|
||||
return None;
|
||||
}
|
||||
|
||||
let next = match pieces.next() {
|
||||
Some(next) => next,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
u32::from_str(next).ok()
|
||||
}
|
158
src/lib.rs
158
src/lib.rs
@ -415,6 +415,46 @@ macro_rules! __bitflags {
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export(local_inner_macros)]
|
||||
#[doc(hidden)]
|
||||
#[cfg(bitflags_const_fn)]
|
||||
macro_rules! __fn_bitflags {
|
||||
(
|
||||
$(# $attr_args:tt)*
|
||||
const fn $($item:tt)*
|
||||
) => {
|
||||
$(# $attr_args)*
|
||||
const fn $($item)*
|
||||
};
|
||||
(
|
||||
$(# $attr_args:tt)*
|
||||
pub const fn $($item:tt)*
|
||||
) => {
|
||||
$(# $attr_args)*
|
||||
pub const fn $($item)*
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export(local_inner_macros)]
|
||||
#[doc(hidden)]
|
||||
#[cfg(not(bitflags_const_fn))]
|
||||
macro_rules! __fn_bitflags {
|
||||
(
|
||||
$(# $attr_args:tt)*
|
||||
const fn $($item:tt)*
|
||||
) => {
|
||||
$(# $attr_args)*
|
||||
fn $($item)*
|
||||
};
|
||||
(
|
||||
$(# $attr_args:tt)*
|
||||
pub const fn $($item:tt)*
|
||||
) => {
|
||||
$(# $attr_args)*
|
||||
pub fn $($item)*
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export(local_inner_macros)]
|
||||
#[doc(hidden)]
|
||||
macro_rules! __impl_bitflags {
|
||||
@ -507,21 +547,24 @@ macro_rules! __impl_bitflags {
|
||||
pub const $Flag: $BitFlags = $BitFlags { bits: $value };
|
||||
)+
|
||||
|
||||
/// Returns an empty set of flags.
|
||||
__fn_bitflags! {
|
||||
/// Returns an empty set of flags
|
||||
#[inline]
|
||||
pub fn empty() -> $BitFlags {
|
||||
pub const fn empty() -> $BitFlags {
|
||||
$BitFlags { bits: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
__fn_bitflags! {
|
||||
/// Returns the set containing all flags.
|
||||
#[inline]
|
||||
pub fn all() -> $BitFlags {
|
||||
pub const fn all() -> $BitFlags {
|
||||
// See `Debug::fmt` for why this approach is taken.
|
||||
#[allow(non_snake_case)]
|
||||
trait __BitFlags {
|
||||
$(
|
||||
#[inline]
|
||||
fn $Flag() -> $T { 0 }
|
||||
const $Flag: $T = 0;
|
||||
)+
|
||||
}
|
||||
impl __BitFlags for $BitFlags {
|
||||
@ -530,18 +573,21 @@ macro_rules! __impl_bitflags {
|
||||
#[allow(deprecated)]
|
||||
#[inline]
|
||||
$(? #[$attr $($args)*])*
|
||||
fn $Flag() -> $T { Self::$Flag.bits }
|
||||
const $Flag: $T = Self::$Flag.bits;
|
||||
}
|
||||
)+
|
||||
}
|
||||
$BitFlags { bits: $(<$BitFlags as __BitFlags>::$Flag())|+ }
|
||||
$BitFlags { bits: $(<$BitFlags as __BitFlags>::$Flag)|+ }
|
||||
}
|
||||
}
|
||||
|
||||
__fn_bitflags! {
|
||||
/// Returns the raw value of the flags currently stored.
|
||||
#[inline]
|
||||
pub fn bits(&self) -> $T {
|
||||
pub const fn bits(&self) -> $T {
|
||||
self.bits
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert from underlying bit representation, unless that
|
||||
/// representation contains bits that do not correspond to a flag.
|
||||
@ -554,35 +600,45 @@ macro_rules! __impl_bitflags {
|
||||
}
|
||||
}
|
||||
|
||||
__fn_bitflags! {
|
||||
/// Convert from underlying bit representation, dropping any bits
|
||||
/// that do not correspond to flags.
|
||||
#[inline]
|
||||
pub fn from_bits_truncate(bits: $T) -> $BitFlags {
|
||||
$BitFlags { bits } & $BitFlags::all()
|
||||
pub const fn from_bits_truncate(bits: $T) -> $BitFlags {
|
||||
$BitFlags { bits: bits & $BitFlags::all().bits }
|
||||
}
|
||||
}
|
||||
|
||||
__fn_bitflags! {
|
||||
/// Returns `true` if no flags are currently stored.
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
*self == $BitFlags::empty()
|
||||
pub const fn is_empty(&self) -> bool {
|
||||
self.bits() == $BitFlags::empty().bits()
|
||||
}
|
||||
}
|
||||
|
||||
__fn_bitflags! {
|
||||
/// Returns `true` if all flags are currently set.
|
||||
#[inline]
|
||||
pub fn is_all(&self) -> bool {
|
||||
*self == $BitFlags::all()
|
||||
pub const fn is_all(&self) -> bool {
|
||||
self.bits == $BitFlags::all().bits
|
||||
}
|
||||
}
|
||||
|
||||
__fn_bitflags! {
|
||||
/// Returns `true` if there are flags common to both `self` and `other`.
|
||||
#[inline]
|
||||
pub fn intersects(&self, other: $BitFlags) -> bool {
|
||||
!(*self & other).is_empty()
|
||||
pub const fn intersects(&self, other: $BitFlags) -> bool {
|
||||
!$BitFlags{ bits: self.bits & other.bits}.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
__fn_bitflags! {
|
||||
/// Returns `true` all of the flags in `other` are contained within `self`.
|
||||
#[inline]
|
||||
pub fn contains(&self, other: $BitFlags) -> bool {
|
||||
(*self & other) == other
|
||||
pub const fn contains(&self, other: $BitFlags) -> bool {
|
||||
(self.bits & other.bits) == other.bits
|
||||
}
|
||||
}
|
||||
|
||||
/// Inserts the specified flags in-place.
|
||||
@ -769,6 +825,61 @@ macro_rules! __impl_bitflags {
|
||||
$(#[$filtered])*
|
||||
fn $($item)*
|
||||
};
|
||||
|
||||
// Every attribute that the user writes on a const is applied to the
|
||||
// corresponding const that we generate, but within the implementation of
|
||||
// Debug and all() we want to ignore everything but #[cfg] attributes. In
|
||||
// particular, including a #[deprecated] attribute on those items would fail
|
||||
// to compile.
|
||||
// https://github.com/bitflags/bitflags/issues/109
|
||||
//
|
||||
// const version
|
||||
//
|
||||
// Input:
|
||||
//
|
||||
// ? #[cfg(feature = "advanced")]
|
||||
// ? #[deprecated(note = "Use somthing else.")]
|
||||
// ? #[doc = r"High quality documentation."]
|
||||
// const f: i32 { /* ... */ }
|
||||
//
|
||||
// Output:
|
||||
//
|
||||
// #[cfg(feature = "advanced")]
|
||||
// const f: i32 { /* ... */ }
|
||||
(
|
||||
$(#[$filtered:meta])*
|
||||
? #[cfg $($cfgargs:tt)*]
|
||||
$(? #[$rest:ident $($restargs:tt)*])*
|
||||
const $($item:tt)*
|
||||
) => {
|
||||
__impl_bitflags! {
|
||||
$(#[$filtered])*
|
||||
#[cfg $($cfgargs)*]
|
||||
$(? #[$rest $($restargs)*])*
|
||||
const $($item)*
|
||||
}
|
||||
};
|
||||
(
|
||||
$(#[$filtered:meta])*
|
||||
// $next != `cfg`
|
||||
? #[$next:ident $($nextargs:tt)*]
|
||||
$(? #[$rest:ident $($restargs:tt)*])*
|
||||
const $($item:tt)*
|
||||
) => {
|
||||
__impl_bitflags! {
|
||||
$(#[$filtered])*
|
||||
// $next filtered out
|
||||
$(? #[$rest $($restargs)*])*
|
||||
const $($item)*
|
||||
}
|
||||
};
|
||||
(
|
||||
$(#[$filtered:meta])*
|
||||
const $($item:tt)*
|
||||
) => {
|
||||
$(#[$filtered])*
|
||||
const $($item)*
|
||||
};
|
||||
}
|
||||
|
||||
// Same as std::stringify but callable from __impl_bitflags, which needs to use
|
||||
@ -996,6 +1107,19 @@ mod tests {
|
||||
assert_eq!(m1, e1);
|
||||
}
|
||||
|
||||
|
||||
#[cfg(bitflags_const_fn)]
|
||||
#[test]
|
||||
fn test_const_fn() {
|
||||
const M1: Flags = Flags::empty();
|
||||
|
||||
const M2: Flags = Flags::A;
|
||||
assert_eq!(M2, Flags::A);
|
||||
|
||||
const M3: Flags = Flags::C;
|
||||
assert_eq!(M3, Flags::C);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extend() {
|
||||
let mut flags;
|
||||
|
Loading…
Reference in New Issue
Block a user