tango.text.convert.Layout convert floating point types with gdc uses just some fixed sizes.
I needed to output muarray that are structs of size 32, so I rewrote that part of the code in a more flexible way, and added a couple of tests more.
By the way does is the statement
static if (is(typeof(args.ptr)))
arglist[i] = args.ptr;
else ....
correct ? is args.ptr automatically updated without any action, without calling va_arg does the compiler do so much magic and keep arg in foreach synchronized with args???
(that branch is not executed on my architecture).
anyway here is my patch
Fawzi
===================================================================
--- Layout.d (revision 3426)
+++ Layout.d (working copy)
@@ -57,7 +57,50 @@
equivalents of each argument.
*******************************************************************************/
+version(GNU) {
+/+
+ + Template to get arbitrary structures out of va_arg
+ + assumes that all argument of the same size are treated in the same way
+ +/
+private const int maxStore=64;
+private struct StoreEl{byte[maxStore] st;};
+private void *dyn_get_argT(int s1,int s2)(in TypeInfo ti,inout va_list argptr,out StoreEl el){
+ const int m = (s1+s2)/2;
+ static if (s1 < s2){
+ if (ti.tsize > m) {
+ return dyn_get_argT!(m+1,s2)(ti,argptr,el);
+ } else {
+ return dyn_get_argT!(s1,m)(ti,argptr,el);
+ }
+ }
+ else{
+ if (ti.tsize == m)
+ {
+ struct ms{byte[m] mse;};
+ ms *st=cast(ms*)⪙
+ *st=va_arg!(ms)(argptr);
+ return cast(void *)st;
+ } else {
+ throw new Exception("hit max size of dyn_va_argT");
+ // if you hit this then either increase the getSizes s2 limit or
+ // hope that the follwing hack works
+ //
+ // assumes a stack based storage, and that the pointer to it
+ // can be retrived via cast...
+ void *v=cast(void*)argptr;
+ void **vv=cast(void**)&argptr;
+ *vv=v+ti.tsize;
+ return v;
+ }
+ }
+}
+private void *dyn_get_arg(in TypeInfo ti,inout va_list argptr,out StoreEl el){
+ return dyn_get_argT!(1,maxStore)(ti,argptr,el);
+}
+
+}
+
class Layout(T)
{
public alias convert opCall;
@@ -184,15 +227,11 @@
version (GNU)
{
Arg[64] arglist = void;
- int[64] intargs = void;
- byte[64] byteargs = void;
- long[64] longargs = void;
- short[64] shortargs = void;
- void[][64] voidargs = void;
real[64] realargs = void;
float[64] floatargs = void;
double[64] doubleargs = void;
-
+ StoreEl[64] bigargs = void;
+
foreach (i, arg; arguments)
{
static if (is(typeof(args.ptr)))
@@ -228,31 +267,8 @@
}
if (! converted)
{
- switch (arg.tsize)
- {
- case 1:
- byteargs[i] = va_arg!(byte)(args);
- arglist[i] = &byteargs[i];
- break;
- case 2:
- shortargs[i] = va_arg!(short)(args);
- arglist[i] = &shortargs[i];
- break;
- case 4:
- intargs[i] = va_arg!(int)(args);
- arglist[i] = &intargs[i];
- break;
- case 8:
- longargs[i] = va_arg!(long)(args);
- arglist[i] = &longargs[i];
- break;
- case 16:
- voidargs[i] = va_arg!(void[])(args);
- arglist[i] = &voidargs[i];
- break;
- default:
- assert (false, "Unknown size: " ~ Integer.toString (arg.tsize));
- }
+ dyn_get_arg(arg,args,bigargs[i]);
+ arglist[i] = & bigargs[i];
}
}
}
@@ -814,6 +830,8 @@
assert( Formatter( "d{{{0}d", "<string>" ) == "d{<string>d");
assert( Formatter( "d{0}}d", "<string>" ) == "d<string>}d");
+ assert( Formatter( "{} {} {} {0:x}",1.3f,cast(bool)1,1.4,cast(bool)1, 0xafe0000 ) == "1.30 true 1.40 true afe0000" );
+ assert( Formatter( "{} {} {} {0:x}",0.0f,cast(bool)1,0.0,cast(bool)1, 0xafe0000 ) == "0.00 true 0.00 true afe0000" );
assert( Formatter( "{0:x}", 0xafe0000 ) == "afe0000" );
// todo: is it correct to print 7 instead of 6 chars???
assert( Formatter( "{0:x7}", 0xafe0000 ) == "afe0000" );
@@ -886,6 +904,8 @@
f[ 1.0 ] = "one".dup;
f[ 3.14 ] = "PI".dup;
assert( Formatter( "{}", f ) == "{ 1.00=>one, 3.14=>PI }" );
+
+
}
}