// REQUIRED_ARGS: -extern-std=c++98 // EXTRA_FILES: imports/plainpackage/plainmodule.d imports/pkgmodule/package.d imports/pkgmodule/plainmodule.d // This file is intended to contain all compilable traits-related tests in an // effort to keep the number of files in the `compilable` folder to a minimum. // https://issues.dlang.org/show_bug.cgi?id=19152 module traits; class C19152 { int OnExecute() { auto name = __traits(getOverloads, this, "OnExecute").stringof; return 0; } } static assert(is(typeof(__traits(getTargetInfo, "cppRuntimeLibrary")) == string)); version (CppRuntime_Microsoft) { static assert(__traits(getTargetInfo, "cppRuntimeLibrary") == "libcmt" || __traits(getTargetInfo, "cppRuntimeLibrary")[0..6] == "msvcrt"); // includes mingw import libs } version (D_HardFloat) static assert(__traits(getTargetInfo, "floatAbi") == "hard"); version (Win64) static assert(__traits(getTargetInfo, "objectFormat") == "coff"); version (OSX) static assert(__traits(getTargetInfo, "objectFormat") == "macho"); version (linux) static assert(__traits(getTargetInfo, "objectFormat") == "elf"); static assert(__traits(getTargetInfo, "cppStd") == 199711); import imports.plainpackage.plainmodule; import imports.pkgmodule.plainmodule; #line 40 struct MyStruct; alias a = imports.plainpackage; alias b = imports.pkgmodule.plainmodule; static assert(__traits(isPackage, imports.plainpackage)); static assert(__traits(isPackage, a)); static assert(!__traits(isPackage, imports.plainpackage.plainmodule)); static assert(!__traits(isPackage, b)); static assert(__traits(isPackage, imports.pkgmodule)); static assert(!__traits(isPackage, MyStruct)); static assert(!__traits(isModule, imports.plainpackage)); static assert(!__traits(isModule, a)); static assert(__traits(isModule, imports.plainpackage.plainmodule)); static assert(__traits(isModule, b)); // This is supposed to work even though we haven't directly imported imports.pkgmodule. static assert(__traits(isModule, imports.pkgmodule)); static assert(!__traits(isModule, MyStruct)); /******************************************/ // https://issues.dlang.org/show_bug.cgi?id=19942 static assert(!__traits(compiles, { a.init; })); static assert(!__traits(compiles, { import m : a; a.init; })); version(Windows) static assert(__traits(getLocation, MyStruct)[0] == `compilable\traits.d`); else static assert(__traits(getLocation, MyStruct)[0] == "compilable/traits.d"); static assert(__traits(getLocation, MyStruct)[1] == 40); static assert(__traits(getLocation, MyStruct)[2] == 1); int foo(); int foo(int); static assert(__traits(getLocation, __traits(getOverloads, traits, "foo")[1])[1] == 74); mixin("int bar;"); static assert(__traits(getLocation, bar)[1] == 78); struct Outer { struct Nested{} void method() {} } static assert(__traits(getLocation, Outer.Nested)[1] == 83); static assert(__traits(getLocation, Outer.method)[1] == 85); /******************************************/ // https://issues.dlang.org/show_bug.cgi?id=19902 // Define hasElaborateCopyConstructor trait // but done as two independent traits per conversation // in https://github.com/dlang/dmd/pull/10265 struct S { this (ref S rhs) {} } struct OuterS { struct S { this (ref S rhs) {} } S s; } void foo(T)() { struct S(U) { this (ref S rhs) {} } static assert (__traits(hasCopyConstructor, S!int)); } struct U(T) { this (ref U rhs) {} } struct SPostblit { this(this) {} } struct DisabledPostblit { @disable this(this); } struct NoCpCtor { } class C19902 { } static assert(__traits(hasCopyConstructor, S)); static assert(__traits(hasCopyConstructor, OuterS.S)); static assert(__traits(hasCopyConstructor, OuterS)); static assert(__traits(compiles, foo!int)); static assert(__traits(compiles, foo!S)); static assert(__traits(hasCopyConstructor, U!int)); static assert(__traits(hasCopyConstructor, U!S)); static assert(!__traits(hasPostblit, U!S)); static assert(__traits(hasPostblit, SPostblit)); static assert(!__traits(hasCopyConstructor, SPostblit)); static assert(!__traits(hasCopyConstructor, NoCpCtor)); static assert(!__traits(hasCopyConstructor, C19902)); static assert(!__traits(hasCopyConstructor, int)); static assert(!__traits(hasPostblit, NoCpCtor)); static assert(!__traits(hasPostblit, C19902)); static assert(!__traits(hasPostblit, int)); static assert(__traits(isCopyable, int)); static assert(!__traits(isCopyable, DisabledPostblit)); struct S1 {} // Fine. Can be copied struct S2 { this(this) {} } // Fine. Can be copied struct S3 { @disable this(this); } // Not fine. Copying is disabled. struct S4 { S3 s; } // Not fine. A field has copying disabled. class C1 {} static assert( __traits(isCopyable, S1)); static assert( __traits(isCopyable, S2)); static assert(!__traits(isCopyable, S3)); static assert(!__traits(isCopyable, S4)); static assert(__traits(isCopyable, C1)); static assert(__traits(isCopyable, int)); static assert(__traits(isCopyable, int[])); enum E1 : S1 { a = S1(), } enum E2 : S2 { a = S2(), } enum E3 : S3 { a = S3(), } enum E4 : S4 { a = S4(), } static assert(__traits(isCopyable, E1)); static assert(__traits(isCopyable, E2)); static assert(!__traits(isCopyable, E3)); static assert(!__traits(isCopyable, E4)); struct S5 { @disable this(ref S5); } static assert(!__traits(isCopyable, S5)); /******************************************/ // https://issues.dlang.org/show_bug.cgi?id=20884 struct S20884 { int x; } alias T20884 = immutable(S20884); enum m20884 = "x"; static assert(is(typeof(__traits(getMember, T20884, m20884)) == immutable(int))); // OK now static assert(is( typeof(mixin("T20884." ~ m20884)) == immutable(int))); static assert(is( typeof(T20884.x) == immutable(int))); /******************************************/ // https://issues.dlang.org/show_bug.cgi?id=20761 alias Seq(T...) = T; static assert(__traits(isSame, Seq!(1, 2), Seq!(1, 2))); static assert(!__traits(isSame, Seq!(1, 1), Seq!(2, 2))); static assert(!__traits(isSame, Seq!(1, 1, 2), Seq!(1, 1))); static assert(!__traits(isSame, Seq!(1, 1), Seq!(1, 1, 2))); static assert(__traits(isSame, Seq!(string, wstring), Seq!(immutable(char)[], immutable(wchar)[])) ); static assert(__traits(isSame, Seq!(i => i.value, (a, b) => a + b), Seq!(a => a.value, (x, y) => x + y) )); static assert(__traits(isSame, Seq!(float, Seq!(double, Seq!real)), Seq!(Seq!(Seq!float, double), real) )); static assert(!__traits(isSame, Seq!(int, Seq!(a => a + a)), Seq!(int, Seq!(a => a * a)) )); // Do these out of order to ensure there are no forward refencing bugs extern(C++, __traits(getCppNamespaces,GetNamespaceTest1)) struct GetNamespaceTest4 {} static assert (__traits(getCppNamespaces,GetNamespaceTest1) == __traits(getCppNamespaces,GetNamespaceTest4)); extern(C++, "ns") struct GetNamespaceTest1 {} extern(C++, "multiple", "namespaces") struct GetNamespaceTest2 {} extern(C++, mixin("Seq!(`ns`, `nt`)")) struct GetNamespaceTest3 {} static assert(__traits(getCppNamespaces,GetNamespaceTest1)[0] == "ns"); static assert(__traits(getCppNamespaces,GetNamespaceTest2) == Seq!("multiple","namespaces")); static assert(__traits(getCppNamespaces,GetNamespaceTest3) == Seq!("ns", "nt")); extern(C++, __traits(getCppNamespaces,GetNamespaceTest5)) struct GetNamespaceTest8 {} static assert (__traits(getCppNamespaces,GetNamespaceTest5) == __traits(getCppNamespaces,GetNamespaceTest8)); extern(C++, ns) struct GetNamespaceTest5 {} extern(C++, multiple) extern(C++, namespaces) struct GetNamespaceTest6 {} static assert(__traits(getCppNamespaces,GetNamespaceTest5)[0] == "ns"); static assert(__traits(getCppNamespaces,GetNamespaceTest6) == Seq!("multiple","namespaces")); extern(C++, NS) { struct GetNamespaceTest9 {} extern(C++, nested) { struct GetNamespaceTest10 {} extern(C++,"nested2") struct GetNamespaceTest11 {} } extern (C++, "nested3") { extern(C++, nested4) struct GetNamespaceTest12 {} } } static assert (__traits(getCppNamespaces,NS.GetNamespaceTest9)[0] == "NS"); static assert (__traits(getCppNamespaces,NS.GetNamespaceTest10) == Seq!("NS", "nested")); static assert (__traits(getCppNamespaces,NS.GetNamespaceTest11) == Seq!("NS", "nested", "nested2")); static assert (__traits(getCppNamespaces,NS.GetNamespaceTest12) == Seq!("NS", "nested4", "nested3")); extern(C++, `ns`) struct GetNamespaceTestTemplated(T) {} extern(C++, `ns`) template GetNamespaceTestTemplated2(T) { struct GetNamespaceTestTemplated2 {} } template GetNamespaceTestTemplated3(T) { extern(C++, `ns`) struct GetNamespaceTestTemplated3 {} } static assert (__traits(getCppNamespaces,GetNamespaceTestTemplated!int) == Seq!("ns")); static assert (__traits(getCppNamespaces,GetNamespaceTestTemplated2!int) == Seq!("ns")); static assert (__traits(getCppNamespaces,GetNamespaceTestTemplated3!int) == Seq!("ns")); extern(C++, `ns2`) template GetNamespaceTestTemplated4(T) { extern(C++, `ns`) struct GetNamespaceTestTemplated4 { struct GetNamespaceTestTemplated5 {} struct GetNamespaceTestTemplated6(T) {} } } static assert (__traits(getCppNamespaces,GetNamespaceTestTemplated4!int) == Seq!("ns2","ns")); static assert (__traits(getCppNamespaces,GetNamespaceTestTemplated4!int.GetNamespaceTestTemplated5) == Seq!("ns2","ns")); static assert (__traits(getCppNamespaces,GetNamespaceTestTemplated4!int.GetNamespaceTestTemplated6!int) == Seq!("ns2","ns")); // Currently ignored due to https://issues.dlang.org/show_bug.cgi?id=21373 extern(C++, `decl`) mixin template GetNamespaceTestTemplatedMixin() { extern(C++, `f`) void foo() {} } extern(C++, `inst`) mixin GetNamespaceTestTemplatedMixin!() GNTT; static assert (__traits(getCppNamespaces, GNTT.foo) == Seq!(`inst`,/*`decl`,*/ `f`));