v.parser: add a generated `.all(.flag1|.flag2)` method to `[flag]` enums

Unlike `.has(.flag1|.flag2)`, which is true, for any of `.flag1` or `.flag2`,
the new method `.all()` tests whether *all flags* are set at the same time.
pull/11987/head
Delyan Angelov 2021-09-26 21:24:35 +03:00
parent 09dfc3f301
commit 6a2ef733de
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
3 changed files with 42 additions and 3 deletions

View File

@ -5344,14 +5344,23 @@ enum BitField {
other
}
fn example_enum_as_bitfield_use() {
fn main() {
assert 1 == int(BitField.read)
assert 2 == int(BitField.write)
mut bf := BitField.read
assert bf.has(.read | .other) // test if *at least one* of the flags is set
assert !bf.all(.read | .other) // test if *all* of the flags is set
bf.set(.write | .other)
assert bf.has(.read | .write | .other)
assert bf.all(.read | .write | .other)
bf.toggle(.other)
assert bf == BitField.read | .write
assert bf.all(.read | .write)
assert !bf.has(.other)
}
```
```v
// Calling this function will result in a deprecation warning
[deprecated]
fn old_function() {
@ -5372,7 +5381,9 @@ fn legacy_function() {}
[deprecated: 'use new_function2() instead']
[deprecated_after: '2021-05-27']
fn legacy_function2() {}
```
```v nofmt
// This function's calls will be inlined.
[inline]
fn inlined_function() {

View File

@ -3146,6 +3146,7 @@ fn (mut p Parser) enum_decl() ast.EnumDecl {
//
[inline] $pubfn ( e &$enum_name) is_empty() bool { return int(*e) == 0 }
[inline] $pubfn ( e &$enum_name) has(flag $enum_name) bool { return (int(*e) & (int(flag))) != 0 }
[inline] $pubfn ( e &$enum_name) all(flag $enum_name) bool { return (int(*e) & (int(flag))) == int(flag) }
[inline] $pubfn (mut e $enum_name) set(flag $enum_name) { unsafe{ *e = ${enum_name}(int(*e) | (int(flag))) } }
[inline] $pubfn (mut e $enum_name) clear(flag $enum_name) { unsafe{ *e = ${enum_name}(int(*e) & ~(int(flag))) } }
[inline] $pubfn (mut e $enum_name) toggle(flag $enum_name) { unsafe{ *e = ${enum_name}(int(*e) ^ (int(flag))) } }

View File

@ -26,6 +26,9 @@ fn test_enum_bitfield() {
assert a.perm.has(.execute)
assert !a.perm.has(.write)
assert !a.perm.has(.other)
}
fn test_enum_bitfield_operators() {
mut b := BfPermission.read | BfPermission.execute
assert int(b) == 1 + 0 + 4 + 0
assert b.has(.read)
@ -42,11 +45,35 @@ fn test_enum_bitfield() {
assert int(b) == 0 + 2 + 0 + 8
assert !b.has(.read)
assert !b.has(.execute)
}
fn test_enum_bitfield_has_vs_all_methods_with_combined_flags() {
mut c := BfPermission.read
c.set(.write | .execute)
assert c.has(.read | .write | .execute)
assert !c.has(.other)
c.toggle(.write | .other)
assert '$c' == 'BfPermission{.read | .execute | .other}'
assert c.has(.read | .write | .execute | .other)
// .all() tests if *ALL* of the given flags are set, i.e. not just any one of them.
// .has() tests if *ANY* of the given flags is set, even though some of the others may not be.
assert c.all(.read | .write | .execute)
assert !c.all(.read | .write | .execute | .other)
}
fn test_enum_bitfield_has_vs_all_methods_with_combined_flags_2() {
mut c := BfPermission.read | .execute | .other
//
assert c.has(.read | .execute | .other | .write)
assert c.has(.read | .write)
assert !c.all(.read | .execute | .other | .write)
assert !c.all(.read | .write)
//
assert c.all(.read | .execute | .other)
assert c.all(.read | .execute)
assert c.all(.execute | .other)
assert c.all(.read | .other)
//
assert c.has(.read | .execute | .other)
assert c.has(.read | .execute)
assert c.has(.execute | .other)
assert c.has(.read | .other)
}