feat(Vector)

This commit is contained in:
2025-07-23 10:36:50 +03:00
parent 83c491ff6f
commit aca4539ce4
21 changed files with 1103 additions and 1533 deletions

1
.gitignore vendored
View File

@ -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

View File

@ -6,3 +6,6 @@ build:
test: test:
npx vitest npx vitest
cover:
npx vitest --coverage

View File

@ -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` |

1873
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,7 @@
"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": "^4.45.1",
"rollup-plugin-dts": "^6.2.1", "rollup-plugin-dts": "^6.2.1",
"vitest": "^3.1.1" "vitest": "^3.1.1"

View File

@ -121,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

158
src/Vector.js Normal file
View 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)

View File

@ -1,5 +1,6 @@
import { BidirectionalIterator } from "../iterators/Bidirectional" import { ForwardIterator } from "../iterators/Forward"
import { getCloneFunc, satisfiesConcept } from "../utils/concept" import { RandomAccessIterator } from "../iterators/RandomAccess"
import { satisfiesConcept } from "../utils/concept"
export class SequenceContainer { export class SequenceContainer {
clone() { clone() {
@ -39,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')
} }
@ -87,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 {
@ -101,8 +112,8 @@ export class SequenceContainer {
} }
} }
} }
} })
) }
} }
clear() { clear() {

View File

@ -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"

View File

@ -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)
} }

View File

@ -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,13 +14,13 @@ 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)

View 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)
}

View File

@ -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;
} }

View File

@ -1,151 +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).toThrow()
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('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])
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 ]')
expect(List.from([0n]).toString()).toEqual('[ 0 ]')
}) })

25
test/Vector.test.js Normal file
View 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)
})
})

View 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())
})
})
}

39
types/Vector.d.ts vendored Normal file
View 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: ListIterator<T>, end: ListIterator<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();
}

View File

@ -1,8 +1,13 @@
import { ForwardIterator } from "../iterators/Forward"; import { ForwardIterator } from "../iterators/Forward";
export class SequenceContainer<T, It extends ForwardIterator<T>> { export interface SequenceContainer<T, It extends ForwardIterator<T>> {
move(rhs: SequenceContainer<T, It>): this; move(rhs: SequenceContainer<T, It>): this;
size(): number; size(): number;
/**
* @param size new size
* @param value to insert
*/
resize(size: number, value: T): void;
begin(): It; begin(): It;
end(): It; end(): It;

View File

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

View File

@ -1,10 +1,12 @@
export class Item<T> { export interface Item<T> {
value: T value: T
} }
export class ForwardIterator<T> { export interface ForwardIterator<T> {
clone(): ForwardIterator<T>; clone(): ForwardIterator<T>;
copy(rhs: ForwardIterator<T>): this; copy(rhs: ForwardIterator<T>): this;
get value(): T;
set value(value: T);
deref(): Item<T>; deref(): Item<T>;
eq(rhs: ForwardIterator<T>): boolean; eq(rhs: ForwardIterator<T>): boolean;
/** /**
@ -18,7 +20,5 @@ export class ForwardIterator<T> {
* @returns {this} * @returns {this}
*/ */
move(rhs: ForwardIterator<T>): this; move(rhs: ForwardIterator<T>): this;
get value(): T;
set value(value: T);
neq(rhs: ForwardIterator<T>): boolean; neq(rhs: ForwardIterator<T>): boolean;
} }

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

@ -0,0 +1,9 @@
import { BidirectionalIterator } from "./Bidirectional";
export interface 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;
}