implementation of minimum, maximum, hasAny and hasAll for bitflags

This commit is contained in:
2026-03-03 21:28:28 +01:00
parent c76b5c3f0a
commit 452810e6bf
22 changed files with 760 additions and 567 deletions

View File

@@ -1,15 +1,6 @@
import type { FlagSet } from '.'
import {
decodeB64Byte,
encodeB64Byte,
normaliseB64String,
ZERO_STRING,
} from '../base64'
import {
Base64BitflagIterator,
EnumerateFlags,
useIterator,
} from '../enumeration'
import { decodeB64Byte, encodeB64Byte, normaliseB64String, ZERO_STRING } from '../base64'
import { Base64BitflagIterator, EnumerateFlags, useIterator } from '../enumeration'
/**
* Provides flags that are stored in strings using a little-endian base 64

View File

@@ -1,11 +1,7 @@
import type { FlagSet } from '.'
import { UnavailableFeatureError } from '../errors'
import { ENV_BI } from '../env'
import {
BigBitFlagsIterator,
EnumerateFlags,
useIterator,
} from '../enumeration'
import { BigBitFlagsIterator, EnumerateFlags, useIterator } from '../enumeration'
export class BigBitFlagSet implements FlagSet<bigint, bigint> {
/**

View File

@@ -67,7 +67,7 @@ export interface FlagSet<F, S> {
/**
* Checks whether the first set of flags includes at least one of the flags
* from the second set.
* from the second set. If there is no required flags, the result will always be `false`.
*
* A flag is considered to be part of the set only if all of its parents are
* present too.
@@ -79,7 +79,7 @@ export interface FlagSet<F, S> {
/**
* Checks whether the first set of flags includes all the flags from the
* second set.
* second set. If there is no required flags, the result will always be `true`.
*
* A flag is considered to be part of the set only if all of its parents are
* present too.

View File

@@ -1,6 +1,6 @@
import type { FlagSet } from '.'
import { BitFlagsIterator, EnumerateFlags, useIterator } from '../enumeration'
import { FlagDefinition, FlagsDictionary } from '../definitions'
import { BitFlagsIterator, EnumerateFlags, useIterator } from '~/enumeration'
import { FlagDefinition, FlagsDictionary } from '~/definitions'
export class BitFlagSet implements FlagSet<number, number> {
private readonly _dictionary: FlagsDictionary<number, number>
@@ -18,10 +18,7 @@ export class BitFlagSet implements FlagSet<number, number> {
}
public named(...aliases: string[]): number {
return aliases.reduce(
(set, alias) => set | (this.getFlag(alias)?.values ?? 0),
0,
)
return aliases.reduce((set, alias) => set | (this.getFlag(alias)?.values ?? 0), 0)
}
public union(first: number, second: number): number {
@@ -37,15 +34,15 @@ export class BitFlagSet implements FlagSet<number, number> {
}
public isSuperset(first: number, second: number): boolean {
return (first & second) == second
return (first & second) === second
}
public hasAny(flags: number, required: number): boolean {
return false
return this.minimum(this.intersection(flags, required)) !== 0
}
public hasAll(flags: number, required: number): boolean {
return false
return this.isSuperset(flags, this.maximum(required))
}
public enumerate(flags: number): EnumerateFlags<number> {
@@ -53,11 +50,25 @@ export class BitFlagSet implements FlagSet<number, number> {
}
public maximum(flags: number): number {
return 0
let result = this.none()
for (const value of this.enumerate(flags)) {
const flag = this._dictionary.findByValue(value)
if (flag !== undefined) {
result = flag.addTo(result)
}
}
return result
}
public minimum(flags: number): number {
return 0
let result = this.none()
for (const value of this.enumerate(flags)) {
const flag = this._dictionary.findByValue(value)
if (flag !== undefined && flag.isIn(flags)) {
result = flag.addTo(result)
}
}
return result
}
public getFlag(alias: string): FlagDefinition<number, number> | undefined {