bitflags_associated_constants/
lib.rs

1// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11#![feature(associated_consts)]
12
13//! A typesafe bitmask flag generator.
14
15#![no_std]
16
17#[cfg(test)]
18#[macro_use]
19extern crate std;
20
21// Re-export libstd/libcore using an alias so that the macros can work in no_std
22// crates while remaining compatible with normal crates.
23#[allow(private_in_public)]
24#[doc(hidden)]
25pub use core as __core;
26
27/// The `bitflags!` macro generates a `struct` that holds a set of C-style
28/// bitmask flags. It is useful for creating typesafe wrappers for C APIs.
29///
30/// The flags should only be defined for integer types, otherwise unexpected
31/// type errors may occur at compile time.
32///
33/// # Example
34///
35/// ```{.rust}
36/// #![feature(associated_consts)]
37///
38/// #[macro_use]
39/// extern crate bitflags;
40///
41/// bitflags! {
42///     flags Flags: u32 {
43///         const FLAG_A       = 0b00000001,
44///         const FLAG_B       = 0b00000010,
45///         const FLAG_C       = 0b00000100,
46///         const FLAG_ABC     = Flags::FLAG_A.bits
47///                            | Flags::FLAG_B.bits
48///                            | Flags::FLAG_C.bits,
49///     }
50/// }
51///
52/// fn main() {
53///     let e1 = Flags::FLAG_A | Flags::FLAG_C;
54///     let e2 = Flags::FLAG_B | Flags::FLAG_C;
55///     assert_eq!((e1 | e2), Flags::FLAG_ABC);   // union
56///     assert_eq!((e1 & e2), Flags::FLAG_C);     // intersection
57///     assert_eq!((e1 - e2), Flags::FLAG_A);     // set difference
58///     assert_eq!(!e2, Flags::FLAG_A);           // set complement
59/// }
60/// ```
61///
62/// The generated `struct`s can also be extended with type and trait
63/// implementations:
64///
65/// ```{.rust}
66/// #![feature(associated_consts)]
67///
68/// #[macro_use]
69/// extern crate bitflags;
70///
71/// use std::fmt;
72///
73/// bitflags! {
74///     flags Flags: u32 {
75///         const FLAG_A   = 0b00000001,
76///         const FLAG_B   = 0b00000010,
77///     }
78/// }
79///
80/// impl Flags {
81///     pub fn clear(&mut self) {
82///         self.bits = 0;  // The `bits` field can be accessed from within the
83///                         // same module where the `bitflags!` macro was invoked.
84///     }
85/// }
86///
87/// impl fmt::Display for Flags {
88///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
89///         write!(f, "hi!")
90///     }
91/// }
92///
93/// fn main() {
94///     let mut flags = Flags::FLAG_A | Flags::FLAG_B;
95///     flags.clear();
96///     assert!(flags.is_empty());
97///     assert_eq!(format!("{}", flags), "hi!");
98///     assert_eq!(format!("{:?}", Flags::FLAG_A | Flags::FLAG_B), "FLAG_A | FLAG_B");
99///     assert_eq!(format!("{:?}", Flags::FLAG_B), "FLAG_B");
100/// }
101/// ```
102///
103/// # Visibility
104///
105/// The generated struct and its associated flag constants are not exported
106/// out of the current module by default. A definition can be exported out of
107/// the current module by adding `pub` before `flags`:
108///
109/// ```{.rust},ignore
110/// #![feature(associated_consts)]
111///
112/// #[macro_use]
113/// extern crate bitflags;
114///
115/// mod example {
116///     bitflags! {
117///         pub flags Flags1: u32 {
118///             const FLAG_A   = 0b00000001,
119///         }
120///     }
121///     bitflags! {
122///         flags Flags2: u32 {
123///             const FLAG_B   = 0b00000010,
124///         }
125///     }
126/// }
127///
128/// fn main() {
129///     let flag1 = example::Flags1::FLAG_A;
130///     let flag2 = example::Flags2::FLAG_B; //~ ERROR associated const `FLAG_B` is inaccessible
131/// }
132/// ```
133///
134/// # Attributes
135///
136/// Attributes can be attached to the generated `struct` by placing them
137/// before the `flags` keyword.
138///
139/// # Trait implementations
140///
141/// The `Copy`, `Clone`, `PartialEq`, `Eq`, `PartialOrd`, `Ord` and `Hash`
142/// traits automatically derived for the `struct` using the `derive` attribute.
143/// Additional traits can be derived by providing an explicit `derive`
144/// attribute on `flags`.
145///
146/// The `Extend` and `FromIterator` traits are implemented for the `struct`,
147/// too: `Extend` adds the union of the instances of the `struct` iterated over,
148/// while `FromIterator` calculates the union.
149///
150/// The `Debug` trait is also implemented by displaying the bits value of the
151/// internal struct.
152///
153/// ## Operators
154///
155/// The following operator traits are implemented for the generated `struct`:
156///
157/// - `BitOr` and `BitOrAssign`: union
158/// - `BitAnd` and `BitAndAssign`: intersection
159/// - `BitXor` and `BitXorAssign`: toggle
160/// - `Sub` and `SubAssign`: set difference
161/// - `Not`: set complement
162///
163/// As long as the assignment operators are unstable rust feature they are only
164/// available with the crate feature `assignment_ops` enabled.
165///
166/// # Methods
167///
168/// The following methods are defined for the generated `struct`:
169///
170/// - `empty`: an empty set of flags
171/// - `all`: the set of all flags
172/// - `bits`: the raw value of the flags currently stored
173/// - `from_bits`: convert from underlying bit representation, unless that
174///                representation contains bits that do not correspond to a flag
175/// - `from_bits_truncate`: convert from underlying bit representation, dropping
176///                         any bits that do not correspond to flags
177/// - `is_empty`: `true` if no flags are currently stored
178/// - `is_all`: `true` if all flags are currently set
179/// - `intersects`: `true` if there are flags common to both `self` and `other`
180/// - `contains`: `true` all of the flags in `other` are contained within `self`
181/// - `insert`: inserts the specified flags in-place
182/// - `remove`: removes the specified flags in-place
183/// - `toggle`: the specified flags will be inserted if not present, and removed
184///             if they are.
185#[macro_export]
186macro_rules! bitflags {
187    ($(#[$attr:meta])* pub flags $BitFlags:ident: $T:ty {
188        $($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+
189    }) => {
190        #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
191        $(#[$attr])*
192        pub struct $BitFlags {
193            bits: $T,
194        }
195
196        bitflags! {
197            @_impl flags $BitFlags: $T {
198                $($(#[$Flag_attr])* const $Flag = $value),+
199            }
200        }
201    };
202    ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
203        $($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+
204    }) => {
205        #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
206        $(#[$attr])*
207        struct $BitFlags {
208            bits: $T,
209        }
210
211        bitflags! {
212            @_impl flags $BitFlags: $T {
213                $($(#[$Flag_attr])* const $Flag = $value),+
214            }
215        }
216    };
217    (@_impl flags $BitFlags:ident: $T:ty {
218        $($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+
219    }) => {
220        impl $crate::__core::fmt::Debug for $BitFlags {
221            #[allow(unused_assignments)]
222            fn fmt(&self, f: &mut $crate::__core::fmt::Formatter) -> $crate::__core::fmt::Result {
223                // This convoluted approach is to handle #[cfg]-based flag
224                // omission correctly. Some of the $Flag variants may not be
225                // defined in this module so we create a trait which defines
226                // *all* flags to the value of 0. Afterwards we define a struct
227                // which overrides the definitions in the trait for all defined
228                // variants, leaving only the undefined ones with the bit value
229                // of 0.
230                trait DummyTrait {
231                    // Now we define the "undefined" versions of the flags.
232                    // This way, all the names exist, even if some are #[cfg]ed
233                    // out.
234                    $(const $Flag: $BitFlags = $BitFlags { bits: 0 };)+
235                };
236                struct DummyStruct;
237                impl DummyTrait for DummyStruct {
238                    // Then we override the "undefined" flags with flags that
239                    // have their proper value. Flags that are #[cfg]ed out
240                    // retain the default value of 0 defined by the trait.
241                    $($(#[$Flag_attr])* const $Flag: $BitFlags = $BitFlags { bits: $value };)+
242                };
243                let mut first = true;
244                $(
245                    // $Flag.bits == 0 means that $Flag doesn't exist
246                    if DummyStruct::$Flag.bits != 0 && self.contains(DummyStruct::$Flag) {
247                        if !first {
248                            try!(f.write_str(" | "));
249                        }
250                        first = false;
251                        try!(f.write_str(stringify!($Flag)));
252                    }
253                )+
254                Ok(())
255            }
256        }
257
258        #[allow(dead_code)]
259        impl $BitFlags {
260            $($(#[$Flag_attr])* pub const $Flag: $BitFlags = $BitFlags { bits: $value };)+
261
262            /// Returns an empty set of flags.
263            #[inline]
264            pub const fn empty() -> $BitFlags {
265                $BitFlags { bits: 0 }
266            }
267
268            /// Returns the set containing all flags.
269            #[inline]
270            pub fn all() -> $BitFlags {
271                // See above for why this approach is taken.
272                trait DummyTrait {
273                    $(const $Flag: $BitFlags = $BitFlags { bits: 0 };)+
274                };
275                struct DummyStruct;
276                impl DummyTrait for DummyStruct {
277                    $($(#[$Flag_attr])* const $Flag: $BitFlags = $BitFlags { bits: $value };)+
278                };
279                $BitFlags { bits: $(DummyStruct::$Flag.bits)|+ }
280            }
281
282            /// Returns the raw value of the flags currently stored.
283            #[inline]
284            pub const fn bits(&self) -> $T {
285                self.bits
286            }
287
288            /// Convert from underlying bit representation, unless that
289            /// representation contains bits that do not correspond to a flag.
290            #[inline]
291            pub fn from_bits(bits: $T) -> $crate::__core::option::Option<$BitFlags> {
292                if (bits & !$BitFlags::all().bits()) == 0 {
293                    $crate::__core::option::Option::Some($BitFlags { bits: bits })
294                } else {
295                    $crate::__core::option::Option::None
296                }
297            }
298
299            /// Convert from underlying bit representation, dropping any bits
300            /// that do not correspond to flags.
301            #[inline]
302            pub fn from_bits_truncate(bits: $T) -> $BitFlags {
303                $BitFlags { bits: bits } & $BitFlags::all()
304            }
305
306            /// Returns `true` if no flags are currently stored.
307            #[inline]
308            pub fn is_empty(&self) -> bool {
309                *self == $BitFlags::empty()
310            }
311
312            /// Returns `true` if all flags are currently set.
313            #[inline]
314            pub fn is_all(&self) -> bool {
315                *self == $BitFlags::all()
316            }
317
318            /// Returns `true` if there are flags common to both `self` and `other`.
319            #[inline]
320            pub fn intersects(&self, other: $BitFlags) -> bool {
321                !(*self & other).is_empty()
322            }
323
324            /// Returns `true` all of the flags in `other` are contained within `self`.
325            #[inline]
326            pub fn contains(&self, other: $BitFlags) -> bool {
327                (*self & other) == other
328            }
329
330            /// Inserts the specified flags in-place.
331            #[inline]
332            pub fn insert(&mut self, other: $BitFlags) {
333                self.bits |= other.bits;
334            }
335
336            /// Removes the specified flags in-place.
337            #[inline]
338            pub fn remove(&mut self, other: $BitFlags) {
339                self.bits &= !other.bits;
340            }
341
342            /// Toggles the specified flags in-place.
343            #[inline]
344            pub fn toggle(&mut self, other: $BitFlags) {
345                self.bits ^= other.bits;
346            }
347        }
348
349        impl $crate::__core::ops::BitOr for $BitFlags {
350            type Output = $BitFlags;
351
352            /// Returns the union of the two sets of flags.
353            #[inline]
354            fn bitor(self, other: $BitFlags) -> $BitFlags {
355                $BitFlags { bits: self.bits | other.bits }
356            }
357        }
358
359        impl $crate::__core::ops::BitOrAssign for $BitFlags {
360
361            /// Adds the set of flags.
362            #[inline]
363            fn bitor_assign(&mut self, other: $BitFlags) {
364                self.bits |= other.bits;
365            }
366        }
367
368        impl $crate::__core::ops::BitXor for $BitFlags {
369            type Output = $BitFlags;
370
371            /// Returns the left flags, but with all the right flags toggled.
372            #[inline]
373            fn bitxor(self, other: $BitFlags) -> $BitFlags {
374                $BitFlags { bits: self.bits ^ other.bits }
375            }
376        }
377
378        impl $crate::__core::ops::BitXorAssign for $BitFlags {
379
380            /// Toggles the set of flags.
381            #[inline]
382            fn bitxor_assign(&mut self, other: $BitFlags) {
383                self.bits ^= other.bits;
384            }
385        }
386
387        impl $crate::__core::ops::BitAnd for $BitFlags {
388            type Output = $BitFlags;
389
390            /// Returns the intersection between the two sets of flags.
391            #[inline]
392            fn bitand(self, other: $BitFlags) -> $BitFlags {
393                $BitFlags { bits: self.bits & other.bits }
394            }
395        }
396
397        impl $crate::__core::ops::BitAndAssign for $BitFlags {
398
399            /// Disables all flags disabled in the set.
400            #[inline]
401            fn bitand_assign(&mut self, other: $BitFlags) {
402                self.bits &= other.bits;
403            }
404        }
405
406        impl $crate::__core::ops::Sub for $BitFlags {
407            type Output = $BitFlags;
408
409            /// Returns the set difference of the two sets of flags.
410            #[inline]
411            fn sub(self, other: $BitFlags) -> $BitFlags {
412                $BitFlags { bits: self.bits & !other.bits }
413            }
414        }
415
416        impl $crate::__core::ops::SubAssign for $BitFlags {
417
418            /// Disables all flags enabled in the set.
419            #[inline]
420            fn sub_assign(&mut self, other: $BitFlags) {
421                self.bits &= !other.bits;
422            }
423        }
424
425        impl $crate::__core::ops::Not for $BitFlags {
426            type Output = $BitFlags;
427
428            /// Returns the complement of this set of flags.
429            #[inline]
430            fn not(self) -> $BitFlags {
431                $BitFlags { bits: !self.bits } & $BitFlags::all()
432            }
433        }
434
435        impl $crate::__core::iter::Extend<$BitFlags> for $BitFlags {
436            fn extend<T: $crate::__core::iter::IntoIterator<Item=$BitFlags>>(&mut self, iterator: T) {
437                for item in iterator {
438                    self.insert(item)
439                }
440            }
441        }
442
443        impl $crate::__core::iter::FromIterator<$BitFlags> for $BitFlags {
444            fn from_iter<T: $crate::__core::iter::IntoIterator<Item=$BitFlags>>(iterator: T) -> $BitFlags {
445                let mut result = Self::empty();
446                result.extend(iterator);
447                result
448            }
449        }
450    };
451    ($(#[$attr:meta])* pub flags $BitFlags:ident: $T:ty {
452        $($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+,
453    }) => {
454        bitflags! {
455            $(#[$attr])*
456            pub flags $BitFlags: $T {
457                $($(#[$Flag_attr])* const $Flag = $value),+
458            }
459        }
460    };
461    ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
462        $($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+,
463    }) => {
464        bitflags! {
465            $(#[$attr])*
466            flags $BitFlags: $T {
467                $($(#[$Flag_attr])* const $Flag = $value),+
468            }
469        }
470    };
471}
472
473#[cfg(test)]
474mod tests {
475    use std::hash::{SipHasher, Hash, Hasher};
476
477    bitflags! {
478        #[doc = "> The first principle is that you must not fool yourself — and"]
479        #[doc = "> you are the easiest person to fool."]
480        #[doc = "> "]
481        #[doc = "> - Richard Feynman"]
482        flags Flags: u32 {
483            const FLAG_A       = 0b00000001,
484            #[doc = "<pcwalton> macros are way better at generating code than trans is"]
485            const FLAG_B       = 0b00000010,
486            const FLAG_C       = 0b00000100,
487            #[doc = "* cmr bed"]
488            #[doc = "* strcat table"]
489            #[doc = "<strcat> wait what?"]
490            const FLAG_ABC     = Flags::FLAG_A.bits
491                               | Flags::FLAG_B.bits
492                               | Flags::FLAG_C.bits,
493        }
494    }
495
496    bitflags! {
497        flags CfgFlags: u32 {
498            #[cfg(windows)]
499            const CFG_A = 0b01,
500            #[cfg(unix)]
501            const CFG_B = 0b01,
502            #[cfg(windows)]
503            const CFG_C = CFG_A.bits | 0b10,
504        }
505    }
506
507    bitflags! {
508        flags AnotherSetOfFlags: i8 {
509            const ANOTHER_FLAG = -1_i8,
510        }
511    }
512
513    #[test]
514    fn test_bits() {
515        assert_eq!(Flags::empty().bits(), 0b00000000);
516        assert_eq!(Flags::FLAG_A.bits(), 0b00000001);
517        assert_eq!(Flags::FLAG_ABC.bits(), 0b00000111);
518
519        assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00);
520        assert_eq!(AnotherSetOfFlags::ANOTHER_FLAG.bits(), !0_i8);
521    }
522
523    #[test]
524    fn test_from_bits() {
525        assert_eq!(Flags::from_bits(0), Some(Flags::empty()));
526        assert_eq!(Flags::from_bits(0b1), Some(Flags::FLAG_A));
527        assert_eq!(Flags::from_bits(0b10), Some(Flags::FLAG_B));
528        assert_eq!(Flags::from_bits(0b11), Some(Flags::FLAG_A | Flags::FLAG_B));
529        assert_eq!(Flags::from_bits(0b1000), None);
530
531        assert_eq!(AnotherSetOfFlags::from_bits(!0_i8), Some(AnotherSetOfFlags::ANOTHER_FLAG));
532    }
533
534    #[test]
535    fn test_from_bits_truncate() {
536        assert_eq!(Flags::from_bits_truncate(0), Flags::empty());
537        assert_eq!(Flags::from_bits_truncate(0b1), Flags::FLAG_A);
538        assert_eq!(Flags::from_bits_truncate(0b10), Flags::FLAG_B);
539        assert_eq!(Flags::from_bits_truncate(0b11), (Flags::FLAG_A | Flags::FLAG_B));
540        assert_eq!(Flags::from_bits_truncate(0b1000), Flags::empty());
541        assert_eq!(Flags::from_bits_truncate(0b1001), Flags::FLAG_A);
542
543        assert_eq!(AnotherSetOfFlags::from_bits_truncate(0_i8), AnotherSetOfFlags::empty());
544    }
545
546    #[test]
547    fn test_is_empty() {
548        assert!(Flags::empty().is_empty());
549        assert!(!Flags::FLAG_A.is_empty());
550        assert!(!Flags::FLAG_ABC.is_empty());
551
552        assert!(!AnotherSetOfFlags::ANOTHER_FLAG.is_empty());
553    }
554
555    #[test]
556    fn test_is_all() {
557        assert!(Flags::all().is_all());
558        assert!(!Flags::FLAG_A.is_all());
559        assert!(Flags::FLAG_ABC.is_all());
560
561        assert!(AnotherSetOfFlags::ANOTHER_FLAG.is_all());
562    }
563
564    #[test]
565    fn test_two_empties_do_not_intersect() {
566        let e1 = Flags::empty();
567        let e2 = Flags::empty();
568        assert!(!e1.intersects(e2));
569
570        assert!(AnotherSetOfFlags::ANOTHER_FLAG.intersects(AnotherSetOfFlags::ANOTHER_FLAG));
571    }
572
573    #[test]
574    fn test_empty_does_not_intersect_with_full() {
575        let e1 = Flags::empty();
576        let e2 = Flags::FLAG_ABC;
577        assert!(!e1.intersects(e2));
578    }
579
580    #[test]
581    fn test_disjoint_intersects() {
582        let e1 = Flags::FLAG_A;
583        let e2 = Flags::FLAG_B;
584        assert!(!e1.intersects(e2));
585    }
586
587    #[test]
588    fn test_overlapping_intersects() {
589        let e1 = Flags::FLAG_A;
590        let e2 = Flags::FLAG_A | Flags::FLAG_B;
591        assert!(e1.intersects(e2));
592    }
593
594    #[test]
595    fn test_contains() {
596        let e1 = Flags::FLAG_A;
597        let e2 = Flags::FLAG_A | Flags::FLAG_B;
598        assert!(!e1.contains(e2));
599        assert!(e2.contains(e1));
600        assert!(Flags::FLAG_ABC.contains(e2));
601
602        assert!(AnotherSetOfFlags::ANOTHER_FLAG.contains(AnotherSetOfFlags::ANOTHER_FLAG));
603    }
604
605    #[test]
606    fn test_insert() {
607        let mut e1 = Flags::FLAG_A;
608        let e2 = Flags::FLAG_A | Flags::FLAG_B;
609        e1.insert(e2);
610        assert_eq!(e1, e2);
611
612        let mut e3 = AnotherSetOfFlags::empty();
613        e3.insert(AnotherSetOfFlags::ANOTHER_FLAG);
614        assert_eq!(e3, AnotherSetOfFlags::ANOTHER_FLAG);
615    }
616
617    #[test]
618    fn test_remove() {
619        let mut e1 = Flags::FLAG_A | Flags::FLAG_B;
620        let e2 = Flags::FLAG_A | Flags::FLAG_C;
621        e1.remove(e2);
622        assert_eq!(e1, Flags::FLAG_B);
623
624        let mut e3 = AnotherSetOfFlags::ANOTHER_FLAG;
625        e3.remove(AnotherSetOfFlags::ANOTHER_FLAG);
626        assert_eq!(e3, AnotherSetOfFlags::empty());
627    }
628
629    #[test]
630    fn test_operators() {
631        let e1 = Flags::FLAG_A | Flags::FLAG_C;
632        let e2 = Flags::FLAG_B | Flags::FLAG_C;
633        assert_eq!((e1 | e2), Flags::FLAG_ABC);     // union
634        assert_eq!((e1 & e2), Flags::FLAG_C);       // intersection
635        assert_eq!((e1 - e2), Flags::FLAG_A);       // set difference
636        assert_eq!(!e2, Flags::FLAG_A);             // set complement
637        assert_eq!(e1 ^ e2, Flags::FLAG_A | Flags::FLAG_B); // toggle
638        let mut e3 = e1;
639        e3.toggle(e2);
640        assert_eq!(e3, Flags::FLAG_A | Flags::FLAG_B);
641
642        let mut m4 = AnotherSetOfFlags::empty();
643        m4.toggle(AnotherSetOfFlags::empty());
644        assert_eq!(m4, AnotherSetOfFlags::empty());
645    }
646
647    #[test]
648    fn test_assignment_operators() {
649        let mut m1 = Flags::empty();
650        let e1 = Flags::FLAG_A | Flags::FLAG_C;
651        // union
652        m1 |= Flags::FLAG_A;
653        assert_eq!(m1, Flags::FLAG_A);
654        // intersection
655        m1 &= e1;
656        assert_eq!(m1, Flags::FLAG_A);
657        // set difference
658        m1 -= m1;
659        assert_eq!(m1, Flags::empty());
660        // toggle
661        m1 ^= e1;
662        assert_eq!(m1, e1);
663    }
664
665    #[test]
666    fn test_extend() {
667        let mut flags;
668
669        flags = Flags::empty();
670        flags.extend([].iter().cloned());
671        assert_eq!(flags, Flags::empty());
672
673        flags = Flags::empty();
674        flags.extend([Flags::FLAG_A, Flags::FLAG_B].iter().cloned());
675        assert_eq!(flags, Flags::FLAG_A | Flags::FLAG_B);
676
677        flags = Flags::FLAG_A;
678        flags.extend([Flags::FLAG_A, Flags::FLAG_B].iter().cloned());
679        assert_eq!(flags, Flags::FLAG_A | Flags::FLAG_B);
680
681        flags = Flags::FLAG_B;
682        flags.extend([Flags::FLAG_A, Flags::FLAG_ABC].iter().cloned());
683        assert_eq!(flags, Flags::FLAG_ABC);
684    }
685
686    #[test]
687    fn test_from_iterator() {
688        assert_eq!([].iter().cloned().collect::<Flags>(), Flags::empty());
689        assert_eq!([Flags::FLAG_A, Flags::FLAG_B].iter().cloned().collect::<Flags>(),
690                   Flags::FLAG_A | Flags::FLAG_B);
691        assert_eq!([Flags::FLAG_A, Flags::FLAG_ABC].iter().cloned().collect::<Flags>(),
692                   Flags::FLAG_ABC);
693    }
694
695    #[test]
696    fn test_lt() {
697        let mut a = Flags::empty();
698        let mut b = Flags::empty();
699
700        assert!(!(a < b) && !(b < a));
701        b = Flags::FLAG_B;
702        assert!(a < b);
703        a = Flags::FLAG_C;
704        assert!(!(a < b) && b < a);
705        b = Flags::FLAG_C | Flags::FLAG_B;
706        assert!(a < b);
707    }
708
709    #[test]
710    fn test_ord() {
711        let mut a = Flags::empty();
712        let mut b = Flags::empty();
713
714        assert!(a <= b && a >= b);
715        a = Flags::FLAG_A;
716        assert!(a > b && a >= b);
717        assert!(b < a && b <= a);
718        b = Flags::FLAG_B;
719        assert!(b > a && b >= a);
720        assert!(a < b && a <= b);
721    }
722
723    fn hash<T: Hash>(t: &T) -> u64 {
724        let mut s = SipHasher::new_with_keys(0, 0);
725        t.hash(&mut s);
726        s.finish()
727    }
728
729    #[test]
730    fn test_hash() {
731        let mut x = Flags::empty();
732        let mut y = Flags::empty();
733        assert_eq!(hash(&x), hash(&y));
734        x = Flags::all();
735        y = Flags::FLAG_ABC;
736        assert_eq!(hash(&x), hash(&y));
737    }
738
739    #[test]
740    fn test_debug() {
741        assert_eq!(format!("{:?}", Flags::FLAG_A | Flags::FLAG_B),
742                   "FLAG_A | FLAG_B");
743        assert_eq!(format!("{:?}", Flags::FLAG_ABC),
744                   "FLAG_A | FLAG_B | FLAG_C | FLAG_ABC");
745    }
746
747    mod submodule {
748        bitflags! {
749            pub flags PublicFlags: i8 {
750                const FLAG_X = 0,
751            }
752        }
753        bitflags! {
754            flags PrivateFlags: i8 {
755                const FLAG_Y = 0,
756            }
757        }
758
759        #[test]
760        fn test_private() {
761            let _ = PrivateFlags::FLAG_Y;
762        }
763    }
764
765    #[test]
766    fn test_public() {
767        let _ = submodule::PublicFlags::FLAG_X;
768    }
769}