+ public concat (...items: Array<T | ConcatArray<T>>): CircularArray<T> {
+ const concatenatedCircularArray = super.concat(items as T[]) as CircularArray<T>
+ concatenatedCircularArray.size = this.size
+ if (concatenatedCircularArray.length > concatenatedCircularArray.size) {
+ concatenatedCircularArray.splice(
+ 0,
+ concatenatedCircularArray.length - concatenatedCircularArray.size
+ )
+ }
+ return concatenatedCircularArray
+ }
+
+ public splice (start: number, deleteCount?: number, ...items: T[]): CircularArray<T> {
+ let itemsRemoved: T[] = []
+ if (arguments.length >= 3 && deleteCount != null) {
+ itemsRemoved = super.splice(start, deleteCount, ...items)
+ if (this.length > this.size) {
+ const itemsOverflowing = super.splice(0, this.length - this.size)
+ itemsRemoved = new CircularArray<T>(
+ itemsRemoved.length + itemsOverflowing.length,
+ ...itemsRemoved,
+ ...itemsOverflowing
+ )
+ }
+ } else if (arguments.length === 2) {
+ itemsRemoved = super.splice(start, deleteCount)
+ } else {
+ itemsRemoved = super.splice(start)
+ }
+ return itemsRemoved as CircularArray<T>
+ }
+
+ public resize (size: number): void {
+ this.checkSize(size)
+ if (size === 0) {
+ this.length = 0
+ } else if (size < this.size) {
+ for (let i = size; i < this.size; i++) {
+ super.pop()
+ }
+ }
+ this.size = size
+ }
+
+ public empty (): boolean {
+ return this.length === 0
+ }
+
+ public full (): boolean {
+ return this.length === this.size
+ }
+
+ private checkSize (size: number): void {
+ if (!Number.isSafeInteger(size)) {
+ throw new TypeError(`Invalid circular array size: ${size} is not a safe integer`)
+ }
+ if (size < 0) {
+ throw new RangeError(`Invalid circular array size: ${size} < 0`)