mirror of
https://github.com/robonen/tools.git
synced 2026-03-20 10:54:44 +00:00
refactor(packages/stdlib): separate flags and helpers in bit tools
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { flagsGenerator, and, or, not, has, is, unset, toggle } from './index';
|
||||
import { flagsGenerator } from '.';
|
||||
|
||||
describe('flagsGenerator', () => {
|
||||
it('generate unique flags', () => {
|
||||
@@ -24,95 +24,3 @@ describe('flagsGenerator', () => {
|
||||
expect(() => generateFlag()).toThrow(new RangeError('Cannot create more than 31 flags'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('flagsAnd', () => {
|
||||
it('no effect on zero flags', () => {
|
||||
const result = and();
|
||||
|
||||
expect(result).toBe(-1);
|
||||
});
|
||||
|
||||
it('source flag is returned if no flags are provided', () => {
|
||||
const result = and(0b1010);
|
||||
|
||||
expect(result).toBe(0b1010);
|
||||
});
|
||||
|
||||
it('perform bitwise AND operation on flags', () => {
|
||||
const result = and(0b1111, 0b1010, 0b1100);
|
||||
|
||||
expect(result).toBe(0b1000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('flagsOr', () => {
|
||||
it('no effect on zero flags', () => {
|
||||
const result = or();
|
||||
|
||||
expect(result).toBe(0);
|
||||
});
|
||||
|
||||
it('source flag is returned if no flags are provided', () => {
|
||||
const result = or(0b1010);
|
||||
|
||||
expect(result).toBe(0b1010);
|
||||
});
|
||||
|
||||
it('perform bitwise OR operation on flags', () => {
|
||||
const result = or(0b1111, 0b1010, 0b1100);
|
||||
|
||||
expect(result).toBe(0b1111);
|
||||
});
|
||||
});
|
||||
|
||||
describe('flagsNot', () => {
|
||||
it('perform bitwise NOT operation on a flag', () => {
|
||||
const result = not(0b101);
|
||||
|
||||
expect(result).toBe(-0b110);
|
||||
});
|
||||
});
|
||||
|
||||
describe('flagsHas', () => {
|
||||
it('check if a flag has a specific bit set', () => {
|
||||
const result = has(0b1010, 0b1000);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('check if a flag has a specific bit unset', () => {
|
||||
const result = has(0b1010, 0b0100);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('flagsIs', () => {
|
||||
it('check if a flag is set', () => {
|
||||
const result = is(0b1010);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('check if a flag is unset', () => {
|
||||
const result = is(0);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('flagsUnset', () => {
|
||||
it('unset a flag', () => {
|
||||
const result = unset(0b1010, 0b1000);
|
||||
|
||||
expect(result).toBe(0b0010);
|
||||
});
|
||||
});
|
||||
|
||||
describe('flagsToggle', () => {
|
||||
it('toggle a flag', () => {
|
||||
const result = toggle(0b1010, 0b1000);
|
||||
|
||||
expect(result).toBe(0b0010);
|
||||
});
|
||||
});
|
||||
@@ -20,104 +20,3 @@ export function flagsGenerator() {
|
||||
return (lastFlag = lastFlag === 0 ? 1 : lastFlag << 1);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @name and
|
||||
* @category Bits
|
||||
* @description Function to combine multiple flags using the AND operator
|
||||
*
|
||||
* @param {number[]} flags - The flags to combine
|
||||
* @returns {number} The combined flags
|
||||
*
|
||||
* @since 0.0.2
|
||||
*/
|
||||
export function and(...flags: number[]) {
|
||||
return flags.reduce((acc, flag) => acc & flag, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name or
|
||||
* @category Bits
|
||||
* @description Function to combine multiple flags using the OR operator
|
||||
*
|
||||
* @param {number[]} flags - The flags to combine
|
||||
* @returns {number} The combined flags
|
||||
*
|
||||
* @since 0.0.2
|
||||
*/
|
||||
export function or(...flags: number[]) {
|
||||
return flags.reduce((acc, flag) => acc | flag, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name not
|
||||
* @category Bits
|
||||
* @description Function to combine multiple flags using the XOR operator
|
||||
*
|
||||
* @param {number} flag - The flag to apply the NOT operator to
|
||||
* @returns {number} The result of the NOT operator
|
||||
*
|
||||
* @since 0.0.2
|
||||
*/
|
||||
export function not(flag: number) {
|
||||
return ~flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name has
|
||||
* @category Bits
|
||||
* @description Function to make sure a flag has a specific bit set
|
||||
*
|
||||
* @param {number} flag - The flag to check
|
||||
* @param {number} other - Flag to check
|
||||
* @returns {boolean} Whether the flag has the bit set
|
||||
*
|
||||
* @since 0.0.2
|
||||
*/
|
||||
export function has(flag: number, other: number) {
|
||||
return (flag & other) === other;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name is
|
||||
* @category Bits
|
||||
* @description Function to check if a flag is set
|
||||
*
|
||||
* @param {number} flag - The flag to check
|
||||
* @returns {boolean} Whether the flag is set
|
||||
*
|
||||
* @since 0.0.2
|
||||
*/
|
||||
export function is(flag: number) {
|
||||
return flag !== 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name unset
|
||||
* @category Bits
|
||||
* @description Function to unset a flag
|
||||
*
|
||||
* @param {number} flag - Source flag
|
||||
* @param {number} other - Flag to unset
|
||||
* @returns {number} The new flag
|
||||
*
|
||||
* @since 0.0.2
|
||||
*/
|
||||
export function unset(flag: number, other: number) {
|
||||
return flag & ~other;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name toggle
|
||||
* @category Bits
|
||||
* @description Function to toggle (xor) a flag
|
||||
*
|
||||
* @param {number} flag - Source flag
|
||||
* @param {number} other - Flag to toggle
|
||||
* @returns {number} The new flag
|
||||
*
|
||||
* @since 0.0.2
|
||||
*/
|
||||
export function toggle(flag: number, other: number) {
|
||||
return flag ^ other;
|
||||
}
|
||||
|
||||
95
packages/stdlib/src/bits/helpers/index.test.ts
Normal file
95
packages/stdlib/src/bits/helpers/index.test.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { and, or, not, has, is, unset, toggle } from '.';
|
||||
|
||||
|
||||
describe('flagsAnd', () => {
|
||||
it('no effect on zero flags', () => {
|
||||
const result = and();
|
||||
|
||||
expect(result).toBe(-1);
|
||||
});
|
||||
|
||||
it('source flag is returned if no flags are provided', () => {
|
||||
const result = and(0b1010);
|
||||
|
||||
expect(result).toBe(0b1010);
|
||||
});
|
||||
|
||||
it('perform bitwise AND operation on flags', () => {
|
||||
const result = and(0b1111, 0b1010, 0b1100);
|
||||
|
||||
expect(result).toBe(0b1000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('flagsOr', () => {
|
||||
it('no effect on zero flags', () => {
|
||||
const result = or();
|
||||
|
||||
expect(result).toBe(0);
|
||||
});
|
||||
|
||||
it('source flag is returned if no flags are provided', () => {
|
||||
const result = or(0b1010);
|
||||
|
||||
expect(result).toBe(0b1010);
|
||||
});
|
||||
|
||||
it('perform bitwise OR operation on flags', () => {
|
||||
const result = or(0b1111, 0b1010, 0b1100);
|
||||
|
||||
expect(result).toBe(0b1111);
|
||||
});
|
||||
});
|
||||
|
||||
describe('flagsNot', () => {
|
||||
it('perform bitwise NOT operation on a flag', () => {
|
||||
const result = not(0b101);
|
||||
|
||||
expect(result).toBe(-0b110);
|
||||
});
|
||||
});
|
||||
|
||||
describe('flagsHas', () => {
|
||||
it('check if a flag has a specific bit set', () => {
|
||||
const result = has(0b1010, 0b1000);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('check if a flag has a specific bit unset', () => {
|
||||
const result = has(0b1010, 0b0100);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('flagsIs', () => {
|
||||
it('check if a flag is set', () => {
|
||||
const result = is(0b1010);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('check if a flag is unset', () => {
|
||||
const result = is(0);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('flagsUnset', () => {
|
||||
it('unset a flag', () => {
|
||||
const result = unset(0b1010, 0b1000);
|
||||
|
||||
expect(result).toBe(0b0010);
|
||||
});
|
||||
});
|
||||
|
||||
describe('flagsToggle', () => {
|
||||
it('toggle a flag', () => {
|
||||
const result = toggle(0b1010, 0b1000);
|
||||
|
||||
expect(result).toBe(0b0010);
|
||||
});
|
||||
});
|
||||
100
packages/stdlib/src/bits/helpers/index.ts
Normal file
100
packages/stdlib/src/bits/helpers/index.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* @name and
|
||||
* @category Bits
|
||||
* @description Function to combine multiple flags using the AND operator
|
||||
*
|
||||
* @param {number[]} flags - The flags to combine
|
||||
* @returns {number} The combined flags
|
||||
*
|
||||
* @since 0.0.2
|
||||
*/
|
||||
export function and(...flags: number[]) {
|
||||
return flags.reduce((acc, flag) => acc & flag, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name or
|
||||
* @category Bits
|
||||
* @description Function to combine multiple flags using the OR operator
|
||||
*
|
||||
* @param {number[]} flags - The flags to combine
|
||||
* @returns {number} The combined flags
|
||||
*
|
||||
* @since 0.0.2
|
||||
*/
|
||||
export function or(...flags: number[]) {
|
||||
return flags.reduce((acc, flag) => acc | flag, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name not
|
||||
* @category Bits
|
||||
* @description Function to combine multiple flags using the XOR operator
|
||||
*
|
||||
* @param {number} flag - The flag to apply the NOT operator to
|
||||
* @returns {number} The result of the NOT operator
|
||||
*
|
||||
* @since 0.0.2
|
||||
*/
|
||||
export function not(flag: number) {
|
||||
return ~flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name has
|
||||
* @category Bits
|
||||
* @description Function to make sure a flag has a specific bit set
|
||||
*
|
||||
* @param {number} flag - The flag to check
|
||||
* @param {number} other - Flag to check
|
||||
* @returns {boolean} Whether the flag has the bit set
|
||||
*
|
||||
* @since 0.0.2
|
||||
*/
|
||||
export function has(flag: number, other: number) {
|
||||
return (flag & other) === other;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name is
|
||||
* @category Bits
|
||||
* @description Function to check if a flag is set
|
||||
*
|
||||
* @param {number} flag - The flag to check
|
||||
* @returns {boolean} Whether the flag is set
|
||||
*
|
||||
* @since 0.0.2
|
||||
*/
|
||||
export function is(flag: number) {
|
||||
return flag !== 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name unset
|
||||
* @category Bits
|
||||
* @description Function to unset a flag
|
||||
*
|
||||
* @param {number} flag - Source flag
|
||||
* @param {number} other - Flag to unset
|
||||
* @returns {number} The new flag
|
||||
*
|
||||
* @since 0.0.2
|
||||
*/
|
||||
export function unset(flag: number, other: number) {
|
||||
return flag & ~other;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name toggle
|
||||
* @category Bits
|
||||
* @description Function to toggle (xor) a flag
|
||||
*
|
||||
* @param {number} flag - Source flag
|
||||
* @param {number} other - Flag to toggle
|
||||
* @returns {number} The new flag
|
||||
*
|
||||
* @since 0.0.2
|
||||
*/
|
||||
export function toggle(flag: number, other: number) {
|
||||
return flag ^ other;
|
||||
}
|
||||
Reference in New Issue
Block a user