This repository has been archived on 2024-08-27. You can view files and clone it, but cannot push or open issues or pull requests.
negromate_origins/web/static/js/libjass/src/utility/set.ts

179 lines
3.9 KiB
TypeScript

/**
* libjass
*
* https://github.com/Arnavion/libjass
*
* Copyright 2013 Arnav Singh
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Set implementation for browsers that don't support it. Only supports Number and String elements.
*
* Elements are stored as properties of an object, with names derived from their type.
*
* @param {!Array.<T>=} iterable Only an array of values is supported.
*/
class SimpleSet<T> implements Set<T> {
private _elements: { [key: string]: T };
private _size: number;
constructor(iterable?: T[]) {
this.clear();
if (iterable === undefined) {
return;
}
if (!Array.isArray(iterable)) {
throw new Error("Non-array iterables are not supported by the SimpleSet constructor.");
}
for (const value of iterable) {
this.add(value);
}
}
/**
* @param {T} value
* @return {libjass.Set.<T>} This set
*/
add(value: T): this {
const property = toProperty(value);
if (property === null) {
throw new Error("This Set implementation only supports Number and String values.");
}
if (!(property in this._elements)) {
this._size++;
}
this._elements[property] = value;
return this;
}
/**
*/
clear(): void {
this._elements = Object.create(null);
this._size = 0;
}
/**
* @param {T} value
* @return {boolean}
*/
has(value: T): boolean {
const property = toProperty(value);
if (property === null) {
return false;
}
return property in this._elements;
}
/**
* @param {function(T, T, libjass.Set.<T>)} callbackfn A function that is called with each value in the set.
* @param {*} thisArg
*/
forEach(callbackfn: (value: T, index: T, set: this) => void, thisArg?: any): void {
for (const property of Object.keys(this._elements)) {
const element = this._elements[property];
callbackfn.call(thisArg, element, element, this);
}
}
/**
* @type {number}
*/
get size(): number {
return this._size;
}
}
/* tslint:disable:variable-name */
/**
* Set to the global implementation of Set if the environment has one, else set to {@link ./utility/set.SimpleSet}
*
* Can be set to a value using {@link libjass.configure}
*
* Set it to null to force {@link ./utility/set.SimpleSet} to be used even if a global Set is present.
*
* @type {function(new:Set, !Array.<T>=)}
*/
export let Set: {
new <T>(iterable?: T[]): Set<T>;
/* tslint:disable-next-line:member-ordering */
prototype: Set<any>;
} = (() => {
const globalSet = global.Set;
if (globalSet === undefined) {
return SimpleSet;
}
if (typeof globalSet.prototype.forEach !== "function") {
return SimpleSet;
}
try {
if ((new globalSet([1, 2])).size !== 2) {
return SimpleSet;
}
}
catch (ex) {
return SimpleSet;
}
return globalSet as any;
})();
/* tslint:enable:variable-name */
/**
* Sets the Set implementation used by libjass to the provided one. If null, {@link ./utility/set.SimpleSet} is used.
*
* @param {?function(new:Set, !Array.<T>=)} value
*/
export function setImplementation(value: typeof Set | null): void {
if (value !== null) {
Set = value;
}
else {
Set = SimpleSet;
}
}
/**
* Converts the given value into a property name for the internal map.
*
* @param {*} value
* @return {?string}
*/
function toProperty(value: any): string | null {
if (typeof value === "number") {
return `#${ value }`;
}
if (typeof value === "string") {
return `'${ value }`;
}
return null;
}