blob: 9d14ecdcc09c8b723a6b9b4463e8495e70cc8921 [file] [log] [blame]
// RUNNABLE_PHOBOS_TEST
/*
PERMUTE_ARGS:
EXTRA_FILES: imports/a9546.d
Windows linker may write something like:
---
Creating library {{RESULTS_DIR}}/runnable/traits_0.lib and object {{RESULTS_DIR}}/runnable/traits_0.exp
---
TRANSFORM_OUTPUT: remove_lines("Creating library")
TEST_OUTPUT:
---
__lambda1
---
*/
module traits;
import std.stdio;
alias int myint;
struct S { void bar() { } int x = 4; static int z = 5; }
class C { void bar() { } final void foo() { } static void abc() { } }
abstract class AC { }
class AC2 { abstract void foo(); }
class AC3 : AC2 { }
final class FC { void foo() { } }
enum E { EMEM }
struct D1 { @disable void true_(); void false_(){} }
/********************************************************/
void test1()
{
auto t = __traits(isArithmetic, int);
writeln(t);
assert(t == true);
assert(__traits(isArithmetic) == false);
assert(__traits(isArithmetic, myint) == true);
assert(__traits(isArithmetic, S) == false);
assert(__traits(isArithmetic, C) == false);
assert(__traits(isArithmetic, E) == true);
assert(__traits(isArithmetic, void*) == false);
assert(__traits(isArithmetic, void[]) == false);
assert(__traits(isArithmetic, void[3]) == false);
assert(__traits(isArithmetic, int[char]) == false);
assert(__traits(isArithmetic, int, int) == true);
assert(__traits(isArithmetic, int, S) == false);
assert(__traits(isArithmetic, void) == false);
assert(__traits(isArithmetic, byte) == true);
assert(__traits(isArithmetic, ubyte) == true);
assert(__traits(isArithmetic, short) == true);
assert(__traits(isArithmetic, ushort) == true);
assert(__traits(isArithmetic, int) == true);
assert(__traits(isArithmetic, uint) == true);
assert(__traits(isArithmetic, long) == true);
assert(__traits(isArithmetic, ulong) == true);
assert(__traits(isArithmetic, float) == true);
assert(__traits(isArithmetic, double) == true);
assert(__traits(isArithmetic, real) == true);
assert(__traits(isArithmetic, ifloat) == true);
assert(__traits(isArithmetic, idouble) == true);
assert(__traits(isArithmetic, ireal) == true);
assert(__traits(isArithmetic, cfloat) == true);
assert(__traits(isArithmetic, cdouble) == true);
assert(__traits(isArithmetic, creal) == true);
assert(__traits(isArithmetic, char) == true);
assert(__traits(isArithmetic, wchar) == true);
assert(__traits(isArithmetic, dchar) == true);
int i;
assert(__traits(isArithmetic, i, i+1, int) == true);
assert(__traits(isArithmetic) == false);
}
/********************************************************/
void test2()
{
auto t = __traits(isScalar, int);
writeln(t);
assert(t == true);
assert(__traits(isScalar) == false);
assert(__traits(isScalar, myint) == true);
assert(__traits(isScalar, S) == false);
assert(__traits(isScalar, C) == false);
assert(__traits(isScalar, E) == true);
assert(__traits(isScalar, void*) == true);
assert(__traits(isScalar, void[]) == false);
assert(__traits(isScalar, void[3]) == false);
assert(__traits(isScalar, int[char]) == false);
assert(__traits(isScalar, int, int) == true);
assert(__traits(isScalar, int, S) == false);
assert(__traits(isScalar, void) == false);
assert(__traits(isScalar, byte) == true);
assert(__traits(isScalar, ubyte) == true);
assert(__traits(isScalar, short) == true);
assert(__traits(isScalar, ushort) == true);
assert(__traits(isScalar, int) == true);
assert(__traits(isScalar, uint) == true);
assert(__traits(isScalar, long) == true);
assert(__traits(isScalar, ulong) == true);
assert(__traits(isScalar, float) == true);
assert(__traits(isScalar, double) == true);
assert(__traits(isScalar, real) == true);
assert(__traits(isScalar, ifloat) == true);
assert(__traits(isScalar, idouble) == true);
assert(__traits(isScalar, ireal) == true);
assert(__traits(isScalar, cfloat) == true);
assert(__traits(isScalar, cdouble) == true);
assert(__traits(isScalar, creal) == true);
assert(__traits(isScalar, char) == true);
assert(__traits(isScalar, wchar) == true);
assert(__traits(isScalar, dchar) == true);
}
/********************************************************/
void test3()
{
assert(__traits(isIntegral) == false);
assert(__traits(isIntegral, myint) == true);
assert(__traits(isIntegral, S) == false);
assert(__traits(isIntegral, C) == false);
assert(__traits(isIntegral, E) == true);
assert(__traits(isIntegral, void*) == false);
assert(__traits(isIntegral, void[]) == false);
assert(__traits(isIntegral, void[3]) == false);
assert(__traits(isIntegral, int[char]) == false);
assert(__traits(isIntegral, int, int) == true);
assert(__traits(isIntegral, int, S) == false);
assert(__traits(isIntegral, void) == false);
assert(__traits(isIntegral, byte) == true);
assert(__traits(isIntegral, ubyte) == true);
assert(__traits(isIntegral, short) == true);
assert(__traits(isIntegral, ushort) == true);
assert(__traits(isIntegral, int) == true);
assert(__traits(isIntegral, uint) == true);
assert(__traits(isIntegral, long) == true);
assert(__traits(isIntegral, ulong) == true);
assert(__traits(isIntegral, float) == false);
assert(__traits(isIntegral, double) == false);
assert(__traits(isIntegral, real) == false);
assert(__traits(isIntegral, ifloat) == false);
assert(__traits(isIntegral, idouble) == false);
assert(__traits(isIntegral, ireal) == false);
assert(__traits(isIntegral, cfloat) == false);
assert(__traits(isIntegral, cdouble) == false);
assert(__traits(isIntegral, creal) == false);
assert(__traits(isIntegral, char) == true);
assert(__traits(isIntegral, wchar) == true);
assert(__traits(isIntegral, dchar) == true);
}
/********************************************************/
void test4()
{
assert(__traits(isFloating) == false);
assert(__traits(isFloating, S) == false);
assert(__traits(isFloating, C) == false);
assert(__traits(isFloating, E) == false);
assert(__traits(isFloating, void*) == false);
assert(__traits(isFloating, void[]) == false);
assert(__traits(isFloating, void[3]) == false);
assert(__traits(isFloating, int[char]) == false);
assert(__traits(isFloating, float, float) == true);
assert(__traits(isFloating, float, S) == false);
assert(__traits(isFloating, void) == false);
assert(__traits(isFloating, byte) == false);
assert(__traits(isFloating, ubyte) == false);
assert(__traits(isFloating, short) == false);
assert(__traits(isFloating, ushort) == false);
assert(__traits(isFloating, int) == false);
assert(__traits(isFloating, uint) == false);
assert(__traits(isFloating, long) == false);
assert(__traits(isFloating, ulong) == false);
assert(__traits(isFloating, float) == true);
assert(__traits(isFloating, double) == true);
assert(__traits(isFloating, real) == true);
assert(__traits(isFloating, ifloat) == true);
assert(__traits(isFloating, idouble) == true);
assert(__traits(isFloating, ireal) == true);
assert(__traits(isFloating, cfloat) == true);
assert(__traits(isFloating, cdouble) == true);
assert(__traits(isFloating, creal) == true);
assert(__traits(isFloating, char) == false);
assert(__traits(isFloating, wchar) == false);
assert(__traits(isFloating, dchar) == false);
}
/********************************************************/
void test5()
{
assert(__traits(isUnsigned) == false);
assert(__traits(isUnsigned, S) == false);
assert(__traits(isUnsigned, C) == false);
assert(__traits(isUnsigned, E) == false);
assert(__traits(isUnsigned, void*) == false);
assert(__traits(isUnsigned, void[]) == false);
assert(__traits(isUnsigned, void[3]) == false);
assert(__traits(isUnsigned, int[char]) == false);
assert(__traits(isUnsigned, float, float) == false);
assert(__traits(isUnsigned, float, S) == false);
assert(__traits(isUnsigned, void) == false);
assert(__traits(isUnsigned, byte) == false);
assert(__traits(isUnsigned, ubyte) == true);
assert(__traits(isUnsigned, short) == false);
assert(__traits(isUnsigned, ushort) == true);
assert(__traits(isUnsigned, int) == false);
assert(__traits(isUnsigned, uint) == true);
assert(__traits(isUnsigned, long) == false);
assert(__traits(isUnsigned, ulong) == true);
assert(__traits(isUnsigned, float) == false);
assert(__traits(isUnsigned, double) == false);
assert(__traits(isUnsigned, real) == false);
assert(__traits(isUnsigned, ifloat) == false);
assert(__traits(isUnsigned, idouble) == false);
assert(__traits(isUnsigned, ireal) == false);
assert(__traits(isUnsigned, cfloat) == false);
assert(__traits(isUnsigned, cdouble) == false);
assert(__traits(isUnsigned, creal) == false);
assert(__traits(isUnsigned, char) == true);
assert(__traits(isUnsigned, wchar) == true);
assert(__traits(isUnsigned, dchar) == true);
}
/********************************************************/
void test6()
{
assert(__traits(isAssociativeArray) == false);
assert(__traits(isAssociativeArray, S) == false);
assert(__traits(isAssociativeArray, C) == false);
assert(__traits(isAssociativeArray, E) == false);
assert(__traits(isAssociativeArray, void*) == false);
assert(__traits(isAssociativeArray, void[]) == false);
assert(__traits(isAssociativeArray, void[3]) == false);
assert(__traits(isAssociativeArray, int[char]) == true);
assert(__traits(isAssociativeArray, float, float) == false);
assert(__traits(isAssociativeArray, float, S) == false);
assert(__traits(isAssociativeArray, void) == false);
assert(__traits(isAssociativeArray, byte) == false);
assert(__traits(isAssociativeArray, ubyte) == false);
assert(__traits(isAssociativeArray, short) == false);
assert(__traits(isAssociativeArray, ushort) == false);
assert(__traits(isAssociativeArray, int) == false);
assert(__traits(isAssociativeArray, uint) == false);
assert(__traits(isAssociativeArray, long) == false);
assert(__traits(isAssociativeArray, ulong) == false);
assert(__traits(isAssociativeArray, float) == false);
assert(__traits(isAssociativeArray, double) == false);
assert(__traits(isAssociativeArray, real) == false);
assert(__traits(isAssociativeArray, ifloat) == false);
assert(__traits(isAssociativeArray, idouble) == false);
assert(__traits(isAssociativeArray, ireal) == false);
assert(__traits(isAssociativeArray, cfloat) == false);
assert(__traits(isAssociativeArray, cdouble) == false);
assert(__traits(isAssociativeArray, creal) == false);
assert(__traits(isAssociativeArray, char) == false);
assert(__traits(isAssociativeArray, wchar) == false);
assert(__traits(isAssociativeArray, dchar) == false);
}
/********************************************************/
void test7()
{
assert(__traits(isStaticArray) == false);
assert(__traits(isStaticArray, S) == false);
assert(__traits(isStaticArray, C) == false);
assert(__traits(isStaticArray, E) == false);
assert(__traits(isStaticArray, void*) == false);
assert(__traits(isStaticArray, void[]) == false);
assert(__traits(isStaticArray, void[3]) == true);
assert(__traits(isStaticArray, int[char]) == false);
assert(__traits(isStaticArray, float, float) == false);
assert(__traits(isStaticArray, float, S) == false);
assert(__traits(isStaticArray, void) == false);
assert(__traits(isStaticArray, byte) == false);
assert(__traits(isStaticArray, ubyte) == false);
assert(__traits(isStaticArray, short) == false);
assert(__traits(isStaticArray, ushort) == false);
assert(__traits(isStaticArray, int) == false);
assert(__traits(isStaticArray, uint) == false);
assert(__traits(isStaticArray, long) == false);
assert(__traits(isStaticArray, ulong) == false);
assert(__traits(isStaticArray, float) == false);
assert(__traits(isStaticArray, double) == false);
assert(__traits(isStaticArray, real) == false);
assert(__traits(isStaticArray, ifloat) == false);
assert(__traits(isStaticArray, idouble) == false);
assert(__traits(isStaticArray, ireal) == false);
assert(__traits(isStaticArray, cfloat) == false);
assert(__traits(isStaticArray, cdouble) == false);
assert(__traits(isStaticArray, creal) == false);
assert(__traits(isStaticArray, char) == false);
assert(__traits(isStaticArray, wchar) == false);
assert(__traits(isStaticArray, dchar) == false);
}
/********************************************************/
void test8()
{
assert(__traits(isAbstractClass) == false);
assert(__traits(isAbstractClass, S) == false);
assert(__traits(isAbstractClass, C) == false);
assert(__traits(isAbstractClass, AC) == true);
assert(__traits(isAbstractClass, E) == false);
assert(__traits(isAbstractClass, void*) == false);
assert(__traits(isAbstractClass, void[]) == false);
assert(__traits(isAbstractClass, void[3]) == false);
assert(__traits(isAbstractClass, int[char]) == false);
assert(__traits(isAbstractClass, float, float) == false);
assert(__traits(isAbstractClass, float, S) == false);
assert(__traits(isAbstractClass, void) == false);
assert(__traits(isAbstractClass, byte) == false);
assert(__traits(isAbstractClass, ubyte) == false);
assert(__traits(isAbstractClass, short) == false);
assert(__traits(isAbstractClass, ushort) == false);
assert(__traits(isAbstractClass, int) == false);
assert(__traits(isAbstractClass, uint) == false);
assert(__traits(isAbstractClass, long) == false);
assert(__traits(isAbstractClass, ulong) == false);
assert(__traits(isAbstractClass, float) == false);
assert(__traits(isAbstractClass, double) == false);
assert(__traits(isAbstractClass, real) == false);
assert(__traits(isAbstractClass, ifloat) == false);
assert(__traits(isAbstractClass, idouble) == false);
assert(__traits(isAbstractClass, ireal) == false);
assert(__traits(isAbstractClass, cfloat) == false);
assert(__traits(isAbstractClass, cdouble) == false);
assert(__traits(isAbstractClass, creal) == false);
assert(__traits(isAbstractClass, char) == false);
assert(__traits(isAbstractClass, wchar) == false);
assert(__traits(isAbstractClass, dchar) == false);
assert(__traits(isAbstractClass, AC2) == true);
assert(__traits(isAbstractClass, AC3) == true);
}
/********************************************************/
void test9()
{
assert(__traits(isFinalClass) == false);
assert(__traits(isFinalClass, C) == false);
assert(__traits(isFinalClass, FC) == true);
}
/********************************************************/
void test10()
{
assert(__traits(isVirtualFunction, C.bar) == true);
assert(__traits(isVirtualFunction, S.bar) == false);
}
/********************************************************/
void test11()
{
assert(__traits(isAbstractFunction, C.bar) == false);
assert(__traits(isAbstractFunction, S.bar) == false);
assert(__traits(isAbstractFunction, AC2.foo) == true);
}
/********************************************************/
void test12()
{
assert(__traits(isFinalFunction, C.bar) == false);
assert(__traits(isFinalFunction, S.bar) == false);
assert(__traits(isFinalFunction, AC2.foo) == false);
assert(__traits(isFinalFunction, FC.foo) == true);
assert(__traits(isFinalFunction, C.foo) == true);
}
/********************************************************/
void test13()
{
S s;
__traits(getMember, s, "x") = 7;
auto i = __traits(getMember, s, "x");
assert(i == 7);
auto j = __traits(getMember, S, "z");
assert(j == 5);
writeln(__traits(hasMember, s, "x"));
assert(__traits(hasMember, s, "x") == true);
assert(__traits(hasMember, S, "z") == true);
assert(__traits(hasMember, S, "aaa") == false);
auto k = __traits(classInstanceSize, C);
writeln(k);
assert(k == C.classinfo.initializer.length);
}
/********************************************************/
// 7123
private struct DelegateFaker7123(F)
{
template GeneratingPolicy() {}
enum WITH_BASE_CLASS = __traits(hasMember, GeneratingPolicy!(), "x");
}
auto toDelegate7123(F)(F fp)
{
alias DelegateFaker7123!F Faker;
}
void test7123()
{
static assert(is(typeof(toDelegate7123(&main))));
}
/********************************************************/
class D14
{
this() { }
~this() { }
void foo() { }
int foo(int) { return 0; }
}
void test14()
{
auto a = [__traits(derivedMembers, D14)];
writeln(a);
assert(a == ["__ctor","__dtor","foo", "__xdtor"]);
}
/********************************************************/
class D15
{
this() { }
~this() { }
void foo() { }
int foo(int) { return 2; }
}
void test15()
{
D15 d = new D15();
foreach (t; __traits(getVirtualFunctions, D15, "foo"))
writeln(typeid(typeof(t)));
alias typeof(__traits(getVirtualFunctions, D15, "foo")) b;
foreach (t; b)
writeln(typeid(t));
auto i = __traits(getVirtualFunctions, d, "foo")[1](1);
assert(i == 2);
}
/********************************************************/
struct S16 { }
int foo16();
int bar16();
void test16()
{
assert(__traits(isSame, foo16, foo16) == true);
assert(__traits(isSame, foo16, bar16) == false);
assert(__traits(isSame, foo16, S16) == false);
assert(__traits(isSame, S16, S16) == true);
assert(__traits(isSame, std, S16) == false);
assert(__traits(isSame, std, std) == true);
}
/********************************************************/
struct S17
{
static int s1;
int s2;
}
int foo17();
void test17()
{
assert(__traits(compiles) == false);
assert(__traits(compiles, foo17) == true);
assert(__traits(compiles, foo17 + 1) == true);
assert(__traits(compiles, &foo17 + 1) == false);
assert(__traits(compiles, typeof(1)) == true);
assert(__traits(compiles, S17.s1) == true);
assert(__traits(compiles, S17.s3) == false);
assert(__traits(compiles, 1,2,3,int,long,std) == true);
assert(__traits(compiles, 3[1]) == false);
assert(__traits(compiles, 1,2,3,int,long,3[1]) == false);
}
/********************************************************/
interface D18
{
extern(Windows):
void foo();
int foo(int);
}
void test18()
{
auto a = __traits(allMembers, D18);
writeln(a);
assert(a.length == 1);
}
/********************************************************/
class C19
{
void mutating_method(){}
const void const_method(){}
void bastard_method(){}
const void bastard_method(int){}
}
void test19()
{
auto a = __traits(allMembers, C19);
writeln(a);
assert(a.length == 9);
foreach( m; __traits(allMembers, C19) )
writeln(m);
}
/********************************************************/
void test20()
{
void fooref(ref int x)
{
static assert(__traits(isRef, x));
static assert(!__traits(isOut, x));
static assert(!__traits(isLazy, x));
}
void fooout(out int x)
{
static assert(!__traits(isRef, x));
static assert(__traits(isOut, x));
static assert(!__traits(isLazy, x));
}
void foolazy(lazy int x)
{
static assert(!__traits(isRef, x));
static assert(!__traits(isOut, x));
static assert(__traits(isLazy, x));
}
}
/********************************************************/
void test21()
{
assert(__traits(isStaticFunction, C.bar) == false);
assert(__traits(isStaticFunction, C.abc) == true);
assert(__traits(isStaticFunction, S.bar) == false);
}
/********************************************************/
class D22
{
this() { }
~this() { }
void foo() { }
int foo(int) { return 2; }
}
void test22()
{
D22 d = new D22();
foreach (t; __traits(getOverloads, D22, "foo"))
writeln(typeid(typeof(t)));
alias typeof(__traits(getOverloads, D22, "foo")) b;
foreach (t; b)
writeln(typeid(t));
auto i = __traits(getOverloads, d, "foo")[1](1);
assert(i == 2);
}
/********************************************************/
string toString23(E)(E value) if (is(E == enum)) {
foreach (s; __traits(allMembers, E)) {
if (value == mixin("E." ~ s)) return s;
}
return null;
}
enum OddWord { acini, alembicated, prolegomena, aprosexia }
void test23()
{
auto w = OddWord.alembicated;
assert(toString23(w) == "alembicated");
}
/********************************************************/
struct Test24
{
public void test24(int){}
private void test24(int, int){}
}
static assert(__traits(getVisibility, __traits(getOverloads, Test24, "test24")[1]) == "private");
/********************************************************/
// 1369
void test1369()
{
class C1
{
static int count;
void func() { count++; }
}
// variable symbol
C1 c1 = new C1;
__traits(getMember, c1, "func")(); // TypeIdentifier -> VarExp
__traits(getMember, mixin("c1"), "func")(); // Expression -> VarExp
assert(C1.count == 2);
// nested function symbol
@property C1 get() { return c1; }
__traits(getMember, get, "func")();
__traits(getMember, mixin("get"), "func")();
assert(C1.count == 4);
class C2
{
C1 c1;
this() { c1 = new C1; }
void test()
{
// variable symbol (this.outer.c1)
__traits(getMember, c1, "func")(); // TypeIdentifier -> VarExp -> DotVarExp
__traits(getMember, mixin("c1"), "func")(); // Expression -> VarExp -> DotVarExp
assert(C1.count == 6);
// nested function symbol (this.outer.get)
__traits(getMember, get, "func")();
__traits(getMember, mixin("get"), "func")();
assert(C1.count == 8);
}
}
C2 c2 = new C2;
c2.test();
}
/********************************************************/
template Foo2234(){ int x; }
struct S2234a{ mixin Foo2234; }
struct S2234b{ mixin Foo2234; mixin Foo2234; }
struct S2234c{ alias Foo2234!() foo; }
static assert([__traits(allMembers, S2234a)] == ["x"]);
static assert([__traits(allMembers, S2234b)] == ["x"]);
static assert([__traits(allMembers, S2234c)] == ["foo"]);
/********************************************************/
// 5878
template J5878(A)
{
static if (is(A P == super))
alias P J5878;
}
alias J5878!(A5878) Z5878;
class X5878 {}
class A5878 : X5878 {}
/********************************************************/
mixin template Members6674()
{
static int i1;
static int i2;
static int i3; //comment out to make func2 visible
static int i4; //comment out to make func1 visible
}
class Test6674
{
mixin Members6674;
alias void function() func1;
alias bool function() func2;
}
static assert([__traits(allMembers,Test6674)] == [
"i1","i2","i3","i4",
"func1","func2",
"toString","toHash","opCmp","opEquals","Monitor","factory"]);
/********************************************************/
// 6073
struct S6073 {}
template T6073(M...) {
//alias int T;
}
alias T6073!traits V6073; // ok
alias T6073!(__traits(parent, S6073)) U6073; // error
static assert(__traits(isSame, V6073, U6073)); // same instantiation == same arguemnts
/********************************************************/
// 7027
struct Foo7027 { int a; }
static assert(!__traits(compiles, { return Foo7027.a; }));
/********************************************************/
// 9213
class Foo9213 { int a; }
static assert(!__traits(compiles, { return Foo9213.a; }));
/********************************************************/
interface AA
{
int YYY();
}
class CC : AA
{
final int YYY() { return 4; }
}
static assert(__traits(isVirtualMethod, CC.YYY));
static assert(__traits(getVirtualMethods, CC, "YYY").length == 1);
class DD
{
final int YYY() { return 4; }
}
static assert(__traits(isVirtualMethod, DD.YYY) == false);
static assert(__traits(getVirtualMethods, DD, "YYY").length == 0);
class EE
{
int YYY() { return 0; }
}
class FF : EE
{
final override int YYY() { return 4; }
}
static assert(__traits(isVirtualMethod, FF.YYY));
static assert(__traits(getVirtualMethods, FF, "YYY").length == 1);
/********************************************************/
// 7608
struct S7608a(bool T)
{
static if (T) { int x; }
int y;
}
struct S7608b
{
version(none) { int x; }
int y;
}
template TypeTuple7608(T...){ alias T TypeTuple7608; }
void test7608()
{
alias TypeTuple7608!(__traits(allMembers, S7608a!false)) MembersA;
static assert(MembersA.length == 1);
static assert(MembersA[0] == "y");
alias TypeTuple7608!(__traits(allMembers, S7608b)) MembersB;
static assert(MembersB.length == 1);
static assert(MembersB[0] == "y");
}
/********************************************************/
// 7858
void test7858()
{
class C
{
final void ffunc(){}
final void ffunc(int){}
void vfunc(){}
void vfunc(int){}
abstract void afunc();
abstract void afunc(int);
static void sfunc(){}
static void sfunc(int){}
}
static assert(__traits(isFinalFunction, C.ffunc) ==
__traits(isFinalFunction, __traits(getOverloads, C, "ffunc")[0])); // NG
static assert(__traits(isVirtualFunction, C.vfunc) ==
__traits(isVirtualFunction, __traits(getOverloads, C, "vfunc")[0])); // NG
static assert(__traits(isVirtualMethod, C.vfunc) ==
__traits(isVirtualMethod, __traits(getOverloads, C, "vfunc")[0])); // NG
static assert(__traits(isAbstractFunction, C.afunc) ==
__traits(isAbstractFunction, __traits(getOverloads, C, "afunc")[0])); // OK
static assert(__traits(isStaticFunction, C.sfunc) ==
__traits(isStaticFunction, __traits(getOverloads, C, "sfunc")[0])); // OK
static assert(__traits(isSame, C.ffunc, __traits(getOverloads, C, "ffunc")[0])); // NG
static assert(__traits(isSame, C.vfunc, __traits(getOverloads, C, "vfunc")[0])); // NG
static assert(__traits(isSame, C.afunc, __traits(getOverloads, C, "afunc")[0])); // NG
static assert(__traits(isSame, C.sfunc, __traits(getOverloads, C, "sfunc")[0])); // NG
}
/********************************************************/
// 8971
template Tuple8971(TL...){ alias TL Tuple8971; }
class A8971
{
void bar() {}
void connect()
{
alias Tuple8971!(__traits(getOverloads, typeof(this), "bar")) overloads;
static assert(__traits(isSame, overloads[0], bar));
}
}
/********************************************************/
// 8972
struct A8972
{
void foo() {}
void connect()
{
alias Tuple8971!(__traits(getOverloads, typeof(this), "foo")) overloads;
static assert(__traits(isSame, overloads[0], foo));
}
}
/********************************************************/
private struct TestProt1 {}
package struct TestProt2 {}
protected struct TestProt3 {}
public struct TestProt4 {}
export struct TestProt5 {}
void getVisibility()
{
class Test
{
private { int va; void fa(){} }
package { int vb; void fb(){} }
protected { int vc; void fc(){} }
public { int vd; void fd(){} }
export { int ve; void fe(){} }
}
Test t;
// TOKvar and VarDeclaration
static assert(__traits(getVisibility, Test.va) == "private");
static assert(__traits(getVisibility, Test.vb) == "package");
static assert(__traits(getVisibility, Test.vc) == "protected");
static assert(__traits(getVisibility, Test.vd) == "public");
static assert(__traits(getVisibility, Test.ve) == "export");
// TOKdotvar and VarDeclaration
static assert(__traits(getVisibility, t.va) == "private");
static assert(__traits(getVisibility, t.vb) == "package");
static assert(__traits(getVisibility, t.vc) == "protected");
static assert(__traits(getVisibility, t.vd) == "public");
static assert(__traits(getVisibility, t.ve) == "export");
// TOKvar and FuncDeclaration
static assert(__traits(getVisibility, Test.fa) == "private");
static assert(__traits(getVisibility, Test.fb) == "package");
static assert(__traits(getVisibility, Test.fc) == "protected");
static assert(__traits(getVisibility, Test.fd) == "public");
static assert(__traits(getVisibility, Test.fe) == "export");
// TOKdotvar and FuncDeclaration
static assert(__traits(getVisibility, t.fa) == "private");
static assert(__traits(getVisibility, t.fb) == "package");
static assert(__traits(getVisibility, t.fc) == "protected");
static assert(__traits(getVisibility, t.fd) == "public");
static assert(__traits(getVisibility, t.fe) == "export");
// TOKtype
static assert(__traits(getVisibility, TestProt1) == "private");
static assert(__traits(getVisibility, TestProt2) == "package");
static assert(__traits(getVisibility, TestProt3) == "protected");
static assert(__traits(getVisibility, TestProt4) == "public");
static assert(__traits(getVisibility, TestProt5) == "export");
// This specific pattern is important to ensure it always works
// through reflection, however that becomes implemented
static assert(__traits(getVisibility, __traits(getMember, t, "va")) == "private");
static assert(__traits(getVisibility, __traits(getMember, t, "vb")) == "package");
static assert(__traits(getVisibility, __traits(getMember, t, "vc")) == "protected");
static assert(__traits(getVisibility, __traits(getMember, t, "vd")) == "public");
static assert(__traits(getVisibility, __traits(getMember, t, "ve")) == "export");
static assert(__traits(getVisibility, __traits(getMember, t, "fa")) == "private");
static assert(__traits(getVisibility, __traits(getMember, t, "fb")) == "package");
static assert(__traits(getVisibility, __traits(getMember, t, "fc")) == "protected");
static assert(__traits(getVisibility, __traits(getMember, t, "fd")) == "public");
static assert(__traits(getVisibility, __traits(getMember, t, "fe")) == "export");
}
/********************************************************/
// 9546
void test9546()
{
import imports.a9546 : S;
S s;
static assert(__traits(getVisibility, s.privA) == "private");
static assert(__traits(getVisibility, s.protA) == "protected");
static assert(__traits(getVisibility, s.packA) == "package");
static assert(__traits(getVisibility, S.privA) == "private");
static assert(__traits(getVisibility, S.protA) == "protected");
static assert(__traits(getVisibility, S.packA) == "package");
static assert(__traits(getVisibility, mixin("s.privA")) == "private");
static assert(__traits(getVisibility, mixin("s.protA")) == "protected");
static assert(__traits(getVisibility, mixin("s.packA")) == "package");
static assert(__traits(getVisibility, mixin("S.privA")) == "private");
static assert(__traits(getVisibility, mixin("S.protA")) == "protected");
static assert(__traits(getVisibility, mixin("S.packA")) == "package");
static assert(__traits(getVisibility, __traits(getMember, s, "privA")) == "private");
static assert(__traits(getVisibility, __traits(getMember, s, "protA")) == "protected");
static assert(__traits(getVisibility, __traits(getMember, s, "packA")) == "package");
static assert(__traits(getVisibility, __traits(getMember, S, "privA")) == "private");
static assert(__traits(getVisibility, __traits(getMember, S, "protA")) == "protected");
static assert(__traits(getVisibility, __traits(getMember, S, "packA")) == "package");
static assert(__traits(getVisibility, s.privF) == "private");
static assert(__traits(getVisibility, s.protF) == "protected");
static assert(__traits(getVisibility, s.packF) == "package");
static assert(__traits(getVisibility, S.privF) == "private");
static assert(__traits(getVisibility, S.protF) == "protected");
static assert(__traits(getVisibility, S.packF) == "package");
static assert(__traits(getVisibility, mixin("s.privF")) == "private");
static assert(__traits(getVisibility, mixin("s.protF")) == "protected");
static assert(__traits(getVisibility, mixin("s.packF")) == "package");
static assert(__traits(getVisibility, mixin("S.privF")) == "private");
static assert(__traits(getVisibility, mixin("S.protF")) == "protected");
static assert(__traits(getVisibility, mixin("S.packF")) == "package");
static assert(__traits(getVisibility, __traits(getMember, s, "privF")) == "private");
static assert(__traits(getVisibility, __traits(getMember, s, "protF")) == "protected");
static assert(__traits(getVisibility, __traits(getMember, s, "packF")) == "package");
static assert(__traits(getVisibility, __traits(getMember, S, "privF")) == "private");
static assert(__traits(getVisibility, __traits(getMember, S, "protF")) == "protected");
static assert(__traits(getVisibility, __traits(getMember, S, "packF")) == "package");
}
/********************************************************/
// 9091
template isVariable9091(X...) if (X.length == 1)
{
enum isVariable9091 = true;
}
class C9091
{
int x; // some class members
void func(int n){ this.x = n; }
void test()
{
alias T = C9091;
enum is_x = isVariable9091!(__traits(getMember, T, "x"));
foreach (i, m; __traits(allMembers, T))
{
enum x = isVariable9091!(__traits(getMember, T, m));
static if (i == 0) // x
{
__traits(getMember, T, m) = 10;
assert(this.x == 10);
}
static if (i == 1) // func
{
__traits(getMember, T, m)(20);
assert(this.x == 20);
}
}
}
}
struct S9091
{
int x; // some struct members
void func(int n){ this.x = n; }
void test()
{
alias T = S9091;
enum is_x = isVariable9091!(__traits(getMember, T, "x"));
foreach (i, m; __traits(allMembers, T))
{
enum x = isVariable9091!(__traits(getMember, T, m));
static if (i == 0) // x
{
__traits(getMember, T, m) = 10;
assert(this.x == 10);
}
static if (i == 1) // func
{
__traits(getMember, T, m)(20);
assert(this.x == 20);
}
}
}
}
void test9091()
{
auto c = new C9091();
c.test();
auto s = S9091();
s.test();
}
/********************************************************/
struct CtorS_9237 { this(int x) { } } // ctor -> POD
struct DtorS_9237 { ~this() { } } // dtor -> nonPOD
struct PostblitS_9237 { this(this) { } } // cpctor -> nonPOD
struct NonPOD1_9237
{
DtorS_9237 field; // nonPOD -> ng
}
struct NonPOD2_9237
{
DtorS_9237[2] field; // static array of nonPOD -> ng
}
struct POD1_9237
{
DtorS_9237* field; // pointer to nonPOD -> ok
}
struct POD2_9237
{
DtorS_9237[] field; // dynamic array of nonPOD -> ok
}
struct POD3_9237
{
int x = 123;
}
class C_9273 { }
void test9237()
{
int x;
struct NS_9237 // acceses .outer -> nested
{
void foo() { x++; }
}
struct NonNS_9237 { } // doesn't access .outer -> non-nested
static struct StatNS_9237 { } // can't access .outer -> non-nested
static assert(!__traits(isPOD, NS_9237));
static assert(__traits(isPOD, NonNS_9237));
static assert(__traits(isPOD, StatNS_9237));
static assert(__traits(isPOD, CtorS_9237));
static assert(!__traits(isPOD, DtorS_9237));
static assert(!__traits(isPOD, PostblitS_9237));
static assert(!__traits(isPOD, NonPOD1_9237));
static assert(!__traits(isPOD, NonPOD2_9237));
static assert(__traits(isPOD, POD1_9237));
static assert(__traits(isPOD, POD2_9237));
static assert(__traits(isPOD, POD3_9237));
// static array of POD/non-POD types
static assert(!__traits(isPOD, NS_9237[2]));
static assert(__traits(isPOD, NonNS_9237[2]));
static assert(__traits(isPOD, StatNS_9237[2]));
static assert(__traits(isPOD, CtorS_9237[2]));
static assert(!__traits(isPOD, DtorS_9237[2]));
static assert(!__traits(isPOD, PostblitS_9237[2]));
static assert(!__traits(isPOD, NonPOD1_9237[2]));
static assert(!__traits(isPOD, NonPOD2_9237[2]));
static assert(__traits(isPOD, POD1_9237[2]));
static assert(__traits(isPOD, POD2_9237[2]));
static assert(__traits(isPOD, POD3_9237[2]));
// non-structs are POD types
static assert(__traits(isPOD, C_9273));
static assert(__traits(isPOD, int));
static assert(__traits(isPOD, int*));
static assert(__traits(isPOD, int[]));
static assert(!__traits(compiles, __traits(isPOD, 123) ));
}
/*************************************************************/
// 5978
void test5978()
{
() {
int x;
pragma(msg, __traits(identifier, __traits(parent, x)));
} ();
}
/*************************************************************/
template T7408() { }
void test7408()
{
auto x = T7408!().stringof;
auto y = T7408!().mangleof;
static assert(__traits(compiles, T7408!().stringof));
static assert(__traits(compiles, T7408!().mangleof));
static assert(!__traits(compiles, T7408!().init));
static assert(!__traits(compiles, T7408!().offsetof));
}
/*************************************************************/
// 9552
class C9552
{
int f() { return 10; }
int f(int n) { return n * 2; }
}
void test9552()
{
auto c = new C9552;
auto dg1 = &(__traits(getOverloads, c, "f")[0]); // DMD crashes
assert(dg1() == 10);
auto dg2 = &(__traits(getOverloads, c, "f")[1]);
assert(dg2(10) == 20);
}
/*************************************************************/
void test9136()
{
int x;
struct S1 { void f() { x++; } }
struct U1 { void f() { x++; } }
static struct S2 { }
static struct S3 { S1 s; }
static struct U2 { }
void f1() { x++; }
static void f2() { }
static assert(__traits(isNested, S1));
static assert(__traits(isNested, U1));
static assert(!__traits(isNested, S2));
static assert(!__traits(isNested, S3));
static assert(!__traits(isNested, U2));
static assert(!__traits(compiles, __traits(isNested, int) ));
static assert(!__traits(compiles, __traits(isNested, f1, f2) ));
static assert(__traits(isNested, f1));
static assert(!__traits(isNested, f2));
static class A { static class SC { } class NC { } }
static assert(!__traits(isNested, A));
static assert(!__traits(isNested, A.SC));
static assert(__traits(isNested, A.NC));
}
/********************************************************/
// 9939
struct Test9939
{
int f;
enum /*Anonymous enum*/
{
A,
B
}
enum NamedEnum
{
C,
D
}
}
static assert([__traits(allMembers, Test9939)] == ["f", "A", "B", "NamedEnum"]);
/********************************************************/
// 10043
void test10043()
{
struct X {}
X d1;
static assert(!__traits(compiles, d1.structuralCast!Refleshable));
}
/********************************************************/
// 10096
struct S10096X
{
string str;
invariant() {}
invariant() {}
unittest {}
unittest {}
this(int) {}
this(this) {}
~this() {}
string getStr() in { assert(str); } out(r) { assert(r == str); } body { return str; }
}
static assert(
[__traits(allMembers, S10096X)] ==
["str", "__ctor", "__postblit", "__dtor", "getStr", "__xdtor", "__xpostblit", "opAssign"]);
class C10096X
{
string str;
invariant() {}
invariant() {}
unittest {}
unittest {}
this(int) {}
~this() {}
string getStr() in { assert(str); } out(r) { assert(r == str); } body { return str; }
}
static assert(
[__traits(allMembers, C10096X)] ==
["str", "__ctor", "__dtor", "getStr", "__xdtor", "toString", "toHash", "opCmp", "opEquals", "Monitor", "factory"]);
// --------
string foo10096(alias var, T = typeof(var))()
{
foreach (idx, member; __traits(allMembers, T))
{
auto x = var.tupleof[idx];
}
return "";
}
string foo10096(T)(T var)
{
return "";
}
struct S10096
{
int i;
string s;
}
void test10096()
{
S10096 s = S10096(1, "");
auto x = foo10096!s;
}
/********************************************************/
unittest { }
struct GetUnitTests
{
unittest { }
}
void test_getUnitTests ()
{
// Always returns empty tuple if the -unittest flag isn't used
static assert(__traits(getUnitTests, mixin(__MODULE__)).length == 0);
static assert(__traits(getUnitTests, GetUnitTests).length == 0);
}
/********************************************************/
void test_getFunctionAttributes()
{
alias tuple(T...) = T;
struct S
{
int noF() { return 0; }
int constF() const { return 0; }
int immutableF() immutable { return 0; }
int inoutF() inout { return 0; }
int sharedF() shared { return 0; }
int x;
ref int refF() { return x; }
int propertyF() @property { return 0; }
int nothrowF() nothrow { return 0; }
int nogcF() @nogc { return 0; }
int systemF() @system { return 0; }
int trustedF() @trusted { return 0; }
int safeF() @safe { return 0; }
int pureF() pure { return 0; }
}
static assert(__traits(getFunctionAttributes, S.noF) == tuple!("@system"));
static assert(__traits(getFunctionAttributes, typeof(S.noF)) == tuple!("@system"));
static assert(__traits(getFunctionAttributes, S.constF) == tuple!("const", "@system"));
static assert(__traits(getFunctionAttributes, typeof(S.constF)) == tuple!("const", "@system"));
static assert(__traits(getFunctionAttributes, S.immutableF) == tuple!("immutable", "@system"));
static assert(__traits(getFunctionAttributes, typeof(S.immutableF)) == tuple!("immutable", "@system"));
static assert(__traits(getFunctionAttributes, S.inoutF) == tuple!("inout", "@system"));
static assert(__traits(getFunctionAttributes, typeof(S.inoutF)) == tuple!("inout", "@system"));
static assert(__traits(getFunctionAttributes, S.sharedF) == tuple!("shared", "@system"));
static assert(__traits(getFunctionAttributes, typeof(S.sharedF)) == tuple!("shared", "@system"));
static assert(__traits(getFunctionAttributes, S.refF) == tuple!("ref", "@system"));
static assert(__traits(getFunctionAttributes, typeof(S.refF)) == tuple!("ref", "@system"));
static assert(__traits(getFunctionAttributes, S.propertyF) == tuple!("@property", "@system"));
static assert(__traits(getFunctionAttributes, typeof(&S.propertyF)) == tuple!("@property", "@system"));
static assert(__traits(getFunctionAttributes, S.nothrowF) == tuple!("nothrow", "@system"));
static assert(__traits(getFunctionAttributes, typeof(S.nothrowF)) == tuple!("nothrow", "@system"));
static assert(__traits(getFunctionAttributes, S.nogcF) == tuple!("@nogc", "@system"));
static assert(__traits(getFunctionAttributes, typeof(S.nogcF)) == tuple!("@nogc", "@system"));
static assert(__traits(getFunctionAttributes, S.systemF) == tuple!("@system"));
static assert(__traits(getFunctionAttributes, typeof(S.systemF)) == tuple!("@system"));
static assert(__traits(getFunctionAttributes, S.trustedF) == tuple!("@trusted"));
static assert(__traits(getFunctionAttributes, typeof(S.trustedF)) == tuple!("@trusted"));
static assert(__traits(getFunctionAttributes, S.safeF) == tuple!("@safe"));
static assert(__traits(getFunctionAttributes, typeof(S.safeF)) == tuple!("@safe"));
static assert(__traits(getFunctionAttributes, S.pureF) == tuple!("pure", "@system"));
static assert(__traits(getFunctionAttributes, typeof(S.pureF)) == tuple!("pure", "@system"));
int pure_nothrow() nothrow pure { return 0; }
static ref int static_ref_property() @property { return *(new int); }
ref int ref_property() @property { return *(new int); }
void safe_nothrow() @safe nothrow { }
static assert(__traits(getFunctionAttributes, pure_nothrow) == tuple!("pure", "nothrow", "@nogc", "@safe"));
static assert(__traits(getFunctionAttributes, typeof(pure_nothrow)) == tuple!("pure", "nothrow", "@nogc", "@safe"));
static assert(__traits(getFunctionAttributes, static_ref_property) == tuple!("pure", "nothrow", "@property", "ref", "@safe"));
static assert(__traits(getFunctionAttributes, typeof(&static_ref_property)) == tuple!("pure", "nothrow", "@property", "ref", "@safe"));
static assert(__traits(getFunctionAttributes, ref_property) == tuple!("pure", "nothrow", "@property", "ref", "@safe"));
static assert(__traits(getFunctionAttributes, typeof(&ref_property)) == tuple!("pure", "nothrow", "@property", "ref", "@safe"));
static assert(__traits(getFunctionAttributes, safe_nothrow) == tuple!("pure", "nothrow", "@nogc", "@safe"));
static assert(__traits(getFunctionAttributes, typeof(safe_nothrow)) == tuple!("pure", "nothrow", "@nogc", "@safe"));
struct S2
{
int pure_const() const pure { return 0; }
int pure_sharedconst() const shared pure { return 0; }
}
static assert(__traits(getFunctionAttributes, S2.pure_const) == tuple!("const", "pure", "@system"));
static assert(__traits(getFunctionAttributes, typeof(S2.pure_const)) == tuple!("const", "pure", "@system"));
static assert(__traits(getFunctionAttributes, S2.pure_sharedconst) == tuple!("const", "shared", "pure", "@system"));
static assert(__traits(getFunctionAttributes, typeof(S2.pure_sharedconst)) == tuple!("const", "shared", "pure", "@system"));
static assert(__traits(getFunctionAttributes, (int a) { }) == tuple!("pure", "nothrow", "@nogc", "@safe"));
static assert(__traits(getFunctionAttributes, typeof((int a) { })) == tuple!("pure", "nothrow", "@nogc", "@safe"));
auto safeDel = delegate() @safe { };
static assert(__traits(getFunctionAttributes, safeDel) == tuple!("pure", "nothrow", "@nogc", "@safe"));
static assert(__traits(getFunctionAttributes, typeof(safeDel)) == tuple!("pure", "nothrow", "@nogc", "@safe"));
auto trustedDel = delegate() @trusted { };
static assert(__traits(getFunctionAttributes, trustedDel) == tuple!("pure", "nothrow", "@nogc", "@trusted"));
static assert(__traits(getFunctionAttributes, typeof(trustedDel)) == tuple!("pure", "nothrow", "@nogc", "@trusted"));
auto systemDel = delegate() @system { };
static assert(__traits(getFunctionAttributes, systemDel) == tuple!("pure", "nothrow", "@nogc", "@system"));
static assert(__traits(getFunctionAttributes, typeof(systemDel)) == tuple!("pure", "nothrow", "@nogc", "@system"));
}
/********************************************************/
class TestIsOverrideFunctionBase
{
void bar () {}
}
class TestIsOverrideFunctionPass : TestIsOverrideFunctionBase
{
override void bar () {}
}
void test_isOverrideFunction ()
{
assert(__traits(isOverrideFunction, TestIsOverrideFunctionPass.bar) == true);
assert(__traits(isOverrideFunction, TestIsOverrideFunctionBase.bar) == false);
}
/********************************************************/
// 11711 - Add __traits(getAliasThis)
alias TypeTuple(T...) = T;
void test11711()
{
struct S1
{
string var;
alias var this;
}
static assert(__traits(getAliasThis, S1) == TypeTuple!("var"));
static assert(is(typeof(__traits(getMember, S1.init, __traits(getAliasThis, S1)[0]))
== string));
struct S2
{
TypeTuple!(int, string) var;
alias var this;
}
static assert(__traits(getAliasThis, S2) == TypeTuple!("var"));
static assert(is(typeof(__traits(getMember, S2.init, __traits(getAliasThis, S2)[0]))
== TypeTuple!(int, string)));
}
/********************************************************/
// Issue 12278
class Foo12278
{
InPlace12278!Bar12278 inside;
}
class Bar12278 { }
struct InPlace12278(T)
{
static assert(__traits(classInstanceSize, T) != 0);
}
/********************************************************/
// 12571
mixin template getScopeName12571()
{
enum string scopeName = __traits(identifier, __traits(parent, scopeName));
}
void test12571()
{
mixin getScopeName12571;
static assert(scopeName == "test12571");
}
/********************************************************/
// 12237
auto f12237(T)(T a)
{
static if (is(typeof(a) == int))
return f12237("");
else
return 10;
}
void test12237()
{
assert(f12237(1) == 10);
assert((a){
static if (is(typeof(a) == int))
{
int x;
return __traits(parent, x)("");
}
else
return 10;
}(1) == 10);
}
/********************************************************/
void async(ARGS...)(ARGS)
{
static void compute(ARGS)
{
}
auto x = __traits(getParameterStorageClasses, compute, 1);
}
alias test17495 = async!(int, int);
/********************************************************/
// 15094
void test15094()
{
static struct Foo { int i; }
static struct Bar { Foo foo; }
Bar bar;
auto n = __traits(getMember, bar.foo, "i");
assert(n == bar.foo.i);
}
/********************************************************/
void testIsDisabled()
{
static assert(__traits(isDisabled, D1.true_));
static assert(!__traits(isDisabled, D1.false_));
static assert(!__traits(isDisabled, D1));
}
/********************************************************/
// https://issues.dlang.org/show_bug.cgi?id=10100
enum E10100
{
value,
_value,
__value,
___value,
____value,
}
static assert(
[__traits(allMembers, E10100)] ==
["value", "_value", "__value", "___value", "____value"]);
/********************************************************/
int main()
{
test1();
test2();
test3();
test4();
test5();
test6();
test7();
test8();
test9();
test10();
test11();
test12();
test13();
test7123();
test14();
test15();
test16();
test17();
test18();
test19();
test20();
test21();
test22();
test23();
test1369();
test7608();
test7858();
test9091();
test5978();
test7408();
test9552();
test9136();
test10096();
test_getUnitTests();
test_getFunctionAttributes();
test_isOverrideFunction();
test12237();
test15094();
writeln("Success");
return 0;
}