/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { MapGetSet } from "./utils.js";
/**
 * A dictionary whose values are keyed off of two objects (key1, key2).
 * As it is a nested map, size() will return the number of distinct key1s.
 * If you need constant-time access to the number of values, use SizedNestedMap instead.
 *
 * This code assumes values will not be undefined (keys can be undefined).
 *
 * @internal
 */
export type NestedMap<Key1, Key2, Value> = Map<Key1, Map<Key2, Value>>;
/**
 * If (key1, key2) already has a value in the map, it is returned, otherwise value is added under (key1, key2) and undefined is returned.
 *
 * @internal
 */
export declare function tryAddToNestedMap<Key1, Key2, Value>(map: NestedMap<Key1, Key2, Value>, key1: Key1, key2: Key2, value: Value): Value | undefined;
/**
 * Copies over all entries from the source map into the destination map.
 *
 * @internal
 */
export declare function populateNestedMap<Key1, Key2, Value>(source: NestedMap<Key1, Key2, Value>, destination: NestedMap<Key1, Key2, Value>, override: boolean): void;
/**
 * Sets the value at (key1, key2) in map to value.
 * If there already is a value for (key1, key2), it is replaced with the provided one.
 *
 * @internal
 */
export declare function setInNestedMap<Key1, Key2, Value>(map: NestedMap<Key1, Key2, Value>, key1: Key1, key2: Key2, value: Value): void;
/**
 * Sets the value at `key` in map to value if not already present.
 * Returns the value at `key` after setting it.
 * This is equivalent to a get or default that adds the default to the map.
 */
export declare function getOrAddInMap<Key, Value>(map: MapGetSet<Key, Value>, key: Key, value: Value): Value;
/**
 * Returns the value at (key1, key2) in map, or undefined if not present.
 *
 * @internal
 */
export declare function tryGetFromNestedMap<Key1, Key2, Value>(map: NestedMap<Key1, Key2, Value>, key1: Key1, key2: Key2): Value | undefined;
/**
 * If (key1, key2) is not in the map, add value to the map.
 * Returns whatever is at (key1, key2) in map (which will be value if it was empty before).
 *
 * @internal
 */
export declare function getOrAddInNestedMap<Key1, Key2, Value>(map: NestedMap<Key1, Key2, Value>, key1: Key1, key2: Key2, value: Value): Value;
/**
 * Does not change map.
 * If (key1, key2) is not in map, returns value.
 * If (key1, key2) is in map, return its entry.
 *
 * @internal
 */
export declare function getOrDefaultInNestedMap<Key1, Key2, Value>(map: NestedMap<Key1, Key2, Value>, key1: Key1, key2: Key2, value: Value): Value;
/**
 * Removes the value at (key1, key2) from the map.
 *
 * @returns true iff found.
 *
 * @internal
 */
export declare function deleteFromNestedMap<Key1, Key2, Value>(map: NestedMap<Key1, Key2, Value>, key1: Key1, key2: Key2): boolean;
/**
 * Converts a nested map to a flat list of triplets.
 */
export declare function nestedMapToFlatList<Key1, Key2, Value>(map: NestedMap<Key1, Key2, Value>): [Key1, Key2, Value][];
/**
 * Builds a nested map from a flat list of triplets.
 */
export declare function nestedMapFromFlatList<Key1, Key2, Value>(list: readonly (readonly [Key1, Key2, Value])[]): NestedMap<Key1, Key2, Value>;
export declare function forEachInNestedMap<Key1, Key2, Value>(map: NestedMap<Key1, Key2, Value>, delegate: (value: Value, key1: Key1, key2: Key2) => void): void;
/**
 * Map with two keys; same semantics as NestedMap, but maintains a size count for the entire collection.
 * Note: undefined is not supported as a value, and will cause incorrect behavior.
 *
 * @internal
 */
export declare class SizedNestedMap<Key1, Key2, Value> {
    private readonly nestedMap;
    private count;
    /**
     * Returns the total number of elements in this nested map.
     */
    get size(): number;
    /**
     * If (key1, key2) already has a value in the map, it is returned, otherwise value is added under (key1, key2) and undefined is
     * returned.
     */
    tryGet(key1: Key1, key2: Key2): Value | undefined;
    /**
     * Does not change map.
     * If (key1, key2) is not in map, returns value.
     * If (key1, key2) is in map, return its entry.
     */
    getOrDefault(key1: Key1, key2: Key2, value: Value): Value;
    /**
     * If (key1, key2) already has a value in the map, it is returned, otherwise value is added under (key1, key2) and undefined is
     * returned.
     */
    tryAdd(key1: Key1, key2: Key2, value: Value): Value | undefined;
    /**
     * Sets the value at (key1, key2) in map to value.
     * If there already is a value for (key1, key2), it is replaced with the provided one.
     */
    set(key1: Key1, key2: Key2, value: Value): void;
    /**
     * Removes the value at (key1, key2) from the map.
     * Returns true iff found.
     */
    delete(key1: Key1, key2: Key2): boolean;
    /**
     * Runs the supplied delegate for every (value, key1, key2).
     */
    forEach(delegate: (value: Value, key1: Key1, key2: Key2) => void): void;
    /**
     * Clears the map.
     */
    clear(): void;
    values(): IterableIterator<Value>;
    [Symbol.iterator](): IterableIterator<[Key1, Map<Key2, Value>]>;
}
//# sourceMappingURL=nestedMap.d.ts.map