Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7e247da8e0 | |||
| 48a9fb7473 | |||
| 60fd0867f5 | |||
| aca4539ce4 | |||
| 83c491ff6f | |||
| 94ce32cff3 | |||
| f762717de5 | |||
| 01e2b30248 | |||
| 7ef36ff9fc | |||
| 87a37b96b6 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,6 +7,7 @@ yarn-error.log*
|
|||||||
pnpm-debug.log*
|
pnpm-debug.log*
|
||||||
lerna-debug.log*
|
lerna-debug.log*
|
||||||
|
|
||||||
|
coverage
|
||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
dist-ssr
|
dist-ssr
|
||||||
|
|||||||
11
Makefile
Normal file
11
Makefile
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
.PHONY: build test
|
||||||
|
|
||||||
|
build:
|
||||||
|
npx esbuild src/index.js --bundle --minify --outfile=dist/index.js --format=esm
|
||||||
|
npx rollup -c
|
||||||
|
|
||||||
|
test:
|
||||||
|
npx vitest
|
||||||
|
|
||||||
|
cover:
|
||||||
|
npx vitest --coverage
|
||||||
22
README.md
22
README.md
@ -6,13 +6,13 @@ A data structures library based on iterators, inspired by libstdc++
|
|||||||
|
|
||||||
| Operator | Naming |
|
| Operator | Naming |
|
||||||
| ----------- | ------------- |
|
| ----------- | ------------- |
|
||||||
| `+` | add |
|
| `+=` | add |
|
||||||
| `-` | sub |
|
| `-=` | sub |
|
||||||
| `++obj` | inc |
|
| `++obj` | inc |
|
||||||
| `--obj` | dec |
|
| `--obj` | dec |
|
||||||
| `*` | mul |
|
| `*=` | mul |
|
||||||
| `/` | div |
|
| `/=` | div |
|
||||||
| `%` | mod |
|
| `%=` | mod |
|
||||||
| `==` | eq |
|
| `==` | eq |
|
||||||
| `!=` | neq |
|
| `!=` | neq |
|
||||||
| `<` | a.cmp(b) < 0 |
|
| `<` | a.cmp(b) < 0 |
|
||||||
@ -24,6 +24,8 @@ A data structures library based on iterators, inspired by libstdc++
|
|||||||
| `=` && | move |
|
| `=` && | move |
|
||||||
| `*obj` | deref |
|
| `*obj` | deref |
|
||||||
| `&obj` | ref |
|
| `&obj` | ref |
|
||||||
|
| `obj[]` | get |
|
||||||
|
| `obj[]=smth`| set |
|
||||||
| `\|\|` | or |
|
| `\|\|` | or |
|
||||||
| `!` | not |
|
| `!` | not |
|
||||||
| `&` | band |
|
| `&` | band |
|
||||||
@ -37,11 +39,11 @@ A data structures library based on iterators, inspired by libstdc++
|
|||||||
| `obj++` | `X` |
|
| `obj++` | `X` |
|
||||||
| `obj--` | `X` |
|
| `obj--` | `X` |
|
||||||
| `->` | `X` |
|
| `->` | `X` |
|
||||||
| `+=` | `X` |
|
| `+` | `X` |
|
||||||
| `-=` | `X` |
|
| `-` | `X` |
|
||||||
| `*=` | `X` |
|
| `*` | `X` |
|
||||||
| `/=` | `X` |
|
| `/` | `X` |
|
||||||
| `%=` | `X` |
|
| `%` | `X` |
|
||||||
| `&=` | `X` |
|
| `&=` | `X` |
|
||||||
| `\|=` | `X` |
|
| `\|=` | `X` |
|
||||||
| `^=` | `X` |
|
| `^=` | `X` |
|
||||||
|
|||||||
1244
package-lock.json
generated
1244
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@ -1,20 +1,20 @@
|
|||||||
{
|
{
|
||||||
"name": "@sek1ro/iterables",
|
"name": "@sek1ro/iterables",
|
||||||
"version": "0.1.1",
|
"version": "0.2.1",
|
||||||
"description": "A data structures library based on iterators, inspired by libstdc++",
|
"description": "A data structures library based on iterators, inspired by libstdc++",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
],
|
],
|
||||||
"scripts": {
|
|
||||||
"build": "esbuild src/index.js --bundle --minify --outfile=dist/index.js --format=esm",
|
|
||||||
"test": "vitest"
|
|
||||||
},
|
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "Vlad Litvinov <vlad@sek1.ro>",
|
"author": "Vlad Litvinov <vlad@sek1.ro>",
|
||||||
"license": "LGPL-3.0-only",
|
"license": "LGPL-3.0-only",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@vitest/coverage-v8": "^3.1.1",
|
||||||
|
"rollup": "^4.45.1",
|
||||||
|
"rollup-plugin-dts": "^6.2.1",
|
||||||
"vitest": "^3.1.1"
|
"vitest": "^3.1.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
rollup.config.js
Normal file
10
rollup.config.js
Normal 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()],
|
||||||
|
}
|
||||||
23
src/List.js
23
src/List.js
@ -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
|
||||||
}
|
}
|
||||||
@ -110,6 +121,14 @@ export class ListIterator {
|
|||||||
this._item = rhs._item
|
this._item = rhs._item
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get value() {
|
||||||
|
return this.deref().value
|
||||||
|
}
|
||||||
|
|
||||||
|
set value(value) {
|
||||||
|
return this.deref().value = value
|
||||||
|
}
|
||||||
|
|
||||||
deref() {
|
deref() {
|
||||||
return this._item
|
return this._item
|
||||||
@ -130,4 +149,4 @@ export class ListIterator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mixinClasses(ListIterator, BidirectionalIterator)
|
mixinClasses(ListIterator, BidirectionalIterator)
|
||||||
|
|||||||
158
src/Vector.js
Normal file
158
src/Vector.js
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
import { SequenceContainer } from "./containers/Sequence"
|
||||||
|
import { RandomAccessIterator } from "./iterators/RandomAccess"
|
||||||
|
import { mixinClasses } from "./utils/mixin"
|
||||||
|
|
||||||
|
export class Vector {
|
||||||
|
|
||||||
|
constructor(...args) {
|
||||||
|
this._array = []
|
||||||
|
if (args.length >= 1) {
|
||||||
|
this.assign(...args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
move(rhs) {
|
||||||
|
this._array = rhs._array
|
||||||
|
rhs._array = undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
size() {
|
||||||
|
return this._array.length
|
||||||
|
}
|
||||||
|
|
||||||
|
begin() {
|
||||||
|
return new VectorIterator(this._array, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
end() {
|
||||||
|
return new VectorIterator(this._array, this._array.length)
|
||||||
|
}
|
||||||
|
|
||||||
|
get(idx) {
|
||||||
|
if (idx < 0 || idx >= this._array.length)
|
||||||
|
throw new Error('out of order')
|
||||||
|
|
||||||
|
return this.begin().add(idx).value
|
||||||
|
}
|
||||||
|
|
||||||
|
set(idx, value) {
|
||||||
|
if (idx < 0 || idx >= this._array.length)
|
||||||
|
throw new Error('out of order')
|
||||||
|
|
||||||
|
return this.begin().add(idx).value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
resize(size, value) {
|
||||||
|
let prev_size = this._array.length
|
||||||
|
this._array.length = size
|
||||||
|
|
||||||
|
if (value === undefined)
|
||||||
|
return
|
||||||
|
|
||||||
|
while (prev_size < size) {
|
||||||
|
this._array[prev_size] = value
|
||||||
|
prev_size++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_shiftRight(dest, generator, offset) {
|
||||||
|
const prev_size = this._array.length
|
||||||
|
this._array.length += offset
|
||||||
|
let idx = dest._idx
|
||||||
|
|
||||||
|
for (let i = idx; i < prev_size; i++) {
|
||||||
|
this._array[i + offset] = this._array[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const value of generator) {
|
||||||
|
this._array[idx] = value
|
||||||
|
idx++
|
||||||
|
}
|
||||||
|
|
||||||
|
return new VectorIterator(this._array, dest._idx)
|
||||||
|
}
|
||||||
|
|
||||||
|
_shiftLeft(dest, _, offset) {
|
||||||
|
let idx = dest._idx - offset
|
||||||
|
|
||||||
|
for (let i = 0; i < offset; i++) {
|
||||||
|
this._array[idx + i] = this._array[dest._idx + i]
|
||||||
|
}
|
||||||
|
|
||||||
|
this._array.length -= offset
|
||||||
|
|
||||||
|
return new VectorIterator(this._array, idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector.from = function(obj) {
|
||||||
|
const vector = new Vector()
|
||||||
|
|
||||||
|
if (typeof obj.length == 'number') {
|
||||||
|
vector.resize(obj.length)
|
||||||
|
} else if (typeof obj.size == 'function') {
|
||||||
|
vector.resize(obj.size())
|
||||||
|
} else {
|
||||||
|
for (const value of obj) {
|
||||||
|
vector.pushBack(value)
|
||||||
|
}
|
||||||
|
return vector
|
||||||
|
}
|
||||||
|
|
||||||
|
let idx = 0
|
||||||
|
|
||||||
|
for (const value of obj) {
|
||||||
|
vector.set(idx, value)
|
||||||
|
idx++
|
||||||
|
}
|
||||||
|
|
||||||
|
return vector
|
||||||
|
}
|
||||||
|
|
||||||
|
mixinClasses(Vector, SequenceContainer)
|
||||||
|
|
||||||
|
export class VectorIterator {
|
||||||
|
|
||||||
|
constructor(array, idx) {
|
||||||
|
this._array = array
|
||||||
|
this._idx = idx
|
||||||
|
}
|
||||||
|
|
||||||
|
clone() {
|
||||||
|
return new VectorIterator(this._array, this._idx)
|
||||||
|
}
|
||||||
|
|
||||||
|
copy(rhs) {
|
||||||
|
this._array = rhs._array
|
||||||
|
this._idx = rhs._idx
|
||||||
|
}
|
||||||
|
|
||||||
|
sub(arg) {
|
||||||
|
if (arg instanceof VectorIterator) {
|
||||||
|
return this._idx - arg._idx
|
||||||
|
} else if (typeof arg == 'number') {
|
||||||
|
this._idx -= arg
|
||||||
|
return this
|
||||||
|
} else {
|
||||||
|
throw new Error('incorrect args')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get value() {
|
||||||
|
return this.deref()
|
||||||
|
}
|
||||||
|
|
||||||
|
set value(value) {
|
||||||
|
return this._array[this._idx] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
deref() {
|
||||||
|
return this._array[this._idx]
|
||||||
|
}
|
||||||
|
|
||||||
|
eq(rhs) {
|
||||||
|
return this._array == rhs._array && this._idx == rhs._idx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mixinClasses(VectorIterator, RandomAccessIterator)
|
||||||
@ -1,4 +1,5 @@
|
|||||||
import { BidirectionalIterator } from "../iterators/Bidirectional"
|
import { ForwardIterator } from "../iterators/Forward"
|
||||||
|
import { RandomAccessIterator } from "../iterators/RandomAccess"
|
||||||
import { satisfiesConcept } from "../utils/concept"
|
import { satisfiesConcept } from "../utils/concept"
|
||||||
|
|
||||||
export class SequenceContainer {
|
export class SequenceContainer {
|
||||||
@ -16,6 +17,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 +28,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
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,40 +40,45 @@ export class SequenceContainer {
|
|||||||
|
|
||||||
insert(dest, arg2, arg3) {
|
insert(dest, arg2, arg3) {
|
||||||
if (
|
if (
|
||||||
BidirectionalIterator.is(arg2) &&
|
ForwardIterator.is(arg2) &&
|
||||||
BidirectionalIterator.is(arg3)
|
ForwardIterator.is(arg3)
|
||||||
) {
|
) {
|
||||||
return this._shiftRight(dest,
|
const generator = {
|
||||||
{
|
[Symbol.iterator]: () => {
|
||||||
[Symbol.iterator]: () => {
|
const local_begin = arg2.clone()
|
||||||
const local_begin = arg2.clone()
|
return {
|
||||||
return {
|
next() {
|
||||||
next() {
|
const res = {
|
||||||
const res = {
|
done: local_begin.eq(arg3),
|
||||||
done: local_begin.eq(arg3),
|
value: local_begin.value,
|
||||||
value: local_begin.value,
|
|
||||||
}
|
|
||||||
local_begin.inc()
|
|
||||||
return res
|
|
||||||
}
|
}
|
||||||
|
local_begin.inc()
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
if (
|
||||||
|
RandomAccessIterator.is(arg2) &&
|
||||||
|
RandomAccessIterator.is(arg3)
|
||||||
|
) {
|
||||||
|
return this._shiftRight(dest, generator, arg3.sub(arg2))
|
||||||
|
} else {
|
||||||
|
return this._shiftRight(dest, generator)
|
||||||
|
}
|
||||||
} else if (
|
} else if (
|
||||||
typeof arg3 == 'number' && arg3 >= 0 ||
|
typeof arg3 == 'number' && arg3 >= 0 ||
|
||||||
arg3 === undefined
|
arg2 !== undefined && arg3 === undefined
|
||||||
) {
|
) {
|
||||||
return this._shiftRight(dest,
|
const generator = {
|
||||||
{
|
[Symbol.iterator]: () => {
|
||||||
[Symbol.iterator]: () => {
|
let local_n = arg3 ?? 1
|
||||||
let local_n = arg3 ?? 1
|
return {
|
||||||
return {
|
next: () => ({ done: local_n-- <= 0, value: arg2 })
|
||||||
next: () => ({ done: local_n-- <= 0, value: arg2 })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
return this._shiftRight(dest, generator, arg3 ?? 1)
|
||||||
} else {
|
} else {
|
||||||
throw new Error('incorrect args')
|
throw new Error('incorrect args')
|
||||||
}
|
}
|
||||||
@ -81,8 +93,13 @@ export class SequenceContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
erase(begin, end = begin.clone().inc()) {
|
erase(begin, end = begin.clone().inc()) {
|
||||||
return this._shiftLeft(end,
|
if (
|
||||||
{
|
RandomAccessIterator.is(begin) &&
|
||||||
|
RandomAccessIterator.is(end)
|
||||||
|
) {
|
||||||
|
return this._shiftLeft(end, undefined, end.sub(begin))
|
||||||
|
} else {
|
||||||
|
return this._shiftLeft(end, {
|
||||||
[Symbol.iterator]: () => {
|
[Symbol.iterator]: () => {
|
||||||
let local_begin = begin.clone()
|
let local_begin = begin.clone()
|
||||||
return {
|
return {
|
||||||
@ -95,8 +112,8 @@ export class SequenceContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
@ -120,13 +137,17 @@ export class SequenceContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toJSON() {
|
toJSON() {
|
||||||
return this.toString()
|
let res = []
|
||||||
|
for (const value of this) {
|
||||||
|
res.push(JSON.stringify(value))
|
||||||
|
}
|
||||||
|
return '[ ' + res.join(', ') + ' ]'
|
||||||
}
|
}
|
||||||
|
|
||||||
toString() {
|
toString() {
|
||||||
let res = []
|
let res = []
|
||||||
for (const value of this) {
|
for (const value of this) {
|
||||||
res.push(JSON.stringify(value))
|
res.push(value.toString())
|
||||||
}
|
}
|
||||||
return '[ ' + res.join(', ') + ' ]'
|
return '[ ' + res.join(', ') + ' ]'
|
||||||
}
|
}
|
||||||
@ -147,10 +168,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',
|
||||||
@ -175,4 +197,4 @@ SequenceContainer.is = function (obj, ...args) {
|
|||||||
'toString',
|
'toString',
|
||||||
]
|
]
|
||||||
return satisfiesConcept(obj, pure_virtual, virtual, ...args)
|
return satisfiesConcept(obj, pure_virtual, virtual, ...args)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
export { ForwardIterator } from "./iterators/Forward"
|
export { ForwardIterator } from "./iterators/Forward"
|
||||||
export { BidirectionalIterator } from "./iterators/Bidirectional"
|
export { BidirectionalIterator } from "./iterators/Bidirectional"
|
||||||
|
export { RandomAccessIterator } from "./iterators/RandomAccess"
|
||||||
export { SequenceContainer } from "./containers/Sequence"
|
export { SequenceContainer } from "./containers/Sequence"
|
||||||
export { List, ListIterator, ListItem } from "./List"
|
export { List, ListIterator, ListItem } from "./List"
|
||||||
|
export { Vector, VectorIterator } from "./Vector"
|
||||||
|
|||||||
@ -8,4 +8,4 @@ mixinClasses(BidirectionalIterator, ForwardIterator)
|
|||||||
|
|
||||||
BidirectionalIterator.is = function (obj, ...args) {
|
BidirectionalIterator.is = function (obj, ...args) {
|
||||||
return ForwardIterator.is(obj, ...args) && satisfiesConcept(obj, ['dec'], [], ...args)
|
return ForwardIterator.is(obj, ...args) && satisfiesConcept(obj, ['dec'], [], ...args)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,14 +5,6 @@ export class ForwardIterator {
|
|||||||
return this.copy(rhs)
|
return this.copy(rhs)
|
||||||
}
|
}
|
||||||
|
|
||||||
get value() {
|
|
||||||
return this.deref()?.value
|
|
||||||
}
|
|
||||||
|
|
||||||
set value(value) {
|
|
||||||
return this.deref().value = value
|
|
||||||
}
|
|
||||||
|
|
||||||
neq(rhs) {
|
neq(rhs) {
|
||||||
return !this.eq(rhs)
|
return !this.eq(rhs)
|
||||||
}
|
}
|
||||||
@ -22,14 +14,14 @@ ForwardIterator.is = function (obj, ...args) {
|
|||||||
const pure_virtual = [
|
const pure_virtual = [
|
||||||
'clone',
|
'clone',
|
||||||
'copy',
|
'copy',
|
||||||
|
'value',
|
||||||
'deref',
|
'deref',
|
||||||
'inc',
|
'inc',
|
||||||
'eq'
|
'eq',
|
||||||
]
|
]
|
||||||
const virtual = [
|
const virtual = [
|
||||||
'move',
|
'move',
|
||||||
'value',
|
|
||||||
'neq',
|
'neq',
|
||||||
]
|
]
|
||||||
return satisfiesConcept(obj, pure_virtual, virtual, ...args)
|
return satisfiesConcept(obj, pure_virtual, virtual, ...args)
|
||||||
}
|
}
|
||||||
|
|||||||
44
src/iterators/RandomAccess.js
Normal file
44
src/iterators/RandomAccess.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { satisfiesConcept } from "../utils/concept";
|
||||||
|
import { mixinClasses } from "../utils/mixin";
|
||||||
|
import { BidirectionalIterator } from "./Bidirectional";
|
||||||
|
|
||||||
|
export class RandomAccessIterator {
|
||||||
|
add(offset) {
|
||||||
|
return this.sub( - offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmp(rhs) {
|
||||||
|
return this.sub(rhs)
|
||||||
|
}
|
||||||
|
|
||||||
|
get(idx) {
|
||||||
|
return this.clone().add(idx).value
|
||||||
|
}
|
||||||
|
|
||||||
|
set(idx, value) {
|
||||||
|
return this.clone().add(idx).value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
inc() {
|
||||||
|
return this.add(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
dec() {
|
||||||
|
return this.sub(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mixinClasses(RandomAccessIterator, BidirectionalIterator)
|
||||||
|
|
||||||
|
RandomAccessIterator.is = function(obj, ...args) {
|
||||||
|
const pure_virtual = [
|
||||||
|
'sub',
|
||||||
|
]
|
||||||
|
const virtual = [
|
||||||
|
'add',
|
||||||
|
'cmp',
|
||||||
|
'get',
|
||||||
|
'set',
|
||||||
|
]
|
||||||
|
return BidirectionalIterator.is(obj, ...args) && satisfiesConcept(obj, pure_virtual, virtual, ...args)
|
||||||
|
}
|
||||||
@ -1,28 +1,31 @@
|
|||||||
export function satisfiesConcept(obj, pure_virtual, virtual, debug) {
|
export function satisfiesConcept(obj, pure_virtual, virtual, debug) {
|
||||||
if (typeof obj !== 'object' || obj === null) {
|
if (typeof obj !== 'object' || obj === null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const desc = Object.getOwnPropertyDescriptors(obj.constructor.prototype)
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
const missingMethods = []
|
const missingMethods = []
|
||||||
|
|
||||||
pure_virtual.forEach((method) => {
|
pure_virtual.forEach((method) => {
|
||||||
if (typeof obj[method] !== 'function') {
|
if (method in desc == false) {
|
||||||
missingMethods.push(method)
|
missingMethods.push(method)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
virtual.forEach((method) => {
|
virtual.forEach((method) => {
|
||||||
if (!(method in obj)) {
|
if (method in obj == false) {
|
||||||
missingMethods.push(method)
|
missingMethods.push(method)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (missingMethods.length !== 0) {
|
if (missingMethods.length !== 0) {
|
||||||
console.debug(obj.constructor.name, missingMethods)
|
console.debug('this class doesn\'t have methods', obj.constructor.name, missingMethods)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!pure_virtual.every((method) => typeof obj[method] === 'function')) {
|
if (!pure_virtual.every((method) => method in desc)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,4 +34,4 @@ export function satisfiesConcept(obj, pure_virtual, virtual, debug) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,137 +1,11 @@
|
|||||||
import { expect, test } from 'vitest'
|
import { describe, expect, test } from "vitest"
|
||||||
import { List, ListIterator } from '../src/List'
|
import { SequenceContainer } from "../src/containers/Sequence"
|
||||||
import { SequenceContainer } from '../src/containers/Sequence'
|
import { List, ListIterator } from "../src/List"
|
||||||
import { BidirectionalIterator } from '../src/iterators/Bidirectional'
|
import { BidirectionalIterator } from "../src/iterators/Bidirectional"
|
||||||
|
|
||||||
function listEquArray(list, arr) {
|
describe(List.name, () => {
|
||||||
if (list.size() != Array.from(arr).length) {
|
test('@concepts', () => {
|
||||||
return false
|
expect(SequenceContainer.is(List.prototype, true)).toBeTruthy()
|
||||||
}
|
expect(BidirectionalIterator.is(ListIterator.prototype, true)).toBeTruthy()
|
||||||
let it = list.begin(), it_end = list.end(), idx = 0
|
})
|
||||||
while (it.neq(it_end)) {
|
|
||||||
if (arr[idx] !== it.value) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
idx++
|
|
||||||
it.inc()
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
test('@concepts', () => {
|
|
||||||
expect(SequenceContainer.is(List.prototype, true)).toBeTruthy()
|
|
||||||
expect(BidirectionalIterator.is(ListIterator.prototype, true)).toBeTruthy()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('from', () => {
|
|
||||||
expect(listEquArray(List.from([]), [])).toBeTruthy()
|
|
||||||
expect(listEquArray(List.from([1, 2, 3]), [1, 2, 3])).toBeTruthy()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('copy, clone', () => {
|
|
||||||
const list = List.from([1, 2, 3])
|
|
||||||
const a = new List(), b = list.clone()
|
|
||||||
a.copy(list)
|
|
||||||
expect(a.size()).toEqual(3)
|
|
||||||
expect(b.size()).toEqual(3)
|
|
||||||
list.clear()
|
|
||||||
expect(a.size()).toEqual(3)
|
|
||||||
expect(b.size()).toEqual(3)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('move, empty', () => {
|
|
||||||
const a = List.from([1, 2, 3])
|
|
||||||
const b = new List()
|
|
||||||
b.move(a)
|
|
||||||
expect(a.empty()).toBeTruthy()
|
|
||||||
expect(b.size()).toEqual(3)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('constructor, assign', () => {
|
|
||||||
expect(new List().size()).toEqual(0)
|
|
||||||
expect(new List().back).toEqual(undefined)
|
|
||||||
expect(listEquArray(new List(null), [null])).toBeTruthy()
|
|
||||||
expect(listEquArray(new List(null, 2), [null, null])).toBeTruthy()
|
|
||||||
{
|
|
||||||
const list = List.from([1, 2, 3])
|
|
||||||
expect(listEquArray(new List(list.begin().inc(), list.end().dec()), [2])).toBeTruthy()
|
|
||||||
list.assign(10)
|
|
||||||
expect(list.size()).toEqual(1)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
test('insert, clone', () => {
|
|
||||||
{
|
|
||||||
const list = List.from([1, 2])
|
|
||||||
const it = list.insert(list.begin().inc(), null, 2)
|
|
||||||
expect(listEquArray(list, [1, null, null, 2])).toBeTruthy()
|
|
||||||
expect(list.size()).toEqual(4)
|
|
||||||
expect(it.eq(list.begin().inc())).toBeTruthy()
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const a = List.from([1, 4])
|
|
||||||
const b = List.from([2, 3])
|
|
||||||
const it = a.insert(a.begin().inc(), b.begin(), b.end())
|
|
||||||
expect(listEquArray(a, [1, 2, 3, 4])).toBeTruthy()
|
|
||||||
expect(a.size()).toEqual(4)
|
|
||||||
expect(it.eq(a.begin().inc())).toBeTruthy()
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const list = List.from([1, 2])
|
|
||||||
expect(() => list.insert()).toThrowError()
|
|
||||||
const it = list.insert(list.begin(), 0, 0)
|
|
||||||
expect(it.eq(list.begin())).toBeTruthy()
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const a = List.from([1, 2])
|
|
||||||
const b = a.clone()
|
|
||||||
expect(listEquArray(b, [1, 2])).toBeTruthy()
|
|
||||||
expect(b.size()).toEqual(2)
|
|
||||||
expect(b.begin().deref().prev).toEqual(undefined)
|
|
||||||
expect(b.begin().deref().next).toEqual(b.end().deref().prev)
|
|
||||||
expect(b.end().deref().prev).toEqual(b.begin().deref().next)
|
|
||||||
expect(b.end().deref().next).toEqual(undefined)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
test('erase, clear', () => {
|
|
||||||
{
|
|
||||||
const list = List.from([1, 2, 3, 4])
|
|
||||||
const it = list.erase(list.begin(), list.end().dec().dec())
|
|
||||||
expect(listEquArray(list, [3, 4])).toBeTruthy()
|
|
||||||
expect(list.size()).toEqual(2)
|
|
||||||
expect(it.eq(list.begin())).toBeTruthy()
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const list = List.from([1, 2, 3])
|
|
||||||
const it = list.erase(list.begin().inc())
|
|
||||||
expect(listEquArray(list, [1, 3])).toBeTruthy()
|
|
||||||
expect(list.size()).toEqual(2)
|
|
||||||
expect(it.deref()).toEqual(list.begin().inc().deref())
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const list = List.from([1, 2])
|
|
||||||
list.clear()
|
|
||||||
expect(list.size()).toEqual(0)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
test('pushBack, pushFront, popBack, popFront, back, front', () => {
|
|
||||||
const list = List.from([1, 2, 3])
|
|
||||||
list.popFront()
|
|
||||||
list.pushFront(5)
|
|
||||||
list.popBack()
|
|
||||||
list.popBack()
|
|
||||||
list.pushBack(10)
|
|
||||||
expect(listEquArray(list, [5, 10])).toBeTruthy()
|
|
||||||
expect(list.front).toEqual(5)
|
|
||||||
expect(list.back).toEqual(10)
|
|
||||||
list.front = 1
|
|
||||||
list.back = 2
|
|
||||||
expect(list.front).toEqual(1)
|
|
||||||
expect(list.back).toEqual(2)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('toJSON, toString', () => {
|
|
||||||
expect(List.from([1, 2]).toJSON()).toEqual('[ 1, 2 ]')
|
|
||||||
})
|
|
||||||
25
test/Vector.test.js
Normal file
25
test/Vector.test.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { describe, expect, test } from "vitest";
|
||||||
|
import { RandomAccessIterator, SequenceContainer, Vector, VectorIterator } from "../src";
|
||||||
|
|
||||||
|
describe(Vector.name, () => {
|
||||||
|
test('@concepts', () => {
|
||||||
|
expect(SequenceContainer.is(Vector.prototype, true)).toBeTruthy()
|
||||||
|
expect(RandomAccessIterator.is(VectorIterator.prototype, true)).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('get, set', () => {
|
||||||
|
const vec = new Vector(0, 2)
|
||||||
|
expect(vec.get(1)).toEqual(0)
|
||||||
|
vec.set(1, 2)
|
||||||
|
expect(vec.get(1)).toEqual(2)
|
||||||
|
expect(() => vec.get(2)).toThrow()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe(VectorIterator.name, () => {
|
||||||
|
test('sub', () => {
|
||||||
|
const vector = Vector.from([1, 2, 3])
|
||||||
|
expect(vector.begin().add(2).value).toEqual(3)
|
||||||
|
expect(vector.begin().add(2).sub(vector.begin())).toEqual(2)
|
||||||
|
})
|
||||||
|
})
|
||||||
176
test/containers/Sequence.test.js
Normal file
176
test/containers/Sequence.test.js
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
import { describe, expect, test } from 'vitest'
|
||||||
|
import { List } from '../../src/List'
|
||||||
|
import { Vector } from '../../src/Vector'
|
||||||
|
|
||||||
|
function seqEquArray(seq, arr) {
|
||||||
|
if (seq.size() != Array.from(arr).length) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
let it = seq.begin(), it_end = seq.end(), idx = 0
|
||||||
|
while (it.neq(it_end)) {
|
||||||
|
if (arr[idx] !== it.value) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
idx++
|
||||||
|
it.inc()
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const Type of [List, Vector]) {
|
||||||
|
describe(Type.name, () => {
|
||||||
|
test('from', () => {
|
||||||
|
expect(seqEquArray(Type.from([]), [])).toBeTruthy()
|
||||||
|
expect(seqEquArray(Type.from([1, 2, 3]), [1, 2, 3])).toBeTruthy()
|
||||||
|
{
|
||||||
|
const seq = Type.from([1, 2, 3])
|
||||||
|
const seq2 = Type.from(seq)
|
||||||
|
seq.clear()
|
||||||
|
expect(seqEquArray(seq2, [1, 2, 3]))
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const iterable = {
|
||||||
|
[Symbol.iterator]: () => {
|
||||||
|
let i = 2;
|
||||||
|
return {
|
||||||
|
next: () => {
|
||||||
|
return {
|
||||||
|
done: i == 0,
|
||||||
|
value: i--,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect(seqEquArray(Type.from(iterable), [2, 1])).toBeTruthy()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test('copy, clone', () => {
|
||||||
|
const seq = Type.from([1, 2, 3])
|
||||||
|
const a = new Type(), b = seq.clone()
|
||||||
|
a.copy(seq)
|
||||||
|
expect(a.size()).toEqual(3)
|
||||||
|
expect(b.size()).toEqual(3)
|
||||||
|
seq.clear()
|
||||||
|
expect(a.size()).toEqual(3)
|
||||||
|
expect(b.size()).toEqual(3)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('move, empty', () => {
|
||||||
|
const a = Type.from([1, 2, 3])
|
||||||
|
const b = new Type()
|
||||||
|
b.move(a)
|
||||||
|
expect(b.size()).toEqual(3)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('constructor, assign', () => {
|
||||||
|
expect(new Type().size()).toEqual(0)
|
||||||
|
expect(() => new Type().back).toThrow()
|
||||||
|
expect(() => new Type().front).toThrow()
|
||||||
|
expect(seqEquArray(new Type(null), [null])).toBeTruthy()
|
||||||
|
expect(seqEquArray(new Type(null, 2), [null, null])).toBeTruthy()
|
||||||
|
{
|
||||||
|
const seq = Type.from([1, 2, 3])
|
||||||
|
expect(seqEquArray(new Type(seq.begin().inc(), seq.end().dec()), [2])).toBeTruthy()
|
||||||
|
seq.assign(10)
|
||||||
|
expect(seq.size()).toEqual(1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test('resize', () => {
|
||||||
|
{
|
||||||
|
const seq = Type.from([1, 2, 3])
|
||||||
|
seq.resize(1)
|
||||||
|
expect(seqEquArray(seq, [1])).toBeTruthy()
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const seq = Type.from([1])
|
||||||
|
seq.resize(3, 2)
|
||||||
|
expect(seqEquArray(seq, [1, 2, 2])).toBeTruthy()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test('insert, clone', () => {
|
||||||
|
{
|
||||||
|
const seq = Type.from([1, 2])
|
||||||
|
expect(() => seq.insert(seq.begin(), undefined)).toThrow()
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const seq = Type.from([1, 2])
|
||||||
|
const it = seq.insert(seq.begin().inc(), null, 2)
|
||||||
|
expect(seqEquArray(seq, [1, null, null, 2])).toBeTruthy()
|
||||||
|
expect(seq.size()).toEqual(4)
|
||||||
|
expect(it.eq(seq.begin().inc())).toBeTruthy()
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const a = Type.from([1, 4])
|
||||||
|
const b = Type.from([2, 3])
|
||||||
|
const it = a.insert(a.begin().inc(), b.begin(), b.end())
|
||||||
|
expect(seqEquArray(a, [1, 2, 3, 4])).toBeTruthy()
|
||||||
|
expect(a.size()).toEqual(4)
|
||||||
|
expect(it.eq(a.begin().inc())).toBeTruthy()
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const seq = Type.from([1, 2])
|
||||||
|
expect(() => seq.insert()).toThrowError()
|
||||||
|
const it = seq.insert(seq.begin(), 0, 0)
|
||||||
|
expect(it.eq(seq.begin())).toBeTruthy()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test('erase, clear', () => {
|
||||||
|
{
|
||||||
|
const seq = Type.from([1, 2, 3, 4])
|
||||||
|
const it = seq.erase(seq.begin(), seq.end().dec().dec())
|
||||||
|
expect(seqEquArray(seq, [3, 4])).toBeTruthy()
|
||||||
|
expect(seq.size()).toEqual(2)
|
||||||
|
expect(it.eq(seq.begin())).toBeTruthy()
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const seq = Type.from([1, 2, 3])
|
||||||
|
const it = seq.erase(seq.begin().inc())
|
||||||
|
expect(seqEquArray(seq, [1, 3])).toBeTruthy()
|
||||||
|
expect(seq.size()).toEqual(2)
|
||||||
|
expect(it.deref()).toEqual(seq.begin().inc().deref())
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const seq = Type.from([1, 2])
|
||||||
|
seq.clear()
|
||||||
|
expect(seq.size()).toEqual(0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test('pushBack, pushFront, popBack, popFront, back, front', () => {
|
||||||
|
const seq = Type.from([1, 2, 3])
|
||||||
|
seq.popFront()
|
||||||
|
seq.pushFront(5)
|
||||||
|
seq.popBack()
|
||||||
|
seq.popBack()
|
||||||
|
seq.pushBack(10)
|
||||||
|
expect(seqEquArray(seq, [5, 10])).toBeTruthy()
|
||||||
|
expect(seq.front).toEqual(5)
|
||||||
|
expect(seq.back).toEqual(10)
|
||||||
|
seq.front = 1
|
||||||
|
seq.back = 2
|
||||||
|
expect(seq.front).toEqual(1)
|
||||||
|
expect(seq.back).toEqual(2)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('toJSON, toString', () => {
|
||||||
|
expect(Type.from([1, 2]).toJSON()).toEqual('[ 1, 2 ]')
|
||||||
|
expect(Type.from([0n]).toString()).toEqual('[ 0 ]')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe(Type.name + 'Iterator', () => {
|
||||||
|
test('copy', () => {
|
||||||
|
const seq = Type.from([1, 2, 3])
|
||||||
|
const it1 = seq.begin()
|
||||||
|
const it2 = seq.end()
|
||||||
|
it2.copy(it1)
|
||||||
|
it1.inc()
|
||||||
|
expect(it2.deref()).toEqual(seq.begin().deref())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
38
types/List.d.ts
vendored
Normal file
38
types/List.d.ts
vendored
Normal 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();
|
||||||
|
}
|
||||||
39
types/Vector.d.ts
vendored
Normal file
39
types/Vector.d.ts
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { RandomAccessIterator } from './iterators/RandomAccess';
|
||||||
|
import { SequenceContainer } from './containers/Sequence';
|
||||||
|
|
||||||
|
export class Vector<T> extends SequenceContainer<T, VectorIterator<T>> {
|
||||||
|
/**
|
||||||
|
* empty vector
|
||||||
|
*/
|
||||||
|
constructor();
|
||||||
|
/**
|
||||||
|
* vector 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 vector
|
||||||
|
* @param begin of another SequenceContainer<T>
|
||||||
|
* @param end of another SequenceContainer<T>
|
||||||
|
*/
|
||||||
|
constructor(begin: VectorIterator<T>, end: VectorIterator<T>);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns vector[idx]
|
||||||
|
*/
|
||||||
|
get(idx: number): T;
|
||||||
|
/**
|
||||||
|
* vector[idx] = value
|
||||||
|
* @returns vector[idx]
|
||||||
|
*/
|
||||||
|
set(idx: number, value: T): T;
|
||||||
|
/**
|
||||||
|
* creates vector from array, string and other iterable object
|
||||||
|
*/
|
||||||
|
static from<T>(obj: Iterable<T>): Vector<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class VectorIterator<T> extends RandomAccessIterator<T> {
|
||||||
|
private constructor();
|
||||||
|
}
|
||||||
84
types/containers/Sequence.d.ts
vendored
Normal file
84
types/containers/Sequence.d.ts
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import { ForwardIterator } from "../iterators/Forward";
|
||||||
|
|
||||||
|
export class SequenceContainer<T, It extends ForwardIterator<T>> {
|
||||||
|
move(rhs: SequenceContainer<T, It>): this;
|
||||||
|
size(): number;
|
||||||
|
/**
|
||||||
|
* @param size new size
|
||||||
|
* @param value to insert
|
||||||
|
*/
|
||||||
|
resize(size: number, value: T): void;
|
||||||
|
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;
|
||||||
|
}
|
||||||
14
types/index.d.ts
vendored
Normal file
14
types/index.d.ts
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import type { ForwardIterator } from "./iterators/Forward"
|
||||||
|
import type { BidirectionalIterator } from "./iterators/Bidirectional"
|
||||||
|
import type { RandomAccessIterator } from "./iterators/RandomAccess"
|
||||||
|
import type { SequenceContainer } from "./containers/Sequence"
|
||||||
|
import type { List, ListIterator, ListItem } from "./List"
|
||||||
|
import type { Vector, VectorIterator } from "./Vector"
|
||||||
|
export type {
|
||||||
|
ForwardIterator,
|
||||||
|
BidirectionalIterator,
|
||||||
|
RandomAccessIterator,
|
||||||
|
SequenceContainer,
|
||||||
|
List, ListIterator, ListItem,
|
||||||
|
Vector, VectorIterator,
|
||||||
|
}
|
||||||
9
types/iterators/Bidirectional.d.ts
vendored
Normal file
9
types/iterators/Bidirectional.d.ts
vendored
Normal 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
24
types/iterators/Forward.d.ts
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
export class Item<T> {
|
||||||
|
value: T
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ForwardIterator<T> {
|
||||||
|
clone(): ForwardIterator<T>;
|
||||||
|
copy(rhs: ForwardIterator<T>): this;
|
||||||
|
get value(): T;
|
||||||
|
set value(value: T);
|
||||||
|
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;
|
||||||
|
neq(rhs: ForwardIterator<T>): boolean;
|
||||||
|
}
|
||||||
9
types/iterators/RandomAccess.d.ts
vendored
Normal file
9
types/iterators/RandomAccess.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { BidirectionalIterator } from "./Bidirectional";
|
||||||
|
|
||||||
|
export class RandomAccessIterator<T> extends BidirectionalIterator<T> {
|
||||||
|
sub(offset: number): this;
|
||||||
|
add(offset: number): this;
|
||||||
|
cmp(rhs: RandomAccessIterator<T>): number;
|
||||||
|
get(idx: number): T;
|
||||||
|
set(idx: number, value: T): T;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user