fix(front, back) -> undefined exception; feat(resize)

This commit is contained in:
2025-07-22 19:22:25 +03:00
parent f762717de5
commit 94ce32cff3
10 changed files with 1648 additions and 44 deletions

View File

@ -1,3 +1,5 @@
.PHONY: build test
build: build:
npx esbuild src/index.js --bundle --minify --outfile=dist/index.js --format=esm npx esbuild src/index.js --bundle --minify --outfile=dist/index.js --format=esm
npx rollup -c npx rollup -c

1587
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -35,6 +35,16 @@ export class List {
return this._end.clone() return this._end.clone()
} }
resize(size, value) {
if (this._size > size)
while (this._size !== size)
this.popBack()
else
while (this._size !== size)
this.pushBack(value)
}
_shiftRight(dest, generator) { _shiftRight(dest, generator) {
let prev, res, new_item, item = dest.deref() let prev, res, new_item, item = dest.deref()
@ -75,7 +85,7 @@ export class List {
} }
} }
List.from = function (obj) { List.from = function(obj) {
const list = new List() const list = new List()
for (const value of obj) { for (const value of obj) {
list.pushBack(value) list.pushBack(value)
@ -98,6 +108,7 @@ export class ListItem {
} }
export class ListIterator { export class ListIterator {
constructor(item) { constructor(item) {
this._item = item this._item = item
} }
@ -130,4 +141,4 @@ export class ListIterator {
} }
} }
mixinClasses(ListIterator, BidirectionalIterator) mixinClasses(ListIterator, BidirectionalIterator)

View File

@ -1,5 +1,5 @@
import { BidirectionalIterator } from "../iterators/Bidirectional" import { BidirectionalIterator } from "../iterators/Bidirectional"
import { satisfiesConcept } from "../utils/concept" import { getCloneFunc, satisfiesConcept } from "../utils/concept"
export class SequenceContainer { export class SequenceContainer {
clone() { clone() {
@ -16,6 +16,9 @@ export class SequenceContainer {
} }
get front() { get front() {
if (this.empty())
throw new Error('front element is undefined')
return this.begin().value return this.begin().value
} }
@ -24,6 +27,9 @@ export class SequenceContainer {
} }
get back() { get back() {
if (this.empty())
throw new Error('back element is undefined')
return this.end().dec().value return this.end().dec().value
} }
@ -151,10 +157,11 @@ export class SequenceContainer {
} }
} }
SequenceContainer.is = function (obj, ...args) { SequenceContainer.is = function(obj, ...args) {
const pure_virtual = [ const pure_virtual = [
'move', 'move',
'size', 'size',
'resize',
'begin', 'begin',
'end', 'end',
'_shiftRight', '_shiftRight',
@ -179,4 +186,4 @@ SequenceContainer.is = function (obj, ...args) {
'toString', 'toString',
] ]
return satisfiesConcept(obj, pure_virtual, virtual, ...args) return satisfiesConcept(obj, pure_virtual, virtual, ...args)
} }

View File

@ -6,7 +6,7 @@ export class ForwardIterator {
} }
get value() { get value() {
return this.deref()?.value return this.deref().value
} }
set value(value) { set value(value) {
@ -32,4 +32,4 @@ ForwardIterator.is = function (obj, ...args) {
'neq', 'neq',
] ]
return satisfiesConcept(obj, pure_virtual, virtual, ...args) return satisfiesConcept(obj, pure_virtual, virtual, ...args)
} }

View File

@ -31,4 +31,4 @@ export function satisfiesConcept(obj, pure_virtual, virtual, debug) {
} }
} }
return true return true
} }

View File

@ -4,4 +4,4 @@ export function mixinClasses(dest, ...sources) {
delete properties.constructor delete properties.constructor
Object.defineProperties(dest.prototype, properties) Object.defineProperties(dest.prototype, properties)
} }
} }

View File

@ -49,7 +49,7 @@ test('move, empty', () => {
test('constructor, assign', () => { test('constructor, assign', () => {
expect(new List().size()).toEqual(0) expect(new List().size()).toEqual(0)
expect(new List().back).toEqual(undefined) expect(() => new List().back).toThrow()
expect(listEquArray(new List(null), [null])).toBeTruthy() expect(listEquArray(new List(null), [null])).toBeTruthy()
expect(listEquArray(new List(null, 2), [null, null])).toBeTruthy() expect(listEquArray(new List(null, 2), [null, null])).toBeTruthy()
{ {
@ -60,6 +60,19 @@ test('constructor, assign', () => {
} }
}) })
test('resize', () => {
{
const list = List.from([1, 2, 3])
list.resize(1)
expect(listEquArray(list, [1])).toBeTruthy()
}
{
const list = List.from([1])
list.resize(3, 2)
expect(listEquArray(list, [1, 2, 2])).toBeTruthy()
}
})
test('insert, clone', () => { test('insert, clone', () => {
{ {
const list = List.from([1, 2]) const list = List.from([1, 2])
@ -135,4 +148,4 @@ test('pushBack, pushFront, popBack, popFront, back, front', () => {
test('toJSON, toString', () => { test('toJSON, toString', () => {
expect(List.from([1, 2]).toJSON()).toEqual('[ 1, 2 ]') expect(List.from([1, 2]).toJSON()).toEqual('[ 1, 2 ]')
expect(List.from([0n]).toString()).toEqual('[ 0 ]') expect(List.from([0n]).toString()).toEqual('[ 0 ]')
}) })

9
types/List.d.ts vendored
View File

@ -2,22 +2,17 @@ import { SequenceContainer } from "./containers/Sequence";
import { BidirectionalIterator } from "./iterators/Bidirectional"; import { BidirectionalIterator } from "./iterators/Bidirectional";
import { Item } from "./iterators/Forward"; import { Item } from "./iterators/Forward";
export class List<T> extends SequenceContainer<T> { export class List<T> extends SequenceContainer<T, ListIterator<T>> {
/** /**
* empty list * empty list
*/ */
constructor(); constructor();
/**
* list with single element
* @param value which will be inserted
*/
constructor(value: T);
/** /**
* list with n similar elements * list with n similar elements
* @param value which will be inserted * @param value which will be inserted
* @param n count of how many values will be inserted * @param n count of how many values will be inserted
*/ */
constructor(value: T, n: number); constructor(value: T, n?: number);
/** /**
* copies range of another list * copies range of another list
* @param begin of another SequenceContainer<T> * @param begin of another SequenceContainer<T>

View File

@ -1,21 +1,23 @@
import { BidirectionalIterator } from "../iterators/Bidirectional"; import { ForwardIterator } from "../iterators/Forward";
export class SequenceContainer<T> { export class SequenceContainer<T, It extends ForwardIterator<T>> {
move(rhs: SequenceContainer<T>): this; move(rhs: SequenceContainer<T, It>): this;
size(): number; size(): number;
begin(): BidirectionalIterator<T>; begin(): It;
end(): BidirectionalIterator<T>; end(): It;
clone(): this; clone(): this;
copy(rhs: SequenceContainer<T>): this; copy(rhs: SequenceContainer<T, It>): this;
empty(): boolean; empty(): boolean;
/** /**
* @returns direct access to front item's value * @returns direct access to front item's value
* @throws Error if size == 0
*/ */
get front(): T; get front(): T;
set front(value: T); set front(value: T);
/** /**
* @returns direct access to back item's value * @returns direct access to back item's value
* @throws Error if size == 0
*/ */
get back(): T; get back(): T;
set back(value: T); set back(value: T);
@ -26,7 +28,7 @@ export class SequenceContainer<T> {
* @param end of another SequenceContainer<T> * @param end of another SequenceContainer<T>
* @returns iterator right after end iterator * @returns iterator right after end iterator
*/ */
insert(dest: BidirectionalIterator<T>, begin: BidirectionalIterator<T>, end: BidirectionalIterator<T>): BidirectionalIterator<T>; insert(dest: It, begin: It, end: It): It;
/** /**
* inserts [begin, end) at dest * inserts [begin, end) at dest
* @param dest where to insert * @param dest where to insert
@ -34,52 +36,39 @@ export class SequenceContainer<T> {
* @param n count of how many values will be inserted * @param n count of how many values will be inserted
* @returns iterator right after last inserted value * @returns iterator right after last inserted value
*/ */
insert(dest: BidirectionalIterator<T>, value: T, n: number): BidirectionalIterator<T>; insert(dest: It, value: T, n?: number): It;
/**
* inserts [begin, end) at dest
* @param dest where to insert
* @param value which will be inserted
* @returns iterator right after inserted value
*/
insert(dest: BidirectionalIterator<T>, value: T): BidirectionalIterator<T>;
/** /**
* same as list.clear(); list.insert(list.begin(), ...) * same as list.clear(); list.insert(list.begin(), ...)
* @param begin of another SequenceContainer<T> * @param begin of another SequenceContainer<T>
* @param end of another SequenceContainer<T> * @param end of another SequenceContainer<T>
* @returns end iterator * @returns end iterator
*/ */
assign(begin: BidirectionalIterator<T>, end: BidirectionalIterator<T>): BidirectionalIterator<T>; assign(begin: It, end: It): It;
/** /**
* same as list.clear(); list.insert(list.begin(), ...) * same as list.clear(); list.insert(list.begin(), ...)
* @param value which will be inserted * @param value which will be inserted
* @param n count of how many values will be inserted * @param n count of how many values will be inserted
* @returns iterator right after last inserted value * @returns iterator right after last inserted value
*/ */
assign(value: T, n: number): BidirectionalIterator<T>; assign(value: T, n?: number): It;
/**
* same as list.clear(); list.insert(list.begin(), ...)
* @param value which will be inserted
* @returns iterator right after inserted value
*/
assign(value: T): BidirectionalIterator<T>;
/** /**
* erases [begin, end) * erases [begin, end)
* @param begin of erased range * @param begin of erased range
* @param end of erased range * @param end of erased range
* @returns iterator right after erased range * @returns iterator right after erased range
*/ */
erase(begin: BidirectionalIterator<T>, end: BidirectionalIterator<T>): BidirectionalIterator<T>; erase(begin: It, end: It): It;
/** /**
* erases single item * erases single item
* @param begin which points to erased item * @param begin which points to erased item
* @returns iterator right after erased value * @returns iterator right after erased value
*/ */
erase(begin: BidirectionalIterator<T>): BidirectionalIterator<T>; erase(item: It): It;
/** /**
* same as list.erase(list.begin(), list.end()) * same as list.erase(list.begin(), list.end())
* @returns end iterator * @returns end iterator
*/ */
clear(): BidirectionalIterator<T>; clear(): It;
pushFront(value: T): void; pushFront(value: T): void;
pushBack(value: T): void; pushBack(value: T): void;
popFront(): void; popFront(): void;