std/collections/flags

std/collections/src/flags.trb

Flags: a set of the cases of a type whose cases stand for powers of two, stored as one bit mask - what a C API, a file format or a protocol means by flags - and FlagsError, what reading a mask with a bit that belongs to no case answers.

It needs no operator and no native: a case is its rawValue() (case Read = 1, docs/design/FLAGS.md), and the mask is the bits of those numbers together.

type Flags

type Flags<Case: RawValue> with Iterate<Case>, Length, From<Iterate<Case>>, TryFrom<UInt64, FlagsError>

A set of the cases of Case, one bit each, with the words a Set has: contains, insert and inserted, remove and removed, Flags.union, Flags.intersection and Flags.difference. It iterates over the cases that are set, the lowest bit first, and a list literal builds one wherever one is expected.

Every case of Case stands for a power of two, which the checker holds wherever Flags<Case> is written or inferred. Outside the program the value is its mask: Flags.bits and UInt64.from(flags) write it, Flags.fromBits and tryFrom read it back, and that pair is how a value is encoded and decoded.

Examples

type Permission {
  case Read = 1
  case Write = 2
  case Execute = 4
}

var access: Flags<Permission> = [.Read, .Write]
access.insert(.Execute)
print access.contains(.Write)
print access.bits()
print Flags<Permission>.fromBits(5)

Pitfalls

The order of iteration is the order of the bits, not the order the cases were inserted in, which is why a Flags is not a Set: every set iterates in insertion order.

Related

  • RawValue - the number a case stands for, which is its bit here.

fn of

static fn of(...cases: Case): Self

The flags of these cases: Flags.of(Permission.Read, Permission.Write).

fn from

static fn from(cases: Iterate<Case>): Self

The flags of every case of cases. This is what a list literal where a Flags is expected builds.

fn fromBits

static fn fromBits(mask: UInt64): Result<Self, FlagsError>

The flags a mask holds - read from a C API, a file or the network.

Errors

  • FlagsError where a bit of the mask belongs to no case of Case.

Examples

type Permission {
  case Read = 1
  case Write = 2
}

print Flags<Permission>.fromBits(3)
print Flags<Permission>.fromBits(4)

fn tryFrom

static fn tryFrom(value: UInt64): Result<Self, FlagsError>

The same as Flags.fromBits: the way in of the pair a value is decoded through.

fn bits

fn bits(): UInt64

The mask, for a C API, a file or the network: the numbers of the cases that are set, together.

fn contains

fn contains(flag: Case): Bool

Whether flag is set.

fn length

fn length(): Int

How many cases are set.

fn insert

var fn insert(flag: Case)

Sets flag, in place; does nothing where it is set already.

fn insertAll

var fn insertAll(flags: Iterate<Case>)

Sets every flag of flags, in place.

fn remove

var fn remove(flag: Case): Bool

Clears flag, in place, and answers whether it was set.

fn removeAll

var fn removeAll(flags: Iterate<Case>)

Clears every flag of flags, in place.

fn clear

var fn clear()

Clears every flag, in place.

fn inserted

fn inserted(flag: Case): Self

The participle of Flags.insert: a changed copy with flag set, for a const binding.

fn removed

fn removed(flag: Case): Self

The participle of Flags.remove: a changed copy with flag cleared.

fn union

static fn union(first: Self, second: Self): Self

The flags set in either. A function of the type, because neither operand is the one that changes.

fn intersection

static fn intersection(first: Self, second: Self): Self

The flags set in both.

fn difference

static fn difference(first: Self, second: Self): Self

The flags set in first and not in second.

fn iterate

fn iterate(): Iterator<Case>

A cursor over the cases that are set, the lowest bit first.

extend UInt64 with From<Flags<Case>>

extend<Case: RawValue> UInt64 with From<Flags<Case>>

The mask of the flags: the way out of the pair a value is encoded through.

fn from

static fn from(value: Flags<Case>): Self

extend Flags<Case> with Show

extend<Case: RawValue & Show> Flags<Case> with Show

{Read, Write} - braces, as a set shows. Empty is {}.

fn show

fn show(): String

type FlagsIterator

type FlagsIterator<Case: RawValue> with Iterator<Case>

The cursor of Flags: the next bit that is set, as its case.

field rest

var rest: Int

The bits that are left, the ones already answered cleared.

fn next

var fn next(): Case?

The case of the lowest bit that is left, or None once none is.

type FlagsError

type FlagsError with Error

A mask with a bit that belongs to no case: what Flags.fromBits answers for it.

field mask

mask: UInt64

The whole mask that was read.

fn show

fn show(): String

the mask 12 has a bit that stands for no case