import type { RMap } from '@rimbu/collection-types/map';
import { EmptyBase, NonEmptyBase, type Elem, type WithElem } from '@rimbu/collection-types/map-custom';
import { Reducer, Stream, type StreamSource } from '@rimbu/stream';
import { TraverseState, type ArrayNonEmpty, type RelatedTo, type ToJSON } from '@rimbu/common';
import type { MultiSetBase } from '@rimbu/multiset/custom';
export interface ContextImplTypes extends MultiSetBase.Types {
    readonly context: MultiSetContext<this['_T'], string>;
}
export declare class MultiSetEmpty<T, Tp extends ContextImplTypes> extends EmptyBase implements MultiSetBase<T, Tp> {
    readonly context: WithElem<Tp, T>['context'];
    _NonEmptyType: WithElem<Tp, T>['nonEmpty'];
    constructor(context: WithElem<Tp, T>['context']);
    add(elem: T, amount?: number): WithElem<Tp, T>['nonEmpty'];
    get countMap(): WithElem<Tp, T>['countMap'];
    get sizeDistinct(): 0;
    streamDistinct(): Stream<T>;
    addAll(values: StreamSource<T>): WithElem<Tp, T>['nonEmpty'];
    addEntries(entries: StreamSource<readonly [T, number]>): WithElem<Tp, T>['normal'];
    remove(): WithElem<Tp, T>['normal'];
    removeAllSingle(): WithElem<Tp, T>['normal'];
    removeAllEvery(): WithElem<Tp, T>['normal'];
    setCount(elem: T, amount: number): WithElem<Tp, T>['normal'];
    modifyCount(value: T, update: (currentCount: number) => number): WithElem<Tp, T>['normal'];
    has(): false;
    count(): 0;
    forEach(): void;
    filterEntries(): WithElem<Tp, T>['normal'];
    toBuilder(): WithElem<Tp, T>['builder'];
    toArray(): [];
    toString(): string;
    toJSON(): ToJSON<[any, number][]>;
}
export declare class MultiSetNonEmpty<T, Tp extends ContextImplTypes, TpG extends WithElem<Tp, T> = WithElem<Tp, T>> extends NonEmptyBase<T> implements MultiSetBase.NonEmpty<T, Tp> {
    readonly context: TpG['context'];
    readonly countMap: TpG['countMapNonEmpty'];
    readonly size: number;
    _NonEmptyType: TpG['nonEmpty'];
    constructor(context: TpG['context'], countMap: TpG['countMapNonEmpty'], size: number);
    assumeNonEmpty(): any;
    copy(countMap: TpG['countMapNonEmpty'], size: number): TpG['nonEmpty'];
    copyE(countMap: TpG['countMap'], size: number): TpG['normal'];
    get sizeDistinct(): number;
    stream(): Stream.NonEmpty<T>;
    streamDistinct(): Stream.NonEmpty<T>;
    has<U>(elem: RelatedTo<T, U>): boolean;
    count<U>(elem: RelatedTo<T, U>): number;
    add(elem: T, amount?: number): WithElem<Tp, T>['nonEmpty'];
    addAll(values: StreamSource<T>): TpG['nonEmpty'];
    addEntries(entries: StreamSource<readonly [T, number]>): TpG['nonEmpty'];
    setCount(elem: T, amount: number): TpG['normal'];
    modifyCount(value: T, update: (currentCount: number) => number): TpG['normal'];
    remove<U>(elem: RelatedTo<T, U>, options?: {
        amount?: number | 'ALL';
    }): TpG['normal'];
    removeAllSingle<U>(elems: StreamSource<RelatedTo<T, U>>): TpG['normal'];
    removeAllEvery<U>(elems: StreamSource<RelatedTo<T, U>>): TpG['normal'];
    forEach(f: (value: T, index: number, halt: () => void) => void, options?: {
        reversed?: boolean;
        state?: TraverseState;
    }): void;
    filterEntries(pred: (entry: readonly [T, number], index: number) => boolean, options?: {
        negate?: boolean | undefined;
    }): TpG['normal'];
    toArray(): ArrayNonEmpty<T>;
    toString(): string;
    toJSON(): ToJSON<(readonly [T, number])[]>;
    toBuilder(): TpG['builder'];
}
export declare class MultiSetBuilder<T, Tp extends ContextImplTypes, TpG extends WithElem<Tp, T> = WithElem<Tp, T>> implements MultiSetBase.Builder<T, Tp> {
    readonly context: TpG['context'];
    source?: TpG["nonEmpty"] | undefined;
    _lock: number;
    _size: number;
    constructor(context: TpG['context'], source?: TpG["nonEmpty"] | undefined);
    _countMap?: RMap.Builder<T, number>;
    get countMap(): RMap.Builder<T, number>;
    checkLock(): void;
    get size(): number;
    get sizeDistinct(): number;
    get isEmpty(): boolean;
    has: <U>(value: RelatedTo<T, U>) => boolean;
    add: (value: T, amount?: number) => boolean;
    addAll: (source: StreamSource<T>) => boolean;
    addEntries: (entries: StreamSource<readonly [T, number]>) => boolean;
    remove: <U>(value: RelatedTo<T, U>, amount?: number | "ALL") => number;
    setCount: (value: T, amount: number) => boolean;
    modifyCount: (value: T, update: (currentCount: number) => number) => boolean;
    count: <U>(value: RelatedTo<T, U>) => number;
    removeAll: <U>(values: StreamSource<RelatedTo<T, U>>, mode: "SINGLE" | "ALL") => boolean;
    removeAllSingle: <U>(values: StreamSource<RelatedTo<T, U>>) => boolean;
    removeAllEvery: <U>(values: StreamSource<RelatedTo<T, U>>) => boolean;
    forEach: (f: (value: T, index: number, halt: () => void) => void, options?: {
        state?: TraverseState;
    }) => void;
    build: () => TpG["normal"];
}
export declare class MultiSetContext<UT, N extends string, Tp extends ContextImplTypes = ContextImplTypes> implements MultiSetBase.Context<UT, Tp> {
    readonly typeTag: N;
    readonly countMapContext: (Tp & Elem<UT>)['countMapContext'];
    constructor(typeTag: N, countMapContext: (Tp & Elem<UT>)['countMapContext']);
    get _types(): Tp;
    isValidElem(elem: any): elem is UT;
    readonly _empty: WithElem<Tp, UT>['normal'];
    isNonEmptyInstance<T>(source: any): source is WithElem<Tp, T>['nonEmpty'];
    createNonEmpty<T extends UT>(countMap: WithElem<Tp, T>['countMapNonEmpty'], size: number): WithElem<Tp, T>['nonEmpty'];
    readonly empty: <T extends UT>() => WithElem<Tp, T>["normal"];
    readonly from: any;
    readonly of: <T>(...values: ArrayNonEmpty<T>) => T extends UT ? WithElem<Tp, T>["nonEmpty"] : never;
    readonly builder: <T extends UT>() => WithElem<Tp, T>["builder"];
    readonly reducer: <T extends UT>(source?: StreamSource<T>) => Reducer<T, WithElem<Tp, T>["normal"]>;
    createBuilder<T extends UT>(source?: WithElem<Tp, T>['nonEmpty']): WithElem<Tp, T>['builder'];
}
