<p>In most languages, <code>enum</code> types intersect with number types, implicitly converting between them so you can do <code>SomeEnum.VariantA | SomeEnum.VariantB</code> to work with flags. In C# <code>enum</code>s are numbers with custom methods, getters and setters and built-ins such as <code>HasFlag()</code>. In GDScript <code>enum</code>s are numbers without custom methods etc. In Rust, IIRC there's a separate <code>bitflags</code> crate with type-safe flags.</p>
<p>How do other languages facilitate working with bitwise flags?</p>
<p>For example:</p>
<ul>
<li>Is there a language that infers the type from where a variant comes (based on Swift (<code>let x: Enum = .variant</code>) or Haxe), a feature from which flags can be wrote faster? Of course as I know neither Swift nor Haxe support flags enums: Haxe uses <code>enum</code>s for algebraic data types.</li>
<li>Is there a language that is type-safe, i.e., that does not allow to assign a number to a flags typed property without explicit conversion?</li>
</ul>

<syntax><types><type-inference>
How do languages handle bitwise flags?
CC BY-SA 4.0
2023-06-25T13:01:19.670Z
Apologies I have [metad your question](https://languagedesign.meta.stackexchange.com/questions/409/what-do-we-think-of-this-style-of-how-is-x-implemented-in-your-language-questi) as I think it raises some interesting questions.
Bruce Adams
<h2>C++</h2>
<p>Famously, C++ supports bit flags in a library, <a href="https://en.cppreference.com/w/cpp/utility/bitset" rel="noreferrer"><code>std::bitset</code></a>. This is often used in conjunction with an enumerated type:</p>
<pre class="lang-cpp prettyprint-override"><code>enum {
    FLAG_1,
    FLAG_2,
    FLAG_3,
    FLAG_COUNT // Not used as an actual flag
};

std::bitset&lt;FLAG_COUNT&gt; flags; // This is how you represent flags.

// This is how you use them.
flags[FLAG_3] = true;
if (flags[FLAG_2]) { /* ... */ }
</code></pre>

CC BY-SA 4.0
2023-06-27T01:43:01.400Z
2023-06-27T01:43:01.400Z
Pseudonym
<p>In Tuplet, <code>enum</code>s are sum types, whereas the &quot;combinable&quot; flag-like options use <code>flags</code>. Here is an example:</p>
<pre><code>FlagRegister /* 6502 &quot;P&quot; flags register */ = [flags(u8)] {
  carry, // least significant bit
  zero, // next bit
  disable_interrupts,
  decimal,
  b_flag,
  // bit 5 is always 1
  [private] bit5 always true, // a `FlagRegister` value must have bit5 == 1, or it fails at construction
  // alternatively, to just ignore it
  [private] bit5 = true,
  overflow,
  negative,
} // The compiler checks that there are 8 bits

a: FlagRegister = 2b0010_0100
b = FlagRegister(carry, decimal) // same as 2b0010_1001
c = a | b // carry, decimal, disable_interrupts(, bit5)
// + and | do the same thing
d = a + FlagRegister.b_flag // disable_interrupts, b_flag(, bit5)
e = a - FlagRegister.disable_interrupts // (bit5)
f = b :~ FlagRegister.disable_interrupts // toggle: carry, decimal, disable_interrupts(, bit5)
g = a :~ FlagRegister.disable_interrupts // (bit5)
h = b &amp; FlagRegister(carry) // carry(, bit5)
i = a &amp; FlagRegister.carry // (bit5)

core::assert(c.decimal) // compile time assertion
core::assert(!c.negative)
core::assert(std::reflect::compile { _: FlagRegister = 0 }.is_empty) // fails because bit5 is false

[runtime] y: u8 = 0
z = FlagRegister(d) // fails at runtime if the compiler can't statically know that bit5 is true
</code></pre>
<p>assuming <code>Q</code> is a type implementing <code>Integer</code>, <code>T</code> is a type implementing <code>Bitwise(Q)</code>, <code>F = [flags(T)] { a, b, ... }</code>, <code>q</code> of type <code>Q</code>, and <code>x</code>, <code>y</code> of type <code>F</code> these are all the supported operations:</p>
<ul>
<li><code>x.value</code> and its alias <code>@x</code> gets the integer representation</li>
<li><code>x | y</code> and its aliases <code>x + y</code> and <code>x.or(y)</code> is <code>F(@x | @y)</code></li>
<li><code>x &amp; y</code> and its alias <code>x.and(y)</code> is <code>F(@x &amp; @y)</code></li>
<li><code>x - y</code> and its alias <code>x.without(y)</code> is <code>F(@x &amp; ~@y)</code></li>
<li><code>x :~ y</code> and its alias <code>x.toggle(y)</code> is <code>F(@x ^ @y)</code></li>
<li><code>x.a</code>, <code>x.b</code>, etc</li>
<li><code>x(q)</code> and its alias <code>x.at(q)</code> gets the <code>q</code>-th bit (0 is the lowest bit)</li>
<li><code>~x</code> and its alias <code>x.negate</code> is <code>F(~@x)</code></li>
</ul>
<p><code>F</code> will of course also inherit the operations from its typeclasses, most notably <code>Show F</code>, <code>Read F</code>, <code>Formattable F</code>, <code>Integer F</code>, <code>Sequence(Bool) F</code>, <code>Bitwise(Q) F</code>, <code>FiniteBitwise(Q) T</code> =&gt; <code>FiniteBitwise(Q) F</code>.</p>

CC BY-SA 4.0
2023-06-25T14:52:53.913Z
2023-06-25T18:28:49.187Z
2023-06-25T18:28:49.187Z
RubenVerg
<h1>VioletScript</h1>
<p>My language has a type-safe (i.e. not mixed with number types) numeric <code>enum</code>. You can work with flags by adding the reserved <code>Flags</code> decorator. It is <em>not</em> necessary to specify the value for each variant; you can omit the <code>= ...</code> part. It supports custom methods, getters and setters and enum variant inference.</p>
<p>Every variant has an unique number and an unique user-friendly string.</p>
<p>I'd say working with flags is safer and more efficient in VioletScript than working with flags in C#. I don't know of another language with the same characteristics (there is one someone mentioned me that has flags enums, but I forgot the name, though I still bet there are differences).</p>
<h4>Enum Variant Inference</h4>
<p>The language implicitly converts string literals, array initializers and object initializers to <code>enum</code>s wherever expected. Even the <code>undefined</code> constant too (equivalent to <code>{}</code> or <code>[]</code>).</p>
<p>You can think of this as similiar to variant inference in Swift or Haxe. I don't know Swift, but in Haxe <code>enum</code>s (that keyword) are algebraic data types; in VioletScript they're rather the equivalent of C#, except they're type-safe and also associate an user-friendly string:</p>
<p>VioletScript example:</p>
<pre><code>const modifiers: Modifiers = 'someModifier'
const modifiers: Modifiers = ['someModifier', 'anotherModifier']
const modifiers: Modifiers = { someModifier: true }
</code></pre>
<h4>Variant Structure</h4>
<p>This is about how the <code>enum</code> defines the variants.</p>
<ul>
<li>Variant has an <code>enum</code> static property.
<ul>
<li>Variant has a number (<code>valueOf()</code>).</li>
<li>Variant has an user-friendly string (<code>toString()</code>).</li>
</ul>
</li>
</ul>
<p>What you assign at the right side of the variant is just a compile-time association:</p>
<ul>
<li>If it's a string literal, associates an user-friendly string and let the compiler infer the number.</li>
<li>If it's a numeric literal, associates a number and let the compiler infer the string.</li>
<li>If it's a <code>[str, num]</code> or <code>[num, str]</code> array, associates the specified number and string.</li>
</ul>
<p>If no initialiser, let the compiler infer the number and string.</p>
<h4>Number and String Inference</h4>
<ul>
<li>The <code>SCREAMING_SNAKE_CASE</code> constant name is implicitly converted into an user-friendly camel-case string (<code>screamingSnakeCase</code>).</li>
<li>Like in all other languages, the number is inferred based on a counter. <em>However</em>, different from C#, it will assign correct flags: for flags the counter will multiply per 2 each increment.</li>
</ul>
<h4>Strictness</h4>
<ul>
<li>Duplicates are not allowed.</li>
<li>A number in a flags type must be either 1 or power of two.</li>
</ul>
<h4>Example</h4>
<pre><code>[Flags]
enum E {
    X
    Y = 32
    Z = 'zZ'
    W = ['k', 512]

    // custom method
    function f(): void {
        trace(this.valueOf())
    }

    // custom getter
    function get prop(): Number (this.valueOf() + 5)
}

const e: E = ['x', 'k']
assert('x' in e) // has flag 'x'

const e: E = { x: true }

// is not empty
assert(e != {})

const e = e.toggle('x')
</code></pre>
<p>To clarify:</p>
<ul>
<li><code>E.X</code>
<ul>
<li><code>E.X.valueOf() == 1</code></li>
<li><code>E.X.toString() == 'x'</code></li>
</ul>
</li>
<li><code>E.Y</code>
<ul>
<li><code>E.Y.valueOf() == 32</code></li>
<li><code>E.Y.toString() == 'y'</code></li>
</ul>
</li>
<li><code>E.Z</code>
<ul>
<li><code>E.Z.valueOf() == 64</code></li>
<li><code>E.Z.toString() == 'zZ'</code></li>
</ul>
</li>
<li><code>E.W</code>
<ul>
<li><code>E.W.valueOf() == 512</code></li>
<li><code>E.W.toString() == 'k'</code></li>
</ul>
</li>
</ul>
<h4>Basic Syntax</h4>
<pre><code>'flag' in f
f = f.toggle('flag')
f = f.filter(other)
f = f.include(other)
f = f.exclude(other)

// specify custom number type
[Flags]
enum E wraps BigInt {
}
</code></pre>

CC BY-SA 4.0
2023-06-25T13:04:55.947Z
2023-06-26T15:36:37.027Z
2023-06-26T15:36:37.027Z
Hydroper
<blockquote>
<p>Of course as I know neither Swift nor Haxe support flags enums: Haxe uses enums for algebraic data types.</p>
</blockquote>
<p>Swift has <code>OptionSet</code>.</p>
<p><code>OptionSet</code>, like the standard hash-based <code>Set&lt;T&gt;</code>, inherits from the <code>SetAlgebra</code> protocol. However, its element type is itself, and you get a lot of the conformances for free.</p>
<p>Consider this short program, which demonstrates most of the common operations:</p>
<pre class="lang-swift prettyprint-override"><code>// Let's define such a type.
struct MyOptions: OptionSet {
  var rawValue: Int

  // ...yep, that's it.

  // Presumably you also want something like these:
  static let foo = MyOptions(rawValue: 1 &lt;&lt; 0)
  static let bar = MyOptions(rawValue: 1 &lt;&lt; 1)
  static let baz = MyOptions(rawValue: 1 &lt;&lt; 2)
}

// Create two values: one that's just foo, and one that's both foo and bar
let first: MyOptions = .foo
let second: MyOptions = [.foo, .bar]

// Check what flags they have in common
print(first.intersection(second)) // first &amp; second in C
// Remove first from second
print(second.subtracting(first)) // second &amp; ~first in C
// Test for membership
if second.contains(first) { // second &amp; first == first in C
  print(&quot;\(first) is in \(second)!&quot;)
}
// Merge it with .baz
print(first.union(.baz)) // first | baz in C
</code></pre>
<p>For further reading, see the documentation at <a href="https://developer.apple.com/documentation/swift/optionset-swift.protocol" rel="nofollow noreferrer">https://developer.apple.com/documentation/swift/optionset-swift.protocol</a>.</p>

CC BY-SA 4.0
2023-06-26T20:31:26.070Z
2023-06-26T21:55:14.793Z
2023-06-26T21:55:14.793Z
Bbrk24
CC BY-SA 4.0
2023-06-26T22:39:21.353Z
Looking here it seems Swift is powerful.
Hydroper
# How do languages handle bitwise flags?
Posted by: username_0 on 2023-06-25
In most languages, `enum` types intersect with number types, implicitly converting between them so you can do `SomeEnum.VariantA | SomeEnum.VariantB` to work with flags. In C# `enum`s are numbers with custom methods, getters and setters and built-ins such as `HasFlag()`. In GDScript `enum`s are numbers without custom methods etc. In Rust, IIRC there's a separate `bitflags` crate with type-safe flags.

How do other languages facilitate working with bitwise flags?

For example:

* Is there a language that infers the type from where a variant comes (based on Swift (`let x: Enum = .variant`) or Haxe), a feature from which flags can be wrote faster? Of course as I know neither Swift nor Haxe support flags enums: Haxe uses `enum`s for algebraic data types.
* Is there a language that is type-safe, i.e., that does not allow to assign a number to a flags typed property without explicit conversion?
**Tags:** syntax types type-inference
> **Comments:**
> **username_1**: Apologies I have [metad your question](https://languagedesign.meta.stackexchange.com/questions/409/what-do-we-think-of-this-style-of-how-is-x-implemented-in-your-language-questi) as I think it raises some interesting questions.  
---
## 4 answers
### Answer by username_2 on 2023-06-27. Score: 5
C++
Famously, C++ supports bit flags in a library, std::bitset. This is often used in conjunction with an enumerated type:
enum {
    FLAG_1,
    FLAG_2,
    FLAG_3,
    FLAG_COUNT // Not used as an actual flag
};

std::bitset flags; // This is how you represent flags.

// This is how you use them.
flags[FLAG_3] = true;
if (flags[FLAG_2]) { /* ... */ }
---
### Answer by username_4 on 2023-06-26. Score: 3
Of course as I know neither Swift nor Haxe support flags enums: Haxe uses enums for algebraic data types.

Swift has OptionSet.
OptionSet, like the standard hash-based Set, inherits from the SetAlgebra protocol. However, its element type is itself, and you get a lot of the conformances for free.
Consider this short program, which demonstrates most of the common operations:
// Let's define such a type.
struct MyOptions: OptionSet {
  var rawValue: Int

  // ...yep, that's it.

  // Presumably you also want something like these:
  static let foo = MyOptions(rawValue: 1 << 0)
  static let bar = MyOptions(rawValue: 1 << 1)
  static let baz = MyOptions(rawValue: 1 << 2)
}

// Create two values: one that's just foo, and one that's both foo and bar
let first: MyOptions = .foo
let second: MyOptions = [.foo, .bar]

// Check what flags they have in common
print(first.intersection(second)) // first & second in C
// Remove first from second
print(second.subtracting(first)) // second & ~first in C
// Test for membership
if second.contains(first) { // second & first == first in C
  print("\(first) is in \(second)!")
}
// Merge it with .baz
print(first.union(.baz)) // first | baz in C

For further reading, see the documentation at https://developer.apple.com/documentation/swift/optionset-swift.protocol.
> **Comments:**
> **username_0** (2023-06-26): Looking here it seems Swift is powerful.  
---
### Answer by username_3 on 2023-06-25. Score: 2
In Tuplet, enums are sum types, whereas the "combinable" flag-like options use flags. Here is an example:
FlagRegister /* 6502 "P" flags register */ = [flags(u8)] {
  carry, // least significant bit
  zero, // next bit
  disable_interrupts,
  decimal,
  b_flag,
  // bit 5 is always 1
  [private] bit5 always true, // a `FlagRegister` value must have bit5 == 1, or it fails at construction
  // alternatively, to just ignore it
  [private] bit5 = true,
  overflow,
  negative,
} // The compiler checks that there are 8 bits

a: FlagRegister = 2b0010_0100
b = FlagRegister(carry, decimal) // same as 2b0010_1001
c = a | b // carry, decimal, disable_interrupts(, bit5)
// + and | do the same thing
d = a + FlagRegister.b_flag // disable_interrupts, b_flag(, bit5)
e = a - FlagRegister.disable_interrupts // (bit5)
f = b :~ FlagRegister.disable_interrupts // toggle: carry, decimal, disable_interrupts(, bit5)
g = a :~ FlagRegister.disable_interrupts // (bit5)
h = b & FlagRegister(carry) // carry(, bit5)
i = a & FlagRegister.carry // (bit5)

core::assert(c.decimal) // compile time assertion
core::assert(!c.negative)
core::assert(std::reflect::compile { _: FlagRegister = 0 }.is_empty) // fails because bit5 is false

[runtime] y: u8 = 0
z = FlagRegister(d) // fails at runtime if the compiler can't statically know that bit5 is true

assuming Q is a type implementing Integer, T is a type implementing Bitwise(Q), F = [flags(T)] { a, b, ... }, q of type Q, and x, y of type F these are all the supported operations:

x.value and its alias @x gets the integer representation
x | y and its aliases x + y and x.or(y) is F(@x | @y)
x & y and its alias x.and(y) is F(@x & @y)
x - y and its alias x.without(y) is F(@x & ~@y)
x :~ y and its alias x.toggle(y) is F(@x ^ @y)
x.a, x.b, etc
x(q) and its alias x.at(q) gets the q-th bit (0 is the lowest bit)
~x and its alias x.negate is F(~@x)

F will of course also inherit the operations from its typeclasses, most notably Show F, Read F, Formattable F, Integer F, Sequence(Bool) F, Bitwise(Q) F, FiniteBitwise(Q) T => FiniteBitwise(Q) F.
---
### Answer by username_0 on 2023-06-25. Score: 1
VioletScript
My language has a type-safe (i.e. not mixed with number types) numeric enum. You can work with flags by adding the reserved Flags decorator. It is not necessary to specify the value for each variant; you can omit the = ... part. It supports custom methods, getters and setters and enum variant inference.
Every variant has an unique number and an unique user-friendly string.
I'd say working with flags is safer and more efficient in VioletScript than working with flags in C#. I don't know of another language with the same characteristics (there is one someone mentioned me that has flags enums, but I forgot the name, though I still bet there are differences).
Enum Variant Inference
The language implicitly converts string literals, array initializers and object initializers to enums wherever expected. Even the undefined constant too (equivalent to {} or []).
You can think of this as similiar to variant inference in Swift or Haxe. I don't know Swift, but in Haxe enums (that keyword) are algebraic data types; in VioletScript they're rather the equivalent of C#, except they're type-safe and also associate an user-friendly string:
VioletScript example:
const modifiers: Modifiers = 'someModifier'
const modifiers: Modifiers = ['someModifier', 'anotherModifier']
const modifiers: Modifiers = { someModifier: true }

Variant Structure
This is about how the enum defines the variants.

Variant has an enum static property.

Variant has a number (valueOf()).
Variant has an user-friendly string (toString()).



What you assign at the right side of the variant is just a compile-time association:

If it's a string literal, associates an user-friendly string and let the compiler infer the number.
If it's a numeric literal, associates a number and let the compiler infer the string.
If it's a [str, num] or [num, str] array, associates the specified number and string.

If no initialiser, let the compiler infer the number and string.
Number and String Inference

The SCREAMING_SNAKE_CASE constant name is implicitly converted into an user-friendly camel-case string (screamingSnakeCase).
Like in all other languages, the number is inferred based on a counter. However, different from C#, it will assign correct flags: for flags the counter will multiply per 2 each increment.

Strictness

Duplicates are not allowed.
A number in a flags type must be either 1 or power of two.

Example
[Flags]
enum E {
    X
    Y = 32
    Z = 'zZ'
    W = ['k', 512]

    // custom method
    function f(): void {
        trace(this.valueOf())
    }

    // custom getter
    function get prop(): Number (this.valueOf() + 5)
}

const e: E = ['x', 'k']
assert('x' in e) // has flag 'x'

const e: E = { x: true }

// is not empty
assert(e != {})

const e = e.toggle('x')

To clarify:

E.X

E.X.valueOf() == 1
E.X.toString() == 'x'


E.Y

E.Y.valueOf() == 32
E.Y.toString() == 'y'


E.Z

E.Z.valueOf() == 64
E.Z.toString() == 'zZ'


E.W

E.W.valueOf() == 512
E.W.toString() == 'k'



Basic Syntax
'flag' in f
f = f.toggle('flag')
f = f.filter(other)
f = f.include(other)
f = f.exclude(other)

// specify custom number type
[Flags]
enum E wraps BigInt {
}
---
