comparison dwt/dwthelper/utils.d.orig @ 329:92aa2d7391f3

Added 'all.d' package import, a dwt.all for everything and a dwt.std for the essential stuff
author Frank Benoit <benoit@tionex.de>
date Sat, 18 Oct 2008 22:01:20 +0200
parents
children
comparison
equal deleted inserted replaced
325:68adc3a367d9 329:92aa2d7391f3
1 /**
2 * Authors: Frank Benoit <keinfarbton@googlemail.com>
3 */
4 module dwt.dwthelper.utils;
5
6 public import dwt.dwthelper.System;
7 public import Math = tango.math.Math;
8
9 public import tango.core.Exception : IllegalArgumentException, IOException;
10
11 import tango.io.Stdout;
12 import tango.io.Print;
13 static import tango.stdc.stringz;
14 static import tango.text.Util;
15 static import tango.text.Text;
16 import tango.text.Unicode;
17 import tango.text.convert.Utf;
18 import tango.core.Exception;
19 import tango.stdc.stdlib : exit;
20
21 import tango.util.log.Trace;
22 import tango.text.UnicodeData;
23 static import tango.util.collection.model.Seq;
24
25 alias char[] String;
26 alias tango.text.Text.Text!(char) StringBuffer;
27
28 void implMissing( String file, uint line ){
29 Stderr.formatln( "implementation missing in file {} line {}", file, line );
30 Stderr.formatln( "exiting ..." );
31 exit(1);
32 }
33
34 abstract class ArrayWrapper{
35 }
36 abstract class ValueWrapper{
37 }
38
39 class ArrayWrapperT(T) : ArrayWrapper {
40 public T[] array;
41 public this( T[] data ){
42 array = data;
43 }
44 public override int opEquals( Object o ){
45 if( auto other = cast(ArrayWrapperT!(T))o){
46 return array == other.array;
47 }
48 return false;
49 }
50 public override hash_t toHash(){
51 return (typeid(T[])).getHash(&array);
52 }
53 }
54
55 class ValueWrapperT(T) : ValueWrapper {
56 public T value;
57 public this( T data ){
58 value = data;
59 }
60 static if( is(T==class) || is(T==interface)){
61 public int opEquals( Object other ){
62 if( auto o = cast(ValueWrapperT!(T))other ){
63 return value == o.value;
64 }
65 if( auto o = cast(T)other ){
66 if( value is o ){
67 return true;
68 }
69 if( value is null || o is null ){
70 return false;
71 }
72 return value == o;
73 }
74 return false;
75 }
76 }
77 else{
78 public int opEquals( Object other ){
79 if( auto o = cast(ValueWrapperT!(T))other ){
80 return value == o.value;
81 }
82 return false;
83 }
84 public int opEquals( T other ){
85 return value == other;
86 }
87 }
88 public override hash_t toHash(){
89 return (typeid(T)).getHash(&value);
90 }
91 }
92
93 class Boolean : ValueWrapperT!(bool) {
94 public static Boolean TRUE;
95 public static Boolean FALSE;
96
97 static this(){
98 TRUE = new Boolean(true);
99 FALSE = new Boolean(false);
100 }
101 public this( bool v ){
102 super(v);
103 }
104
105 alias ValueWrapperT!(bool).opEquals opEquals;
106 public int opEquals( int other ){
107 return value == ( other !is 0 );
108 }
109 public int opEquals( Object other ){
110 if( auto o = cast(Boolean)other ){
111 return value == o.value;
112 }
113 return false;
114 }
115 public bool booleanValue(){
116 return value;
117 }
118 public static Boolean valueOf( String s ){
119 if( s == "yes" || s == "true" ){
120 return TRUE;
121 }
122 return FALSE;
123 }
124 public static Boolean valueOf( bool b ){
125 return b ? TRUE : FALSE;
126 }
127 }
128
129 alias Boolean ValueWrapperBool;
130
131
132 class Byte : ValueWrapperT!(byte) {
133 public static byte parseByte( String s ){
134 try{
135 int res = tango.text.convert.Integer.parse( s );
136 if( res < byte.min || res > byte.max ){
137 throw new NumberFormatException( "out of range" );
138 }
139 return res;
140 }
141 catch( IllegalArgumentException e ){
142 throw new NumberFormatException( e );
143 }
144 }
145 this( byte value ){
146 super( value );
147 }
148 }
149 alias Byte ValueWrapperByte;
150
151
152 class Integer : ValueWrapperT!(int) {
153
154 public static const int MIN_VALUE = 0x80000000;
155 public static const int MAX_VALUE = 0x7fffffff;
156 public static const int SIZE = 32;
157
158 public this ( int value ){
159 super( value );
160 }
161
162 public this ( String s ){
163 super(parseInt(s));
164 }
165
166 public static String toString( int i, int radix ){
167 switch( radix ){
168 case 2:
169 return toBinaryString(i);
170 case 8:
171 return toOctalString(i);
172 case 10:
173 return toString(i);
174 case 16:
175 return toHexString(i);
176 default:
177 implMissing( __FILE__, __LINE__ );
178 return null;
179 }
180 }
181
182 public static String toHexString( int i ){
183 return tango.text.convert.Integer.toString(i, "x" );
184 }
185
186 public static String toOctalString( int i ){
187 return tango.text.convert.Integer.toString(i, "o" );
188 }
189
190 public static String toBinaryString( int i ){
191 return tango.text.convert.Integer.toString(i, "b" );
192 }
193
194 public static String toString( int i ){
195 return tango.text.convert.Integer.toString(i);
196 }
197
198 public static int parseInt( String s, int radix ){
199 try{
200 return tango.text.convert.Integer.toLong( s, radix );
201 }
202 catch( IllegalArgumentException e ){
203 throw new NumberFormatException( e );
204 }
205 }
206
207 public static int parseInt( String s ){
208 try{
209 return tango.text.convert.Integer.toLong( s );
210 }
211 catch( IllegalArgumentException e ){
212 throw new NumberFormatException( e );
213 }
214 }
215
216 public static Integer valueOf( String s, int radix ){
217 implMissing( __FILE__, __LINE__ );
218 return null;
219 }
220
221 public static Integer valueOf( String s ){
222 return valueOf( parseInt(s));
223 }
224
225 public static Integer valueOf( int i ){
226 return new Integer(i);
227 }
228
229 public byte byteValue(){
230 return cast(byte)value;
231 }
232
233 public short shortValue(){
234 return cast(short)value;
235 }
236
237 public int intValue(){
238 return value;
239 }
240
241 public long longValue(){
242 return cast(long)value;
243 }
244
245 public float floatValue(){
246 return cast(float)value;
247 }
248
249 public double doubleValue(){
250 return cast(double)value;
251 }
252
253 public override hash_t toHash(){
254 return intValue();
255 }
256
257 public override String toString(){
258 return tango.text.convert.Integer.toString( value );
259 }
260 }
261 alias Integer ValueWrapperInt;
262
263 class Double : ValueWrapperT!(double) {
264 public static double MAX_VALUE = double.max;
265 public static double MIN_VALUE = double.min;
266 this( double value ){
267 super(value);
268 }
269 this( String str ){
270 implMissing( __FILE__, __LINE__ );
271 super(0.0);
272 }
273 public double doubleValue(){
274 return value;
275 }
276 public static String toString( double value ){
277 implMissing( __FILE__, __LINE__ );
278 return null;
279 }
280 }
281
282 class Float : ValueWrapperT!(float) {
283
284 public static float POSITIVE_INFINITY = (1.0f / 0.0f);
285 public static float NEGATIVE_INFINITY = ((-1.0f) / 0.0f);
286 public static float NaN = (0.0f / 0.0f);
287 public static float MAX_VALUE = 3.4028235e+38f;
288 public static float MIN_VALUE = 1.4e-45f;
289 public static int SIZE = 32;
290
291 this( float value ){
292 super(value);
293 }
294 this( String str ){
295 implMissing( __FILE__, __LINE__ );
296 super(0.0);
297 }
298 public float floatValue(){
299 return value;
300 }
301 public static String toString( float value ){
302 implMissing( __FILE__, __LINE__ );
303 return null;
304 }
305 public static float parseFloat( String s ){
306 try{
307 return tango.text.convert.Float.toFloat( s );
308 }
309 catch( IllegalArgumentException e ){
310 throw new NumberFormatException( e );
311 }
312 }
313
314 }
315 class Long : ValueWrapperT!(long) {
316 public static const long MIN_VALUE = long.min;
317 public static const long MAX_VALUE = long.max;
318 this( long value ){
319 super(value);
320 }
321 this( String str ){
322 implMissing( __FILE__, __LINE__ );
323 super(0);
324 }
325 public long longValue(){
326 return value;
327 }
328 public static long parseLong(String s){
329 implMissing( __FILE__, __LINE__ );
330 return 0;
331 }
332 public static String toString( double value ){
333 implMissing( __FILE__, __LINE__ );
334 return null;
335 }
336 }
337 alias Long ValueWrapperLong;
338
339
340 // alias ValueWrapperT!(int) ValueWrapperInt;
341
342 alias ArrayWrapperT!(byte) ArrayWrapperByte;
343 alias ArrayWrapperT!(int) ArrayWrapperInt;
344 alias ArrayWrapperT!(Object) ArrayWrapperObject;
345 alias ArrayWrapperT!(char) ArrayWrapperString;
346 alias ArrayWrapperT!(String) ArrayWrapperString2;
347
348 Object[] StringArrayToObjectArray( String[] strs ){
349 Object[] res = new Object[strs.length];
350 foreach( idx, str; strs ){
351 res[idx] = new ArrayWrapperString(str);
352 }
353 return res;
354 }
355 int codepointIndexToIndex( String str, int cpIndex ){
356 int cps = cpIndex;
357 int res = 0;
358 while( cps > 0 ){
359 cps--;
360 if( str[res] < 0x80 ){
361 res+=1;
362 }
363 else if( str[res] < 0xE0 ){
364 res+=2;
365 }
366 else if( str[res] & 0xF0 ){
367 res+=3;
368 }
369 else{
370 res+=4;
371 }
372 }
373 return res;
374 }
375
376 /++
377 +
378 +/
379 int indexToCodepointIndex( String str, int index ){
380 if( index < 0 ) return index;
381 int i = 0;
382 int res = 0;
383 while( i < index ){
384 if( i >= str.length ){
385 break;
386 }
387 if( str[i] < 0x80 ){
388 i+=1;
389 }
390 else if( str[i] < 0xE0 ){
391 i+=2;
392 }
393 else if( str[i] & 0xF0 ){
394 i+=3;
395 }
396 else{
397 i+=4;
398 }
399 res++;
400 }
401 return res;
402 }
403
404 /++
405 + Get that String, that contains the next codepoint of a String.
406 +/
407 String firstCodePointStr( String str, out int consumed ){
408 dchar[1] buf;
409 uint ate;
410 dchar[] res = str.toString32( buf, &ate );
411 consumed = ate;
412 return str[ 0 .. ate ];
413 }
414
415 /++
416 + Get first codepoint of a String. If an offset is needed, simply use a slice:
417 + ---
418 + dchar res = str[ offset .. $ ].firstCodePoint();
419 + ---
420 +/
421 dchar firstCodePoint( String str ){
422 int dummy;
423 return firstCodePoint( str, dummy );
424 }
425 dchar firstCodePoint( String str, out int consumed ){
426 dchar[1] buf;
427 uint ate;
428 dchar[] res = str.toString32( buf, &ate );
429 consumed = ate;
430 if( ate is 0 || res.length is 0 ){
431 Trace.formatln( "dwthelper.utils {}: str.length={} str={:X2}", __LINE__, str.length, cast(ubyte[])str );
432 }
433 assert( ate > 0 );
434 assert( res.length is 1 );
435 return res[0];
436 }
437
438 String dcharToString( dchar key ){
439 dchar[1] buf;
440 buf[0] = key;
441 return tango.text.convert.Utf.toString( buf );
442 }
443
444 int codepointCount( String str ){
445 scope dchar[] buf = new dchar[]( str.length );
446 uint ate;
447 dchar[] res = tango.text.convert.Utf.toString32( str, buf, &ate );
448 assert( ate is str.length );
449 return res.length;
450 }
451
452 alias tango.text.convert.Utf.toString16 toString16;
453 alias tango.text.convert.Utf.toString toString;
454
455 int length( String str ){
456 return str.length;
457 }
458
459 int getRelativeCodePointOffset( String str, int startIndex, int searchRelCp ){
460 int ignore;
461 int i = startIndex;
462 if( searchRelCp > 0 ){
463 while( searchRelCp !is 0 ){
464
465 if( ( i < str.length )
466 && ( str[i] & 0x80 ) is 0x00 )
467 {
468 i+=1;
469 }
470 else if( ( i+1 < str.length )
471 && (( str[i+1] & 0xC0 ) is 0x80 )
472 && (( str[i ] & 0xE0 ) is 0xC0 ))
473 {
474 i+=2;
475 }
476 else if( ( i+2 < str.length )
477 && (( str[i+2] & 0xC0 ) is 0x80 )
478 && (( str[i+1] & 0xC0 ) is 0x80 )
479 && (( str[i ] & 0xF0 ) is 0xE0 ))
480 {
481 i+=3;
482 }
483 else if(( i+3 < str.length )
484 && (( str[i+3] & 0xC0 ) is 0x80 )
485 && (( str[i+2] & 0xC0 ) is 0x80 )
486 && (( str[i+1] & 0xC0 ) is 0x80 )
487 && (( str[i ] & 0xF8 ) is 0xF0 ))
488 {
489 i+=4;
490 }
491 else{
492 Trace.formatln( "invalid utf8 characters: {:X2}", cast(ubyte[]) str );
493 tango.text.convert.Utf.onUnicodeError( "invalid utf8 input", i );
494 }
495 searchRelCp--;
496 }
497 }
498 else if( searchRelCp < 0 ){
499 while( searchRelCp !is 0 ){
500 do{
501 i--;
502 if( i < 0 ){
503 return -1;
504 //Trace.formatln( "dwthelper.utils getRelativeCodePointOffset {}: str={}, startIndex={}, searchRelCp={}", __LINE__, str, startIndex, searchRelCp );
505 //tango.text.convert.Utf.onUnicodeError( "invalid utf8 input", i );
506 }
507 } while(( str[i] & 0xC0 ) is 0x80 );
508 searchRelCp++;
509 }
510 }
511 return i - startIndex;
512 }
513 dchar getRelativeCodePoint( String str, int startIndex, int searchRelCp, out int relIndex ){
514 relIndex = getRelativeCodePointOffset( str, startIndex, searchRelCp );
515 int ignore;
516 return firstCodePoint( str[ startIndex+relIndex .. $ ], ignore );
517 }
518
519 int utf8AdjustOffset( String str, int offset ){
520 if( str.length <= offset || offset <= 0 ){
521 return offset;
522 }
523 while(( str[offset] & 0xC0 ) is 0x80 ){
524 offset--;
525 }
526 return offset;
527 }
528 int utf8OffsetIncr( String str, int offset ){
529 int res = offset +1;
530 if( str.length <= res || res <= 0 ){
531 return res;
532 }
533 int tries = 4;
534 while(( str[res] & 0xC0 ) is 0x80 ){
535 res++;
536 assert( tries-- > 0 );
537 }
538 return res;
539 }
540 int utf8OffsetDecr( String str, int offset ){
541 int res = offset-1;
542 if( str.length <= res || res <= 0 ){
543 return res;
544 }
545 int tries = 4;
546 while(( str[res] & 0xC0 ) is 0x80 ){
547 res--;
548 assert( tries-- > 0 );
549 }
550 Trace.formatln( "utf8OffsetDecr {}->{}", offset, res );
551 Trace.memory( str );
552 return res;
553 }
554
555 bool CharacterIsDefined( dchar ch ){
556 return (ch in tango.text.UnicodeData.unicodeData) !is null;
557 }
558 dchar CharacterFirstToLower( String str ){
559 int consumed;
560 return CharacterFirstToLower( str, consumed );
561 }
562 dchar CharacterFirstToLower( String str, out int consumed ){
563 dchar[1] buf;
564 buf[0] = firstCodePoint( str, consumed );
565 dchar[] r = tango.text.Unicode.toLower( buf );
566 return r[0];
567 }
568
569 dchar CharacterToLower( dchar c ){
570 dchar[] r = tango.text.Unicode.toLower( [c] );
571 return r[0];
572 }
573 dchar CharacterToUpper( dchar c ){
574 dchar[] r = tango.text.Unicode.toUpper( [c] );
575 return r[0];
576 }
577 bool CharacterIsWhitespace( dchar c ){
578 return tango.text.Unicode.isWhitespace( c );
579 }
580 bool CharacterIsDigit( dchar c ){
581 return tango.text.Unicode.isDigit( c );
582 }
583 bool CharacterIsLetter( dchar c ){
584 return tango.text.Unicode.isLetter( c );
585 }
586 public String toUpperCase( String str ){
587 return tango.text.Unicode.toUpper( str );
588 }
589
590 public int indexOf( String str, char searched ){
591 int res = tango.text.Util.locate( str, searched );
592 if( res is str.length ) res = -1;
593 return res;
594 }
595
596 public int indexOf( String str, char searched, int startpos ){
597 int res = tango.text.Util.locate( str, searched, startpos );
598 if( res is str.length ) res = -1;
599 return res;
600 }
601
602 public int indexOf(String str, String ch){
603 return indexOf( str, ch, 0 );
604 }
605
606 public int indexOf(String str, String ch, int start){
607 int res = tango.text.Util.locatePattern( str, ch, start );
608 if( res is str.length ) res = -1;
609 return res;
610 }
611
612 public int lastIndexOf(String str, char ch){
613 return lastIndexOf( str, ch, str.length );
614 }
615 public int lastIndexOf(String str, char ch, int formIndex){
616 int res = tango.text.Util.locatePrior( str, ch, formIndex );
617 if( res is str.length ) res = -1;
618 return res;
619 }
620 public int lastIndexOf(String str, String ch ){
621 return lastIndexOf( str, ch, str.length );
622 }
623 public int lastIndexOf(String str, String ch, int start ){
624 int res = tango.text.Util.locatePatternPrior( str, ch, start );
625 if( res is str.length ) res = -1;
626 return res;
627 }
628
629 public String replace( String str, char from, char to ){
630 return tango.text.Util.replace( str.dup, from, to );
631 }
632
633 public String substring( String str, int start ){
634 return str[ start .. $ ].dup;
635 }
636
637 public String substring( String str, int start, int end ){
638 return str[ start .. end ].dup;
639 }
640
641 public wchar[] substring( wchar[] str, int start ){
642 return str[ start .. $ ].dup;
643 }
644
645 public wchar[] substring( wchar[] str, int start, int end ){
646 return str[ start .. end ].dup;
647 }
648
649 public char charAt( String str, int pos ){
650 return str[ pos ];
651 }
652
653 public void getChars( String src, int srcBegin, int srcEnd, String dst, int dstBegin){
654 dst[ dstBegin .. dstBegin + srcEnd - srcBegin ] = src[ srcBegin .. srcEnd ];
655 }
656
657 public wchar[] toCharArray( String str ){
658 return toString16( str );
659 }
660
661 public bool endsWith( String src, String pattern ){
662 if( src.length < pattern.length ){
663 return false;
664 }
665 return src[ $-pattern.length .. $ ] == pattern;
666 }
667
668 public bool equals( String src, String other ){
669 return src == other;
670 }
671
672 public bool equalsIgnoreCase( String src, String other ){
673 return tango.text.Unicode.toFold(src) == tango.text.Unicode.toFold(other);
674 }
675
676 public int compareToIgnoreCase( String src, String other ){
677 return compareTo( tango.text.Unicode.toFold(src), tango.text.Unicode.toFold(other));
678 }
679 public int compareTo( String src, String other ){
680 return typeid(String).compare( cast(void*)&src, cast(void*)&other );
681 }
682
683 public bool startsWith( String src, String pattern ){
684 if( src.length < pattern.length ){
685 return false;
686 }
687 return src[ 0 .. pattern.length ] == pattern;
688 }
689
690 public String toLowerCase( String src ){
691 return tango.text.Unicode.toLower( src );
692 }
693
694 public hash_t toHash( String src ){
695 return typeid(String).getHash(&src);
696 }
697
698 public String trim( String str ){
699 return tango.text.Util.trim( str ).dup;
700 }
701 public String intern( String str ){
702 return str;
703 }
704
705 public char* toStringzValidPtr( String src ){
706 if( src ){
707 return src.toStringz();
708 }
709 else{
710 static const String nullPtr = "\0";
711 return nullPtr.ptr;
712 }
713 }
714
715 public alias tango.stdc.stringz.toStringz toStringz;
716 public alias tango.stdc.stringz.toString16z toString16z;
717 public alias tango.stdc.stringz.fromStringz fromStringz;
718 public alias tango.stdc.stringz.fromString16z fromString16z;
719
720 static String toHex(uint value, bool prefix = true, int radix = 8){
721 return tango.text.convert.Integer.toString(
722 value,
723 radix is 10 ? "d" :
724 radix is 8 ? "o" :
725 radix is 16 ? "x" :
726 "d" );
727 }
728
729 class RuntimeException : Exception {
730 this( String e = null){
731 super(e);
732 }
733 this( Exception e ){
734 super(e.toString);
735 next = e;
736 }
737 public Exception getCause() {
738 return next;
739 }
740
741 }
742 class IndexOutOfBoundsException : Exception {
743 this( String e = null){
744 super(e);
745 }
746 }
747
748 class UnsupportedOperationException : RuntimeException {
749 this( String e = null){
750 super(e);
751 }
752 this( Exception e ){
753 super(e.toString);
754 }
755 }
756 class NumberFormatException : IllegalArgumentException {
757 this( String e ){
758 super(e);
759 }
760 this( Exception e ){
761 super(e.toString);
762 }
763 }
764 class NullPointerException : Exception {
765 this( String e = null ){
766 super(e);
767 }
768 this( Exception e ){
769 super(e.toString);
770 }
771 }
772 class IllegalStateException : Exception {
773 this( String e = null ){
774 super(e);
775 }
776 this( Exception e ){
777 super(e.toString);
778 }
779 }
780 class InterruptedException : Exception {
781 this( String e = null ){
782 super(e);
783 }
784 this( Exception e ){
785 super(e.toString);
786 }
787 }
788 class InvocationTargetException : Exception {
789 Exception cause;
790 this( Exception e = null, String msg = null ){
791 super(msg);
792 cause = e;
793 }
794
795 alias getCause getTargetException;
796 Exception getCause(){
797 return cause;
798 }
799 }
800 class MissingResourceException : Exception {
801 String classname;
802 String key;
803 this( String msg, String classname, String key ){
804 super(msg);
805 this.classname = classname;
806 this.key = key;
807 }
808 }
809 class ParseException : Exception {
810 this( String e = null ){
811 super(e);
812 }
813 }
814
815 interface Cloneable{
816 }
817
818 interface Comparable {
819 int compareTo(Object o);
820 }
821 interface Comparator {
822 int compare(Object o1, Object o2);
823 }
824 interface EventListener{
825 }
826
827 class EventObject {
828 protected Object source;
829
830 public this(Object source) {
831 if (source is null)
832 throw new IllegalArgumentException( "null arg" );
833 this.source = source;
834 }
835
836 public Object getSource() {
837 return source;
838 }
839
840 public override String toString() {
841 return this.classinfo.name ~ "[source=" ~ source.toString() ~ "]";
842 }
843 }
844
845 private struct GCStats {
846 size_t poolsize; // total size of pool
847 size_t usedsize; // bytes allocated
848 size_t freeblocks; // number of blocks marked FREE
849 size_t freelistsize; // total of memory on free lists
850 size_t pageblocks; // number of blocks marked PAGE
851 }
852 private extern(C) GCStats gc_stats();
853
854 size_t RuntimeTotalMemory(){
855 GCStats s = gc_stats();
856 return s.poolsize;
857 }
858
859 String ExceptionGetLocalizedMessage( Exception e ){
860 return e.msg;
861 }
862
863 void ExceptionPrintStackTrace( Exception e ){
864 ExceptionPrintStackTrace( e, Stderr );
865 }
866 void ExceptionPrintStackTrace( Exception e, Print!(char) print ){
867 Exception exception = e;
868 while( exception !is null ){
869 print.formatln( "Exception in {}({}): {}", exception.file, exception.line, exception.msg );
870 if( exception.info !is null ){
871 foreach( msg; exception.info ){
872 print.formatln( "trc {}", msg );
873 }
874 }
875 exception = exception.next;
876 }
877 }
878
879 interface Reader{
880 }
881 interface Writer{
882 }
883
884
885 class Collator : Comparator {
886 public static Collator getInstance(){
887 implMissing( __FILE__, __LINE__ );
888 return null;
889 }
890 private this(){
891 }
892 int compare(Object o1, Object o2){
893 implMissing( __FILE__, __LINE__ );
894 return 0;
895 }
896 }
897
898 template arraycast(T) {
899 T[] arraycast(U) (U[] u) {
900 static if (
901 (is (T == interface ) && is (U == interface )) ||
902 (is (T == class ) && is (U == class ))) {
903 return(cast(T[])u);
904 }
905 else {
906 int l = u.length;
907 T[] res;
908 res.length = l;
909 for (int i = 0; i < l; i++) {
910 res[i] = cast(T)u[i];
911 }
912 return(res);
913 }
914 }
915 }
916
917 String stringcast( Object o ){
918 if( auto str = cast(ArrayWrapperString) o ){
919 return str.array;
920 }
921 return null;
922 }
923 String[] stringcast( Object[] objs ){
924 String[] res = new String[](objs.length);
925 foreach( idx, obj; objs ){
926 res[idx] = stringcast(obj);
927 }
928 return res;
929 }
930 ArrayWrapperString stringcast( String str ){
931 return new ArrayWrapperString( str );
932 }
933 ArrayWrapperString[] stringcast( String[] strs ){
934 ArrayWrapperString[] res = new ArrayWrapperString[ strs.length ];
935 foreach( idx, str; strs ){
936 res[idx] = stringcast(str);
937 }
938 return res;
939 }
940
941 String[] stringArrayFromObject( Object obj ){
942 if( auto wrapper = cast(ArrayWrapperString2)obj ){
943 return wrapper.array;
944 }
945 if( auto wrapper = cast(ArrayWrapperObject)obj ){
946 String[] res = new String[ wrapper.array.length ];
947 foreach( idx, o; wrapper.array ){
948 if( auto swrapper = cast(ArrayWrapperString) o ){
949 res[idx] = swrapper.array;
950 }
951 }
952 return res;
953 }
954 assert( obj is null ); // if not null, it was the wrong type
955 return null;
956 }
957
958 T[] arrayFromObject(T)( Object obj ){
959 if( auto wrapper = cast(ArrayWrapperObject)obj ){
960 T[] res = new T[ wrapper.array.length ];
961 foreach( idx, o; wrapper.array ){
962 res[idx] = cast(T)o;
963 }
964 return res;
965 }
966 assert( obj is null ); // if not null, it was the wrong type
967 return null;
968 }
969
970
971 bool ArrayEquals(T)( T[] a, T[] b ){
972 if( a.length !is b.length ){
973 return false;
974 }
975 for( int i = 0; i < a.length; i++ ){
976 static if( is( T==class) || is(T==interface)){
977 if( a[i] !is null && b[i] !is null ){
978 if( a[i] != b[i] ){
979 return false;
980 }
981 }
982 else if( a[i] is null && b[i] is null ){
983 }
984 else{
985 return false;
986 }
987 }
988 else{
989 if( a[i] != b[i] ){
990 return false;
991 }
992 }
993 }
994 return true;
995 }
996
997 int SeqIndexOf(T)( tango.util.collection.model.Seq.Seq!(T) s, T src ){
998 int idx;
999 foreach( e; s ){
1000 if( e == src ){
1001 return idx;
1002 }
1003 idx++;
1004 }
1005 return -1;
1006 }
1007 int arrayIndexOf(T)( T[] arr, T v ){
1008 int res = -1;
1009 int idx = 0;
1010 foreach( p; arr ){
1011 if( p == v){
1012 res = idx;
1013 break;
1014 }
1015 idx++;
1016 }
1017 return res;
1018 }
1019
1020 int seqIndexOf( tango.util.collection.model.Seq.Seq!(Object) seq, Object v ){
1021 int res = -1;
1022 int idx = 0;
1023 foreach( p; seq ){
1024 if( p == v){
1025 res = idx;
1026 break;
1027 }
1028 idx++;
1029 }
1030 return res;
1031 }
1032
1033 void PrintStackTrace( int deepth = 100, String prefix = "trc" ){
1034 auto e = new Exception( null );
1035 int idx = 0;
1036 const start = 3;
1037 foreach( msg; e.info ){
1038 if( idx >= start && idx < start+deepth ) {
1039 Trace.formatln( "{}: {}", prefix, msg );
1040 }
1041 idx++;
1042 }
1043 }
1044
1045 struct ImportData{
1046 void[] data;
1047 String name;
1048
1049 public static ImportData opCall( void[] data, String name ){
1050 ImportData res;
1051 res.data = data;
1052 res.name = name;
1053 return res;
1054 }
1055 }
1056
1057 template getImportData(String name ){
1058 const ImportData getImportData = ImportData( import(name), name );
1059 }
1060