blob: 2d0736ded66d8fe24ed343645065320d89c83e4b [file] [log] [blame]
alias TypeTuple(T...) = T;
class A { }
class B : A { }
class C : B { }
/***************************************/
template Foo(int a, int b, int c)
{
const int Foo = 1;
}
template Foo(A...)
{
const int Foo = 2;
}
void test1()
{
int y = Foo!(1,2,3);
assert(y == 1);
y = Foo!(1,2);
assert(y == 2);
y = Foo!(1,2,3,4);
assert(y == 2);
}
/***************************************/
template Foo2(int a, int b, int c)
{
const int Foo2 = 1;
}
template Foo2(int a, int b, int c, A...)
{
const int Foo2 = 2;
}
void test2()
{
int y = Foo2!(1,2,3);
assert(y == 1);
y = Foo2!(1,2,3,4);
assert(y == 2);
}
/***************************************/
void bar3(int x, int y)
{
assert(x == 2);
assert(y == 3);
}
template Foo3(T, A...)
{
int Foo3(T t, A a)
{
assert(A.length == 2);
assert(a.length == 2);
bar3(a);
assert([a] == [2, 3]);
assert([cast(double)a] == [2.0, 3.0]);
assert(a[0] == 2);
assert(a[1] == 3);
assert(a[$ - 2] == 2);
assert(a[$ - 1] == 3);
static if (1 || a[6])
assert(1);
assert([a[]] == [2, 3]);
assert([a[0 .. $]] == [2, 3]);
assert([a[0 .. $ - 1]] == [2]);
return 3;
}
}
void test3()
{
int y = Foo3(1,2,3);
assert(y == 3);
}
/***************************************/
void foo4(A...)()
{
int[] ai;
int[] aa;
aa = null;
foreach (a; A)
{
aa ~= a;
}
assert(aa == [7,4,9]);
aa = null;
foreach (int a; A)
{
aa ~= a;
}
assert(aa == [7,4,9]);
ai = null;
aa = null;
foreach (int i, a; A)
{
ai ~= i;
aa ~= a;
}
assert(ai == [0,1,2]);
assert(aa == [7,4,9]);
ai = null;
aa = null;
foreach_reverse (uint i, a; A)
{
ai ~= i;
aa ~= a;
}
assert(ai == [2,1,0]);
assert(aa == [9,4,7]);
ai = null;
aa = null;
foreach_reverse (i, a; A)
{
ai ~= i;
aa ~= a;
}
assert(ai == [2,1,0]);
assert(aa == [9,4,7]);
ai = null;
aa = null;
foreach (int i, a; A)
{
ai ~= i;
aa ~= a;
if (i == 1)
break;
continue;
}
assert(ai == [0,1]);
assert(aa == [7,4]);
}
void test4()
{
foo4!(7,4,9)();
}
/***************************************/
int a12(TypeTuple!(int, int) t)
{
return t[0] + t[1];
}
int b12(TypeTuple!(TypeTuple!(int), TypeTuple!(int)) t)
{
return t[0] + t[1];
}
int c12(TypeTuple!(TypeTuple!(int), TypeTuple!(TypeTuple!(), int), TypeTuple!()) t)
{
return t[0] + t[1];
}
void test12()
{
assert(a12(1, 2) == 3);
assert(b12(1, 2) == 3);
assert(c12(1, 2) == 3);
}
/***************************************/
int plus13(TypeTuple!(int, long, float)[0 .. 2] t)
{
typeof(t)[0] e;
assert(typeid(typeof(e)) == typeid(int));
typeof(t)[1] f;
assert(typeid(typeof(f)) == typeid(long));
return t[0] + cast(int)t[1];
}
void test13()
{
assert(plus13(5, 6) == 11);
}
/***************************************/
int plus14(TypeTuple!(int, long, float)[0 .. $ - 1] t)
{
typeof(t)[$ - 2] e;
assert(typeid(typeof(e)) == typeid(int));
typeof(t)[1] f;
assert(typeid(typeof(f)) == typeid(long));
return t[0] + cast(int)t[1];
}
void test14()
{
assert(plus14(5, 6) == 11);
}
/***************************************/
void returnAndArgs(T, U...) (T delegate(U) dg)
{
static if (U.length == 0)
assert(dg() == 0);
else static if (U.length == 1)
assert(dg(false) == 1);
else
assert(dg(false, 63L) == 2);
}
void test24()
{
returnAndArgs(delegate int(){ return 0; });
returnAndArgs(delegate int(bool b){ return 1; });
returnAndArgs(delegate int(bool b, long c){ return 2; });
}
/***************************************/
void test28()
{
alias TypeTuple!(int, long, double) TL;
foreach (int i, T; TL)
{
switch (i)
{
case 0: assert(is(T == int)); break;
case 1: assert(is(T == long)); break;
case 2: assert(is(T == double)); break;
default:assert(0);
}
}
}
/***************************************/
template g32(alias B)
{
int g32 = 2;
}
int f32(A...)(A a)
{
return g32!(a);
}
void test32()
{
assert(f32(4) == 2);
}
/***************************************/
struct S34
{
int x;
long y;
double z;
}
void foo34(int x, long y, double z)
{
assert(x == 3);
assert(y == 8);
assert(z == 6.8);
}
void test34()
{
S34 s;
s.x = 3;
s.y = 8;
s.z = 6.8;
foo34(s.tupleof);
}
/***************************************/
alias TypeTuple!(int, long, double) TL35;
struct S35
{
TL35 tl;
}
void foo35(int x, long y, double z)
{
assert(x == 3);
assert(y == 8);
assert(z == 6.8);
}
void test35()
{
S35 s;
s.tl[0] = 3;
s.tl[1] = 8;
s.tl[2] = 6.8;
foo35(s.tupleof);
foo35(s.tl);
}
/***************************************/
alias TypeTuple!(int, long, double) TL36;
class C36
{
TL36 tl;
}
void foo36(int x, long y, double z)
{
assert(x == 3);
assert(y == 8);
assert(z == 6.8);
}
void test36()
{
C36 s = new C36;
s.tl[0] = 3;
s.tl[1] = 8;
s.tl[2] = 6.8;
foo36(s.tupleof);
foo36(s.tl);
}
/***************************************/
alias TypeTuple!(int, long, double) TL37;
class C37
{
TL37 tl;
}
void foo37(int x, long y, double z)
{
assert(x == 3);
assert(y == 8);
assert(z == 6.8);
}
void test37()
{
C37 s = new C37;
s.tl[0] = 3;
s.tl[1] = 8;
s.tl[2] = 6.8;
foo37(s.tupleof);
TL37 x;
assert(x[0] == 0);
x[0] = 3;
assert(x[0] == 3);
assert(x[1] == 0);
x[1] = 8;
x[2] = 6.8;
foo37(x);
}
/***************************************/
interface I38A { }
interface I38B { }
alias TypeTuple!(I38A, I38B) IL38;
class C38 : IL38
{
}
void test38()
{
auto c = new C38;
}
/***************************************/
void test39()
{
static const string a = "\x01";
static const char b = a[0];
static const string c = "test";
static assert(c[a[0]] == 'e');
alias TypeTuple!(ulong,uint,ushort,ubyte) tuple;
static assert(is(tuple[1] == uint));
static assert(is(tuple[a[0]] == uint));
}
/***************************************/
struct Foo45
{
static TypeTuple!(int) selements1;
TypeTuple!(int) elements1;
static TypeTuple!() selements0;
TypeTuple!() elements0;
}
void test45()
{
Foo45 foo;
static assert(Foo45.selements1.length == 1);
static assert(Foo45.elements1.length == 1);
static assert(Foo45.selements0.length == 0);
static assert(Foo45.elements0.length == 0);
static assert(foo.selements1.length == 1);
static assert(foo.elements1.length == 1);
static assert(foo.selements0.length == 0);
static assert(foo.elements0.length == 0);
}
/***************************************/
template Tuple46(E ...) { alias E Tuple46; }
alias Tuple46!(float, float, 3) TP46;
alias TP46[1..$] TQ46;
void test46()
{
TQ46[0] f = TQ46[1];
assert(is(typeof(f) == float));
assert(f == 3);
}
/***************************************/
template Foo47(T, Args...)
{
void bar(Args args, T t)
{
}
}
void test47()
{
alias Foo47!(int) aFoo;
}
/***************************************/
template Tuple48(E...)
{
alias E Tuple48;
}
void VarArg48(T...)(T args)
{
}
void test48()
{
VarArg48( );
VarArg48( Tuple48!(1,2,3) );
VarArg48( Tuple48!() );
}
/***************************************/
alias TypeTuple!(int, long) TX49;
void foo49(TX49 t)
{
TX49 s;
s = t;
assert(s[0] == 1);
assert(s[1] == 2);
}
void test49()
{
foo49(1, 2);
}
/***************************************/
void foo51(U...)(int t, U u)
{
assert(t == 1);
assert(u[0] == 2);
assert(u[1] == 3);
}
void bar51(U...)(U u, int t)
{
assert(u[0] == 1);
assert(u[1] == 2);
assert(t == 3);
}
void abc51(U...)(int s, U u, int t)
{
assert(s == 1);
assert(u[0] == 2);
assert(u[1] == 3);
assert(t == 4);
}
void test51()
{
foo51(1, 2, 3);
bar51(1, 2, 3);
bar51!(int, int)(1, 2, 3);
abc51(1,2,3,4);
}
/***************************************/
string to55(U, V)(V s) { return "he"; }
private S wyda(S, T...)(T args)
{
S result;
foreach (i, arg; args)
{
result ~= to55!(S)(args[i]);
}
return result;
}
string giba(U...)(U args)
{
return wyda!(string, U)(args);
}
void test55()
{
assert(giba(42, ' ', 1.5, ": xyz") == "hehehehe");
}
/***************************************/
private template implicitlyConverts(U, V)
{
enum bool implicitlyConverts = V.sizeof >= U.sizeof
&& is(typeof({U s; V t = s;}()));
}
T to56(T, S)(S s)
if (!implicitlyConverts!(S, T) /*&& isSomeString!(T)
&& isSomeString!(S)*/)
{
return T.init;
}
void test56()
{
auto x = to56!(int)("4");
assert(x == 0);
assert(!implicitlyConverts!(const(char)[], string));
assert(implicitlyConverts!(string, const(char)[]));
}
/***************************************/
struct A57(B...) {}
void test57()
{
alias A57!(int, float) X;
static if (!is(X Y == A57!(Z), Z...))
{
static assert(false);
}
}
/***************************************/
struct A58(B...) {}
void test58()
{
alias A58!(int, float) X;
static if (!is(X Y == A58!(Z), Z...))
{
static assert(false);
}
}
/***************************************/
struct Tuple59(T...)
{
T field;
}
template reduce(fun...)
{
alias Reduce!(fun).reduce reduce;
}
template Reduce(fun...)
{
Tuple59!(double, double)
reduce(Range)(Range r)
{
typeof(Tuple59!(double,double).field)[0] y;
typeof(typeof(return).field)[0] x;
Tuple59!(double, double) s;
return s;
}
}
void test59()
{
double[] a = [ 3.0, 4, 7, 11, 3, 2, 5 ];
static double sum(double a, double b) {return a + b;}
auto r = reduce!((a, b) { return a + b; },
(a, b) { return a + b; })(a);
}
/***************************************/
template tuple60(T...)
{
alias T tuple60;
}
template Foo60(S : void delegate(tuple60!(int))) {}
template Foo60(S : void delegate(tuple60!(int, int))) {}
alias Foo60!(void delegate(int)) Bar60;
void test60()
{
}
/***************************************/
template TypeTuple61(TList...){
alias TList TypeTuple61;
}
template List61(lst...) { alias lst list; }
alias TypeTuple61!(List61!(void)) A61;
alias TypeTuple61!(A61[0].list) B61;
void test61()
{
}
/***************************************/
template Tuple63(T...){
alias T Tuple63;
}
// https://issues.dlang.org/show_bug.cgi?id=3336
static assert(!is(int[ Tuple63!(int, int) ]));
void test63()
{
}
/***************************************/
template Tuple1411(T ...) { alias T Tuple1411; }
void test1411()
{
int delegate(ref Tuple1411!(int, char[], real)) dg; // (*)
int f(ref int a, ref char[] b, ref real c) { return 77; }
dg = &f;
}
/***************************************/
// https://issues.dlang.org/show_bug.cgi?id=4444
void test4444()
{
alias TypeTuple!(1) index;
auto arr = new int[4];
auto x = arr[index]; // error
}
/***************************************/
// https://issues.dlang.org/show_bug.cgi?id=13864
struct Tuple13864(T...)
{
T expand;
alias expand this;
}
auto tuple13864(T...)(T args)
{
return Tuple13864!T(args);
}
void test13864()
{
int[] x = [2,3,4];
auto y = x[tuple13864(0).expand];
assert(y == 2);
}
/***************************************/
// https://issues.dlang.org/show_bug.cgi?id=4884
struct A4884(T...)
{
void foo(T) {}
void bar(bool, T) {}
}
void test4884()
{
auto a1 = A4884!(int)();
auto a2 = A4884!(int, long)();
}
/***************************************/
// https://issues.dlang.org/show_bug.cgi?id=4920
struct Test4920(parameters_...)
{
alias parameters_ parameters;
}
void test4920()
{
Test4920!(10, 20, 30) test;
static assert(typeof(test).parameters[1] == 20); // okay
static assert( test .parameters[1] == 20); // (7)
}
/***************************************/
// https://issues.dlang.org/show_bug.cgi?id=4940
template Tuple4940(T...)
{
alias T Tuple4940;
}
struct S4940
{
Tuple4940!(int, int) x;
this(int) { }
}
void test4940()
{
auto w = S4940(0).x;
}
//----
struct S4940add
{
string s;
long x;
}
ref S4940add get4940add(return ref S4940add s){ return s; }
void test4940add()
{
S4940add s;
get4940add(s).tupleof[1] = 20;
assert(s.x == 20);
}
/***************************************/
// https://issues.dlang.org/show_bug.cgi?id=6530
struct S6530
{
int a, b, c;
}
struct HasPostblit6530
{
this(this) {} // Bug goes away without this.
}
auto toRandomAccessTuple6530(T...)(T input, HasPostblit6530 hasPostblit)
{
return S6530(1, 2, 3);
}
void doStuff6530(T...)(T args)
{
HasPostblit6530 hasPostblit;
// Bug goes away without the .tupleof.
auto foo = toRandomAccessTuple6530(args, hasPostblit).tupleof;
}
void test6530()
{
doStuff6530(1, 2, 3);
}
/***************************************/
import core.stdc.stdarg;
extern(C)
void func9495(int a, string format, ...)
{
va_list ap;
va_start(ap, format);
auto a1 = va_arg!int(ap);
auto a2 = va_arg!int(ap);
auto a3 = va_arg!int(ap);
assert(a1 == 0x11111111);
assert(a2 == 0x22222222);
assert(a3 == 0x33333333);
va_end(ap);
}
void test9495()
{
func9495(0, "", 0x11111111, 0x22222222, 0x33333333);
}
/***************************************/
void copya(int a, string format, ...)
{
va_list ap;
va_start(ap, format);
va_list ap2;
va_copy(ap2, ap);
auto a1 = va_arg!int(ap);
auto a2 = va_arg!int(ap);
auto a3 = va_arg!int(ap);
assert(a1 == 0x11111111);
assert(a2 == 0x22222222);
assert(a3 == 0x33333333);
auto b1 = va_arg!int(ap2);
auto b2 = va_arg!int(ap2);
auto b3 = va_arg!int(ap2);
assert(b1 == 0x11111111);
assert(b2 == 0x22222222);
assert(b3 == 0x33333333);
va_end(ap);
va_end(ap2);
}
void testCopy()
{
copya(0, "", 0x11111111, 0x22222222, 0x33333333);
}
/***************************************/
// https://issues.dlang.org/show_bug.cgi?id=6700
template bug6700(TList ...) {
const int bug6700 = 2;
}
TypeTuple!(int, long) TT6700;
static assert(bug6700!( (TT6700[1..$]) )==2);
/***************************************/
// https://issues.dlang.org/show_bug.cgi?id=6966
template X6966(T...)
{
alias const(T[0]) X6966;
}
static assert(is(X6966!(int) == const(int)));
static assert(is(X6966!(int, 0) == const(int)));
/***************************************/
// https://issues.dlang.org/show_bug.cgi?id=7233
struct Foo7233 { int x, y; }
Foo7233[] front7233(Foo7233[][] a)
{
return a[0];
}
class Bar7233 { int x, y; }
Bar7233[] front7233(Bar7233[][] a)
{
return a[0];
}
void test7233()
{
Foo7233[][] b1 = [[Foo7233()]];
auto xy1 = b1.front7233[0].tupleof;
Bar7233[][] b2 = [[new Bar7233()]];
auto xy2 = b2.front7233[0].tupleof;
}
/***************************************/
// https://issues.dlang.org/show_bug.cgi?id=7263
template TypeTuple7263(T...){ alias T TypeTuple7263; }
struct tuple7263
{
TypeTuple7263!(int, int) field;
alias field this;
}
auto front7263(T)(ref T arr){ return arr[0]; }
void test7263()
{
auto bars = [tuple7263(0, 0), tuple7263(1, 1)];
auto spam1 = bars.front7263[1];
auto spam2 = bars.front7263[1..2];
}
/***************************************/
// https://issues.dlang.org/show_bug.cgi?id=8244
TypeTuple!(int,int)[] x8244;
static assert(is(typeof(x8244) == TypeTuple!(int, int)));
/***************************************/
// https://issues.dlang.org/show_bug.cgi?id=9017
template X9017(Args...)
{
static if(__traits(compiles, { enum e = Args; }))
enum e = Args;
}
alias X9017!0 x9017;
static assert(x9017.e[0] == 0);
void test9017()
{
enum tup1 = TypeTuple!(11, 22);
enum tup2 = TypeTuple!("one", "two");
static assert(tup1 == TypeTuple!(11, 22));
static assert(tup2 == TypeTuple!("one", "two"));
static assert(tup1[0] == 11 && tup1[1] == 22);
static assert(tup2[0] == "one" && tup2[1] == "two");
shared const tup3 = TypeTuple!(10, 3.14);
immutable tup4 = TypeTuple!("a", [1,2]);
static assert(is(typeof(tup3[0]) == shared const int));
static assert(is(typeof(tup3[1]) == shared const double));
static assert(is(typeof(tup4[0]) == immutable string));
static assert(is(typeof(tup4[1]) == immutable int[]));
}
/***************************************/
// https://issues.dlang.org/show_bug.cgi?id=10279
void foo10279(int[][] strs...) @trusted { }
void bar10279() @safe { foo10279(); }
/***************************************/
// https://issues.dlang.org/show_bug.cgi?id=13508
struct S13508
{
this(T)(T[] t...) {}
}
template make13508(T)
{
T make13508(Args...)(Args args)
{
return T(args);
}
}
void test13508() @safe @nogc
{
S13508 s = make13508!S13508(5);
}
/***************************************/
// https://issues.dlang.org/show_bug.cgi?id=14395
int v2u14395(uint[1] ar...)
{
return ar[0];
}
void print14395(int size = v2u14395(7))
{
assert(size == 7);
}
void test14395()
{
print14395();
}
/***************************************/
// https://issues.dlang.org/show_bug.cgi?id=10414
void foo10414(void delegate()[] ...) { }
void bar10414() { }
void test10414()
{
foo10414
(
{ bar10414(); },
{ bar10414(); },
);
}
/***************************************/
import core.stdc.stdarg;
struct S14179
{
const(char)* filename;
uint linnum;
uint charnum;
}
extern(C++) const(char)* func14179(S14179 x, const(char)* string, ...)
{
return string;
}
void test14179()
{
const(char)* s = "hello";
assert(func14179(S14179(), s) == s);
}
/***************************************/
// https://issues.dlang.org/show_bug.cgi?id=10722
struct S10722
{
int x;
}
template GetSomething10722(S...)
{
alias GetSomething = int;
}
void test10722()
{
alias X10722 = GetSomething10722!(S10722.tupleof[0]);
}
/***************************************/
void testx15417(ulong c1, ...)
{
check(c1, _argptr, _arguments);
}
class C15417
{
private void method ()
{
void test1 (ulong c1, ...)
{
check(c1, _argptr, _arguments);
}
void test2 (ulong c1, ...)
{
va_list ap;
va_start(ap, c1);
check(c1, ap, _arguments);
}
testx15417(4242UL, char.init);
test1(4242UL, char.init);
test2(4242UL, char.init);
}
}
void check (ulong c1, va_list arglist, TypeInfo[] ti)
{
assert(ti.length == 1);
assert(ti[0].toString() == "char");
assert(char.init == va_arg!(char)(arglist));
}
void test15417()
{
auto c = new C15417;
c.method;
}
/***************************************/
int main()
{
test1();
test2();
test3();
test4();
test12();
test13();
test14();
test24();
test28();
test32();
test34();
test35();
test36();
test37();
test38();
test39();
test45();
test46();
test47();
test48();
test49();
test51();
test55();
test56();
test57();
test58();
test59();
test60();
test61();
test63();
test1411();
test4444();
test13864();
test4884();
test4920();
test4940();
test4940add();
test6530();
test7233();
test7263();
test9017();
test14395();
test10414();
test9495();
testCopy();
test14179();
test15417();
return 0;
}