mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-25 09:03:14 +01:00
[svn r230] Added vararg3 sample tangotest.
This commit is contained in:
219
tangotests/vararg3.d
Normal file
219
tangotests/vararg3.d
Normal file
@@ -0,0 +1,219 @@
|
||||
// tries to implement a fairly complete variadic print function
|
||||
module tangotests.vararg3;
|
||||
|
||||
extern(C) int printf(char*, ...);
|
||||
|
||||
struct User
|
||||
{
|
||||
char[] name;
|
||||
char[] nick;
|
||||
uint age;
|
||||
|
||||
char[] toString()
|
||||
{
|
||||
return nick ~ "(" ~ name ~ ")";
|
||||
}
|
||||
}
|
||||
|
||||
struct Infidel
|
||||
{
|
||||
char[] whocares;
|
||||
}
|
||||
|
||||
class Obj
|
||||
{
|
||||
private char[] ty;
|
||||
|
||||
this(char[] t)
|
||||
{
|
||||
ty = t;
|
||||
}
|
||||
|
||||
char[] toString()
|
||||
{
|
||||
return "Obj(" ~ ty ~ ")";
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
User user = User("Bob Doe", "bd", 47);
|
||||
char[] str = user.toString();
|
||||
printf("Direct call:\n%.*s\nBy typeinfo:\n", str.length, str.ptr);
|
||||
print(user, '\n');
|
||||
|
||||
print("Without toString:\n");
|
||||
Infidel inf = Infidel("not me");
|
||||
print(inf, '\n');
|
||||
|
||||
print("Character arrays:\n");
|
||||
print("hello world\n");
|
||||
|
||||
print("Signed integers:\n");
|
||||
print(cast(byte)byte.max,' ',cast(short)short.max,' ',cast(int)int.max,' ',cast(long)long.max,'\n');
|
||||
|
||||
print("Unsigned integers:\n");
|
||||
print(cast(ubyte)ubyte.max,' ',cast(ushort)ushort.max,' ',cast(uint)uint.max,' ',cast(ulong)ulong.max,'\n');
|
||||
|
||||
print("Floating point:\n");
|
||||
print(cast(float)1.273f, ' ', cast(double)3.412367, ' ', cast(real)142.96731112, '\n');
|
||||
|
||||
print("Arrays:\n");
|
||||
int[] ia1 = [1,2,3,4,5,6,7,8,9];
|
||||
print(ia1, '\n');
|
||||
float[] fa1 = [0.1f, 0.15f, 0.2f, 0.25f, 0.3f];
|
||||
print(fa1, '\n');
|
||||
|
||||
print("Pointers:\n");
|
||||
print(&user,'\n');
|
||||
print(&inf,'\n');
|
||||
print(&ia1,'\n');
|
||||
print(&fa1,'\n');
|
||||
|
||||
print("Static arrays:\n");
|
||||
int[5] isa1 = [1,2,4,8,16];
|
||||
print(isa1,'\n');
|
||||
|
||||
print("Classes:\n");
|
||||
Obj o = new Obj("foo");
|
||||
print(o, '\n');
|
||||
|
||||
print("Mixed:\n");
|
||||
print(123, ' ', 42.536f, " foobar ", ia1, ' ', user, '\n');
|
||||
print(42, ' ', cast(byte)12, ' ', user, ' ', cast(short)1445, " foo\n");
|
||||
}
|
||||
|
||||
private void* get_va_arg(TypeInfo ti, ref void* vp)
|
||||
{
|
||||
auto tisize = ti.tsize;
|
||||
assert(tisize);
|
||||
size_t size = tisize > size_t.sizeof ? size_t.sizeof : tisize;
|
||||
void* vptmp = cast(void*)((cast(size_t)vp + size - 1) & ~(size - 1));
|
||||
vp = vptmp + tisize;
|
||||
return vptmp;
|
||||
}
|
||||
|
||||
void print(TypeInfo ti, void* arg)
|
||||
{
|
||||
if (ti == typeid(byte))
|
||||
printf("%d", *cast(byte*)arg);
|
||||
else if (ti == typeid(short))
|
||||
printf("%d", *cast(short*)arg);
|
||||
else if (ti == typeid(int))
|
||||
printf("%d", *cast(int*)arg);
|
||||
else if (ti == typeid(long))
|
||||
printf("%lld", *cast(long*)arg);
|
||||
|
||||
else if (ti == typeid(ubyte))
|
||||
printf("%u", *cast(ubyte*)arg);
|
||||
else if (ti == typeid(ushort))
|
||||
printf("%u", *cast(ushort*)arg);
|
||||
else if (ti == typeid(uint))
|
||||
printf("%u", *cast(uint*)arg);
|
||||
else if (ti == typeid(ulong))
|
||||
printf("%llu", *cast(ulong*)arg);
|
||||
|
||||
else if (ti == typeid(float))
|
||||
printf("%f", *cast(float*)arg);
|
||||
else if (ti == typeid(double))
|
||||
printf("%f", *cast(double*)arg);
|
||||
else if (ti == typeid(real)) // FIXME: 80bit?
|
||||
printf("%f", *cast(real*)arg);
|
||||
|
||||
else if (ti == typeid(char))
|
||||
printf("%.*s", 1, arg);
|
||||
else if (ti == typeid(wchar))
|
||||
printf("%.*s", 2, arg);
|
||||
else if (ti == typeid(dchar))
|
||||
printf("%.*s", 4, arg);
|
||||
|
||||
else if (ti == typeid(char[]))
|
||||
{
|
||||
char[] str = *cast(char[]*)arg;
|
||||
printf("%.*s", str.length, str.ptr);
|
||||
}
|
||||
else if (ti == typeid(wchar[]))
|
||||
{
|
||||
wchar[] str = *cast(wchar[]*)arg;
|
||||
printf("%.*s", str.length*2, str.ptr);
|
||||
}
|
||||
else if (ti == typeid(dchar[]))
|
||||
{
|
||||
dchar[] str = *cast(dchar[]*)arg;
|
||||
printf("%.*s", str.length*4, str.ptr);
|
||||
}
|
||||
|
||||
else if (auto pti = cast(TypeInfo_Pointer)ti)
|
||||
{
|
||||
printf("%p", *cast(void**)arg);
|
||||
}
|
||||
|
||||
else if (auto sti = cast(TypeInfo_Struct)ti)
|
||||
{
|
||||
if (sti.xtoString !is null)
|
||||
{
|
||||
char[] str = sti.xtoString(arg);
|
||||
printf("%.*s", str.length, str.ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
char[] str = sti.toString();
|
||||
printf("%.*s", str.length, str.ptr);
|
||||
}
|
||||
}
|
||||
|
||||
else if (auto ati = cast(TypeInfo_Array)ti)
|
||||
{
|
||||
auto tnext = ati.next;
|
||||
size_t len = *cast(size_t*)arg;
|
||||
void* ptr = *(cast(void**)arg + 1);
|
||||
printf("[");
|
||||
for(auto i=0; i<len; ++i)
|
||||
{
|
||||
print(tnext, get_va_arg(tnext, ptr));
|
||||
if (i < len-1)
|
||||
printf(",");
|
||||
}
|
||||
printf("]");
|
||||
}
|
||||
|
||||
else if (auto cti = cast(TypeInfo_Class)ti)
|
||||
{
|
||||
auto o = *cast(Object*)arg;
|
||||
char[] str = o.toString();
|
||||
printf("%.*s", str.length, str.ptr);
|
||||
}
|
||||
|
||||
// static arrays are converted to dynamic arrays when passed to variadic functions
|
||||
else if (auto sati = cast(TypeInfo_StaticArray)ti)
|
||||
{
|
||||
assert(0, "static arrays not supported");
|
||||
}
|
||||
|
||||
else if (auto aati = cast(TypeInfo_AssociativeArray)ti)
|
||||
{
|
||||
assert(0, "associative array not supported");
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
char[] str = ti.toString();
|
||||
printf("typeinfo: %.*s\n", str.length, str.ptr);
|
||||
str = ti.classinfo.name;
|
||||
printf("typeinfo.classinfo: %.*s\n", str.length, str.ptr);
|
||||
assert(0, "unsupported type ^");
|
||||
}
|
||||
}
|
||||
|
||||
void print(...)
|
||||
{
|
||||
void* argptr = _argptr;
|
||||
assert(argptr);
|
||||
|
||||
foreach(i,ti; _arguments)
|
||||
{
|
||||
void* arg = get_va_arg(ti, argptr);
|
||||
assert(arg);
|
||||
print(ti, arg);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user