2022-03-08 03:13:53 -05:00
|
|
|
package funkin.audiovis.dsp;
|
2021-09-27 22:30:38 -04:00
|
|
|
|
|
|
|
/**
|
2023-01-22 22:25:45 -05:00
|
|
|
A view into an Array with an indexing offset.
|
2021-09-27 22:30:38 -04:00
|
|
|
|
2023-01-22 22:25:45 -05:00
|
|
|
Usages include 1-indexed sequences or zero-centered buffers with negative indexing.
|
2021-09-27 22:30:38 -04:00
|
|
|
**/
|
|
|
|
@:forward(array, offset)
|
|
|
|
abstract OffsetArray<T>({
|
2023-01-22 22:25:45 -05:00
|
|
|
final array:Array<T>;
|
|
|
|
final offset:Int;
|
2022-02-10 13:17:46 -05:00
|
|
|
})
|
|
|
|
{
|
2023-01-22 22:25:45 -05:00
|
|
|
public inline function new(array:Array<T>, offset:Int)
|
|
|
|
this = {array: array, offset: offset};
|
|
|
|
|
|
|
|
public var length(get, never):Int;
|
|
|
|
|
|
|
|
inline function get_length()
|
|
|
|
return this.array.length;
|
|
|
|
|
|
|
|
@:arrayAccess
|
|
|
|
public inline function get(index:Int):T
|
|
|
|
return this.array[index - this.offset];
|
|
|
|
|
|
|
|
@:arrayAccess
|
|
|
|
public inline function set(index:Int, value:T):Void
|
|
|
|
this.array[index - this.offset] = value;
|
|
|
|
|
|
|
|
/**
|
|
|
|
Iterates through items in their original order while providing the altered indexes as keys.
|
|
|
|
**/
|
|
|
|
public inline function keyValueIterator():KeyValueIterator<Int, T>
|
|
|
|
return new OffsetArrayIterator(this.array, this.offset);
|
|
|
|
|
|
|
|
@:from
|
|
|
|
static inline function fromArray<T>(array:Array<T>)
|
|
|
|
return new OffsetArray(array, 0);
|
|
|
|
|
|
|
|
@:to
|
|
|
|
inline function toArray()
|
|
|
|
return this.array;
|
|
|
|
|
|
|
|
/**
|
|
|
|
Makes a shifted version of the given `array`, where elements are in the
|
|
|
|
same order but shifted by `n` positions (to the right if positive and to
|
|
|
|
the left if negative) in **circular** fashion (no elements discarded).
|
|
|
|
**/
|
|
|
|
public static function circShift<T>(array:Array<T>, n:Int):Array<T>
|
|
|
|
{
|
|
|
|
if (n < 0) return circShift(array, array.length + n);
|
|
|
|
|
|
|
|
var shifted = new Array<T>();
|
|
|
|
|
|
|
|
n = n % array.length;
|
|
|
|
for (i in array.length - n...array.length)
|
|
|
|
shifted.push(array[i]);
|
|
|
|
for (i in 0...array.length - n)
|
|
|
|
shifted.push(array[i]);
|
|
|
|
|
|
|
|
return shifted;
|
|
|
|
}
|
2021-09-27 22:30:38 -04:00
|
|
|
}
|
|
|
|
|
2022-02-10 13:17:46 -05:00
|
|
|
private class OffsetArrayIterator<T>
|
|
|
|
{
|
2023-01-22 22:25:45 -05:00
|
|
|
final array:Array<T>;
|
|
|
|
final offset:Int;
|
|
|
|
var enumeration:Int;
|
|
|
|
|
|
|
|
public inline function new(array:Array<T>, offset:Int)
|
|
|
|
{
|
|
|
|
this.array = array;
|
|
|
|
this.offset = offset;
|
|
|
|
this.enumeration = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public inline function next():{key:Int, value:T}
|
|
|
|
{
|
|
|
|
final i = this.enumeration++;
|
|
|
|
return {key: i + this.offset, value: this.array[i]};
|
|
|
|
}
|
|
|
|
|
|
|
|
public inline function hasNext():Bool
|
|
|
|
return this.enumeration < this.array.length;
|
2021-09-27 22:30:38 -04:00
|
|
|
}
|