Compare commits

...

6 Commits

Author SHA1 Message Date
83c491ff6f 0.1.4 2025-07-22 19:24:03 +03:00
94ce32cff3 fix(front, back) -> undefined exception; feat(resize) 2025-07-22 19:22:25 +03:00
f762717de5 0.1.3 2025-07-17 15:17:10 +03:00
01e2b30248 feat(d.ts) 2025-07-17 15:16:40 +03:00
7ef36ff9fc 0.1.2 2025-06-09 16:07:12 +03:00
87a37b96b6 fix(List): toString is different from toJSON 2025-06-09 16:06:43 +03:00
15 changed files with 2207 additions and 50 deletions

8
Makefile Normal file
View File

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

2013
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,19 @@
{
"name": "@sek1ro/iterables",
"version": "0.1.1",
"version": "0.1.4",
"description": "A data structures library based on iterators, inspired by libstdc++",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "esbuild src/index.js --bundle --minify --outfile=dist/index.js --format=esm",
"test": "vitest"
},
"keywords": [],
"author": "Vlad Litvinov <vlad@sek1.ro>",
"license": "LGPL-3.0-only",
"type": "module",
"devDependencies": {
"rollup": "^4.45.1",
"rollup-plugin-dts": "^6.2.1",
"vitest": "^3.1.1"
}
}

10
rollup.config.js Normal file
View File

@ -0,0 +1,10 @@
import { dts } from "rollup-plugin-dts";
export default {
input: 'types/index.d.ts',
output: {
file: 'dist/index.d.ts',
format: 'es',
},
plugins: [dts()],
}

View File

@ -35,6 +35,16 @@ export class List {
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) {
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()
for (const value of obj) {
list.pushBack(value)
@ -98,6 +108,7 @@ export class ListItem {
}
export class ListIterator {
constructor(item) {
this._item = item
}

View File

@ -1,5 +1,5 @@
import { BidirectionalIterator } from "../iterators/Bidirectional"
import { satisfiesConcept } from "../utils/concept"
import { getCloneFunc, satisfiesConcept } from "../utils/concept"
export class SequenceContainer {
clone() {
@ -16,6 +16,9 @@ export class SequenceContainer {
}
get front() {
if (this.empty())
throw new Error('front element is undefined')
return this.begin().value
}
@ -24,6 +27,9 @@ export class SequenceContainer {
}
get back() {
if (this.empty())
throw new Error('back element is undefined')
return this.end().dec().value
}
@ -120,13 +126,17 @@ export class SequenceContainer {
}
toJSON() {
return this.toString()
let res = []
for (const value of this) {
res.push(JSON.stringify(value))
}
return '[ ' + res.join(', ') + ' ]'
}
toString() {
let res = []
for (const value of this) {
res.push(JSON.stringify(value))
res.push(value.toString())
}
return '[ ' + res.join(', ') + ' ]'
}
@ -147,10 +157,11 @@ export class SequenceContainer {
}
}
SequenceContainer.is = function (obj, ...args) {
SequenceContainer.is = function(obj, ...args) {
const pure_virtual = [
'move',
'size',
'resize',
'begin',
'end',
'_shiftRight',

View File

@ -6,7 +6,7 @@ export class ForwardIterator {
}
get value() {
return this.deref()?.value
return this.deref().value
}
set value(value) {

View File

@ -49,7 +49,7 @@ test('move, empty', () => {
test('constructor, assign', () => {
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, 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', () => {
{
const list = List.from([1, 2])
@ -134,4 +147,5 @@ test('pushBack, pushFront, popBack, popFront, back, front', () => {
test('toJSON, toString', () => {
expect(List.from([1, 2]).toJSON()).toEqual('[ 1, 2 ]')
expect(List.from([0n]).toString()).toEqual('[ 0 ]')
})

38
types/List.d.ts vendored Normal file
View File

@ -0,0 +1,38 @@
import { SequenceContainer } from "./containers/Sequence";
import { BidirectionalIterator } from "./iterators/Bidirectional";
import { Item } from "./iterators/Forward";
export class List<T> extends SequenceContainer<T, ListIterator<T>> {
/**
* empty list
*/
constructor();
/**
* list with n similar elements
* @param value which will be inserted
* @param n count of how many values will be inserted
*/
constructor(value: T, n?: number);
/**
* copies range of another list
* @param begin of another SequenceContainer<T>
* @param end of another SequenceContainer<T>
*/
constructor(begin: ListIterator<T>, end: ListIterator<T>);
/**
* creates list from array, string and other iterable object
*/
static from<T>(obj: Iterable<T>): List<T>;
}
export class ListItem<T> extends Item<T> {
get next(): ListItem<T>;
get prev(): ListItem<T>;
private constructor();
}
export class ListIterator<T> extends BidirectionalIterator<T> {
private constructor();
}

79
types/containers/Sequence.d.ts vendored Normal file
View File

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

5
types/index.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
import type { ForwardIterator } from "./iterators/Forward"
import type { BidirectionalIterator } from "./iterators/Bidirectional"
import type { SequenceContainer } from "./containers/Sequence"
import type { List, ListIterator, ListItem } from "./List"
export type { ForwardIterator, BidirectionalIterator, SequenceContainer, List, ListIterator, ListItem }

9
types/iterators/Bidirectional.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
import { ForwardIterator } from "./Forward";
export class BidirectionalIterator<T> extends ForwardIterator<T> {
/**
* decrements iterator, it doesn't make copy
* @returns {this}
*/
dec(): this;
}

24
types/iterators/Forward.d.ts vendored Normal file
View File

@ -0,0 +1,24 @@
export class Item<T> {
value: T
}
export class ForwardIterator<T> {
clone(): ForwardIterator<T>;
copy(rhs: ForwardIterator<T>): this;
deref(): Item<T>;
eq(rhs: ForwardIterator<T>): boolean;
/**
* increments iterator, it doesn't make copy
* @returns {this}
*/
inc(): this;
/**
* move-semantics, here it just copies rhs into this
* @returns {this}
*/
move(rhs: ForwardIterator<T>): this;
get value(): T;
set value(value: T);
neq(rhs: ForwardIterator<T>): boolean;
}