changeset 23:aaa0a4e20edf

Added missing files to repository
author Frank Benoit <benoit@tionex.de>
date Fri, 20 Mar 2009 13:17:52 +0100
parents 4642ab680468
children b7a1d02a0e1f
files java/src/java/lang/String.d java/src/java/lang/interfaces.d java/src/java/lang/wrappers.d
diffstat 3 files changed, 937 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/src/java/lang/String.d	Fri Mar 20 13:17:52 2009 +0100
@@ -0,0 +1,781 @@
+module java.lang.String;
+
+import java.lang.util;
+import java.lang.interfaces;
+import java.lang.exceptions;
+
+version(Tango){
+    static import tango.stdc.stringz;
+    static import tango.text.Util;
+    static import tango.text.Unicode;
+    static import tango.text.convert.Utf;
+} else { // Phobos
+    static import core.exception;
+    static import std.uni;
+    static import std.utf;
+    static import std.string;
+}
+
+version(Tango){
+    alias char[] String;
+    alias char[] CString;
+    alias wchar[] CString16;
+} else { // Phobos
+    alias string String;
+    alias wstring String16;
+    mixin("alias const(char)[] CString;");
+    mixin("alias const(wchar)[] CString16;");
+}
+
+int codepointIndexToIndex( String str, int cpIndex ){
+    int cps = cpIndex;
+    int res = 0;
+    while( cps > 0 ){
+        cps--;
+        if( str[res] < 0x80 ){
+            res+=1;
+        }
+        else if( str[res] < 0xE0 ){
+            res+=2;
+        }
+        else if( str[res] & 0xF0 ){
+            res+=3;
+        }
+        else{
+            res+=4;
+        }
+    }
+    return res;
+}
+
+/++
++
++/
+int indexToCodepointIndex( String str, int index ){
+    if( index < 0 ) return index;
+    int i = 0;
+    int res = 0;
+    while( i < index ){
+        if( i >= str.length ){
+            break;
+        }
+        if( str[i] < 0x80 ){
+            i+=1;
+        }
+        else if( str[i] < 0xE0 ){
+            i+=2;
+        }
+        else if( str[i] & 0xF0 ){
+            i+=3;
+        }
+        else{
+            i+=4;
+        }
+        res++;
+    }
+    return res;
+}
+
+/++
++ Get that String, that contains the next codepoint of a String.
++/
+String firstCodePointStr( String str, out int consumed ){
+    version(Tango){
+        dchar[1] buf;
+        uint ate;
+        dchar[] res = tango.text.convert.Utf.toString32( str, buf, &ate );
+        consumed = ate;
+        return str[ 0 .. ate ];
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+
+/++
++ Get first codepoint of a String. If an offset is needed, simply use a slice:
++ ---
++ dchar res = str[ offset .. $ ].firstCodePoint();
++ ---
++/
+dchar firstCodePoint( String str ){
+    int dummy;
+    return firstCodePoint( str, dummy );
+}
+dchar firstCodePoint( String str, out int consumed ){
+    version(Tango){
+        dchar[1] buf;
+        uint ate;
+        dchar[] res = tango.text.convert.Utf.toString32( str, buf, &ate );
+        consumed = ate;
+        if( ate is 0 || res.length is 0 ){
+            getDwtLogger().trace( __FILE__, __LINE__, "str.length={} str={:X2}", str.length, cast(ubyte[])str );
+        }
+        assert( ate > 0 );
+        assert( res.length is 1 );
+        return res[0];
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return '\0';
+    }
+}
+dchar firstCodePoint( wchar[] str, out int consumed ){
+    version(Tango){
+        dchar[1] buf;
+        uint ate;
+        dchar[] res = tango.text.convert.Utf.toString32( str, buf, &ate );
+        consumed = ate;
+        if( ate is 0 || res.length is 0 ){
+            getDwtLogger().trace( __FILE__, __LINE__, "str.length={} str={:X2}", str.length, cast(ubyte[])str );
+        }
+        assert( ate > 0 );
+        assert( res.length is 1 );
+        return res[0];
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return '\0';
+    }
+}
+
+String dcharToString( dchar key ){
+    version(Tango){
+        dchar[1] buf;
+        buf[0] = key;
+        return tango.text.convert.Utf.toString( buf );
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+
+int codepointCount( String str ){
+    version(Tango){
+        scope dchar[] buf = new dchar[]( str.length );
+        uint ate;
+        dchar[] res = tango.text.convert.Utf.toString32( str, buf, &ate );
+        assert( ate is str.length );
+        return res.length;
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
+}
+
+//alias tango.text.convert.Utf.toString16 toString16;
+//alias tango.text.convert.Utf.toString toString;
+
+int toAbsoluteCodePointStartOffset( String str, int index ){
+    //getDwtLogger().trace( __FILE__, __LINE__, "str={}, str.length={}, index={}", str, str.length, index );
+    //getDwtLogger().trace( __FILE__, __LINE__, Trace.memory( str );
+    if( str.length is index ){
+        return index;
+    }
+    if( ( str[index] & 0x80 ) is 0x00 ) {
+        return index;
+    }
+    else{
+        int steps = 0;
+        while(( str[index] & 0xC0 ) is 0x80 ){
+            index--;
+            steps++;
+            if( steps > 3 || index < 0 ){
+                break;
+            }
+        }
+        if((( str[index] & 0xE0 ) is 0xC0) && ( steps <= 1 )){
+            // ok
+        }
+        else if((( str[index] & 0xF0 ) is 0xE0) && ( steps <= 2 )){
+            // ok
+        }
+        else if((( str[index] & 0xF8 ) is 0xF0) && ( steps <= 3 )){
+            // ok
+        }
+        else{
+            throw new UnicodeException( "invalid utf8 input to toAbsoluteCodePointStartOffset", index );
+        }
+        return index;
+    }
+}
+int getRelativeCodePointOffset( String str, int startIndex, int searchRelCp ){
+    return getAbsoluteCodePointOffset( str, startIndex, searchRelCp ) - startIndex;
+}
+int getAbsoluteCodePointOffset( String str, int startIndex, int searchRelCp ){
+
+    //getDwtLogger().trace( __FILE__, __LINE__, "str={}, str.length={}, startIndex={}, searchRelCp={}", str, str.length, startIndex, searchRelCp );
+    //getDwtLogger().trace( __FILE__, __LINE__, Trace.memory( str );
+
+    int ignore;
+    int i = startIndex;
+    if( searchRelCp > 0 ){
+        while( searchRelCp !is 0 ){
+
+            if( ( i < str.length )
+                    && (( str[i] & 0x80 ) is 0x00 ))
+            {
+                i+=1;
+            }
+            else if( ( i+1 < str.length )
+                    && (( str[i+1] & 0xC0 ) is 0x80 )
+                    && (( str[i  ] & 0xE0 ) is 0xC0 ))
+            {
+                i+=2;
+            }
+            else if( ( i+2 < str.length )
+                    && (( str[i+2] & 0xC0 ) is 0x80 )
+                    && (( str[i+1] & 0xC0 ) is 0x80 )
+                    && (( str[i  ] & 0xF0 ) is 0xE0 ))
+            {
+                i+=3;
+            }
+            else if(( i+3 < str.length )
+                    && (( str[i+3] & 0xC0 ) is 0x80 )
+                    && (( str[i+2] & 0xC0 ) is 0x80 )
+                    && (( str[i+1] & 0xC0 ) is 0x80 )
+                    && (( str[i  ] & 0xF8 ) is 0xF0 ))
+            {
+                i+=4;
+            }
+            else{
+                getDwtLogger().trace( __FILE__, __LINE__, "getAbsoluteCodePointOffset invalid utf8 characters:  {:X2}", cast(ubyte[]) str );
+                throw new UnicodeException( "invalid utf8 input", i );
+            }
+            searchRelCp--;
+        }
+    }
+    else if( searchRelCp < 0 ){
+        while( searchRelCp !is 0 ){
+            do{
+                i--;
+                if( i < 0 ){
+                    return startIndex-1;
+                }
+            } while(( str[i] & 0xC0 ) is 0x80 );
+            searchRelCp++;
+        }
+    }
+    return i;
+}
+int getAbsoluteCodePointOffset( wchar[] str, int startIndex, int searchRelCp ){
+    int ignore;
+    int i = startIndex;
+    if( searchRelCp > 0 ){
+        while( searchRelCp !is 0 ){
+
+            if( ( i < str.length )
+                    && ( str[i] & 0xD800 ) !is 0xD800 )
+            {
+                i+=1;
+            }
+            else if( ( i+1 < str.length )
+                    && (( str[i+1] & 0xDC00 ) is 0xDC00 )
+                    && (( str[i  ] & 0xDC00 ) is 0xD800 ))
+            {
+                i+=2;
+            }
+            else{
+                getDwtLogger().trace( __FILE__, __LINE__, "invalid utf16 characters:  {:X2}", cast(ubyte[]) str );
+                throw new UnicodeException( "invalid utf16 input", i );
+            }
+            searchRelCp--;
+        }
+    }
+    else if( searchRelCp < 0 ){
+        while( searchRelCp !is 0 ){
+            do{
+                i--;
+                if( i < 0 ){
+                    return startIndex-1;
+                    //getDwtLogger().trace( __FILE__, __LINE__, "dwthelper.utils getRelativeCodePointOffset {}: str={}, startIndex={}, searchRelCp={}", __LINE__, str, startIndex, searchRelCp );
+                    //tango.text.convert.Utf.onUnicodeError( "invalid utf16 input", i );
+                }
+            } while(( str[i] & 0xDC00 ) is 0xDC00 );
+            searchRelCp++;
+        }
+    }
+    return i;
+}
+dchar getRelativeCodePoint( String str, int startIndex, int searchRelCp ){
+    int dummy;
+    return getRelativeCodePoint( str, startIndex, dummy );
+}
+dchar getRelativeCodePoint( String str, int startIndex, int searchRelCp, out int relIndex ){
+    relIndex = getRelativeCodePointOffset( str, startIndex, searchRelCp );
+    int ignore;
+    return firstCodePoint( str[ startIndex+relIndex .. $ ], ignore );
+}
+
+int utf8AdjustOffset( String str, int offset ){
+    if( str.length <= offset || offset <= 0 ){
+        return offset;
+    }
+    while(( str[offset] & 0xC0 ) is 0x80 ){
+        offset--;
+    }
+    return offset;
+}
+int utf8OffsetIncr( String str, int offset ){
+    int res = offset +1;
+    if( str.length <= res || res <= 0 ){
+        return res;
+    }
+    int tries = 4;
+    while(( str[res] & 0xC0 ) is 0x80 ){
+        res++;
+        assert( tries-- > 0 );
+    }
+    return res;
+}
+int utf8OffsetDecr( String str, int offset ){
+    int res = offset-1;
+    if( str.length <= res || res <= 0 ){
+        return res;
+    }
+    int tries = 4;
+    while(( str[res] & 0xC0 ) is 0x80 ){
+        res--;
+        assert( tries-- > 0 );
+    }
+    getDwtLogger().trace( __FILE__, __LINE__, "utf8OffsetDecr {}->{}", offset, res );
+    getDwtLogger().trace( __FILE__, __LINE__, "{}", str );
+    return res;
+}
+
+String new_String( String cont, int offset, int len ){
+    version(D_Version2){
+        return cont[ offset .. offset+len ].idup;
+    } else {
+        return cont[ offset .. offset+len ].dup;
+    }
+}
+
+String new_String( String cont ){
+    version(D_Version2){
+        return cont.idup;
+    } else {
+        return cont.dup;
+    }
+}
+
+String String_valueOf( bool v ){
+    return v ? "true" : "false";
+}
+
+String String_valueOf( byte v ){
+    version(Tango){
+        return tango.text.convert.Integer.toString(v);
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+
+String String_valueOf( ubyte v ){
+    version(Tango){
+        return tango.text.convert.Integer.toString(v);
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+
+String String_valueOf( short v ){
+    version(Tango){
+        return tango.text.convert.Integer.toString(v);
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+
+String String_valueOf( int v ){
+    version(Tango){
+        return tango.text.convert.Integer.toString(v);
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+
+String String_valueOf( uint v ){
+    version(Tango){
+        return tango.text.convert.Integer.toString(v);
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+
+String String_valueOf( long v ){
+    version(Tango){
+        return tango.text.convert.Integer.toString(v);
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+
+String String_valueOf( float v ){
+    version(Tango){
+        return tango.text.convert.Float.toString(v);
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+
+String String_valueOf( double v ){
+    version(Tango){
+        return tango.text.convert.Float.toString(v);
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+
+String String_valueOf( dchar v ){
+    return dcharToString(v);
+}
+
+String String_valueOf( char[] v ){
+    version(D_Version2){
+        return v.idup;
+    } else {
+        return v.dup;
+    }
+}
+
+String String_valueOf( char[] v, int offset, int len ){
+    version(D_Version2){
+        return v[ offset .. offset+len ].idup;
+    } else {
+        return v[ offset .. offset+len ].dup;
+    }
+}
+
+String String_valueOf( Object v ){
+    return v is null ? "null" : v.toString();
+}
+
+String String_valueOf( wchar[] wstr ){
+    version(Tango){
+        return tango.text.convert.Utf.toString(wstr);
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+
+int length( String str ){
+    return str.length;
+}
+
+/// Extension to String
+public String toUpperCase( String str ){
+    version(Tango){
+        return tango.text.Unicode.toUpper( str );
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+
+/// Extension to String
+public String replaceFirst( String str, String regex, String replacement ){
+    implMissing(__FILE__,__LINE__);
+    return str;
+}
+
+/// Extension to String
+public int indexOf( String str, char searched ){
+    version(Tango){
+        int res = tango.text.Util.locate( str, searched );
+        if( res is str.length ) res = -1;
+        return res;
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
+}
+
+/// Extension to String
+public int indexOf( String str, char searched, int startpos ){
+    version(Tango){
+        int res = tango.text.Util.locate( str, searched, startpos );
+        if( res is str.length ) res = -1;
+        return res;
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
+}
+
+/// Extension to String
+public int indexOf(String str, String ch){
+    return indexOf( str, ch, 0 );
+}
+
+/// Extension to String
+public int indexOf(String str, String ch, int start){
+    version(Tango){
+        int res = tango.text.Util.locatePattern( str, ch, start );
+        if( res is str.length ) res = -1;
+        return res;
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
+}
+
+/// Extension to String
+public int lastIndexOf(String str, char ch){
+    return lastIndexOf( str, ch, str.length );
+}
+
+/// Extension to String
+public int lastIndexOf(String str, char ch, int formIndex){
+    version(Tango){
+        int res = tango.text.Util.locatePrior( str, ch, formIndex );
+        if( res is str.length ) res = -1;
+        return res;
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
+}
+
+/// Extension to String
+public int lastIndexOf(String str, String ch ){
+    return lastIndexOf( str, ch, str.length );
+}
+
+/// Extension to String
+public int lastIndexOf(String str, String ch, int start ){
+    version(Tango){
+        int res = tango.text.Util.locatePatternPrior( str, ch, start );
+        if( res is str.length ) res = -1;
+        return res;
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
+}
+
+/// Extension to String
+public String replaceAll( String str, String regex, String replacement ){
+    implMissing(__FILE__,__LINE__);
+    return null;
+}
+
+/// Extension to String
+public String replace( String str, char from, char to ){
+    version(Tango){
+        return tango.text.Util.replace( str.dup, from, to );
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+
+/// Extension to String
+public String substring( String str, int start ){
+    return cast(String)str[ start .. $ ].dup;
+}
+
+/// Extension to String
+public String substring( String str, int start, int end ){
+    return cast(String)str[ start .. end ].dup;
+}
+
+/// Extension to String
+public wchar[] substring( wchar[] str, int start ){
+    return cast(wchar[])(str[ start .. $ ].dup);
+}
+
+/// Extension to String
+public wchar[] substring( wchar[] str, int start, int end ){
+    return str[ start .. end ].dup;
+}
+
+/// Extension to String
+public char charAt( String str, int pos ){
+    return str[ pos ];
+}
+
+/// Extension to String
+public dchar dcharAt( String str, int pos ){
+    return str[ pos .. $ ].firstCodePoint();
+}
+
+/// Extension to String
+public void getChars( String src, int srcBegin, int srcEnd, char[] dst, int dstBegin){
+    dst[ dstBegin .. dstBegin + srcEnd - srcBegin ] = src[ srcBegin .. srcEnd ];
+}
+
+/// Extension to String
+public wchar[] toWCharArray( String str ){
+    version(Tango){
+        return tango.text.convert.Utf.toString16(str);
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+
+/// Extension to String
+public char[] toCharArray( String str ){
+    return cast(char[])str;
+}
+
+/// Extension to String
+public bool endsWith( String src, String pattern ){
+    if( src.length < pattern.length ){
+        return false;
+    }
+    return src[ $-pattern.length .. $ ] == pattern;
+}
+
+/// Extension to String
+public bool equals( String src, String other ){
+    return src == other;
+}
+
+/// Extension to String
+public bool equalsIgnoreCase( String src, String other ){
+    version(Tango){
+        return tango.text.Unicode.toFold(src) == tango.text.Unicode.toFold(other);
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return false;
+    }
+}
+
+/// Extension to String
+public int compareToIgnoreCase( String src, String other ){
+    version(Tango){
+        return compareTo( tango.text.Unicode.toFold(src), tango.text.Unicode.toFold(other));
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
+}
+
+/// Extension to String
+public int compareTo( String src, String other ){
+    return typeid(String).compare( cast(void*)&src, cast(void*)&other );
+}
+
+/// Extension to String
+public bool startsWith( String src, String pattern ){
+    if( src.length < pattern.length ){
+        return false;
+    }
+    return src[ 0 .. pattern.length ] == pattern;
+}
+
+/// Extension to String
+public String toLowerCase( String src ){
+    version(Tango){
+        return tango.text.Unicode.toLower( src );
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+
+/// Extension to String
+public hash_t toHash( String src ){
+    return typeid(String).getHash(&src);
+}
+
+/// Extension to String
+public String trim( String str ){
+    version(Tango){
+        return tango.text.Util.trim( str ).dup;
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+
+/// Extension to String
+public String intern( String str ){
+    return str;
+}
+
+/++
++ This is like tango.stdc.stringz.toStringz, but in case of an empty input string,
+    + this function returns a pointer to a null value instead of a null ptr.
+    +/
+    public char* toStringzValidPtr( String src ){
+        if( src ){
+            return src.toStringz();
+        }
+        else{
+            static const char[] nullPtr = "\0";
+            return cast(char*)nullPtr.ptr;
+        }
+    }
+
+version(Tango){
+    public alias tango.stdc.stringz.toStringz toStringz;
+    public alias tango.stdc.stringz.toString16z toString16z;
+    public alias tango.stdc.stringz.fromStringz fromStringz;
+    public alias tango.stdc.stringz.fromString16z fromString16z;
+} else { // Phobos
+    public char* toStringz( String s ){
+        implMissing(__FILE__,__LINE__);
+        return null;
+    }
+    public wchar* toString16z( String16 s ){
+        implMissing(__FILE__,__LINE__);
+        return null;
+    }
+    public char[] fromStringz( String s ){
+        implMissing(__FILE__,__LINE__);
+        return null;
+    }
+    public char[] fromString16z( String16 s ){
+        implMissing(__FILE__,__LINE__);
+        return null;
+    }
+}
+
+static String toHex(uint value, bool prefix = true, int radix = 8){
+    version(Tango){
+        return tango.text.convert.Integer.toString(
+                value,
+                radix is 10 ? "d" :
+                radix is  8 ? "o" :
+                radix is 16 ? "x" :
+                "d" );
+    } else { // Phobos
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+
+/++
++ String in java is implementing the interface CharSequence
++/
+class StringCharSequence : CharSequence {
+    private String str;
+    this( String str ){
+        this.str = str;
+    }
+    char           charAt(int index){
+        return str[index];
+    }
+    int             length(){
+        return str.length;
+    }
+    CharSequence    subSequence(int start, int end){
+        return new StringCharSequence( str[ start .. end ]);
+    }
+    String          toString(){
+        return str;
+    }
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/src/java/lang/interfaces.d	Fri Mar 20 13:17:52 2009 +0100
@@ -0,0 +1,21 @@
+module java.lang.interfaces;
+
+import java.lang.String;
+
+interface Cloneable{
+}
+
+interface Comparable {
+    int compareTo(Object o);
+}
+interface Comparator {
+    int compare(Object o1, Object o2);
+}
+
+interface CharSequence {
+    char         charAt(int index);
+    int          length();
+    CharSequence subSequence(int start, int end);
+    String       toString();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/src/java/lang/wrappers.d	Fri Mar 20 13:17:52 2009 +0100
@@ -0,0 +1,135 @@
+module java.lang.wrappers;
+
+import java.lang.String;
+
+abstract class ArrayWrapper{
+}
+abstract class ValueWrapper{
+}
+
+class ArrayWrapperT(T) : ArrayWrapper {
+    public T[] array;
+    public this( T[] data ){
+        array = data;
+    }
+    public override equals_t opEquals( Object o ){
+        if( auto other = cast(ArrayWrapperT!(T))o){
+            return array == other.array;
+        }
+        return false;
+    }
+    public override hash_t toHash(){
+        return (typeid(T[])).getHash(&array);
+    }
+    static if( is( T == char )){
+        public override String toString(){
+            return cast(String)array;
+        }
+    }
+}
+
+class ValueWrapperT(T) : ValueWrapper {
+    public T value;
+    public this( T data ){
+        value = data;
+    }
+    static if( is(T==class) || is(T==interface)){
+        public equals_t opEquals( Object other ){
+            if( auto o = cast(ValueWrapperT!(T))other ){
+                return value == o.value;
+            }
+            if( auto o = cast(T)other ){
+                if( value is o ){
+                    return true;
+                }
+                if( value is null || o is null ){
+                    return false;
+                }
+                return value == o;
+            }
+            return false;
+        }
+    }
+    else{
+        public equals_t opEquals( Object other ){
+            if( auto o = cast(ValueWrapperT!(T))other ){
+                return value == o.value;
+            }
+            return false;
+        }
+        public equals_t opEquals( T other ){
+            return value == other;
+        }
+    }
+    public override hash_t toHash(){
+        return (typeid(T)).getHash(&value);
+    }
+}
+
+alias ArrayWrapperT!(byte)    ArrayWrapperByte;
+alias ArrayWrapperT!(int)     ArrayWrapperInt;
+alias ArrayWrapperT!(Object)  ArrayWrapperObject;
+alias ArrayWrapperT!(char)    ArrayWrapperString;
+alias ArrayWrapperT!(String)  ArrayWrapperString2;
+
+Object[] StringArrayToObjectArray( String[] strs ){
+    Object[] res = new Object[strs.length];
+    foreach( idx, str; strs ){
+        res[idx] = new ArrayWrapperString(cast(char[])str);
+    }
+    return res;
+}
+
+String stringcast( Object o ){
+    if( auto str = cast(ArrayWrapperString) o ){
+        return cast(String)str.array;
+    }
+    return null;
+}
+String[] stringcast( Object[] objs ){
+    String[] res = new String[](objs.length);
+    foreach( idx, obj; objs ){
+        res[idx] = stringcast(obj);
+    }
+    return res;
+}
+ArrayWrapperString stringcast( String str ){
+    return new ArrayWrapperString( cast(char[])str );
+}
+ArrayWrapperString[] stringcast( String[] strs ){
+    ArrayWrapperString[] res = new ArrayWrapperString[ strs.length ];
+    foreach( idx, str; strs ){
+        res[idx] = stringcast(str);
+    }
+    return res;
+}
+
+String[] stringArrayFromObject( Object obj ){
+    if( auto wrapper = cast(ArrayWrapperString2)obj ){
+        return wrapper.array;
+    }
+    if( auto wrapper = cast(ArrayWrapperObject)obj ){
+        String[] res = new String[ wrapper.array.length ];
+        foreach( idx, o; wrapper.array ){
+            if( auto swrapper = cast(ArrayWrapperString) o ){
+                res[idx] = cast(String)swrapper.array;
+            }
+        }
+        return res;
+    }
+    assert( obj is null ); // if not null, it was the wrong type
+    return null;
+}
+
+T[] arrayFromObject(T)( Object obj ){
+    if( auto wrapper = cast(ArrayWrapperObject)obj ){
+        T[] res = new T[ wrapper.array.length ];
+        foreach( idx, o; wrapper.array ){
+            res[idx] = cast(T)o;
+        }
+        return res;
+    }
+    assert( obj is null ); // if not null, it was the wrong type
+    return null;
+}
+