import { EmptyBase, NonEmptyBase } from '@rimbu/collection-types/map-custom';
import { IndexRange, OptLazy, TraverseState } from '@rimbu/common';
import { Stream } from '@rimbu/stream';
export declare class SortedEmpty extends EmptyBase {
    min<O>(otherwise?: OptLazy<O>): O;
    max<O>(otherwise?: OptLazy<O>): O;
    getAtIndex<O>(index: number, otherwise?: OptLazy<O>): O;
    take(): any;
    drop(): any;
    sliceIndex(): any;
}
export declare abstract class SortedNonEmptyBase<E, TS extends SortedNonEmptyBase<E, TS>> extends NonEmptyBase<E> {
    abstract getAtIndex<O>(index: number, otherwise?: OptLazy<O>): E | O;
    abstract get entries(): readonly E[];
    abstract takeInternal(amount: number): TS;
    abstract dropInternal(amount: number): TS;
    abstract mutateSplitRight(index?: number): [E, TS];
    abstract mutateGiveToLeft(left: TS, toLeft: E): [E, TS];
    abstract mutateGiveToRight(right: TS, toRight: E): [E, TS];
    abstract mutateGetFromLeft(left: TS, toMe: E): [E, TS];
    abstract mutateGetFromRight(right: TS, toMe: E): [E, TS];
    abstract mutateJoinLeft(left: TS, entry: E): void;
    abstract mutateJoinRight(right: TS, entry: E): void;
    abstract deleteMin(): [E, TS];
    abstract deleteMax(): [E, TS];
    get mutateEntries(): E[];
}
export interface LeafMutateSource<TS extends LeafMutateSource<TS, E>, E> {
    mutateEntries: E[];
    entries: readonly E[];
    copy(entries: readonly E[]): TS;
}
export declare function leafDeleteMin<S extends LeafMutateSource<S, E>, E>(source: S): [E, S];
export declare function leafDeleteMax<S extends LeafMutateSource<S, E>, E>(source: S): [E, S];
export declare function leafMutateSplitRight<S extends LeafMutateSource<S, E>, E>(source: S, index?: number): [E, S];
export declare function leafMutateGiveToLeft<S extends LeafMutateSource<S, E>, E>(source: S, left: S, toLeft: E): [E, S];
export declare function leafMutateGiveToRight<S extends LeafMutateSource<S, E>, E>(source: S, right: S, toRight: E): [E, S];
export declare function leafMutateGetFromLeft<S extends LeafMutateSource<S, E>, E>(source: S, left: S, toMe: E): [E, S];
export declare function leafMutateGetFromRight<S extends LeafMutateSource<S, E>, E>(source: S, right: S, toMe: E): [E, S];
export declare function leafMutateJoinLeft<S extends LeafMutateSource<S, E>, E>(source: S, left: S, entry: E): void;
export declare function leafMutateJoinRight<S extends LeafMutateSource<S, E>, E>(source: S, right: S, entry: E): void;
export interface InnerChild<E> {
    readonly size: number;
    getAtIndex<O>(index: number, otherwise?: OptLazy<O>): E | O;
    stream(options?: {
        reversed?: boolean;
    }): Stream<E>;
    streamSliceIndex(range: IndexRange, options?: {
        reversed?: boolean;
    }): Stream<E>;
    readonly entries: readonly E[];
    takeInternal(amount: number): InnerChild<E>;
    dropInternal(amount: number): InnerChild<E>;
    deleteMin(): [E, InnerChild<E>];
    deleteMax(): [E, InnerChild<E>];
    mutateGiveToLeft(left: InnerChild<E>, toLeft: E): [E, InnerChild<E>];
    mutateGiveToRight(right: InnerChild<E>, toRight: E): [E, InnerChild<E>];
    mutateSplitRight(index?: number): [E, InnerChild<E>];
    mutateJoinLeft(left: InnerChild<E>, entry: E): void;
    mutateJoinRight(right: InnerChild<E>, entry: E): void;
    mutateGetFromLeft(left: InnerChild<E>, toMe: E): [E, InnerChild<E>];
    mutateGetFromRight(right: InnerChild<E>, toMe: E): [E, InnerChild<E>];
}
export interface InnerMutateSource<TS extends InnerMutateSource<TS, E>, E> {
    readonly context: {
        readonly minEntries: number;
        readonly maxEntries: number;
        inner(entries: readonly E[], children: readonly InnerChild<E>[], size: number): TS;
    };
    size: number;
    entries: readonly E[];
    mutateEntries: E[];
    children: readonly InnerChild<E>[];
    mutateChildren: InnerChild<E>[];
    stream(options?: {
        reversed?: boolean;
    }): Stream.NonEmpty<E>;
    copy(entries?: readonly E[], children?: readonly InnerChild<E>[], size?: number): TS;
    addInternal(entry: E): TS;
    normalizeDownsizeChild(childIndex: number, newChild: InnerChild<E>, newSize: number): TS;
    normalizeIncreaseChild(childIndex: number, newChild: InnerChild<E>, newSize: number): TS;
}
export declare function innerDeleteMin<S extends InnerMutateSource<S, E>, E>(source: S): [E, S];
export declare function innerDeleteMax<S extends InnerMutateSource<S, E>, E>(source: S): [E, S];
export declare function innerMutateSplitRight<S extends InnerMutateSource<S, E>, E>(source: S, index?: number): [E, S];
export declare function innerMutateGiveToLeft<S extends InnerMutateSource<S, E>, E>(source: S, left: S, toLeft: E): [E, S];
export declare function innerMutateGiveToRight<S extends InnerMutateSource<S, E>, E>(source: S, right: S, toRight: E): [E, S];
export declare function innerMutateGetFromLeft<S extends InnerMutateSource<S, E>, E>(source: S, left: S, toMe: E): [E, S];
export declare function innerMutateGetFromRight<S extends InnerMutateSource<S, E>, E>(source: S, right: S, toMe: E): [E, S];
export declare function innerMutateJoinLeft<S extends InnerMutateSource<S, E>, E>(source: S, left: S, entry: E): void;
export declare function innerMutateJoinRight<S extends InnerMutateSource<S, E>, E>(source: S, right: S, entry: E): void;
export declare function innerNormalizeDownsizeChild<S extends InnerMutateSource<S, E>, E>(source: S, childIndex: number, newChild: InnerChild<E>, newSize: number): S;
export declare function innerNormalizeIncreaseChild<S extends InnerMutateSource<S, E>, E>(source: S, childIndex: number, newChild: InnerChild<E>, newSize: number): S;
/**
 * Returns the index of the element in the sources element array, or a tuple with the child index and the index within the child
 * @param source the collection to operate on
 * @param index the index to find
 */
export declare function innerGetSubIndex(source: InnerMutateSource<any, any>, index: number): number | [number, number];
export declare function innerGetAtIndex<E, O>(source: InnerMutateSource<any, E>, index: number, otherwise?: OptLazy<O>): E | O;
export declare function innerTakeInternal<S extends InnerMutateSource<S, E>, E>(source: S, amount: number): S;
export declare function innerDropInternal<S extends InnerMutateSource<S, E>, E>(source: S, amount: number): S;
export declare function innerStreamSliceIndex<E>(source: InnerMutateSource<any, E>, range: IndexRange, reversed?: boolean): Stream<E>;
export declare abstract class SortedBuilder<E> {
    abstract get context(): {
        minEntries: number;
        maxEntries: number;
    };
    abstract source?: undefined | {
        min<O>(otherwise?: OptLazy<O>): E | O;
        max<O>(otherwise?: OptLazy<O>): E | O;
        getAtIndex<O>(index: number, otherwise?: OptLazy<O>): E | O;
        forEach(f: (entry: E, index: number, halt: () => void) => void, options?: {
            state?: TraverseState;
        }): void;
    };
    abstract _entries?: undefined | E[];
    abstract _children?: undefined | SortedBuilder<E>[];
    abstract get children(): SortedBuilder<E>[];
    abstract set children(value: SortedBuilder<E>[]);
    abstract size: number;
    abstract prepareMutate(): void;
    abstract createNew(source?: undefined | unknown, entries?: undefined | E[], children?: undefined | SortedBuilder<E>[], size?: undefined | number): SortedBuilder<E>;
    _lock: number;
    checkLock(): void;
    get entries(): E[];
    set entries(value: E[]);
    get hasChildren(): boolean;
    get isEmpty(): boolean;
    min<O>(otherwise?: OptLazy<O>): E | O;
    max<O>(otherwise?: OptLazy<O>): E | O;
    getAtIndex<O>(index: number, otherwise?: OptLazy<O>): E | O;
    forEach(f: (entry: E, index: number, halt: () => void) => void, options?: {
        state?: TraverseState;
    }): void;
    normalize(): void;
    normalizeChildIncrease(childIndex: number): void;
    normalizeChildDecrease(childIndex: number): void;
    deleteMin(): E;
    deleteMax(): E;
}
