// 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. macro_rules! bitflags { ($(#[$attr:meta])* 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 };)+ 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 { $BitFlags { bits: $($value)|+ } } /// 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) -> ::std::option::Option<$BitFlags> { if (bits & !$BitFlags::all().bits()) != 0 { ::std::option::Option::None } else { ::std::option::Option::Some($BitFlags { bits: bits }) } } /// 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 ::std::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 ::std::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 ::std::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 ::std::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 ::std::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() } } }; ($(#[$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),+ } } }; }