/* TEST_OUTPUT: --- This actually gets evaluated! () (bool) (bool, short) (bool, short, int) Alias Test instantiated Alias Test instantiated --- */ import core.stdc.stdio; /*********************************************************/ template Foo(T) { static if ( is(T : int) ) alias T t1; static if (T.sizeof == 4) alias T t2; static if ( is(T AB : int) ) alias AB t3; static if ( is(T* V : V*) ) alias V t4; static if ( is(T W) ) alias W t5; else alias char t5; static if ( is(T* X : X*) ) { } } void test1() { Foo!(int).t1 x1; assert(typeid(typeof(x1)) == typeid(int)); Foo!(int).t2 x2; assert(typeid(typeof(x2)) == typeid(int)); Foo!(int).t3 x3; assert(typeid(typeof(x3)) == typeid(int)); Foo!(int).t4 x4; assert(typeid(typeof(x4)) == typeid(int)); Foo!(int).t5 x5; assert(typeid(typeof(x5)) == typeid(int)); Foo!(int).X x6; assert(typeid(typeof(x6)) == typeid(int)); } /*********************************************************/ void test2() { alias int T; static if ( is(T : int) ) alias T t1; static if (T.sizeof == 4) alias T t2; static if ( is(T U : int) ) alias U t3; static if ( is(T* V : V*) ) alias V t4; static if ( is(T W) ) alias W t5; else alias char t5; static if ( is(T* X : X*) ) { } t1 x1; assert(typeid(typeof(x1)) == typeid(int)); t2 x2; assert(typeid(typeof(x2)) == typeid(int)); t3 x3; assert(typeid(typeof(x3)) == typeid(int)); t4 x4; assert(typeid(typeof(x4)) == typeid(int)); t5 x5; assert(typeid(typeof(x5)) == typeid(int)); X x6; assert(typeid(typeof(x6)) == typeid(int)); } /*********************************************************/ void test3() { static if ( is(short : int) ) { printf("1\n"); } else assert(0); static if ( is(short == int) ) assert(0); static if ( is(int == int) ) { printf("3\n"); } else assert(0); } /*********************************************************/ void test4() { alias void Function(int); static if (is(Function Void == function)) printf("if\n"); else assert(0); // static if (is(Void == void)) // printf("if\n"); // else // assert(0); alias byte delegate(int) Delegate; static if (is(Delegate Foo == delegate)) printf("if\n"); else assert(0); static if (is(Foo Byte == function)) printf("if\n"); else assert(0); // static if (is(Byte == byte)) // printf("if\n"); // else // assert(0); union Union { } static if (is(Union == union)) printf("if\n"); else assert(0); struct Struct { } static if (is(Struct == struct)) printf("if\n"); else assert(0); enum Enum : short { EnumMember } static if (is(Enum Short == enum)) printf("if\n"); else assert(0); static if (is(Short == short)) printf("if\n"); else assert(0); class Class { } static if (is(Class == class)) printf("if\n"); else assert(0); interface Interface { } static if (is(Interface == interface)) printf("if\n"); else assert(0); } /*********************************************************/ class Foo5(T) { Node sentinel; struct Node { int value; } } void test5() { Foo5!(int) bar=new Foo5!(int); bar.sentinel.value = 7; } /*********************************************************/ template factorial6(int n) { static if (n == 1) const int factorial6 = 1; else const int factorial6 = n * .factorial6!(n-1); } void test6() { int i = factorial6!(4); printf("%d\n", i); assert(i == 24); } /*********************************************************/ template whale(string walrus) { const char [] whale = walrus; } template dolphin(string fish) { const char [] dolphin = whale!(fish[0..3]); } const char [] urchin1 = dolphin!("anenome"); const char [] urchin2 = whale!("anenome"[0..3]); template dolphin3(string fish) { const char [] dolphin3 = fish[0..3]; } const char [] urchin3 = dolphin3!("anenome"); template dolphin4(string fish) { const char [] dolphin4 = whale!(fish[0..(3)]); } const char [] urchin4 = dolphin4!("anenome"); template dolphin5(string fish) { const char [] dolphin5 = whale!(fish[(0)..3]); } const char [] urchin5 = dolphin5!("anenome"); void test8() { assert(urchin1 == "ane"); assert(urchin2 == "ane"); assert(urchin3 == "ane"); assert(urchin4 == "ane"); assert(urchin5 == "ane"); } /*********************************************************/ int testEmpty(string s) { return 0; } template Recurse(string pattern){ } template slice(string str, int from, int to) { const string slice = str[from..to]; } template Compile(string pattern) { const string left = slice!(pattern,4,pattern.length); const string remaining = slice!(left,1,left.length); alias Recurse!(remaining) fn; } template Match(string pattern) { alias Compile!(pattern) Match; } void test9() { alias Match!("abcdefghijk") f; } /*********************************************************/ template Foo10(string s) { const string Foo10 = s; } void test10() { string s; s = Foo10!("abc" ~ "e"); assert(s == "abce"); s = Foo10!("abc" ~ 'f'); assert(s == "abcf"); s = Foo10!('g' ~ "abc"); assert(s == "gabc"); s = Foo10!('g' ~ "abc" ~ 'h'); assert(s == "gabch"); } /*********************************************************/ template Foo11(string s) { const string Foo11 = s; } void test11() { string s; s = Foo11!("abcdef"[1..$ - 1]); assert(s == "bcde"); } /*********************************************************/ template Foo12(int i) { const int Foo12 = i; } void test12() { int i; i = Foo12!("abcdef" == "abcdef"); assert(i == 1); i = Foo12!("abcdef" == "abcqef"); assert(i == 0); i = Foo12!("abcdef" == "abc"); assert(i == 0); i = Foo12!("abc" == "abcdef"); assert(i == 0); } /*********************************************************/ const a13 = 3; static if (a13 == 3) int b13 = 7; template Foo13(int i) { const int j = i + 1; static if (j == 3) const int k = 2; } void test13() { assert(b13 == 7); assert(Foo13!(2).k == 2); } /*********************************************************/ template zebra(string w) { static if (w.length > 2 && w[1] == 'q') const bool zebra = true; else const bool zebra = false; } template horse(string w) { static if (w.length == 1 || w[1] == 'q') const bool horse = true; else const bool horse = false; } void test14() { bool lion = zebra!("a"); assert(!lion); lion = zebra!("aqb"); assert(lion); lion = horse!("a"); assert(lion); lion = horse!("aqb"); assert(lion); lion = horse!("ab"); assert(!lion); } /*********************************************************/ template factorial15(int n) { static if (n<2) const int factorial15 = 1; else const int factorial15 = n * factorial15!(n-1); } template rhino15(alias hippo) { const int rhino15 = hippo!(3); } void test15() { const int lion = rhino15!(factorial15); assert(lion == 6); } /*********************************************************/ // Create a constant array of int or uint sized items // as a dstring string. n is the index of the last item. template makeLookup(alias entry, int n) { static if (n == -1) // start with an empty array... const dchar [] makeLookup = ""; else // ... and fill it up const dchar [] makeLookup = makeLookup!(entry, n-1) ~ cast(dchar)entry!(n); } template factorial16(uint n) { static if (n<2) const uint factorial16 = 1; else const factorial16 = n * factorial16!(n-1); } // Make an array of factorials from 0 to 13 (14!> uint.max) const smallfactorials = makeLookup!(factorial16, 13); const uint[14] testtable = [ 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 1932053504, ]; void test16() { for (int i=0; i99 && fish!( (bird[95])) ) const int dog = 2; else const int dog = 3; } const int pig = dog!("a"); void test23() { } /*********************************************************/ T delegate (T) acc24 (T) (T n) { return (T i) { return n += i; }; } void test24() { auto acc1 = acc24 (4); } /*********************************************************/ T func25(T, T c = 1)(T x) { return x * c; } void test25() { double d; d = func25(1.0); assert(d == 1.0); d = func25(2.0); assert(d == 2.0); d = func25!(double)(2.0); assert(d == 2.0); d = func25!(double, 3)(2.0); assert(d == 6.0); } /*********************************************************/ class Foo26 {} class Bar26 {} string name26; template aliastest(alias A) { pragma(msg,"Alias Test instantiated"); void aliastest() { name26 = (new A!().al).classinfo.name; //writefln("Alias Test: ", name26); } } template boxtpl(alias A) { template box() { alias A al; } } void test26() { aliastest!(boxtpl!(Foo26).box) (); assert(name26 == "template4.Foo26"); aliastest!(boxtpl!(Bar26).box) (); assert(name26 == "template4.Bar26"); } /*********************************************************/ struct TFoo27(int x) { } alias TFoo27!(3) a; alias TFoo27!(2+1) b; alias TFoo27!(3u) c; static assert(is(TFoo27!(3) == TFoo27!(2 + 1))); static assert(is(TFoo27!(3) == TFoo27!(3u))); void test27() { } /*********************************************************/ struct SiQuantity { real value = 0; static assert(SiQuantity.sizeof == real.sizeof); template AddDimensions(int mul, U) { } } void test28() { } /*********************************************************/ template Count29() { const Count29 = 5; } void test29() { int[Count29!()] x; assert(x.length == 5); } /*********************************************************/ class FooClass(T) { T data; } struct FooStruct(T) { T data; } void bar_struct(T)(FooStruct!(T) a) {} void bar_class(T)(FooClass!(T) a) {} void test30() { auto C = new FooClass!(double); FooStruct!(double) S; bar_struct(S); bar_class!(double)(C); bar_class(C); } /*********************************************************/ V get31(V,K)(V[K] dict, K key, V def = V.init) { V* ptr = key in dict; return ptr? *ptr: def; } string get31x(string[int] dict, int key, string def = null) { string* ptr = key in dict; return ptr? *ptr: def; } void test31() { string[int] i2s; i2s[1] = "Hello"; i2s[5] = "There"; auto result = i2s.get31(1, "yeh"); printf("%.*s\n", cast(int)result.length, result.ptr); result = i2s.get31(2, "default"); printf("%.*s\n", cast(int)result.length, result.ptr); result = i2s.get31(1); printf("%.*s\n", cast(int)result.length, result.ptr); result = i2s.get31(2); printf("%.*s\n", cast(int)result.length, result.ptr); } /*********************************************************/ void delegate(T, S) Concat(S, T...)(void delegate(T) one, void delegate(S) two) { return( delegate void(T t, S s){} ); } void test32() { void delegate(char, char, int) wtf = Concat( delegate void(char a, char b) {}, delegate void(int lol) {} ); } /*********************************************************/ struct Composer(T) { alias T delegate(T) Fun; Fun[] funs; public T opCall()(T x) { T result = x; foreach_reverse (f; funs) { result = f(result); } return result; } public void opOpAssign(string op)(Fun f) if (op == "+") { funs ~= f; } } struct square(T) { T opCall(T t) { return t*t; } } struct plus1(T) { T opCall(T t) { return t+1; } } struct div3(T) { T opCall(T t) { return t/3.0; } } T delegate(T) tofp(T : S!(T), alias S)() { class Foo { div3!(T) arg; T bar(T t) { return arg(t); } } Foo f = new Foo; return &f.bar; } void test33() { Composer!(double) comp; comp += delegate double (double x) { return x/3.0;}; comp += delegate double (double x) { return x*x;}; comp += (double x) => x + 1.0; printf("%f\n", comp(2.0)); // Try function objects Composer!(double) comp2; comp2 += tofp!(div3!(double))(); comp2 += tofp!(square!(double))(); comp2 += tofp!(plus1!(double))(); printf("%f\n", comp2( 2.0)); } /*********************************************************/ template Print34(Ts ...) { pragma (msg, Ts.stringof); } template Tuple34(Ts ...) { alias Ts Tuple34; } template Decode34( T ) { alias Tuple34!() Types; } template Decode34( T : TT!(U1), alias TT, U1 ) { alias Tuple34!(U1) Types; } template Decode34( T : TT!(U1,U2), alias TT, U1, U2 ) { alias Tuple34!(U1,U2) Types; } template Decode34( T : TT!(U1,U2,U3), alias TT, U1, U2, U3 ) { alias Tuple34!(U1,U2,U3) Types; } struct S34_1(T1) {} struct S34_2(T1, T2) {} struct S34_3(T1, T2, T3) {} alias Decode34!( bool ).Types SQ0; alias Decode34!( S34_1!(bool) ).Types SQ1; alias Decode34!( S34_2!(bool,short) ).Types SQ2; alias Decode34!( S34_3!(bool,short,int) ).Types SQ3; mixin Print34!(SQ0); mixin Print34!(SQ1); mixin Print34!(SQ2); mixin Print34!(SQ3); void test34() { } /*********************************************************/ template strof(T) { static string strof = T.stringof; } void test35() { alias typeof(delegate () { return (char[]).init;} ) del; auto a = strof!(del); auto aa = strof!(int); auto ab = strof!(typeof(5)); auto meth = delegate () { return (char[]).init;}; auto b = strof!(typeof(meth)); auto c = strof!(typeof(delegate () { return 5; } )); auto d = strof!(typeof(delegate () { return (char[]).init;} )); } /*********************************************************/ struct Number36(int N) { const int value = N; } struct Foo36(T) { int talk() { printf("Not so special:\n"); return 1; } } struct Foo36(T : Number36!(N), int N) { int talk() { printf("Ooh special - NUMBER N\n"); return 2; } } void test36() { Foo36!(Number36!(5)) x; auto i = x.talk(); assert(i == 2); } /*********************************************************/ struct Base37(T) {} alias Base37 Alias37; void foo37(T)(Alias37!(T) x) {} void test37() { Base37!(float) b; foo37(b); // fails! } /*********************************************************/ void sort(alias dg, T)(T[] arr) { bool a = dg(1,2); printf("a = %d\n", a); assert(a == true); } void test38() { int[] arr; int i = 3; sort!( (x,y){ return x + i > y; } )(arr); sort!( (int x,int y){ return x + i > y; } )(arr); } /*********************************************************/ void bug4652(U, T...)(long y, T x, U num) {} void bug4652default(T) (T value, int x=2) {} void bug4652default(T) (T value, int y) {} void bug4676(T...)(T args, string str) {} void bug4676(T...)(T args) {} void instantiate4652() { bug4652(2, 'c', 27, 'e', 'f',1); // rejects-valid bug4652(2, 1); // infinite loop on valid code bug4652default(true); bug4676(1, 2, 3); } /*********************************************************/ // https://issues.dlang.org/show_bug.cgi?id=7589 struct T7589(T) { void n; } static assert(!__traits(compiles, T7589!(int))); int bug7589b(T)() @safe { int *p; *(p + 8) = 6; } static assert(!__traits(compiles, bug7589b!(int)()+7 )); /*********************************************************/ int bar39(alias dg)(int i) { return dg(i); } void test39() { auto i = bar39!(a => a + 1)(3); if (i != 4) assert(0); } /*********************************************************/ // https://issues.dlang.org/show_bug.cgi?id=6701 uint foo_6701(uint v:0)() { return 1; } uint foo_6701(uint v)() { return 0; } uint foo2_6701(uint v:0, string op)() { return 1; } uint foo2_6701(uint v, string op)() { return 0; } void test6701() { assert(foo_6701!(0u)() == 1); assert(foo2_6701!(0u, "+")() == 1); } /******************************************/ // https://issues.dlang.org/show_bug.cgi?id=7469 struct Foo7469a(int x) { } struct Foo7469b(int x) { } struct Foo7469c(alias v) { } struct Foo7469d(T...) { } struct Foo7469e(int a, T...) { } struct Foo7469f(T, int k=1) { } struct Foo7469g(T, int k=1) { } struct Foo7469h(uint x) { } import core.demangle : demangleType; void test7469() { static assert(demangleType(Foo7469a!(3 ) .mangleof) == "template4.Foo7469a!(3).Foo7469a"); static assert(demangleType(Foo7469a!(3u) .mangleof) == "template4.Foo7469a!(3).Foo7469a"); static assert(demangleType(Foo7469b!(3u) .mangleof) == "template4.Foo7469b!(3).Foo7469b"); static assert(demangleType(Foo7469b!(3 ) .mangleof) == "template4.Foo7469b!(3).Foo7469b"); static assert(demangleType(Foo7469c!(3 ) .mangleof) == "template4.Foo7469c!(3).Foo7469c"); static assert(demangleType(Foo7469c!(3u) .mangleof) == "template4.Foo7469c!(3u).Foo7469c"); static assert(demangleType(Foo7469d!(3 ) .mangleof) == "template4.Foo7469d!(3).Foo7469d"); static assert(demangleType(Foo7469d!(3u) .mangleof) == "template4.Foo7469d!(3u).Foo7469d"); static assert(demangleType(Foo7469e!(3u, 5u).mangleof) == "template4.Foo7469e!(3, 5u).Foo7469e"); static assert(demangleType(Foo7469f!(int, 1).mangleof) == "template4.Foo7469f!(int, 1).Foo7469f"); static assert(demangleType(Foo7469f!(int) .mangleof) == "template4.Foo7469f!(int, 1).Foo7469f"); static assert(demangleType(Foo7469g!(int) .mangleof) == "template4.Foo7469g!(int, 1).Foo7469g"); static assert(demangleType(Foo7469g!(int, 1).mangleof) == "template4.Foo7469g!(int, 1).Foo7469g"); static assert(demangleType(Foo7469h!(3 ) .mangleof) == "template4.Foo7469h!(3u).Foo7469h"); static assert(demangleType(Foo7469h!(3u) .mangleof) == "template4.Foo7469h!(3u).Foo7469h"); } /******************************************/ template foo7698a(T, T val : 0) { enum foo7698a = val; } T foo7698b(T, T val : 0)() { return val; } T foo7698c(T, T val : T.init)() { return val; } void test7698() { static assert(foo7698a!(int, 0) == 0); assert(foo7698b!(int, 0)() == 0); assert(foo7698c!(int, 0)() == 0); } /*********************************************************/ int main() { test1(); test2(); test3(); test4(); test5(); test6(); test8(); test9(); test10(); test11(); test12(); test13(); test14(); test15(); test16(); test17(); test18(); test19(); test20(); test21(); test22(); test23(); test24(); test25(); test26(); test27(); test28(); test29(); test30(); test31(); test32(); test33(); test34(); test35(); test36(); test37(); test38(); test39(); test6701(); test7698(); printf("Success\n"); return 0; }