//================================================================ /** * @packageDocumentation * @module std */ //================================================================ import { MultiTreeMap } from "../internal/container/associative/MultiTreeMap"; import { ITreeContainer } from "../internal/container/associative/ITreeContainer"; import { IForwardIterator } from "../iterator/IForwardIterator"; import { MapElementList } from "../internal/container/associative/MapElementList"; import { MultiMapTree } from "../internal/tree/MultiMapTree"; import { Comparator } from "../internal/functional/Comparator"; import { IPair } from "../utility/IPair"; import { Entry } from "../utility/Entry"; import { Temporary } from "../internal/functional/Temporary"; /** * Multiple-key Map based on Tree. * * @author Jeongho Nam - https://github.com/samchon */ export class TreeMultiMap extends MultiTreeMap< Key, T, TreeMultiMap, TreeMultiMap.Iterator, TreeMultiMap.ReverseIterator > { private tree_!: MultiMapTree>; /* --------------------------------------------------------- CONSTURCTORS --------------------------------------------------------- */ /** * Default Constructor. * * @param comp A binary function predicates *x* element would be placed before *y*. When returns `true`, then *x* precedes *y*. Note that, because *equality* is predicated by `!comp(x, y) && !comp(y, x)`, the function must not cover the *equality* like `<=` or `>=`. It must exclude the *equality* like `<` or `>`. Default is {@link less}. */ public constructor(comp?: Comparator); /** * Initializer Constructor. * * @param items Items to assign. * @param comp A binary function predicates *x* element would be placed before *y*. When returns `true`, then *x* precedes *y*. Note that, because *equality* is predicated by `!comp(x, y) && !comp(y, x)`, the function must not cover the *equality* like `<=` or `>=`. It must exclude the *equality* like `<` or `>`. Default is {@link less}. */ public constructor(items: IPair[], comp?: Comparator); /** * Copy Constructor. * * @param obj Object to copy. */ public constructor(obj: TreeMultiMap); /** * Range Constructor. * * @param first Input iterator of the first position. * @param last Input iterator of the last position. * @param comp A binary function predicates *x* element would be placed before *y*. When returns `true`, then *x* precedes *y*. Note that, because *equality* is predicated by `!comp(x, y) && !comp(y, x)`, the function must not cover the *equality* like `<=` or `>=`. It must exclude the *equality* like `<` or `>`. Default is {@link less}. */ public constructor( first: Readonly>>, last: Readonly>>, comp?: Comparator, ); public constructor(...args: any[]) { super((thisArg) => new MapElementList(thisArg) as Temporary); ITreeContainer.construct< Key, Entry, TreeMultiMap, TreeMultiMap.Iterator, TreeMultiMap.ReverseIterator, IPair >( this, TreeMultiMap, (comp) => { this.tree_ = new MultiMapTree( this as TreeMultiMap, comp, ); }, ...args, ); } /** * @inheritDoc */ public clear(): void { super.clear(); this.tree_.clear(); } /** * @inheritDoc */ public swap(obj: TreeMultiMap): void { // SWAP CONTENTS [this.data_, obj.data_] = [obj.data_, this.data_]; MapElementList._Swap_associative( this.data_ as Temporary, obj.data_ as Temporary, ); // SWAP RB-TREE MultiMapTree._Swap_source(this.tree_, obj.tree_); [this.tree_, obj.tree_] = [obj.tree_, this.tree_]; } /* --------------------------------------------------------- ACCESSORS --------------------------------------------------------- */ /** * @inheritDoc */ public key_comp(): Comparator { return this.tree_.key_comp(); } /** * @inheritDoc */ public lower_bound(key: Key): TreeMultiMap.Iterator { return this.tree_.lower_bound(key); } /** * @inheritDoc */ public upper_bound(key: Key): TreeMultiMap.Iterator { return this.tree_.upper_bound(key); } /* --------------------------------------------------------- POST-PROCESS --------------------------------------------------------- */ protected _Handle_insert( first: TreeMultiMap.Iterator, last: TreeMultiMap.Iterator, ): void { for (; !first.equals(last); first = first.next()) this.tree_.insert(first); } protected _Handle_erase( first: TreeMultiMap.Iterator, last: TreeMultiMap.Iterator, ): void { for (; !first.equals(last); first = first.next()) this.tree_.erase(first); } } /** * */ export namespace TreeMultiMap { // HEAD /** * Iterator of {@link TreeMultiMap} */ export type Iterator = MapElementList.Iterator< Key, T, false, TreeMultiMap >; /** * Iterator of {@link TreeMultiMap} */ export type ReverseIterator = MapElementList.ReverseIterator< Key, T, false, TreeMultiMap >; // BODY export const Iterator = MapElementList.Iterator; export const ReverseIterator = MapElementList.ReverseIterator; }