import { ListNode } from '../core/list-node.js';

type Factory<T, A extends unknown[]> = (...args: A) => T;
interface ListOptions<T, A extends unknown[]> {
    initValues?: T[];
    factory?: Factory<T, A>;
}
declare class LinkedList<T, A extends unknown[] = [T]> {
    #private;
    constructor({ initValues, factory }?: ListOptions<T, A>);
    [Symbol.iterator](): IterableIterator<T>;
    rbegin(): IterableIterator<T>;
    begin(): IterableIterator<T>;
    pushFront(value: T): void;
    pushBack(value: T): void;
    popFront(): T | undefined;
    popBack(): T | undefined;
    insertAt(val: T, index: number): void;
    eraseAt(index: number): T | undefined;
    emplaceFront(...args: A): void;
    emplaceBack(...args: A): void;
    emplaceAt(index: number, ...args: A): void;
    isEmpty(): boolean;
    clear(): void;
    toArray(): T[];
    assign(count: number, value: T): void;
    assign(values: T[], start?: number, end?: number): void;
    forEach(callback: (value: T, index: number, list: LinkedList<T, A>) => void | false, thisArg?: unknown): void;
    reverse(): void;
    remove(val: T, compareFn?: (currValue: T, constValue: T) => boolean): number;
    get length(): number;
    get front(): T | undefined;
    set front(val: T);
    get back(): T | void;
    set back(val: T);
    static swap<U, V extends unknown[] = [U]>(list1: LinkedList<U, V> | null, list2: LinkedList<U, V> | null): void;
    static merge<U, V extends unknown[] = [U]>(target: LinkedList<U, V> | null, source: LinkedList<U, V> | null, compareFn?: (a: U, b: U) => number): void;
    static buildNodes<T>(values: T[]): {
        head: ListNode<T> | null;
        tail: ListNode<T> | null;
    };
}

export { LinkedList };
