blob: 3c65dac09328d75591428d608b328b71e433e5ec [file] [log] [blame]
// 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`));