|
1 | 1 | import { arrayExpression } from "@babel/types";
|
| 2 | +import { start } from "repl"; |
2 | 3 |
|
3 | 4 | // File: index.ts //
|
4 | 5 | // Project: lieene.@lieene/ts-utility //
|
@@ -142,79 +143,60 @@ export function IsArrayOf<T>(array: any, isT: (obj: any) => obj is T): array is
|
142 | 143 | }
|
143 | 144 |
|
144 | 145 | export function DefAccessor(o: any, p: PropertyKey, get?: () => any, set?: (v: any) => void)
|
145 |
| -{ |
146 |
| - Object.defineProperty(o, p, { get, set }); |
147 |
| -} |
| 146 | +{ Object.defineProperty(o, p, { get, set }); } |
148 | 147 |
|
149 |
| -export interface Range |
150 |
| -{ |
151 |
| - start: number; |
152 |
| - length: number; |
153 |
| - end: number; |
154 |
| - contains(index: number): boolean; |
155 |
| -} |
156 |
| -interface InternalRange extends Range |
| 148 | +export class Range |
157 | 149 | {
|
158 |
| - _len: number; |
159 |
| -} |
160 |
| -function contains(this: Range, index: number): boolean |
161 |
| -{ |
162 |
| - return index >= this.start && index < this.end; |
163 |
| -} |
| 150 | + constructor(start: number, length: number); |
| 151 | + constructor(startEnd: [number, number]); |
| 152 | + constructor(start: number | [number, number], length: number = 0) |
| 153 | + { |
| 154 | + [start, length] = IsNumber(start) ? [start, length] : [start[0], start[1] - start[0]] |
| 155 | + if (start < 0 || length < 0) { throw new Error('index out off range'); } |
| 156 | + this.start = start >>> 0; |
| 157 | + this.length = length >>> 0; |
| 158 | + } |
| 159 | + readonly start: number; |
| 160 | + readonly length: number; |
| 161 | + get end(): number { return this.start + this.end; } |
164 | 162 |
|
165 |
| -function rangeInfo(this: Range): string |
166 |
| -{ |
167 |
| - return `[${this.length}:${this.start},${this.end})`; |
168 |
| -} |
169 |
| -function getLen(this: InternalRange): number |
170 |
| -{ |
171 |
| - return this._len; |
172 |
| -} |
173 |
| -function setLen(this: InternalRange, len: number): void |
174 |
| -{ |
175 |
| - this._len = Math.max(len, 0); |
176 |
| -} |
177 |
| -function getEnd(this: InternalRange): number |
178 |
| -{ |
179 |
| - return this.start + this.length; |
180 |
| -} |
181 |
| -function setEnd(this: InternalRange, end: number): void |
182 |
| -{ |
183 |
| - end = end >>> 0; |
184 |
| - if (end < this.start) |
| 163 | + intersection(other: Range): Range | undefined |
185 | 164 | {
|
186 |
| - throw new Error('index out off range'); |
| 165 | + if (this.start >= other.end && this.end <= other.start) { return undefined; } |
| 166 | + else { return new Range([Math.max(this.start, other.start), Math.min(this.end, other.end)]); } |
187 | 167 | }
|
188 |
| - this.length = end - this.start; |
189 |
| -} |
190 | 168 |
|
191 |
| -export function StartLen(start: number, length: number): Range |
192 |
| -{ |
193 |
| - start = start >>> 0; |
194 |
| - length = length >>> 0; |
195 |
| - if (start < 0 || length < 0) |
| 169 | + union(other: Range): Range { return new Range([Math.min(this.start, other.start), Math.max(this.end, other.end)]); } |
| 170 | + |
| 171 | + isEqual(other: Range): boolean { return this.start === other.start && this.end === other.end; } |
| 172 | + |
| 173 | + isEmpty(): boolean { return this.length === 0; } |
| 174 | + |
| 175 | + isPositive(): boolean { return this.start >= 0; } |
| 176 | + |
| 177 | + shrinkStart(count: number): Range | undefined |
196 | 178 | {
|
197 |
| - throw new Error('index out off range'); |
| 179 | + count = count >>> 0; |
| 180 | + let end = this.end; |
| 181 | + let start = this.start + count; |
| 182 | + if (start > end) { return undefined; } |
| 183 | + return new Range([start, end]); |
198 | 184 | }
|
199 |
| - let rg: InternalRange = { contains, start, _len: length } as any; |
200 |
| - rg.toString = rangeInfo; |
201 |
| - DefAccessor(rg, 'end', getEnd, setEnd); |
202 |
| - DefAccessor(rg, 'length', getLen, setLen); |
203 |
| - return rg; |
204 |
| -} |
205 | 185 |
|
206 |
| -export function StartEnd(start: number, end: number): Range |
207 |
| -{ |
208 |
| - start = start >>> 0; |
209 |
| - end = end >>> 0; |
210 |
| - if (start < 0 || end < start) |
| 186 | + shrinkEnd(count: number): Range | undefined |
211 | 187 | {
|
212 |
| - throw new Error('index out off range'); |
| 188 | + count = count >>> 0; |
| 189 | + let start = this.start; |
| 190 | + let end = this.end - count; |
| 191 | + if (end < start) { return undefined; } |
| 192 | + return new Range([this.start, end]); |
213 | 193 | }
|
214 |
| - let rg: Range = { contains, start, _len: end - start } as any; |
215 |
| - DefAccessor(rg, 'end', getEnd, setEnd); |
216 |
| - DefAccessor(rg, 'length', getLen, setLen); |
217 |
| - return rg; |
| 194 | + |
| 195 | + shift(count: number): Range { return new Range(this.start + count, this.end + count); } |
| 196 | + |
| 197 | + contains(index: number): boolean { return index >= this.start && index < this.end; } |
| 198 | + |
| 199 | + toString(): string { return `[${this.length}:${this.start},${this.end})`; } |
218 | 200 | }
|
219 | 201 |
|
220 | 202 | export function applyMixins(derivedCtor: any, baseCtors: any[])
|
|
0 commit comments