1 // Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
3 const DEFAULT_CIRCULAR_ARRAY_SIZE
= 1024
6 * Array with a maximum length and shifting items when full.
8 export class CircularArray
<T
> extends Array<T
> {
11 constructor (size
: number = DEFAULT_CIRCULAR_ARRAY_SIZE
, ...items
: T
[]) {
15 if (arguments.length
> 1) {
20 public push (...items
: T
[]): number {
21 const length
= super.push(...items
)
22 if (length
> this.size
) {
23 super.splice(0, length
- this.size
)
28 public unshift (...items
: T
[]): number {
29 const length
= super.unshift(...items
)
30 if (length
> this.size
) {
31 super.splice(this.size
, items
.length
)
36 public concat (...items
: Array<T
| ConcatArray
<T
>>): CircularArray
<T
> {
37 const concatenatedCircularArray
= super.concat(
40 concatenatedCircularArray
.size
= this.size
41 if (concatenatedCircularArray
.length
> concatenatedCircularArray
.size
) {
42 concatenatedCircularArray
.splice(
44 concatenatedCircularArray
.length
- concatenatedCircularArray
.size
47 return concatenatedCircularArray
50 public splice (start
: number, deleteCount
?: number, ...items
: T
[]): T
[] {
52 if (arguments.length
>= 3 && deleteCount
!== undefined) {
53 itemsRemoved
= super.splice(start
, deleteCount
)
54 // FIXME: that makes the items insert not in place
56 } else if (arguments.length
=== 2) {
57 itemsRemoved
= super.splice(start
, deleteCount
)
59 itemsRemoved
= super.splice(start
)
64 public resize (size
: number): void {
68 } else if (size
< this.size
) {
69 for (let i
= size
; i
< this.size
; i
++) {
76 public empty (): boolean {
77 return this.length
=== 0
80 public full (): boolean {
81 return this.length
=== this.size
84 private checkSize (size
: number): void {
85 if (!Number.isSafeInteger(size
)) {
87 `Invalid circular array size: ${size} is not a safe integer`
91 throw new RangeError(`Invalid circular array size: ${size} < 0`)