From 4de756b5fd6221c9d953c45e2ee0692f34a34683 Mon Sep 17 00:00:00 2001 From: lurchi Date: Tue, 13 Sep 2016 16:18:07 +0200 Subject: [PATCH] bundle bitflags --- rust/Cargo.toml | 2 +- rust/third_party/bitflags/.gitignore | 2 + rust/third_party/bitflags/.travis.yml | 24 + rust/third_party/bitflags/Cargo.toml | 13 + rust/third_party/bitflags/LICENSE-APACHE | 201 +++++ rust/third_party/bitflags/LICENSE-MIT | 25 + rust/third_party/bitflags/README.md | 24 + rust/third_party/bitflags/src/lib.rs | 808 ++++++++++++++++++ rust/third_party/bitflags/tests/external.rs | 21 + .../bitflags/tests/external_no_std.rs | 22 + 10 files changed, 1141 insertions(+), 1 deletion(-) create mode 100644 rust/third_party/bitflags/.gitignore create mode 100644 rust/third_party/bitflags/.travis.yml create mode 100644 rust/third_party/bitflags/Cargo.toml create mode 100644 rust/third_party/bitflags/LICENSE-APACHE create mode 100644 rust/third_party/bitflags/LICENSE-MIT create mode 100644 rust/third_party/bitflags/README.md create mode 100644 rust/third_party/bitflags/src/lib.rs create mode 100644 rust/third_party/bitflags/tests/external.rs create mode 100644 rust/third_party/bitflags/tests/external_no_std.rs diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 5302866..b3a2c40 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -6,4 +6,4 @@ build = "build.rs" description = "rust bindings for libpsyc" [dependencies] -bitflags = "0.7.0" +bitflags = { path = "third_party/bitflags", version = "0.7.0" } diff --git a/rust/third_party/bitflags/.gitignore b/rust/third_party/bitflags/.gitignore new file mode 100644 index 0000000..4fffb2f --- /dev/null +++ b/rust/third_party/bitflags/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/rust/third_party/bitflags/.travis.yml b/rust/third_party/bitflags/.travis.yml new file mode 100644 index 0000000..6034446 --- /dev/null +++ b/rust/third_party/bitflags/.travis.yml @@ -0,0 +1,24 @@ +language: rust +rust: + - stable + - beta + - nightly +sudo: false +script: + - cargo build --verbose + - cargo test --verbose + - cargo doc +after_success: | + [ $TRAVIS_BRANCH = master ] && + [ $TRAVIS_PULL_REQUEST = false ] && + [ $TRAVIS_RUST_VERSION = nightly ] && + echo '' > target/doc/index.html && + pip install ghp-import --user $USER && + $HOME/.local/bin/ghp-import -n target/doc && + git push -qf https://${TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages +env: + global: + secure: d+l63TtlF6cfFVDGauYRexgx4lBww4ORqqK4Vt75nWbiCbjZYsKXbcTUdhAr193nIVGiNW50A8SekM01F3EngHwHwr6u5kFleOggm+HA0kkBVeX+k2A4WCVVfYI+gth+zk99WaF8h46MA0evhx6FYDoqeyl9oqmVifI4kaqhMwc= +notifications: + email: + on_success: never diff --git a/rust/third_party/bitflags/Cargo.toml b/rust/third_party/bitflags/Cargo.toml new file mode 100644 index 0000000..042497e --- /dev/null +++ b/rust/third_party/bitflags/Cargo.toml @@ -0,0 +1,13 @@ +[package] + +name = "bitflags" +version = "0.7.0" +authors = ["The Rust Project Developers"] +license = "MIT/Apache-2.0" +readme = "README.md" +repository = "https://github.com/rust-lang/bitflags" +homepage = "https://github.com/rust-lang/bitflags" +documentation = "https://doc.rust-lang.org/bitflags" +description = """ +A macro to generate structures which behave like bitflags. +""" diff --git a/rust/third_party/bitflags/LICENSE-APACHE b/rust/third_party/bitflags/LICENSE-APACHE new file mode 100644 index 0000000..16fe87b --- /dev/null +++ b/rust/third_party/bitflags/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/rust/third_party/bitflags/LICENSE-MIT b/rust/third_party/bitflags/LICENSE-MIT new file mode 100644 index 0000000..39d4bdb --- /dev/null +++ b/rust/third_party/bitflags/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/rust/third_party/bitflags/README.md b/rust/third_party/bitflags/README.md new file mode 100644 index 0000000..b221dd8 --- /dev/null +++ b/rust/third_party/bitflags/README.md @@ -0,0 +1,24 @@ +bitflags +======== + +A Rust macro to generate structures which behave like a set of bitflags + +[![Build Status](https://travis-ci.org/rust-lang-nursery/bitflags.svg?branch=master)](https://travis-ci.org/rust-lang-nursery/bitflags) + +[Documentation](https://doc.rust-lang.org/bitflags) + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +bitflags = "0.7" +``` + +and this to your crate root: + +```rust +#[macro_use] +extern crate bitflags; +``` diff --git a/rust/third_party/bitflags/src/lib.rs b/rust/third_party/bitflags/src/lib.rs new file mode 100644 index 0000000..698799d --- /dev/null +++ b/rust/third_party/bitflags/src/lib.rs @@ -0,0 +1,808 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! A typesafe bitmask flag generator. + +#![no_std] + +#[cfg(test)] +#[macro_use] +extern crate std; + +// Re-export libstd/libcore using an alias so that the macros can work in no_std +// crates while remaining compatible with normal crates. +#[allow(private_in_public)] +#[doc(hidden)] +pub use core as __core; + +/// The `bitflags!` macro generates a `struct` that holds a set of C-style +/// bitmask flags. It is useful for creating typesafe wrappers for C APIs. +/// +/// The flags should only be defined for integer types, otherwise unexpected +/// type errors may occur at compile time. +/// +/// # Example +/// +/// ```{.rust} +/// #[macro_use] +/// extern crate bitflags; +/// +/// bitflags! { +/// flags Flags: u32 { +/// const FLAG_A = 0b00000001, +/// const FLAG_B = 0b00000010, +/// const FLAG_C = 0b00000100, +/// const FLAG_ABC = FLAG_A.bits +/// | FLAG_B.bits +/// | FLAG_C.bits, +/// } +/// } +/// +/// fn main() { +/// let e1 = FLAG_A | FLAG_C; +/// let e2 = FLAG_B | FLAG_C; +/// assert_eq!((e1 | e2), FLAG_ABC); // union +/// assert_eq!((e1 & e2), FLAG_C); // intersection +/// assert_eq!((e1 - e2), FLAG_A); // set difference +/// assert_eq!(!e2, FLAG_A); // set complement +/// } +/// ``` +/// +/// The generated `struct`s can also be extended with type and trait +/// implementations: +/// +/// ```{.rust} +/// #[macro_use] +/// extern crate bitflags; +/// +/// use std::fmt; +/// +/// bitflags! { +/// flags Flags: u32 { +/// const FLAG_A = 0b00000001, +/// const FLAG_B = 0b00000010, +/// } +/// } +/// +/// impl Flags { +/// pub fn clear(&mut self) { +/// self.bits = 0; // The `bits` field can be accessed from within the +/// // same module where the `bitflags!` macro was invoked. +/// } +/// } +/// +/// impl fmt::Display for Flags { +/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +/// write!(f, "hi!") +/// } +/// } +/// +/// fn main() { +/// let mut flags = FLAG_A | FLAG_B; +/// flags.clear(); +/// assert!(flags.is_empty()); +/// assert_eq!(format!("{}", flags), "hi!"); +/// assert_eq!(format!("{:?}", FLAG_A | FLAG_B), "FLAG_A | FLAG_B"); +/// assert_eq!(format!("{:?}", FLAG_B), "FLAG_B"); +/// } +/// ``` +/// +/// # Visibility +/// +/// The generated struct and its associated flag constants are not exported +/// out of the current module by default. A definition can be exported out of +/// the current module by adding `pub` before `flags`: +/// +/// ```{.rust},ignore +/// #[macro_use] +/// extern crate bitflags; +/// +/// mod example { +/// bitflags! { +/// pub flags Flags1: u32 { +/// const FLAG_A = 0b00000001, +/// } +/// } +/// bitflags! { +/// flags Flags2: u32 { +/// const FLAG_B = 0b00000010, +/// } +/// } +/// } +/// +/// fn main() { +/// let flag1 = example::FLAG_A; +/// let flag2 = example::FLAG_B; // error: const `FLAG_B` is private +/// } +/// ``` +/// +/// # Attributes +/// +/// Attributes can be attached to the generated `struct` by placing them +/// before the `flags` keyword. +/// +/// # Trait implementations +/// +/// The `Copy`, `Clone`, `PartialEq`, `Eq`, `PartialOrd`, `Ord` and `Hash` +/// traits automatically derived for the `struct` using the `derive` attribute. +/// Additional traits can be derived by providing an explicit `derive` +/// attribute on `flags`. +/// +/// The `Extend` and `FromIterator` traits are implemented for the `struct`, +/// too: `Extend` adds the union of the instances of the `struct` iterated over, +/// while `FromIterator` calculates the union. +/// +/// The `Debug` trait is also implemented by displaying the bits value of the +/// internal struct. +/// +/// ## Operators +/// +/// The following operator traits are implemented for the generated `struct`: +/// +/// - `BitOr` and `BitOrAssign`: union +/// - `BitAnd` and `BitAndAssign`: intersection +/// - `BitXor` and `BitXorAssign`: toggle +/// - `Sub` and `SubAssign`: set difference +/// - `Not`: set complement +/// +/// As long as the assignment operators are unstable rust feature they are only +/// available with the crate feature `assignment_ops` enabled. +/// +/// # Methods +/// +/// The following methods are defined for the generated `struct`: +/// +/// - `empty`: an empty set of flags +/// - `all`: the set of all flags +/// - `bits`: the raw value of the flags currently stored +/// - `from_bits`: convert from underlying bit representation, unless that +/// representation contains bits that do not correspond to a flag +/// - `from_bits_truncate`: convert from underlying bit representation, dropping +/// any bits that do not correspond to flags +/// - `is_empty`: `true` if no flags are currently stored +/// - `is_all`: `true` if all flags are currently set +/// - `intersects`: `true` if there are flags common to both `self` and `other` +/// - `contains`: `true` all of the flags in `other` are contained within `self` +/// - `insert`: inserts the specified flags in-place +/// - `remove`: removes the specified flags in-place +/// - `toggle`: the specified flags will be inserted if not present, and removed +/// if they are. +#[macro_export] +macro_rules! bitflags { + ($(#[$attr:meta])* pub flags $BitFlags:ident: $T:ty { + $($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+ + }) => { + #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)] + $(#[$attr])* + pub struct $BitFlags { + bits: $T, + } + + $($(#[$Flag_attr])* pub const $Flag: $BitFlags = $BitFlags { bits: $value };)+ + + bitflags! { + @_impl flags $BitFlags: $T { + $($(#[$Flag_attr])* const $Flag = $value),+ + } + } + }; + ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty { + $($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+ + }) => { + #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)] + $(#[$attr])* + struct $BitFlags { + bits: $T, + } + + $($(#[$Flag_attr])* const $Flag: $BitFlags = $BitFlags { bits: $value };)+ + + bitflags! { + @_impl flags $BitFlags: $T { + $($(#[$Flag_attr])* const $Flag = $value),+ + } + } + }; + (@_impl flags $BitFlags:ident: $T:ty { + $($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+ + }) => { + impl $crate::__core::fmt::Debug for $BitFlags { + fn fmt(&self, f: &mut $crate::__core::fmt::Formatter) -> $crate::__core::fmt::Result { + // This convoluted approach is to handle #[cfg]-based flag + // omission correctly. Some of the $Flag variants may not be + // defined in this module so we create an inner module which + // defines *all* flags to the value of 0. We then create a + // second inner module that defines all of the flags with #[cfg] + // to their real values. Afterwards the glob will import + // variants from the second inner module, shadowing all + // defined variants, leaving only the undefined ones with the + // bit value of 0. + #[allow(dead_code)] + #[allow(unused_assignments)] + mod dummy { + // We can't use the real $BitFlags struct because it may be + // private, which prevents us from using it to define + // public constants. + pub struct $BitFlags { + bits: u64, + } + mod real_flags { + use super::$BitFlags; + $($(#[$Flag_attr])* pub const $Flag: $BitFlags = $BitFlags { + bits: super::super::$Flag.bits as u64 + };)+ + } + // Now we define the "undefined" versions of the flags. + // This way, all the names exist, even if some are #[cfg]ed + // out. + $(const $Flag: $BitFlags = $BitFlags { bits: 0 };)+ + + #[inline] + pub fn fmt(self_: u64, + f: &mut $crate::__core::fmt::Formatter) + -> $crate::__core::fmt::Result { + // Now we import the real values for the flags. + // Only ones that are #[cfg]ed out will be 0. + use self::real_flags::*; + + let mut first = true; + $( + // $Flag.bits == 0 means that $Flag doesn't exist + if $Flag.bits != 0 && self_ & $Flag.bits as u64 == $Flag.bits as u64 { + if !first { + try!(f.write_str(" | ")); + } + first = false; + try!(f.write_str(stringify!($Flag))); + } + )+ + Ok(()) + } + } + dummy::fmt(self.bits as u64, f) + } + } + + #[allow(dead_code)] + impl $BitFlags { + /// Returns an empty set of flags. + #[inline] + pub fn empty() -> $BitFlags { + $BitFlags { bits: 0 } + } + + /// Returns the set containing all flags. + #[inline] + pub fn all() -> $BitFlags { + // See above `dummy` module for why this approach is taken. + #[allow(dead_code)] + mod dummy { + pub struct $BitFlags { + bits: u64, + } + mod real_flags { + use super::$BitFlags; + $($(#[$Flag_attr])* pub const $Flag: $BitFlags = $BitFlags { + bits: super::super::$Flag.bits as u64 + };)+ + } + $(const $Flag: $BitFlags = $BitFlags { bits: 0 };)+ + + #[inline] + pub fn all() -> u64 { + use self::real_flags::*; + $($Flag.bits)|+ + } + } + $BitFlags { bits: dummy::all() as $T } + } + + /// Returns the raw value of the flags currently stored. + #[inline] + pub fn bits(&self) -> $T { + self.bits + } + + /// Convert from underlying bit representation, unless that + /// representation contains bits that do not correspond to a flag. + #[inline] + pub fn from_bits(bits: $T) -> $crate::__core::option::Option<$BitFlags> { + if (bits & !$BitFlags::all().bits()) == 0 { + $crate::__core::option::Option::Some($BitFlags { bits: bits }) + } else { + $crate::__core::option::Option::None + } + } + + /// 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: bits } & $BitFlags::all() + } + + /// Returns `true` if no flags are currently stored. + #[inline] + pub fn is_empty(&self) -> bool { + *self == $BitFlags::empty() + } + + /// Returns `true` if all flags are currently set. + #[inline] + pub fn is_all(&self) -> bool { + *self == $BitFlags::all() + } + + /// Returns `true` if there are flags common to both `self` and `other`. + #[inline] + pub fn intersects(&self, other: $BitFlags) -> bool { + !(*self & other).is_empty() + } + + /// Returns `true` all of the flags in `other` are contained within `self`. + #[inline] + pub fn contains(&self, other: $BitFlags) -> bool { + (*self & other) == other + } + + /// Inserts the specified flags in-place. + #[inline] + pub fn insert(&mut self, other: $BitFlags) { + self.bits |= other.bits; + } + + /// Removes the specified flags in-place. + #[inline] + pub fn remove(&mut self, other: $BitFlags) { + self.bits &= !other.bits; + } + + /// Toggles the specified flags in-place. + #[inline] + pub fn toggle(&mut self, other: $BitFlags) { + self.bits ^= other.bits; + } + } + + impl $crate::__core::ops::BitOr for $BitFlags { + type Output = $BitFlags; + + /// Returns the union of the two sets of flags. + #[inline] + fn bitor(self, other: $BitFlags) -> $BitFlags { + $BitFlags { bits: self.bits | other.bits } + } + } + + impl $crate::__core::ops::BitOrAssign for $BitFlags { + + /// Adds the set of flags. + #[inline] + fn bitor_assign(&mut self, other: $BitFlags) { + self.bits |= other.bits; + } + } + + impl $crate::__core::ops::BitXor for $BitFlags { + type Output = $BitFlags; + + /// Returns the left flags, but with all the right flags toggled. + #[inline] + fn bitxor(self, other: $BitFlags) -> $BitFlags { + $BitFlags { bits: self.bits ^ other.bits } + } + } + + impl $crate::__core::ops::BitXorAssign for $BitFlags { + + /// Toggles the set of flags. + #[inline] + fn bitxor_assign(&mut self, other: $BitFlags) { + self.bits ^= other.bits; + } + } + + impl $crate::__core::ops::BitAnd for $BitFlags { + type Output = $BitFlags; + + /// Returns the intersection between the two sets of flags. + #[inline] + fn bitand(self, other: $BitFlags) -> $BitFlags { + $BitFlags { bits: self.bits & other.bits } + } + } + + impl $crate::__core::ops::BitAndAssign for $BitFlags { + + /// Disables all flags disabled in the set. + #[inline] + fn bitand_assign(&mut self, other: $BitFlags) { + self.bits &= other.bits; + } + } + + impl $crate::__core::ops::Sub for $BitFlags { + type Output = $BitFlags; + + /// Returns the set difference of the two sets of flags. + #[inline] + fn sub(self, other: $BitFlags) -> $BitFlags { + $BitFlags { bits: self.bits & !other.bits } + } + } + + impl $crate::__core::ops::SubAssign for $BitFlags { + + /// Disables all flags enabled in the set. + #[inline] + fn sub_assign(&mut self, other: $BitFlags) { + self.bits &= !other.bits; + } + } + + impl $crate::__core::ops::Not for $BitFlags { + type Output = $BitFlags; + + /// Returns the complement of this set of flags. + #[inline] + fn not(self) -> $BitFlags { + $BitFlags { bits: !self.bits } & $BitFlags::all() + } + } + + impl $crate::__core::iter::Extend<$BitFlags> for $BitFlags { + fn extend>(&mut self, iterator: T) { + for item in iterator { + self.insert(item) + } + } + } + + impl $crate::__core::iter::FromIterator<$BitFlags> for $BitFlags { + fn from_iter>(iterator: T) -> $BitFlags { + let mut result = Self::empty(); + result.extend(iterator); + result + } + } + }; + ($(#[$attr:meta])* pub flags $BitFlags:ident: $T:ty { + $($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+, + }) => { + bitflags! { + $(#[$attr])* + pub flags $BitFlags: $T { + $($(#[$Flag_attr])* const $Flag = $value),+ + } + } + }; + ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty { + $($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+, + }) => { + bitflags! { + $(#[$attr])* + flags $BitFlags: $T { + $($(#[$Flag_attr])* const $Flag = $value),+ + } + } + }; +} + +#[cfg(test)] +#[allow(non_upper_case_globals, dead_code)] +mod tests { + use std::hash::{SipHasher, Hash, Hasher}; + + bitflags! { + #[doc = "> The first principle is that you must not fool yourself — and"] + #[doc = "> you are the easiest person to fool."] + #[doc = "> "] + #[doc = "> - Richard Feynman"] + flags Flags: u32 { + const FlagA = 0b00000001, + #[doc = " macros are way better at generating code than trans is"] + const FlagB = 0b00000010, + const FlagC = 0b00000100, + #[doc = "* cmr bed"] + #[doc = "* strcat table"] + #[doc = " wait what?"] + const FlagABC = FlagA.bits + | FlagB.bits + | FlagC.bits, + } + } + + bitflags! { + flags _CfgFlags: u32 { + #[cfg(windows)] + const _CfgA = 0b01, + #[cfg(unix)] + const _CfgB = 0b01, + #[cfg(windows)] + const _CfgC = _CfgA.bits | 0b10, + } + } + + bitflags! { + flags AnotherSetOfFlags: i8 { + const AnotherFlag = -1_i8, + } + } + + #[test] + fn test_bits(){ + assert_eq!(Flags::empty().bits(), 0b00000000); + assert_eq!(FlagA.bits(), 0b00000001); + assert_eq!(FlagABC.bits(), 0b00000111); + + assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00); + assert_eq!(AnotherFlag.bits(), !0_i8); + } + + #[test] + fn test_from_bits() { + assert_eq!(Flags::from_bits(0), Some(Flags::empty())); + assert_eq!(Flags::from_bits(0b1), Some(FlagA)); + assert_eq!(Flags::from_bits(0b10), Some(FlagB)); + assert_eq!(Flags::from_bits(0b11), Some(FlagA | FlagB)); + assert_eq!(Flags::from_bits(0b1000), None); + + assert_eq!(AnotherSetOfFlags::from_bits(!0_i8), Some(AnotherFlag)); + } + + #[test] + fn test_from_bits_truncate() { + assert_eq!(Flags::from_bits_truncate(0), Flags::empty()); + assert_eq!(Flags::from_bits_truncate(0b1), FlagA); + assert_eq!(Flags::from_bits_truncate(0b10), FlagB); + assert_eq!(Flags::from_bits_truncate(0b11), (FlagA | FlagB)); + assert_eq!(Flags::from_bits_truncate(0b1000), Flags::empty()); + assert_eq!(Flags::from_bits_truncate(0b1001), FlagA); + + assert_eq!(AnotherSetOfFlags::from_bits_truncate(0_i8), AnotherSetOfFlags::empty()); + } + + #[test] + fn test_is_empty(){ + assert!(Flags::empty().is_empty()); + assert!(!FlagA.is_empty()); + assert!(!FlagABC.is_empty()); + + assert!(!AnotherFlag.is_empty()); + } + + #[test] + fn test_is_all() { + assert!(Flags::all().is_all()); + assert!(!FlagA.is_all()); + assert!(FlagABC.is_all()); + + assert!(AnotherFlag.is_all()); + } + + #[test] + fn test_two_empties_do_not_intersect() { + let e1 = Flags::empty(); + let e2 = Flags::empty(); + assert!(!e1.intersects(e2)); + + assert!(AnotherFlag.intersects(AnotherFlag)); + } + + #[test] + fn test_empty_does_not_intersect_with_full() { + let e1 = Flags::empty(); + let e2 = FlagABC; + assert!(!e1.intersects(e2)); + } + + #[test] + fn test_disjoint_intersects() { + let e1 = FlagA; + let e2 = FlagB; + assert!(!e1.intersects(e2)); + } + + #[test] + fn test_overlapping_intersects() { + let e1 = FlagA; + let e2 = FlagA | FlagB; + assert!(e1.intersects(e2)); + } + + #[test] + fn test_contains() { + let e1 = FlagA; + let e2 = FlagA | FlagB; + assert!(!e1.contains(e2)); + assert!(e2.contains(e1)); + assert!(FlagABC.contains(e2)); + + assert!(AnotherFlag.contains(AnotherFlag)); + } + + #[test] + fn test_insert(){ + let mut e1 = FlagA; + let e2 = FlagA | FlagB; + e1.insert(e2); + assert_eq!(e1, e2); + + let mut e3 = AnotherSetOfFlags::empty(); + e3.insert(AnotherFlag); + assert_eq!(e3, AnotherFlag); + } + + #[test] + fn test_remove(){ + let mut e1 = FlagA | FlagB; + let e2 = FlagA | FlagC; + e1.remove(e2); + assert_eq!(e1, FlagB); + + let mut e3 = AnotherFlag; + e3.remove(AnotherFlag); + assert_eq!(e3, AnotherSetOfFlags::empty()); + } + + #[test] + fn test_operators() { + let e1 = FlagA | FlagC; + let e2 = FlagB | FlagC; + assert_eq!((e1 | e2), FlagABC); // union + assert_eq!((e1 & e2), FlagC); // intersection + assert_eq!((e1 - e2), FlagA); // set difference + assert_eq!(!e2, FlagA); // set complement + assert_eq!(e1 ^ e2, FlagA | FlagB); // toggle + let mut e3 = e1; + e3.toggle(e2); + assert_eq!(e3, FlagA | FlagB); + + let mut m4 = AnotherSetOfFlags::empty(); + m4.toggle(AnotherSetOfFlags::empty()); + assert_eq!(m4, AnotherSetOfFlags::empty()); + } + + #[test] + fn test_assignment_operators() { + let mut m1 = Flags::empty(); + let e1 = FlagA | FlagC; + // union + m1 |= FlagA; + assert_eq!(m1, FlagA); + // intersection + m1 &= e1; + assert_eq!(m1, FlagA); + // set difference + m1 -= m1; + assert_eq!(m1, Flags::empty()); + // toggle + m1 ^= e1; + assert_eq!(m1, e1); + } + + #[test] + fn test_extend() { + let mut flags; + + flags = Flags::empty(); + flags.extend([].iter().cloned()); + assert_eq!(flags, Flags::empty()); + + flags = Flags::empty(); + flags.extend([FlagA, FlagB].iter().cloned()); + assert_eq!(flags, FlagA | FlagB); + + flags = FlagA; + flags.extend([FlagA, FlagB].iter().cloned()); + assert_eq!(flags, FlagA | FlagB); + + flags = FlagB; + flags.extend([FlagA, FlagABC].iter().cloned()); + assert_eq!(flags, FlagABC); + } + + #[test] + fn test_from_iterator() { + assert_eq!([].iter().cloned().collect::(), Flags::empty()); + assert_eq!([FlagA, FlagB].iter().cloned().collect::(), FlagA | FlagB); + assert_eq!([FlagA, FlagABC].iter().cloned().collect::(), FlagABC); + } + + #[test] + fn test_lt() { + let mut a = Flags::empty(); + let mut b = Flags::empty(); + + assert!(!(a < b) && !(b < a)); + b = FlagB; + assert!(a < b); + a = FlagC; + assert!(!(a < b) && b < a); + b = FlagC | FlagB; + assert!(a < b); + } + + #[test] + fn test_ord() { + let mut a = Flags::empty(); + let mut b = Flags::empty(); + + assert!(a <= b && a >= b); + a = FlagA; + assert!(a > b && a >= b); + assert!(b < a && b <= a); + b = FlagB; + assert!(b > a && b >= a); + assert!(a < b && a <= b); + } + + fn hash(t: &T) -> u64 { + let mut s = SipHasher::new_with_keys(0, 0); + t.hash(&mut s); + s.finish() + } + + #[test] + fn test_hash() { + let mut x = Flags::empty(); + let mut y = Flags::empty(); + assert_eq!(hash(&x), hash(&y)); + x = Flags::all(); + y = FlagABC; + assert_eq!(hash(&x), hash(&y)); + } + + #[test] + fn test_debug() { + assert_eq!(format!("{:?}", FlagA | FlagB), "FlagA | FlagB"); + assert_eq!(format!("{:?}", FlagABC), "FlagA | FlagB | FlagC | FlagABC"); + } + + mod submodule { + bitflags! { + pub flags PublicFlags: i8 { + const FlagX = 0, + } + } + bitflags! { + flags PrivateFlags: i8 { + const FlagY = 0, + } + } + + #[test] + fn test_private() { + let _ = FlagY; + } + } + + #[test] + fn test_public() { + let _ = submodule::FlagX; + } + + mod t1 { + mod foo { + pub type Bar = i32; + } + + bitflags! { + /// baz + flags Flags: foo::Bar { + const A = 0b00000001, + #[cfg(foo)] + const B = 0b00000010, + #[cfg(foo)] + const C = 0b00000010, + } + } + } +} diff --git a/rust/third_party/bitflags/tests/external.rs b/rust/third_party/bitflags/tests/external.rs new file mode 100644 index 0000000..0f0c7f6 --- /dev/null +++ b/rust/third_party/bitflags/tests/external.rs @@ -0,0 +1,21 @@ +#![allow(dead_code)] + +#[macro_use] +extern crate bitflags; + +bitflags! { + /// baz + flags Flags: u32 { + const A = 0b00000001, + #[doc = "bar"] + const B = 0b00000010, + const C = 0b00000100, + #[doc = "foo"] + const ABC = A.bits | B.bits | C.bits, + } +} + +#[test] +fn smoke() { + assert_eq!(ABC, A | B | C); +} diff --git a/rust/third_party/bitflags/tests/external_no_std.rs b/rust/third_party/bitflags/tests/external_no_std.rs new file mode 100644 index 0000000..46526fd --- /dev/null +++ b/rust/third_party/bitflags/tests/external_no_std.rs @@ -0,0 +1,22 @@ +#![allow(dead_code)] +#![no_std] + +#[macro_use] +extern crate bitflags; + +bitflags! { + /// baz + flags Flags: u32 { + const A = 0b00000001, + #[doc = "bar"] + const B = 0b00000010, + const C = 0b00000100, + #[doc = "foo"] + const ABC = A.bits | B.bits | C.bits, + } +} + +#[test] +fn smoke() { + assert_eq!(ABC, A | B | C); +}