"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RedBlackTreeIterator = exports.Direction = void 0; var Arr = _interopRequireWildcard(require("../../Array.js")); var Option = _interopRequireWildcard(require("../../Option.js")); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } /** @internal */ const Direction = exports.Direction = { Forward: 0, Backward: 1 << 0 }; /** @internal */ class RedBlackTreeIterator { self; stack; direction; count = 0; constructor(self, stack, direction) { this.self = self; this.stack = stack; this.direction = direction; } /** * Clones the iterator */ clone() { return new RedBlackTreeIterator(this.self, this.stack.slice(), this.direction); } /** * Reverse the traversal direction */ reversed() { return new RedBlackTreeIterator(this.self, this.stack.slice(), this.direction === Direction.Forward ? Direction.Backward : Direction.Forward); } /** * Iterator next */ next() { const entry = this.entry; this.count++; if (this.direction === Direction.Forward) { this.moveNext(); } else { this.movePrev(); } switch (entry._tag) { case "None": { return { done: true, value: this.count }; } case "Some": { return { done: false, value: entry.value }; } } } /** * Returns the key */ get key() { if (this.stack.length > 0) { return Option.some(this.stack[this.stack.length - 1].key); } return Option.none(); } /** * Returns the value */ get value() { if (this.stack.length > 0) { return Option.some(this.stack[this.stack.length - 1].value); } return Option.none(); } /** * Returns the key */ get entry() { return Option.map(Arr.last(this.stack), node => [node.key, node.value]); } /** * Returns the position of this iterator in the sorted list */ get index() { let idx = 0; const stack = this.stack; if (stack.length === 0) { const r = this.self._root; if (r != null) { return r.count; } return 0; } else if (stack[stack.length - 1].left != null) { idx = stack[stack.length - 1].left.count; } for (let s = stack.length - 2; s >= 0; --s) { if (stack[s + 1] === stack[s].right) { ; ++idx; if (stack[s].left != null) { idx += stack[s].left.count; } } } return idx; } /** * Advances iterator to next element in list */ moveNext() { const stack = this.stack; if (stack.length === 0) { return; } let n = stack[stack.length - 1]; if (n.right != null) { n = n.right; while (n != null) { stack.push(n); n = n.left; } } else { stack.pop(); while (stack.length > 0 && stack[stack.length - 1].right === n) { n = stack[stack.length - 1]; stack.pop(); } } } /** * Checks if there is a next element */ get hasNext() { const stack = this.stack; if (stack.length === 0) { return false; } if (stack[stack.length - 1].right != null) { return true; } for (let s = stack.length - 1; s > 0; --s) { if (stack[s - 1].left === stack[s]) { return true; } } return false; } /** * Advances iterator to previous element in list */ movePrev() { const stack = this.stack; if (stack.length === 0) { return; } let n = stack[stack.length - 1]; if (n != null && n.left != null) { n = n.left; while (n != null) { stack.push(n); n = n.right; } } else { stack.pop(); while (stack.length > 0 && stack[stack.length - 1].left === n) { n = stack[stack.length - 1]; stack.pop(); } } } /** * Checks if there is a previous element */ get hasPrev() { const stack = this.stack; if (stack.length === 0) { return false; } if (stack[stack.length - 1].left != null) { return true; } for (let s = stack.length - 1; s > 0; --s) { if (stack[s - 1].right === stack[s]) { return true; } } return false; } } exports.RedBlackTreeIterator = RedBlackTreeIterator; //# sourceMappingURL=iterator.js.map