1#![allow(non_snake_case)]
2use vstd::arithmetic::power::*;
39use vstd::arithmetic::power2::*;
40use vstd::bits::*;
41use vstd::prelude::*;
42
43pub use paste;
44
45#[doc(hidden)]
46#[macro_export]
47macro_rules! __bitflags_cfg_expr {
48 (() $base:expr) => {
49 $base
50 };
51 ((#[cfg($($cfg:tt)*)] $($rest:tt)*) $base:expr) => {
52 (cfg!($($cfg)*) && $crate::__bitflags_cfg_expr!(($($rest)*) $base))
53 };
54 ((#[$_other:meta] $($rest:tt)*) $base:expr) => {
55 $crate::__bitflags_cfg_expr!(($($rest)*) $base)
56 };
57}
58
59#[doc(hidden)]
60#[macro_export]
61macro_rules! __bitflags_cfg_guarded_expr {
62 (() $e:expr) => {
63 $e
64 };
65 ((#[cfg($($cfg:tt)*)] $($rest:tt)*) $e:expr) => {{
66 #[cfg($($cfg)*)]
67 {
68 $crate::__bitflags_cfg_guarded_expr!(($($rest)*) $e)
69 }
70 #[cfg(not($($cfg)*))]
71 {
72 true
73 }
74 }};
75 ((#[$_other:meta] $($rest:tt)*) $e:expr) => {
76 $crate::__bitflags_cfg_guarded_expr!(($($rest)*) $e)
77 };
78}
79
80#[doc(hidden)]
81#[macro_export]
82macro_rules! __bitflags_cfg_guarded_stmt {
83 (() $stmt:stmt) => {
84 $stmt
85 };
86 ((#[cfg($($cfg:tt)*)] $($rest:tt)*) $stmt:stmt) => {
87 #[cfg($($cfg)*)]
88 {
89 $crate::__bitflags_cfg_guarded_stmt!(($($rest)*) $stmt)
90 }
91 };
92 ((#[$_other:meta] $($rest:tt)*) $stmt:stmt) => {
93 $crate::__bitflags_cfg_guarded_stmt!(($($rest)*) $stmt)
94 };
95}
96
97#[doc(hidden)]
98#[macro_export]
99macro_rules! __bitflags_flag {
100 (
101 {
102 name: _,
103 named: { $($named:tt)* },
104 unnamed: { $($unnamed:tt)* },
105 }
106 ) => {
107 $($unnamed)*
108 };
109 (
110 {
111 name: $Flag:ident,
112 named: { $($named:tt)* },
113 unnamed: { $($unnamed:tt)* },
114 }
115 ) => {
116 $($named)*
117 };
118}
119
120#[verusfmt::skip]
140#[rustfmt::skip]
141#[macro_export]
142macro_rules! bitflags {
143 (
144 $(#[$outer:meta])*
145 $vis:vis struct $name:ident: $T:ty {
146 $(
147 $(#[$inner:ident $($args:tt)*])*
148 const $Flag:ident = $value:expr;
149 )*
150 }
151 ) => {
152 $crate::paste::paste! {
153 verus! {
154 $(#[$outer])*
155 #[repr(transparent)]
156 $vis struct $name {
157 bits: $T,
159 }
160
161 impl ::core::clone::Clone for $name {
162 #[inline]
163 fn clone(&self) -> (r: Self)
164 returns self
165 {
166 Self {
167 bits: self.bits,
168 }
169 }
170 }
171
172 impl ::core::marker::Copy for $name {}
173
174 impl ::core::default::Default for $name {
175 #[inline]
176 fn default() -> (r: Self)
177 ensures
178 r.bits() == 0,
179 r.flags_spec() == Self::flags_from_bits(0),
180 returns
181 Self::empty(),
182 {
183 Self::empty()
184 }
185 }
186
187 impl ::vstd::view::View for $name {
188 type V = ::vstd::set::Set<[< __ghost $name >]>;
189
190 open spec fn view(&self) -> Self::V {
191 Self::flags_from_bits(self.bits())
192 }
193 }
194
195 #[allow(non_camel_case_types)]
197 $vis ghost enum [< __ghost $name >] {
198 $(
199 [< __ghost $Flag >],
200 )*
201 }
202
203 impl [< __ghost $name >] {
204 $vis open spec fn enabled(self) -> bool {
205 match self {
206 $(
207 [< __ghost $name >]::[< __ghost $Flag >] => $crate::__bitflags_cfg_expr! {
208 ($(#[$inner $($args)*])*) true
209 },
210 )*
211 }
212 }
213
214 $vis open spec fn bit(self) -> $T {
215 match self {
216 $(
217 [< __ghost $name >]::[< __ghost $Flag >] => (($value) as $T),
218 )*
219 }
220 }
221 }
222
223 impl ::vstd::set_lib::FiniteFull for [< __ghost $name >] {
224 proof fn full_properties() {
225 let s = ::vstd::iset::ISet::empty()
226 $(.insert([< __ghost $name >]::[< __ghost $Flag >]))*;
227 assert(::vstd::iset::ISet::new(|a: [< __ghost $name >]| true) =~= s);
228 }
229 }
230
231 impl $name {
232 $vis open spec fn flags_spec(&self) -> ::vstd::set::Set<[< __ghost $name >]> {
233 Self::flags_from_bits(self.bits())
234 }
235
236 $vis open spec fn flags_from_bits(bits: $T) -> ::vstd::set::Set<[< __ghost $name >]> {
237 ::vstd::set::Set::< [< __ghost $name >] >::from_finite_type(|flag: [< __ghost $name >]| {
238 flag.enabled() && (bits & flag.bit()) == flag.bit()
239 })
240 }
241
242 closed spec fn from_bits_unchecked_spec(bits: $T) -> Self {
243 Self { bits }
244 }
245
246 #[verifier::when_used_as_spec(from_bits_unchecked_spec)]
247 const fn from_bits_unchecked(bits: $T) -> (r: Self)
248 ensures
249 r.bits() == bits,
250 r.flags_spec() == Self::flags_from_bits(bits),
251 returns
252 Self::from_bits_unchecked(bits),
253 {
254 Self { bits }
255 }
256
257 $(
258 $vis closed spec fn [< $Flag _spec >]() -> Self {
259 Self::from_bits_unchecked_spec($value as $T)
260 }
261
262 $(#[$inner $($args)*])*
263 #[verifier::when_used_as_spec([< $Flag _spec >])]
264 $vis const fn $Flag() -> (r: Self)
265 ensures
266 r.bits() == ($value),
267 r.flags_spec() == Self::flags_from_bits(($value) as $T),
268 returns Self::[< $Flag _spec >](),
269 {
270 Self::from_bits_unchecked($value)
271 }
272 )*
273
274 closed spec fn declared_bits_spec() -> $T {
276 (0 as $T) $(| (
277 if $crate::__bitflags_cfg_expr! { ($(#[$inner $($args)*])*) true } {
278 (($value) as $T)
279 } else {
280 0 as $T
281 }
282 ))*
283 }
284
285 $vis proof fn lemma_all_constant()
287 ensures
288 Self::all().bits() == Self::all_spec().bits_spec(),
289 Self::all_spec().bits_spec() == (0 as $T) $(| (
290 if $crate::__bitflags_cfg_expr! { ($(#[$inner $($args)*])*) true } {
291 (($value) as $T)
292 } else {
293 0 as $T
294 }
295 ))*,
296 Self::all().bits() == (0 as $T) $(| (
297 if $crate::__bitflags_cfg_expr! { ($(#[$inner $($args)*])*) true } {
298 (($value) as $T)
299 } else {
300 0 as $T
301 }
302 ))*,
303 {
304 }
305
306 $vis broadcast proof fn lemma_consts()
307 ensures
308 #![trigger Self::all().bits()]
309 Self::all().bits() == (0 as $T) $(| (
310 if $crate::__bitflags_cfg_expr! { ($(#[$inner $($args)*])*) true } {
311 (($value) as $T)
312 } else {
313 0 as $T
314 }
315 ))*,
316 $(
317 #![trigger $crate::__bitflags_cfg_guarded_expr!(
318 ($(#[$inner $($args)*])*)
319 Self::$Flag().bits()
320 )]
321 $crate::__bitflags_cfg_guarded_expr!(
322 ($(#[$inner $($args)*])*)
323 Self::$Flag().bits() == (($value) as $T)
324 ),
325 )*
326 {
327 Self::lemma_all_constant();
328 }
329
330 $vis proof fn lemma_from_bits_bits(bits: $T)
331 requires
332 bits & Self::all().bits() == bits,
333 ensures
334 Self::from_bits(bits)->0.bits() == bits,
335 {
336 }
337
338 $vis proof fn lemma_eq_from_bits(left: Self, right: Self)
339 requires
340 left.bits() == right.bits(),
341 ensures
342 left == right,
343 {
344 }
345
346 $vis closed spec fn bits_spec(&self) -> $T { self.bits }
348
349 #[verifier::when_used_as_spec(bits_spec)]
350 $vis const fn bits(&self) -> $T
351 returns self.bits(),
352 {
353 self.bits
354 }
355
356 $vis closed spec fn empty_spec() -> Self {
357 Self::from_bits_unchecked_spec(0)
358 }
359
360 #[verifier::when_used_as_spec(empty_spec)]
361 $vis const fn empty() -> (r: Self)
362 ensures
363 r.bits() == 0,
364 r.flags_spec() == Self::flags_from_bits(0),
365 returns Self::empty(),
366 {
367 Self::from_bits_unchecked(0)
368 }
369
370 $vis closed spec fn all_spec() -> Self {
371 Self::from_bits_unchecked_spec(Self::declared_bits_spec())
372 }
373
374 #[verifier::when_used_as_spec(all_spec)]
375 $vis const fn all() -> (r: Self)
376 ensures
377 r == Self::all_spec(),
378 r.bits() == Self::all().bits(),
379 r.flags_spec() == Self::flags_from_bits(Self::all().bits()),
380 {
381 Self::from_bits_unchecked(
382 (0 as $T) $(| (
383 if $crate::__bitflags_cfg_expr! { ($(#[$inner $($args)*])*) true } {
384 (($value) as $T)
385 } else {
386 0 as $T
387 }
388 ))*
389 )
390 }
391
392 $vis closed spec fn known_bits_spec(&self) -> $T {
394 self.bits() & Self::all().bits()
395 }
396
397 #[verifier::when_used_as_spec(known_bits_spec)]
398 $vis const fn known_bits(&self) -> (r: $T)
399 returns self.known_bits(),
400 {
401 self.bits & Self::all().bits()
402 }
403
404 $vis closed spec fn unknown_bits_spec(&self) -> $T {
406 self.bits() & !Self::all().bits()
407 }
408
409 #[verifier::when_used_as_spec(unknown_bits_spec)]
410 $vis const fn unknown_bits(&self) -> (r: $T)
411 returns self.unknown_bits(),
412 {
413 self.bits & !Self::all().bits()
414 }
415
416 $vis open spec fn contains_unknown_bits_spec(&self) -> bool {
418 self.unknown_bits() != 0
419 }
420
421 #[verifier::when_used_as_spec(contains_unknown_bits_spec)]
422 $vis const fn contains_unknown_bits(&self) -> (r: bool)
423 returns self.contains_unknown_bits(),
424 {
425 self.unknown_bits() != 0
426 }
427
428 $vis open spec fn is_empty_spec(&self) -> bool {
430 self.bits() == 0
431 }
432
433 #[verifier::when_used_as_spec(is_empty_spec)]
434 $vis const fn is_empty(&self) -> (r: bool)
435 returns self.is_empty(),
436 {
437 self.bits == 0
438 }
439
440 $vis open spec fn is_all_spec(&self) -> bool {
442 Self::all().bits() | self.bits() == self.bits()
443 }
444
445 #[verifier::when_used_as_spec(is_all_spec)]
446 $vis const fn is_all(&self) -> (r: bool)
447 returns self.is_all(),
448 {
449 Self::all().bits() | self.bits == self.bits
450 }
451
452 $vis open spec fn contains_spec(&self, other: Self) -> bool {
454 (self.bits() & other.bits()) == other.bits()
455 }
456
457 $vis open spec fn contains_flags_spec(&self, other: Self) -> bool {
458 self.contains(other)
459 }
460
461 #[verifier::when_used_as_spec(contains_spec)]
462 $vis const fn contains(&self, other: Self) -> (r: bool)
463 returns self.contains(other),
464 {
465 (self.bits & other.bits) == other.bits
466 }
467
468 $vis open spec fn intersects_spec(&self, other: Self) -> bool {
470 (self.bits() & other.bits()) != 0
471 }
472
473 #[verifier::when_used_as_spec(intersects_spec)]
474 $vis const fn intersects(&self, other: Self) -> (r: bool)
475 returns self.intersects(other),
476 {
477 (self.bits & other.bits) != 0
478 }
479
480 $vis closed spec fn from_bits_truncate_spec(bits: $T) -> Self {
481 Self::from_bits_unchecked_spec(bits & Self::all().bits())
482 }
483
484 $vis closed spec fn from_bits_retain_spec(bits: $T) -> Self {
485 Self::from_bits_unchecked_spec(bits)
486 }
487
488 #[verifier::when_used_as_spec(from_bits_retain_spec)]
489 $vis const fn from_bits_retain(bits: $T) -> (r: Self)
490 ensures
491 r.bits() == bits,
492 r.flags_spec() == Self::flags_from_bits(bits),
493 returns Self::from_bits_retain(bits),
494 {
495 Self::from_bits_unchecked(bits)
496 }
497
498 $vis fn from_name(name: &str) -> (r: Option<Self>)
503 ensures
504 r matches Some(flags_value) ==> {
505 &&& flags_value.flags_spec()
506 == Self::flags_from_bits(flags_value.bits())
507 },
508 {
509 if name.is_empty() {
510 return ::core::option::Option::None;
511 }
512 $(
513 $crate::__bitflags_flag!({
514 name: $Flag,
515 named: {
516 $crate::__bitflags_cfg_guarded_stmt!(
517 ($(#[$inner $($args)*])*)
518 {
519 if name == ::core::stringify!($Flag) {
520 return ::core::option::Option::Some(
521 Self::$Flag()
522 );
523 }
524 }
525 );
526 },
527 unnamed: {},
528 });
529 )*
530 ::core::option::Option::None
531 }
532
533 #[verifier::when_used_as_spec(from_bits_truncate_spec)]
534 $vis const fn from_bits_truncate(bits: $T) -> (r: Self)
535 ensures
536 r.bits() == (bits & Self::all().bits()),
537 r.flags_spec() == Self::flags_from_bits(bits & Self::all().bits()),
538 returns Self::from_bits_truncate(bits),
539 {
540 Self::from_bits_unchecked(bits & Self::all().bits())
541 }
542
543 $vis closed spec fn from_bits_spec(bits: $T) -> Option<Self> {
544 if (bits & Self::all().bits()) == bits {
545 Some(Self::from_bits_unchecked_spec(bits))
546 } else {
547 None
548 }
549 }
550
551 #[verifier::when_used_as_spec(from_bits_spec)]
552 $vis const fn from_bits(bits: $T) -> (r: Option<Self>)
553 ensures
554 r is Some == ((bits & Self::all().bits()) == bits),
555 r matches Some(flags_value) ==> {
556 &&& flags_value.bits() == bits
557 &&& flags_value.flags_spec() == Self::flags_from_bits(bits)
558 },
559 returns
560 Self::from_bits(bits),
561 {
562 let truncated = Self::from_bits_truncate(bits).bits();
563 if truncated == bits {
564 Some(Self::from_bits_retain(bits))
565 } else {
566 None
567 }
568 }
569
570 $vis closed spec fn remove_spec(self, other: Self) -> Self {
571 Self::from_bits_unchecked_spec(self.bits() & !other.bits())
572 }
573
574 $vis fn insert(&mut self, other: Self)
575 ensures
576 final(self).bits() == (old(self).bits() | other.bits()),
577 final(self).flags_spec() == Self::flags_from_bits(
578 old(self).bits() | other.bits(),
579 ),
580 {
581 *self = Self::from_bits_retain(self.bits()).union(other);
582 }
583
584 $vis fn remove(&mut self, other: Self)
585 ensures
586 *final(self) == old(self).remove_spec(other),
587 final(self).bits() == (old(self).bits() & !other.bits()),
588 final(self).flags_spec() == Self::flags_from_bits(
589 old(self).bits() & !other.bits(),
590 ),
591 {
592 *self = Self::from_bits_retain(self.bits()).difference(other);
593 }
594
595 $vis fn toggle(&mut self, other: Self)
597 ensures
598 final(self).bits() == (old(self).bits() ^ other.bits()),
599 final(self).flags_spec() == Self::flags_from_bits(
600 old(self).bits() ^ other.bits(),
601 ),
602 {
603 *self = Self::from_bits_retain(self.bits()).symmetric_difference(other);
604 }
605
606 $vis fn set(&mut self, other: Self, value: bool)
608 ensures
609 value ==> final(self).bits() == (old(self).bits() | other.bits()),
610 !value ==> final(self).bits() == (old(self).bits() & !other.bits()),
611 {
612 if value {
613 self.insert(other);
614 } else {
615 self.remove(other);
616 }
617 }
618
619 $vis fn truncate(&mut self)
621 ensures
622 final(self).bits() == (old(self).bits() & Self::all().bits()),
623 final(self).flags_spec() == Self::flags_from_bits(
624 old(self).bits() & Self::all().bits(),
625 ),
626 {
627 *self = Self::from_bits_truncate(self.bits());
628 }
629
630 $vis fn clear(&mut self)
632 ensures
633 final(self).bits() == 0,
634 final(self).flags_spec() == Self::flags_from_bits(0),
635 {
636 *self = Self::empty();
637 }
638
639 $vis closed spec fn union_spec(self, other: Self) -> Self {
640 Self::from_bits_unchecked_spec(self.bits() | other.bits())
641 }
642
643 #[verifier::when_used_as_spec(union_spec)]
644 $vis const fn union(self, other: Self) -> (r: Self)
645 ensures
646 r.bits() == (self.bits() | other.bits()),
647 returns self.union(other),
648 {
649 Self::from_bits_unchecked(self.bits | other.bits)
650 }
651
652 $vis closed spec fn intersection_spec(self, other: Self) -> Self {
653 Self::from_bits_unchecked_spec(self.bits() & other.bits())
654 }
655
656 #[verifier::when_used_as_spec(intersection_spec)]
657 $vis const fn intersection(self, other: Self) -> (r: Self)
658 ensures
659 r.bits() == (self.bits() & other.bits()),
660 returns self.intersection(other),
661 {
662 Self::from_bits_unchecked(self.bits & other.bits)
663 }
664
665 $vis closed spec fn difference_spec(self, other: Self) -> Self {
666 Self::from_bits_unchecked_spec(self.bits() & !other.bits())
667 }
668
669 #[verifier::when_used_as_spec(difference_spec)]
670 $vis const fn difference(self, other: Self) -> (r: Self)
671 ensures
672 r.bits() == (self.bits() & !other.bits()),
673 returns self.difference(other),
674 {
675 Self::from_bits_unchecked(self.bits & !other.bits)
676 }
677
678 $vis closed spec fn symmetric_difference_spec(self, other: Self) -> Self {
679 Self::from_bits_unchecked_spec(self.bits() ^ other.bits())
680 }
681
682 #[verifier::when_used_as_spec(symmetric_difference_spec)]
683 $vis const fn symmetric_difference(self, other: Self) -> (r: Self)
684 ensures
685 r.bits() == (self.bits() ^ other.bits()),
686 returns self.symmetric_difference(other),
687 {
688 Self::from_bits_unchecked(self.bits ^ other.bits)
689 }
690
691 $vis closed spec fn complement_spec(self) -> Self {
692 Self::from_bits_truncate_spec(!self.bits())
693 }
694
695 #[verifier::when_used_as_spec(complement_spec)]
696 $vis const fn complement(self) -> (r: Self)
697 ensures
698 r.bits() == (!self.bits() & Self::all().bits()),
699 r.flags_spec() == Self::flags_from_bits(!self.bits() & Self::all().bits()),
700 returns self.complement(),
701 {
702 Self::from_bits_truncate(!self.bits)
703 }
704 }
705
706 impl core::cmp::PartialEq for $name {
707 fn eq(&self, other: &Self) -> (r: bool)
708 ensures r == (self.bits() == other.bits()),
709 {
710 self.bits == other.bits
711 }
712 }
713
714 impl ::vstd::std_specs::cmp::PartialEqSpecImpl for $name {
715 closed spec fn obeys_eq_spec() -> bool { true }
716
717 closed spec fn eq_spec(&self, other: &Self) -> bool {
718 self.bits() == other.bits()
719 }
720 }
721
722 impl core::cmp::Eq for $name {}
723
724 impl ::vstd::std_specs::ops::BitOrSpecImpl for $name {
725 open spec fn obeys_bitor_spec() -> bool { true }
726
727 open spec fn bitor_req(self, rhs: Self) -> bool { true }
728
729 open spec fn bitor_spec(self, rhs: Self) -> Self::Output {
730 self.union(rhs)
731 }
732 }
733
734 impl core::ops::BitOr for $name {
735 type Output = Self;
736 fn bitor(self, other: Self) -> (r: Self)
737 ensures
738 r.bits() == (self.bits() | other.bits()),
739 {
740 self.union(other)
741 }
742 }
743
744 impl vstd::std_specs::ops::BitAndSpecImpl for $name {
745 open spec fn obeys_bitand_spec() -> bool { true }
746
747 open spec fn bitand_req(self, rhs: Self) -> bool { true }
748
749 open spec fn bitand_spec(self, rhs: Self) -> Self::Output {
750 self.intersection(rhs)
751 }
752 }
753
754 impl core::ops::BitAnd for $name {
755 type Output = Self;
756 fn bitand(self, other: Self) -> (r: Self)
757 ensures
758 r.bits() == (self.bits() & other.bits()),
759 {
760 self.intersection(other)
761 }
762 }
763
764 impl vstd::std_specs::ops::BitXorSpecImpl for $name {
765 open spec fn obeys_bitxor_spec() -> bool { true }
766
767 open spec fn bitxor_req(self, rhs: Self) -> bool { true }
768
769 open spec fn bitxor_spec(self, rhs: Self) -> Self::Output {
770 self.symmetric_difference(rhs)
771 }
772 }
773
774 impl core::ops::BitXor for $name {
775 type Output = Self;
776 fn bitxor(self, other: Self) -> (r: Self)
777 ensures
778 r.bits() == (self.bits() ^ other.bits()),
779 {
780 self.symmetric_difference(other)
781 }
782 }
783
784 impl vstd::std_specs::ops::SubSpecImpl for $name {
785 open spec fn obeys_sub_spec() -> bool { true }
786
787 open spec fn sub_req(self, rhs: Self) -> bool { true }
788
789 open spec fn sub_spec(self, rhs: Self) -> Self::Output {
790 self.difference(rhs)
791 }
792 }
793
794 impl core::ops::Sub for $name {
795 type Output = Self;
796 fn sub(self, other: Self) -> (r: Self)
797 ensures
798 r.bits() == (self.bits() & !other.bits()),
799 {
800 self.difference(other)
801 }
802 }
803
804 impl vstd::std_specs::ops::NotSpecImpl for $name {
805 open spec fn obeys_not_spec() -> bool { true }
806
807 open spec fn not_req(self) -> bool { true }
808
809 closed spec fn not_spec(self) -> Self::Output {
810 self.complement()
811 }
812 }
813
814 impl core::ops::Not for $name {
815 type Output = Self;
816
817 fn not(self) -> (r: Self)
818 ensures
819 r.bits() == (!self.bits() & $name::all().bits()),
820 {
821 self.complement()
822 }
823 }
824
825 } impl ::core::fmt::Debug for $name {
827 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
828 f.debug_tuple(stringify!($name)).field(&self.bits).finish()
829 }
830 }
831
832 impl ::core::ops::BitOrAssign for $name {
833 #[inline]
834 fn bitor_assign(&mut self, other: Self) {
835 self.insert(other);
836 }
837 }
838
839 impl ::core::ops::BitAndAssign for $name {
840 #[inline]
841 fn bitand_assign(&mut self, other: Self) {
842 *self = Self::from_bits_retain(self.bits()).intersection(other);
843 }
844 }
845
846 impl ::core::ops::BitXorAssign for $name {
847 #[inline]
848 fn bitxor_assign(&mut self, other: Self) {
849 self.toggle(other);
850 }
851 }
852
853 impl ::core::ops::SubAssign for $name {
854 #[inline]
855 fn sub_assign(&mut self, other: Self) {
856 self.remove(other);
857 }
858 }
859
860 } };
862}
863
864bitflags! {
870 pub struct Flags: u32 {
871 const A = 0b00000001;
872 const B = 0b00000010;
873 const C = 0b00000100;
874 const ABC = 0b00000111;
875 }
876}
877
878verus! {
879
880#[allow(dead_code)]
881fn _bitflags_smoke_test() {
882 let a = Flags::A();
883 let b = Flags::B();
884 let c = Flags::C();
885 let mut flags = Flags::ABC();
886
887 flags.remove(a);
888 flags.insert(a);
889 flags.toggle(b);
890 flags.set(c, false);
891 flags.set(b, true);
892 flags.insert(c);
893 flags = flags.intersection(Flags::from_bits_retain(0b101u32));
894 flags.toggle(a);
895
896 let unknown = Flags::from_bits_retain(0b1000u32);
897 unknown.known_bits();
898 unknown.unknown_bits();
899 unknown.contains_unknown_bits();
900 Flags::from_bits(0b1000u32);
901 let truncated_unknown = Flags::from_bits_truncate(0b1001u32);
902 truncated_unknown.bits();
903
904}
905
906}