@@ -7,12 +7,26 @@ import {
7
7
storeUnsafe
8
8
} from "./internal/arraybuffer" ;
9
9
10
+ import {
11
+ allocateUnsafe as allocateUnsafeString ,
12
+ freeUnsafe as freeUnsafeString ,
13
+ copyUnsafe as copyUnsafeString
14
+ } from "./internal/string" ;
15
+
10
16
import {
11
17
defaultComparator ,
12
18
insertionSort ,
13
19
weakHeapSort
14
20
} from "./internal/array" ;
15
21
22
+ import {
23
+ itoa ,
24
+ dtoa ,
25
+ itoa_stream ,
26
+ dtoa_stream ,
27
+ MAX_DOUBLE_LENGTH
28
+ } from "./internal/number" ;
29
+
16
30
export class Array < T > {
17
31
18
32
/* @internal */ buffer_ : ArrayBuffer ;
@@ -118,16 +132,9 @@ export class Array<T> {
118
132
return this ;
119
133
}
120
134
135
+ @inline
121
136
includes ( searchElement : T , fromIndex : i32 = 0 ) : bool {
122
- var length = this . length_ ;
123
- if ( length == 0 || fromIndex >= length ) return false ;
124
- if ( fromIndex < 0 ) fromIndex = max ( length + fromIndex , 0 ) ;
125
- var buffer = this . buffer_ ;
126
- while ( fromIndex < length ) {
127
- if ( loadUnsafe < T , T > ( buffer , fromIndex ) == searchElement ) return true ;
128
- ++ fromIndex ;
129
- }
130
- return false ;
137
+ return this . indexOf ( searchElement , fromIndex ) >= 0 ;
131
138
}
132
139
133
140
indexOf ( searchElement : T , fromIndex : i32 = 0 ) : i32 {
@@ -356,6 +363,169 @@ export class Array<T> {
356
363
}
357
364
}
358
365
366
+ join ( separator : string = "," ) : string {
367
+ var lastIndex = this . length_ - 1 ;
368
+ if ( lastIndex < 0 ) return "" ;
369
+ var result = "" ;
370
+ var value : T ;
371
+ var buffer = this . buffer_ ;
372
+ var sepLen = separator . length ;
373
+ var hasSeparator = sepLen != 0 ;
374
+ if ( value instanceof bool ) {
375
+ if ( ! lastIndex ) {
376
+ return select < string > ( "true" , "false" , loadUnsafe < T , bool > ( buffer , 0 ) ) ;
377
+ }
378
+ let valueLen = 5 ; // max possible length of element len("false")
379
+ let estLen = ( valueLen + sepLen ) * lastIndex + valueLen ;
380
+ let result = allocateUnsafeString ( estLen ) ;
381
+ let offset = 0 ;
382
+ for ( let i = 0 ; i < lastIndex ; ++ i ) {
383
+ value = loadUnsafe < T , bool > ( buffer , i ) ;
384
+ valueLen = 4 + < i32 > ( ! value ) ;
385
+ copyUnsafeString ( result , offset , select < string > ( "true" , "false" , value ) , 0 , valueLen ) ;
386
+ offset += valueLen ;
387
+ if ( hasSeparator ) {
388
+ copyUnsafeString ( result , offset , changetype < String > ( separator ) , 0 , sepLen ) ;
389
+ offset += sepLen ;
390
+ }
391
+ }
392
+ value = loadUnsafe < T , bool > ( buffer , lastIndex ) ;
393
+ valueLen = 4 + < i32 > ( ! value ) ;
394
+ copyUnsafeString ( result , offset , select < string > ( "true" , "false" , value ) , 0 , valueLen ) ;
395
+ offset += valueLen ;
396
+
397
+ let out = result ;
398
+ if ( estLen > offset ) {
399
+ out = result . substring ( 0 , offset ) ;
400
+ freeUnsafeString ( result ) ;
401
+ }
402
+ return out ;
403
+ } else if ( isInteger < T > ( ) ) {
404
+ if ( ! lastIndex ) {
405
+ return changetype < string > ( itoa < T > ( loadUnsafe < T , T > ( buffer , 0 ) ) ) ;
406
+ }
407
+ const valueLen = ( sizeof < T > ( ) <= 4 ? 10 : 20 ) + < i32 > isSigned < T > ( ) ;
408
+ let estLen = ( valueLen + sepLen ) * lastIndex + valueLen ;
409
+ let result = allocateUnsafeString ( estLen ) ;
410
+ let offset = 0 ;
411
+ for ( let i = 0 ; i < lastIndex ; ++ i ) {
412
+ value = loadUnsafe < T , T > ( buffer , i ) ;
413
+ offset += itoa_stream < T > ( changetype < usize > ( result ) , offset , value ) ;
414
+ if ( hasSeparator ) {
415
+ copyUnsafeString ( result , offset , separator , 0 , sepLen ) ;
416
+ offset += sepLen ;
417
+ }
418
+ }
419
+ value = loadUnsafe < T , T > ( buffer , lastIndex ) ;
420
+ offset += itoa_stream < T > ( changetype < usize > ( result ) , offset , value ) ;
421
+ let out = result ;
422
+ if ( estLen > offset ) {
423
+ out = result . substring ( 0 , offset ) ;
424
+ freeUnsafeString ( result ) ;
425
+ }
426
+ return out ;
427
+ } else if ( isFloat < T > ( ) ) {
428
+ if ( ! lastIndex ) {
429
+ return changetype < string > ( dtoa ( loadUnsafe < T , f64 > ( buffer , 0 ) ) ) ;
430
+ }
431
+ const valueLen = MAX_DOUBLE_LENGTH ;
432
+ let estLen = ( valueLen + sepLen ) * lastIndex + valueLen ;
433
+ let result = allocateUnsafeString ( estLen ) ;
434
+ let offset = 0 ;
435
+ for ( let i = 0 ; i < lastIndex ; ++ i ) {
436
+ value = loadUnsafe < T , f64 > ( buffer , i ) ;
437
+ offset += dtoa_stream ( changetype < usize > ( result ) , offset , value ) ;
438
+ if ( hasSeparator ) {
439
+ copyUnsafeString ( result , offset , separator , 0 , sepLen ) ;
440
+ offset += sepLen ;
441
+ }
442
+ }
443
+ value = loadUnsafe < T , f64 > ( buffer , lastIndex ) ;
444
+ offset += dtoa_stream ( changetype < usize > ( result ) , offset , value ) ;
445
+ let out = result ;
446
+ if ( estLen > offset ) {
447
+ out = result . substring ( 0 , offset ) ;
448
+ freeUnsafeString ( result ) ;
449
+ }
450
+ return out ;
451
+ } else if ( isString < T > ( ) ) {
452
+ if ( ! lastIndex ) {
453
+ return loadUnsafe < T , string > ( buffer , 0 ) ;
454
+ }
455
+ let estLen = 0 ;
456
+ for ( let i = 0 , len = lastIndex + 1 ; i < len ; ++ i ) {
457
+ estLen += loadUnsafe < T , string > ( buffer , i ) . length ;
458
+ }
459
+ let offset = 0 ;
460
+ let result = allocateUnsafeString ( estLen + sepLen * lastIndex ) ;
461
+ for ( let i = 0 ; i < lastIndex ; ++ i ) {
462
+ value = loadUnsafe < T , String > ( buffer , i ) ;
463
+ if ( value ) {
464
+ let valueLen = value . length ; // tslint:disable-line:no-unsafe-any
465
+ copyUnsafeString ( result , offset , value , 0 , valueLen ) ; // tslint:disable-line:no-unsafe-any
466
+ offset += valueLen ; // tslint:disable-line:no-unsafe-any
467
+ }
468
+ if ( hasSeparator ) {
469
+ copyUnsafeString ( result , offset , separator , 0 , sepLen ) ;
470
+ offset += sepLen ;
471
+ }
472
+ }
473
+ value = loadUnsafe < T , String > ( buffer , lastIndex ) ;
474
+ if ( value ) {
475
+ let valueLen = value . length ; // tslint:disable-line:no-unsafe-any
476
+ copyUnsafeString ( result , offset , value , 0 , valueLen ) ; // tslint:disable-line:no-unsafe-any
477
+ }
478
+ return result ;
479
+ } else if ( isArray < T > ( ) ) {
480
+ if ( ! lastIndex ) {
481
+ value = loadUnsafe < T , T > ( buffer , 0 ) ;
482
+ return value ? value . join ( separator ) : "" ; // tslint:disable-line:no-unsafe-any
483
+ }
484
+ for ( let i = 0 ; i < lastIndex ; ++ i ) {
485
+ value = loadUnsafe < T , T > ( buffer , i ) ;
486
+ if ( value ) result += value . join ( separator ) ; // tslint:disable-line:no-unsafe-any
487
+ if ( hasSeparator ) result += separator ;
488
+ }
489
+ value = loadUnsafe < T , T > ( buffer , lastIndex ) ;
490
+ if ( value ) result += value . join ( separator ) ; // tslint:disable-line:no-unsafe-any
491
+ return result ;
492
+ } else if ( isReference < T > ( ) ) { // References
493
+ if ( ! lastIndex ) return "[object Object]" ;
494
+ const valueLen = 15 ; // max possible length of element len("[object Object]")
495
+ let estLen = ( valueLen + sepLen ) * lastIndex + valueLen ;
496
+ let result = allocateUnsafeString ( estLen ) ;
497
+ let offset = 0 ;
498
+ for ( let i = 0 ; i < lastIndex ; ++ i ) {
499
+ value = loadUnsafe < T , T > ( buffer , i ) ;
500
+ if ( value ) {
501
+ copyUnsafeString ( result , offset , changetype < String > ( "[object Object]" ) , 0 , valueLen ) ;
502
+ offset += valueLen ;
503
+ }
504
+ if ( hasSeparator ) {
505
+ copyUnsafeString ( result , offset , changetype < String > ( separator ) , 0 , sepLen ) ;
506
+ offset += sepLen ;
507
+ }
508
+ }
509
+ if ( loadUnsafe < T , T > ( buffer , lastIndex ) ) {
510
+ copyUnsafeString ( result , offset , changetype < String > ( "[object Object]" ) , 0 , valueLen ) ;
511
+ offset += valueLen ;
512
+ }
513
+ let out = result ;
514
+ if ( estLen > offset ) {
515
+ out = result . substring ( 0 , offset ) ;
516
+ freeUnsafeString ( result ) ;
517
+ }
518
+ return out ;
519
+ } else {
520
+ assert ( false ) ; // Unsupported generic typename
521
+ }
522
+ }
523
+
524
+ @inline
525
+ toString ( ) : string {
526
+ return this . join ( ) ;
527
+ }
528
+
359
529
private __gc ( ) : void {
360
530
var buffer = this . buffer_ ;
361
531
__gc_mark ( changetype < usize > ( buffer ) ) ; // tslint:disable-line
0 commit comments