表紙 編集 短縮
serializer
ubyte[] serialize(T)(in T t)
{
ubyte[] rv;
static if( is(T==struct) ) {{
foreach(x;t.tupleof)
rv~=serialize(x);
}} else
static if( __traits(isIntegral,T) ) {{
rv=(cast(ubyte*)[t].ptr)[0..T.sizeof];
}} else
static if(__traits(isStaticArray,T)) {{
rv=cast(ubyte[])t;
}} else
static if(__traits(isAssociativeArray,T)) {{
rv=serialize(t.length);
foreach( i, v; t) {
rv~= serialize(i);
rv~= serialize(v);
}
}} else
static if(is(T U:U[])) {{
rv=serialize(t.length);
foreach( v; t) {
rv~= serialize(v);
}
}} else {{
assert(0,"unsupported");
}}
return rv;
}
template ReturnType(T)
{
static if(__traits(isStaticArray,T) && is(T U:U[])) {
alias U[] ReturnType;
} else
static if( is(T U:const(U)[]) || is(T U:invariant(U)[]) ) {
alias U[] ReturnType;
} else
static if( is(T U:const U) || is(T U:invariant U) ) {
alias U ReturnType;
} else {
alias T ReturnType;
}
}
ReturnType!(T) deserialize(T)(ubyte[] t)
{
ubyte* ptr = t.ptr;
return _deserialize!(T)(ptr);
}
private ReturnType!(T) _deserialize(T)(ref ubyte* t){
static if(is(T==struct)) {{
ReturnType!(T) rv;
foreach(i,x;rv.tupleof) {
static if(__traits(isStaticArray,typeof(x)))
rv.tupleof[i][]/*x[]=*/=_deserialize!(typeof(x))(t)[];
else
rv.tupleof[i]/*x=*/=_deserialize!(typeof(x))(t);
}
return rv;
}} else
static if(__traits(isIntegral,T)){{
ReturnType!(T) rv=*cast(T*)t;
t+=T.sizeof;
return rv;
}} else
static if(__traits(isStaticArray,T)&&is(T U:U[])){{
ReturnType!(T) rv;
rv=cast(U[])t[0..T.sizeof];
t+=T.sizeof;
return rv;
}} else
static if( __traits(isAssociativeArray,T) && is(T A:U[A],U) ) {{
ReturnType!(T) rv;
int len = _deserialize!(size_t)(t);
foreach( i; 0..len) {
A key= _deserialize!(A)(t);
rv[key]= _deserialize!(U)(t);
}
return rv;
}} else
static if(is(T U:U[])){{
ReturnType!(T) rv;
int len = _deserialize!(size_t)(t);
rv.length= len;
foreach( i; 0..len) {
rv[i]= _deserialize!(U)(t);
}
return rv;
}} else {{
assert(0,"unsupported");
}}
}