Skip to content

Commit

Permalink
parser: add set_all + clear_all methods to [flag] enum bitfields (
Browse files Browse the repository at this point in the history
  • Loading branch information
larpon committed Nov 1, 2023
1 parent c82c760 commit 1356c61
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
3 changes: 3 additions & 0 deletions vlib/v/parser/parser.v
Original file line number Diff line number Diff line change
Expand Up @@ -4085,13 +4085,16 @@ fn (mut p Parser) enum_decl() ast.EnumDecl {
}
}
pubfn := if p.mod == 'main' { 'fn' } else { 'pub fn' }
all_bits_set_value := '0b' + '1'.repeat(fields.len)
p.codegen('
//
[inline] ${pubfn} ( e &${enum_name}) is_empty() bool { return ${senum_type}(*e) == 0 }
[inline] ${pubfn} ( e &${enum_name}) has(flag ${enum_name}) bool { return (${senum_type}(*e) & (${senum_type}(flag))) != 0 }
[inline] ${pubfn} ( e &${enum_name}) all(flag ${enum_name}) bool { return (${senum_type}(*e) & (${senum_type}(flag))) == ${senum_type}(flag) }
[inline] ${pubfn} (mut e ${enum_name}) set(flag ${enum_name}) { unsafe{ *e = ${enum_name}(${senum_type}(*e) | (${senum_type}(flag))) } }
[inline] ${pubfn} (mut e ${enum_name}) set_all() { unsafe{ *e = ${enum_name}(${all_bits_set_value}) } }
[inline] ${pubfn} (mut e ${enum_name}) clear(flag ${enum_name}) { unsafe{ *e = ${enum_name}(${senum_type}(*e) & ~(${senum_type}(flag))) } }
[inline] ${pubfn} (mut e ${enum_name}) clear_all() { unsafe{ *e = ${enum_name}(0) } }
[inline] ${pubfn} (mut e ${enum_name}) toggle(flag ${enum_name}) { unsafe{ *e = ${enum_name}(${senum_type}(*e) ^ (${senum_type}(flag))) } }
//
')
Expand Down
37 changes: 37 additions & 0 deletions vlib/v/tests/enum_bitfield_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,40 @@ fn test_enum_bitfield_has_vs_all_methods_with_combined_flags_2() {
assert c.has(.execute | .other)
assert c.has(.read | .other)
}

fn test_enum_bitfield_set_all() {
mut a := BfFile{}

a.perm.set_all()

assert a.perm.has(.read)
assert a.perm.has(.execute)
assert a.perm.has(.write)
assert a.perm.has(.other)

mut b := BfFile{}
b.perm.set(.read | .execute | .write | .other)
println(b.perm)
println(a.perm)
assert a.perm == b.perm, '.set_all() should be equivalent to using .set() with all the bit names'
}

fn test_enum_bitfield_clear_all() {
mut a := BfFile{}

a.perm.set(.read)
assert a.perm.has(.read)
a.perm.set(.write)
assert a.perm.has(.write)
a.perm.set(.execute)
assert a.perm.has(.execute)
a.perm.set(.other)
assert a.perm.has(.other)

a.perm.clear_all()

assert !a.perm.has(.read)
assert !a.perm.has(.execute)
assert !a.perm.has(.write)
assert !a.perm.has(.other)
}

0 comments on commit 1356c61

Please sign in to comment.