UNPKG

scontainers

Version:

A container/collection/iterator library for JavaScript, comfortable to use, performant and versatile.

142 lines (107 loc) 2.77 kB
"use strict"; function _implSymbol(target, sym, value) { Object.defineProperty(target, sym, { value, configurable: true }); return target[sym]; } function _getSymbol(targetSymName, ...traitSets) { let symbol; traitSets.forEach(traitSet => { const sym = traitSet[targetSymName]; if (typeof sym === 'symbol') { if (!!symbol && symbol !== sym) { throw new Error(`Symbol ${targetSymName} offered by multiple trait sets.`); } symbol = sym; } }); if (!symbol) { throw new Error(`No trait set is providing symbol ${targetSymName}.`); } return symbol; } function _testTraitSet(traitSet) { if (!traitSet || typeof traitSet === 'boolean' || typeof traitSet === 'number' || typeof traitSet === 'string') { throw new Error(`${traitSet} cannot be used as a trait set.`); } } const { traits, id } = require('../utils.js'); _testTraitSet(traits.utils); _testTraitSet(traits.scontainers); _testTraitSet(traits.semantics); const _describeScontainer = _getSymbol("describeScontainer", traits.utils, traits.scontainers, traits.semantics); const _implCoreGenerators = _getSymbol("implCoreGenerators", traits.utils, traits.scontainers, traits.semantics); const _plus = _getSymbol("plus", traits.utils, traits.scontainers, traits.semantics); const _minus = _getSymbol("minus", traits.utils, traits.scontainers, traits.semantics); const _implCoreTraits = _getSymbol("implCoreTraits", traits.utils, traits.scontainers, traits.semantics); class Range { constructor(begin, end) { if (end !== undefined) { if (begin !== undefined) { this.begin = begin; } this.end = end; } else if (begin !== undefined) { this.end = begin; this.begin = 0; } else { this.end = Infinity; this.begin = 0; } } len() { return this.end - this.begin; } toString() { return `${this.begin}${this.end}`; } } Range[_describeScontainer]({ argKeys: [id`begin`, id`end`] }); Range[_implCoreGenerators]({ nToKey(n) { return n[_plus](this.args.begin); }, keyToN(key) { return key[_minus](this.args.begin); }, nthUnchecked(n) { return n[_plus](this.args.begin); }, // add: nope len() { const { begin, end } = this.args; return end[_minus](begin); } }); Range[_implCoreTraits]({ nthUnchecked(n) { return this.begin + n; }, keyToN(key) { return key - this.begin; }, nToKey(n) { return n + this.begin; }, len() { return this.len(); }, // optimizations sum() { return (this.begin + this.end - 1) * this.len() / 2; }, slice(begin, end) { return new Range(this.begin + begin, this.begin + end); } }); module.exports = Range;