rc-js-util
Version:
A collection of TS and C++ utilities to help writing performant and correct applications, achieved through strict typing and (removable) invariant checking.
74 lines (61 loc) • 1.79 kB
text/typescript
import { arrayCopyInto } from "../array/impl/array-copy-into.js";
/**
* @public
* Presents an array as if it were circular, going past the end or start loops around.
*
* @remarks
* Supports negative indexes.
*/
export class CircularBuffer<TValue>
{
public readonly size: number;
public static createEmpty<TValue>(size: number): CircularBuffer<TValue>
{
return new CircularBuffer<TValue>(new Array<TValue>(size));
}
public static createOne<TValue>(initialValues: TValue[]): CircularBuffer<TValue>
{
return new CircularBuffer<TValue>(initialValues);
}
public clone(): CircularBuffer<TValue>
{
const clone = CircularBuffer.createEmpty<TValue>(this.size);
arrayCopyInto(this.values, clone.values);
return clone;
}
public getValue(index: number): TValue
{
return this.values[this.getAdjustedIndex(index)];
}
public setValue(index: number, value: TValue): void
{
this.values[this.getAdjustedIndex(index)] = value;
}
/**
* returns the value stored at the index and sets the provided value
*/
public getSetValue(index: number, value: TValue): TValue
{
const adjustedIndex = this.getAdjustedIndex(index);
const previousValue = this.values[adjustedIndex];
this.values[adjustedIndex] = value;
return previousValue;
}
protected constructor
(
private readonly values: TValue[],
)
{
this.size = values.length;
}
private getAdjustedIndex(index: number): number
{
const length = this.values.length;
const remainder = index % length;
if (remainder >= 0)
{
return remainder;
}
return length + remainder;
}
}