Update traits completion
This commit is contained in:
parent
5c3e15b58a
commit
e6e6e8e174
|
|
@ -23,7 +23,8 @@ immutable ConstantCompletion[] traits = [
|
||||||
ConstantCompletion("allMembers", `$(P Takes a single argument, which must evaluate to either
|
ConstantCompletion("allMembers", `$(P Takes a single argument, which must evaluate to either
|
||||||
a module, a struct, a union, a class, an interface, an enum, or a
|
a module, a struct, a union, a class, an interface, an enum, or a
|
||||||
template instantiation.
|
template instantiation.
|
||||||
|
)
|
||||||
|
$(P
|
||||||
A sequence of string literals is returned, each of which
|
A sequence of string literals is returned, each of which
|
||||||
is the name of a member of that argument combined with all
|
is the name of a member of that argument combined with all
|
||||||
of the members of its base classes (if the argument is a class).
|
of the members of its base classes (if the argument is a class).
|
||||||
|
|
@ -120,14 +121,27 @@ polymorphic type.
|
||||||
compile (are semantically correct).
|
compile (are semantically correct).
|
||||||
The arguments can be symbols, types, or expressions that
|
The arguments can be symbols, types, or expressions that
|
||||||
are syntactically correct.
|
are syntactically correct.
|
||||||
The arguments cannot be statements or declarations.
|
The arguments cannot be statements or declarations - instead
|
||||||
|
these can be wrapped in a $(DDSUBLINK spec/expression, function_literals,
|
||||||
|
function literal) expression.
|
||||||
)
|
)
|
||||||
|
|
||||||
$(P If there are no arguments, the result is $(D false).)
|
$(P If there are no arguments, the result is $(D false).)
|
||||||
|
|
||||||
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
---
|
---
|
||||||
import std.stdio;
|
static assert(!__traits(compiles));
|
||||||
|
static assert(__traits(compiles, 1 + 1)); // expression
|
||||||
|
static assert(__traits(compiles, typeof(1))); // type
|
||||||
|
static assert(__traits(compiles, object)); // symbol
|
||||||
|
static assert(__traits(compiles, 1, 2, 3, int, long));
|
||||||
|
static assert(!__traits(compiles, 3[1])); // semantic error
|
||||||
|
static assert(!__traits(compiles, 1, 2, 3, int, long, 3[1]));
|
||||||
|
|
||||||
|
enum n = 3;
|
||||||
|
// wrap a declaration/statement in a function literal
|
||||||
|
static assert(__traits(compiles, { int[n] arr; }));
|
||||||
|
static assert(!__traits(compiles, { foreach (e; n) {} }));
|
||||||
|
|
||||||
struct S
|
struct S
|
||||||
{
|
{
|
||||||
|
|
@ -135,29 +149,23 @@ struct S
|
||||||
int s2;
|
int s2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int foo();
|
static assert(__traits(compiles, S.s1 = 0));
|
||||||
int bar();
|
static assert(!__traits(compiles, S.s2 = 0));
|
||||||
|
static assert(!__traits(compiles, S.s3));
|
||||||
|
|
||||||
void main()
|
int foo();
|
||||||
{
|
|
||||||
writeln(__traits(compiles)); // false
|
static assert(__traits(compiles, foo));
|
||||||
writeln(__traits(compiles, foo)); // true
|
static assert(__traits(compiles, foo + 1)); // call foo with optional parens
|
||||||
writeln(__traits(compiles, foo + 1)); // true
|
static assert(!__traits(compiles, &foo + 1));
|
||||||
writeln(__traits(compiles, &foo + 1)); // false
|
|
||||||
writeln(__traits(compiles, typeof(1))); // true
|
|
||||||
writeln(__traits(compiles, S.s1)); // true
|
|
||||||
writeln(__traits(compiles, S.s3)); // false
|
|
||||||
writeln(__traits(compiles, 1,2,3,int,long,std)); // true
|
|
||||||
writeln(__traits(compiles, 3[1])); // false
|
|
||||||
writeln(__traits(compiles, 1,2,3,int,long,3[1])); // false
|
|
||||||
}
|
|
||||||
---
|
---
|
||||||
)
|
)
|
||||||
|
|
||||||
$(P This is useful for:)
|
$(P This is useful for:)
|
||||||
|
|
||||||
$(UL
|
$(UL
|
||||||
$(LI Giving better error messages inside generic code than
|
$(LI Giving better error messages (using $(DDSUBLINK spec/version, static-assert,
|
||||||
|
` ~ "`" ~ `static assert` ~ "`" ~ `)) inside generic code than
|
||||||
the sometimes hard to follow compiler ones.)
|
the sometimes hard to follow compiler ones.)
|
||||||
$(LI Doing a finer grained specialization than template
|
$(LI Doing a finer grained specialization than template
|
||||||
partial specialization allows for.)
|
partial specialization allows for.)
|
||||||
|
|
@ -193,6 +201,53 @@ void main()
|
||||||
|
|
||||||
$(P The order in which the strings appear in the result
|
$(P The order in which the strings appear in the result
|
||||||
is not defined.)`),
|
is not defined.)`),
|
||||||
|
ConstantCompletion("fullyQualifiedName", `$(P Gets the fully qualified name of a type or symbol.)
|
||||||
|
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
|
-----------------
|
||||||
|
module myModule;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
static assert(__traits(fullyQualifiedName, i) == "myModule.i");
|
||||||
|
|
||||||
|
struct MyStruct {}
|
||||||
|
static assert(__traits(fullyQualifiedName, const MyStruct[]) == "const(myModule.MyStruct[])");
|
||||||
|
-----------------
|
||||||
|
)`),
|
||||||
|
ConstantCompletion("fullyQualifiedName", `$(P Takes one argument, which can be a type, expression, or symbol, and returns a string.)
|
||||||
|
|
||||||
|
$(UL
|
||||||
|
$(LI A $(D type) returns a string representing the type.)
|
||||||
|
$(LI A $(D expression) returns a string representing the type of the expression.)
|
||||||
|
$(LI A $(D symbol) returns a string representing the fully qualified name of the symbol.)
|
||||||
|
)
|
||||||
|
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
|
---
|
||||||
|
module plugh;
|
||||||
|
import std.stdio;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
auto s = __traits(fullyQualifiedName, int);
|
||||||
|
writeln(s);
|
||||||
|
|
||||||
|
auto t = __traits(fullyQualifiedName, 1.0);
|
||||||
|
writeln(t);
|
||||||
|
|
||||||
|
auto u = __traits(fullyQualifiedName, t);
|
||||||
|
writeln(u);
|
||||||
|
}
|
||||||
|
---
|
||||||
|
)
|
||||||
|
|
||||||
|
Prints:
|
||||||
|
|
||||||
|
$(CONSOLE
|
||||||
|
int
|
||||||
|
double
|
||||||
|
plugh.main.t
|
||||||
|
)`),
|
||||||
ConstantCompletion("getAliasThis", `$(P Takes one argument, a type. If the type has ` ~ "`" ~ `alias this` ~ "`" ~ ` declarations,
|
ConstantCompletion("getAliasThis", `$(P Takes one argument, a type. If the type has ` ~ "`" ~ `alias this` ~ "`" ~ ` declarations,
|
||||||
returns a *ValueSeq* of the names (as ` ~ "`" ~ `string` ~ "`" ~ `s) of the members used in
|
returns a *ValueSeq* of the names (as ` ~ "`" ~ `string` ~ "`" ~ `s) of the members used in
|
||||||
those declarations. Otherwise returns an empty sequence.
|
those declarations. Otherwise returns an empty sequence.
|
||||||
|
|
@ -251,6 +306,49 @@ tuple(3)
|
||||||
tuple("string", 7)
|
tuple("string", 7)
|
||||||
tuple((Foo))
|
tuple((Foo))
|
||||||
)
|
)
|
||||||
|
)`),
|
||||||
|
ConstantCompletion("getBitfieldOffset", `$(P Takes one argument, a qualified name that resolve to a field in a struct or class.
|
||||||
|
)
|
||||||
|
$(P If the field is a bitfield, it returns as a ` ~ "`" ~ `uint` ~ "`" ~ ` the bit number of the least significant
|
||||||
|
bit in the field. The rightmost bit is at offset 0, the leftmost bit is at offset 31 (for
|
||||||
|
32 bit int fields).
|
||||||
|
)
|
||||||
|
$(P If the field is a not bitfield, it returns as a ` ~ "`" ~ `uint` ~ "`" ~ ` the number 0.
|
||||||
|
)
|
||||||
|
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
|
---
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
int a,b;
|
||||||
|
int :2, c:3;
|
||||||
|
}
|
||||||
|
|
||||||
|
static assert(__traits(getBitfieldOffset, S.b) == 0);
|
||||||
|
static assert(__traits(getBitfieldOffset, S.c) == 2);
|
||||||
|
---
|
||||||
|
)
|
||||||
|
|
||||||
|
)`),
|
||||||
|
ConstantCompletion("getBitfieldWidth", `$(P Takes one argument, a qualified name that resolve to a field in a struct or class.
|
||||||
|
)
|
||||||
|
$(P If the field is a bitfield, it returns as a ` ~ "`" ~ `uint` ~ "`" ~ ` the width of the bit field as
|
||||||
|
a number of bits.
|
||||||
|
)
|
||||||
|
$(P If the field is a not bitfield, it returns the number of bits in the type.
|
||||||
|
)
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
|
---
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
int a,b;
|
||||||
|
int :2, c:3;
|
||||||
|
}
|
||||||
|
|
||||||
|
static assert(__traits(getBitfieldWidth, S.b) == 32);
|
||||||
|
static assert(__traits(getBitfieldWidth, S.c) == 3);
|
||||||
|
---
|
||||||
|
)
|
||||||
)`),
|
)`),
|
||||||
ConstantCompletion("getCppNamespaces", `$(P The argument is a symbol.
|
ConstantCompletion("getCppNamespaces", `$(P The argument is a symbol.
|
||||||
The result is a *ValueSeq* of strings, possibly empty, that correspond to the namespaces the symbol resides in.
|
The result is a *ValueSeq* of strings, possibly empty, that correspond to the namespaces the symbol resides in.
|
||||||
|
|
@ -432,13 +530,13 @@ void main()
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
)`),
|
)`),
|
||||||
ConstantCompletion("getOverloads", `$(P The first argument is an aggregate (e.g. struct/class/module).
|
ConstantCompletion("getOverloads", `* The first argument is an aggregate type or instance, or a module.
|
||||||
The second argument is a ` ~ "`" ~ `string` ~ "`" ~ ` that matches the name of
|
* The second argument is a ` ~ "`" ~ `string` ~ "`" ~ ` that matches the name of
|
||||||
the member(s) to return.
|
the member(s) to return.
|
||||||
The third argument is a ` ~ "`" ~ `bool` ~ "`" ~ `, and is optional. If ` ~ "`" ~ `true` ~ "`" ~ `, the
|
* The third argument is a ` ~ "`" ~ `bool` ~ "`" ~ `, and is optional. If ` ~ "`" ~ `true` ~ "`" ~ `, the
|
||||||
result will also include template overloads.
|
result will also include template overloads.
|
||||||
The result is a symbol sequence of all the overloads of the supplied name.
|
* The result is a $(DDSUBLINK spec/template, homogeneous_sequences, symbol sequence)
|
||||||
)
|
of all the overloads of the supplied name.
|
||||||
|
|
||||||
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
---
|
---
|
||||||
|
|
@ -446,8 +544,6 @@ import std.stdio;
|
||||||
|
|
||||||
class D
|
class D
|
||||||
{
|
{
|
||||||
this() { }
|
|
||||||
~this() { }
|
|
||||||
void foo() { }
|
void foo() { }
|
||||||
int foo(int) { return 2; }
|
int foo(int) { return 2; }
|
||||||
void bar(T)() { return T.init; }
|
void bar(T)() { return T.init; }
|
||||||
|
|
@ -458,18 +554,24 @@ void main()
|
||||||
{
|
{
|
||||||
D d = new D();
|
D d = new D();
|
||||||
|
|
||||||
foreach (t; __traits(getOverloads, D, "foo"))
|
alias fooOverloads = __traits(getOverloads, D, "foo");
|
||||||
writeln(typeid(typeof(t)));
|
foreach (o; fooOverloads)
|
||||||
|
writeln(typeid(typeof(o)));
|
||||||
|
|
||||||
alias b = typeof(__traits(getOverloads, D, "foo"));
|
// typeof on a symbol sequence gives a type sequence
|
||||||
foreach (t; b)
|
foreach (T; typeof(fooOverloads))
|
||||||
writeln(typeid(t));
|
writeln(typeid(T));
|
||||||
|
|
||||||
auto i = __traits(getOverloads, d, "foo")[1](1);
|
// calls d.foo(3)
|
||||||
writeln(i);
|
auto i = __traits(getOverloads, d, "foo")[1](3);
|
||||||
|
assert(i == 2);
|
||||||
|
|
||||||
foreach (t; __traits(getOverloads, D, "bar", true))
|
// pass true to include templates
|
||||||
writeln(t.stringof);
|
// calls std.stdio.writeln(i)
|
||||||
|
__traits(getOverloads, std.stdio, "writeln", true)[0](i);
|
||||||
|
|
||||||
|
foreach (o; __traits(getOverloads, D, "bar", true))
|
||||||
|
writeln(o.stringof);
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
)
|
)
|
||||||
|
|
@ -477,10 +579,10 @@ void main()
|
||||||
Prints:
|
Prints:
|
||||||
|
|
||||||
$(CONSOLE
|
$(CONSOLE
|
||||||
void()
|
void function()
|
||||||
int()
|
int function(int)
|
||||||
void()
|
void function()
|
||||||
int()
|
int function(int)
|
||||||
2
|
2
|
||||||
bar(T)()
|
bar(T)()
|
||||||
bar(int n)
|
bar(int n)
|
||||||
|
|
@ -577,15 +679,13 @@ $(LI $(D "objectFormat") - Target object format)
|
||||||
Takes one argument, a symbol of an aggregate (e.g. struct/class/module).
|
Takes one argument, a symbol of an aggregate (e.g. struct/class/module).
|
||||||
The result is a symbol sequence of all the unit test functions of that aggregate.
|
The result is a symbol sequence of all the unit test functions of that aggregate.
|
||||||
The functions returned are like normal nested static functions,
|
The functions returned are like normal nested static functions,
|
||||||
$(DDSUBLINK glossary, ctfe, CTFE) will work and
|
$(DDSUBLINK spec/glossary, ctfe, CTFE) will work and
|
||||||
$(DDSUBLINK spec/attribute, uda, UDAs) will be accessible.
|
$(DDSUBLINK spec/attribute, uda, UDAs) will be accessible.
|
||||||
)
|
)
|
||||||
|
|
||||||
$(H4 Note:)
|
$(NOTE
|
||||||
|
The ` ~ "`" ~ `-unittest` ~ "`" ~ ` flag needs to be passed to the compiler. If the flag
|
||||||
$(P
|
is not passed, $(CODE __traits(getUnitTests)) will always return an
|
||||||
The -unittest flag needs to be passed to the compiler. If the flag
|
|
||||||
is not passed $(CODE __traits(getUnitTests)) will always return an
|
|
||||||
empty sequence.
|
empty sequence.
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -737,7 +837,9 @@ $(CONSOLE
|
||||||
export
|
export
|
||||||
public
|
public
|
||||||
)`),
|
)`),
|
||||||
ConstantCompletion("hasCopyConstructor", `$(P The argument is a type. If it is a struct with a copy constructor, returns $(D true). Otherwise, return $(D false). Note that a copy constructor is distinct from a postblit.
|
ConstantCompletion("hasCopyConstructor", `$(P The argument is a type.
|
||||||
|
If it is a struct with a copy constructor, returns $(D true). Otherwise, return $(D false).
|
||||||
|
A copy constructor is distinct from a move constructor or a postblit.
|
||||||
)
|
)
|
||||||
|
|
||||||
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
|
|
@ -745,22 +847,18 @@ $(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
|
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
|
|
||||||
struct S
|
struct S { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
class C
|
class C { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
struct P
|
struct P
|
||||||
{
|
{
|
||||||
this(ref P rhs) {}
|
this(ref P rhs) {} // copy constructor
|
||||||
}
|
}
|
||||||
|
|
||||||
struct B
|
struct B
|
||||||
{
|
{
|
||||||
this(this) {}
|
this(this) {} // postblit
|
||||||
}
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
|
|
@ -792,11 +890,48 @@ void main()
|
||||||
{
|
{
|
||||||
S s;
|
S s;
|
||||||
|
|
||||||
writeln(__traits(hasMember, S, "m")); // true
|
static assert(__traits(hasMember, S, "m"));
|
||||||
writeln(__traits(hasMember, s, "m")); // true
|
static assert(__traits(hasMember, s, "m"));
|
||||||
writeln(__traits(hasMember, S, "y")); // false
|
static assert(!__traits(hasMember, S, "y"));
|
||||||
writeln(__traits(hasMember, S, "write")); // false, but callable like a member via UFCS
|
static assert(!__traits(hasMember, S, "write")); // false, but callable like a member via UFCS
|
||||||
writeln(__traits(hasMember, int, "sizeof")); // true
|
static assert(__traits(hasMember, int, "sizeof"));
|
||||||
|
static assert(__traits(hasMember, 5, "sizeof"));
|
||||||
|
}
|
||||||
|
---
|
||||||
|
)`),
|
||||||
|
ConstantCompletion("hasMoveConstructor", `$(P The argument is a type.
|
||||||
|
If it is a struct with a move constructor, returns $(D true). Otherwise, return $(D false).
|
||||||
|
A move constructor is distinct from a copy constructor or a postblit.
|
||||||
|
)
|
||||||
|
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
|
---
|
||||||
|
|
||||||
|
import std.stdio;
|
||||||
|
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
this(S rhs) {} // move constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
class C { }
|
||||||
|
|
||||||
|
struct P
|
||||||
|
{
|
||||||
|
this(ref P rhs) {} // copy constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
struct B
|
||||||
|
{
|
||||||
|
this(this) {} // postblit
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
writeln(__traits(hasMoveConstructor, S)); // true
|
||||||
|
writeln(__traits(hasMoveConstructor, C)); // false
|
||||||
|
writeln(__traits(hasMoveConstructor, P)); // false
|
||||||
|
writeln(__traits(hasMoveConstructor, B)); // false, this is a postblit
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
)`),
|
)`),
|
||||||
|
|
@ -839,25 +974,22 @@ void main()
|
||||||
ConstantCompletion("identifier", `$(P Takes one argument, a symbol. Returns the identifier
|
ConstantCompletion("identifier", `$(P Takes one argument, a symbol. Returns the identifier
|
||||||
for that symbol as a string literal.
|
for that symbol as a string literal.
|
||||||
)
|
)
|
||||||
$(SPEC_RUNNABLE_EXAMPLE_RUN
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
---
|
---
|
||||||
int var = 123;
|
int var = 123;
|
||||||
pragma(msg, typeof(var)); // int
|
static assert(__traits(identifier, var) == "var");
|
||||||
pragma(msg, typeof(__traits(identifier, var))); // string
|
|
||||||
writeln(var); // 123
|
|
||||||
writeln(__traits(identifier, var)); // "var"
|
|
||||||
---
|
---
|
||||||
)`),
|
)`),
|
||||||
ConstantCompletion("initSymbol", `$(P Takes a single argument, which must evaluate to a ` ~ "`" ~ `class` ~ "`" ~ `, ` ~ "`" ~ `struct` ~ "`" ~ ` or ` ~ "`" ~ `union` ~ "`" ~ ` type.
|
ConstantCompletion("initSymbol", `$(P Takes a single argument, which must evaluate to a ` ~ "`" ~ `class` ~ "`" ~ `, ` ~ "`" ~ `struct` ~ "`" ~ ` or ` ~ "`" ~ `union` ~ "`" ~ ` type.
|
||||||
Returns a ` ~ "`" ~ `const(void)[]` ~ "`" ~ ` that holds the initial state of any instance of the supplied type.
|
Returns a ` ~ "`" ~ `const(void)[]` ~ "`" ~ ` that holds the initial state of any instance of the supplied type.
|
||||||
The slice is constructed for any type ` ~ "`" ~ `T` ~ "`" ~ ` as follows:
|
The slice is constructed for any type ` ~ "`" ~ `T` ~ "`" ~ ` as follows:
|
||||||
|
)
|
||||||
|
|
||||||
- ` ~ "`" ~ `ptr` ~ "`" ~ ` points to either the initializer symbol of ` ~ "`" ~ `T` ~ "`" ~ `
|
- ` ~ "`" ~ `ptr` ~ "`" ~ ` points to either the initializer symbol of ` ~ "`" ~ `T` ~ "`" ~ `
|
||||||
or ` ~ "`" ~ `null` ~ "`" ~ ` if ` ~ "`" ~ `T` ~ "`" ~ ` is a zero-initialized struct / unions.
|
or ` ~ "`" ~ `null` ~ "`" ~ ` if ` ~ "`" ~ `T` ~ "`" ~ ` is a $(RELATIVE_LINK2 isZeroInit, zero-initialized) struct/union.
|
||||||
|
|
||||||
- ` ~ "`" ~ `length` ~ "`" ~ ` is equal to the size of an instance, i.e. ` ~ "`" ~ `T.sizeof` ~ "`" ~ ` for structs / unions and
|
- ` ~ "`" ~ `length` ~ "`" ~ ` is equal to the size of an instance, i.e. ` ~ "`" ~ `T.sizeof` ~ "`" ~ ` for a struct/union and
|
||||||
$(RELATIVE_LINK2 classInstanceSize, $(D __traits(classInstanceSize, T)` ~ "`" ~ `)) for classes.
|
$(RELATIVE_LINK2 classInstanceSize, $(D __traits(classInstanceSize, T))) for a class.
|
||||||
)
|
|
||||||
|
|
||||||
$(P
|
$(P
|
||||||
This trait matches the behaviour of ` ~ "`" ~ `TypeInfo.initializer()` ~ "`" ~ ` but can also be used when
|
This trait matches the behaviour of ` ~ "`" ~ `TypeInfo.initializer()` ~ "`" ~ ` but can also be used when
|
||||||
|
|
@ -865,11 +997,14 @@ $(P
|
||||||
)
|
)
|
||||||
|
|
||||||
$(P
|
$(P
|
||||||
This traits is not available during $(DDSUBLINK glossary, ctfe, CTFE) because the actual address
|
This trait is not available during $(DDSUBLINK spec/glossary, ctfe, CTFE) because the actual address
|
||||||
of the initializer symbol will be set by the linker and hence is not available at compile time.
|
of the initializer symbol will be set by the linker and hence is not available at compile time.
|
||||||
)
|
)
|
||||||
|
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_RUN
|
||||||
---
|
---
|
||||||
|
import core.stdc.stdlib;
|
||||||
|
|
||||||
class C
|
class C
|
||||||
{
|
{
|
||||||
int i = 4;
|
int i = 4;
|
||||||
|
|
@ -883,12 +1018,14 @@ void main()
|
||||||
void* ptr = malloc(initSym.length);
|
void* ptr = malloc(initSym.length);
|
||||||
scope (exit) free(ptr);
|
scope (exit) free(ptr);
|
||||||
|
|
||||||
ptr[0..initSym.length] = initSym[];
|
// Note: allocated memory will only be written to through ` ~ "`" ~ `c` ~ "`" ~ `, so cast is safe
|
||||||
|
ptr[0..initSym.length] = cast(void[]) initSym[];
|
||||||
|
|
||||||
C c = cast(C) ptr;
|
C c = cast(C) ptr;
|
||||||
assert(c.i == 4);
|
assert(c.i == 4);
|
||||||
}
|
}
|
||||||
---`),
|
---
|
||||||
|
)`),
|
||||||
ConstantCompletion("isAbstractClass", `$(P If the arguments are all either types that are abstract classes,
|
ConstantCompletion("isAbstractClass", `$(P If the arguments are all either types that are abstract classes,
|
||||||
or expressions that are typed as abstract classes, then $(D true)
|
or expressions that are typed as abstract classes, then $(D true)
|
||||||
is returned.
|
is returned.
|
||||||
|
|
@ -984,6 +1121,10 @@ false
|
||||||
)`),
|
)`),
|
||||||
ConstantCompletion("isAssociativeArray", `$(P Works like $(D isArithmetic), except it's for associative array
|
ConstantCompletion("isAssociativeArray", `$(P Works like $(D isArithmetic), except it's for associative array
|
||||||
types.)`),
|
types.)`),
|
||||||
|
ConstantCompletion("isCOMClass", `$(P Takes one argument. If that argument is a symbol that refers to a
|
||||||
|
$(DDSUBLINK spec/class, ClassDeclaration, class declaration) and is a COM class then $(D true) is retuned,
|
||||||
|
otherwise $(D false).
|
||||||
|
)`),
|
||||||
ConstantCompletion("isCopyable", `$(P Takes one argument. If that argument is a copyable type then $(D true) is returned,
|
ConstantCompletion("isCopyable", `$(P Takes one argument. If that argument is a copyable type then $(D true) is returned,
|
||||||
otherwise $(D false).
|
otherwise $(D false).
|
||||||
)
|
)
|
||||||
|
|
@ -1003,7 +1144,26 @@ static assert(!__traits(isCopyable, T));
|
||||||
---
|
---
|
||||||
)`),
|
)`),
|
||||||
ConstantCompletion("isDeprecated", `$(P Takes one argument. It returns ` ~ "`" ~ `true` ~ "`" ~ ` if the argument is a symbol
|
ConstantCompletion("isDeprecated", `$(P Takes one argument. It returns ` ~ "`" ~ `true` ~ "`" ~ ` if the argument is a symbol
|
||||||
marked with the ` ~ "`" ~ `deprecated` ~ "`" ~ ` keyword, otherwise ` ~ "`" ~ `false` ~ "`" ~ `.)`),
|
marked with the ` ~ "`" ~ `deprecated` ~ "`" ~ ` keyword, otherwise ` ~ "`" ~ `false` ~ "`" ~ `.)
|
||||||
|
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
|
---
|
||||||
|
deprecated("No longer supported")
|
||||||
|
int i;
|
||||||
|
|
||||||
|
struct A
|
||||||
|
{
|
||||||
|
int foo() { return 1; }
|
||||||
|
|
||||||
|
deprecated("please use foo")
|
||||||
|
int bar() { return 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
static assert(__traits(isDeprecated, i));
|
||||||
|
static assert(!__traits(isDeprecated, A.foo));
|
||||||
|
static assert(__traits(isDeprecated, A.bar));
|
||||||
|
---
|
||||||
|
)`),
|
||||||
ConstantCompletion("isDisabled", `$(P Takes one argument and returns ` ~ "`" ~ `true` ~ "`" ~ ` if it's a function declaration
|
ConstantCompletion("isDisabled", `$(P Takes one argument and returns ` ~ "`" ~ `true` ~ "`" ~ ` if it's a function declaration
|
||||||
marked with ` ~ "`" ~ `@disable` ~ "`" ~ `.)
|
marked with ` ~ "`" ~ `@disable` ~ "`" ~ `.)
|
||||||
|
|
||||||
|
|
@ -1020,8 +1180,8 @@ static assert(!__traits(isDisabled, Foo.bar));
|
||||||
---
|
---
|
||||||
)
|
)
|
||||||
|
|
||||||
$(P For any other declaration even if ` ~ "`" ~ `@disable` ~ "`" ~ ` is a syntactically valid
|
$(P For any other declaration, even if ` ~ "`" ~ `@disable` ~ "`" ~ ` is a syntactically valid
|
||||||
attribute ` ~ "`" ~ `false` ~ "`" ~ ` is returned because the annotation has no effect.)
|
attribute, ` ~ "`" ~ `false` ~ "`" ~ ` is returned because the annotation has no effect.)
|
||||||
|
|
||||||
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
---
|
---
|
||||||
|
|
@ -1091,8 +1251,9 @@ static assert(!__traits(isFloating, float[4]));
|
||||||
---
|
---
|
||||||
)`),
|
)`),
|
||||||
ConstantCompletion("isFuture", `$(P Takes one argument. It returns ` ~ "`" ~ `true` ~ "`" ~ ` if the argument is a symbol
|
ConstantCompletion("isFuture", `$(P Takes one argument. It returns ` ~ "`" ~ `true` ~ "`" ~ ` if the argument is a symbol
|
||||||
marked with the ` ~ "`" ~ `@future` ~ "`" ~ ` keyword, otherwise ` ~ "`" ~ `false` ~ "`" ~ `. Currently, only
|
marked with the $(DDSUBLINK spec/attribute, future, ` ~ "`" ~ `@__future` ~ "`" ~ ` attribute),
|
||||||
functions and variable declarations have support for the ` ~ "`" ~ `@future` ~ "`" ~ ` keyword.)`),
|
otherwise ` ~ "`" ~ `false` ~ "`" ~ `. Currently, only
|
||||||
|
functions and variable declarations have support for the ` ~ "`" ~ `@__future` ~ "`" ~ ` keyword.)`),
|
||||||
ConstantCompletion("isIntegral", `$(P If the arguments are all either types that are integral types,
|
ConstantCompletion("isIntegral", `$(P If the arguments are all either types that are integral types,
|
||||||
or expressions that are typed as integral types, then $(D true)
|
or expressions that are typed as integral types, then $(D true)
|
||||||
is returned.
|
is returned.
|
||||||
|
|
@ -1234,18 +1395,20 @@ void main()
|
||||||
---
|
---
|
||||||
)`),
|
)`),
|
||||||
ConstantCompletion("isPOD", `$(P Takes one argument, which must be a type. It returns
|
ConstantCompletion("isPOD", `$(P Takes one argument, which must be a type. It returns
|
||||||
$(D true) if the type is a $(DDSUBLINK glossary, pod, POD) type, otherwise $(D false).)`),
|
$(D true) if the type is a $(DDSUBLINK spec/glossary, pod, POD) type, otherwise $(D false).)`),
|
||||||
ConstantCompletion("isPackage", `$(P Takes one argument. If that argument is a symbol that refers to a
|
ConstantCompletion("isPackage", `$(P Takes one argument. If that argument is a symbol that refers to a
|
||||||
$(DDSUBLINK spec/module, PackageName, package) then $(D true) is returned,
|
$(DDSUBLINK spec/module, PackageName, package) then $(D true) is returned,
|
||||||
otherwise $(D false).
|
otherwise $(D false).
|
||||||
)
|
)
|
||||||
|
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
---
|
---
|
||||||
import std.algorithm.sorting;
|
import std.algorithm.sorting;
|
||||||
static assert(__traits(isPackage, std));
|
static assert(__traits(isPackage, std));
|
||||||
static assert(__traits(isPackage, std.algorithm));
|
static assert(__traits(isPackage, std.algorithm));
|
||||||
static assert(!__traits(isPackage, std.algorithm.sorting));
|
static assert(!__traits(isPackage, std.algorithm.sorting));
|
||||||
---`),
|
---
|
||||||
|
)`),
|
||||||
ConstantCompletion("isRef", `$(P Takes one argument. If that argument is a declaration,
|
ConstantCompletion("isRef", `$(P Takes one argument. If that argument is a declaration,
|
||||||
$(D true) is returned if it is $(D_KEYWORD ref), $(D_KEYWORD out),
|
$(D true) is returned if it is $(D_KEYWORD ref), $(D_KEYWORD out),
|
||||||
or $(D_KEYWORD lazy), otherwise $(D false).
|
or $(D_KEYWORD lazy), otherwise $(D false).
|
||||||
|
|
@ -1330,6 +1493,30 @@ alias daz = foo;
|
||||||
static assert(__traits(isSame, foo, daz));
|
static assert(__traits(isSame, foo, daz));
|
||||||
---
|
---
|
||||||
)
|
)
|
||||||
|
$(P isSame matches against non-instantiated templates.)
|
||||||
|
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
|
---
|
||||||
|
struct Foo(T){
|
||||||
|
T x;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Bar(T){
|
||||||
|
T x;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Point(T){
|
||||||
|
T x;
|
||||||
|
T y;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum isFooOrBar(alias FB) = __traits(isSame, FB, Foo) || __traits(isSame, FB, Bar);
|
||||||
|
|
||||||
|
static assert(isFooOrBar!(Foo));
|
||||||
|
static assert(isFooOrBar!(Bar));
|
||||||
|
static assert(!isFooOrBar!(Point));
|
||||||
|
---
|
||||||
|
)
|
||||||
|
|
||||||
$(P The result is ` ~ "`" ~ `true` ~ "`" ~ ` if the two arguments are expressions
|
$(P The result is ` ~ "`" ~ `true` ~ "`" ~ ` if the two arguments are expressions
|
||||||
made up of literals or enums that evaluate to the same value.)
|
made up of literals or enums that evaluate to the same value.)
|
||||||
|
|
@ -1515,9 +1702,9 @@ then $(D true) is returned, otherwise $(D false).
|
||||||
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
---
|
---
|
||||||
void foo(T)(){}
|
void foo(T)(){}
|
||||||
static assert(__traits(isTemplate,foo));
|
static assert(__traits(isTemplate, foo));
|
||||||
static assert(!__traits(isTemplate,foo!int()));
|
static assert(!__traits(isTemplate, foo!int()));
|
||||||
static assert(!__traits(isTemplate,"string"));
|
static assert(!__traits(isTemplate, "string"));
|
||||||
---
|
---
|
||||||
)`),
|
)`),
|
||||||
ConstantCompletion("isUnsigned", `$(P If the arguments are all either types that are unsigned types,
|
ConstantCompletion("isUnsigned", `$(P If the arguments are all either types that are unsigned types,
|
||||||
|
|
@ -1610,12 +1797,26 @@ static assert(__traits(isZeroInit, void));
|
||||||
---
|
---
|
||||||
)`),
|
)`),
|
||||||
ConstantCompletion("parameters", `$(P May only be used inside a function. Takes no arguments, and returns
|
ConstantCompletion("parameters", `$(P May only be used inside a function. Takes no arguments, and returns
|
||||||
a sequence of the enclosing function's parameters.)
|
an $(DDSUBLINK spec/template, lvalue-sequences, lvalue sequence) of the
|
||||||
|
enclosing function's parameters.)
|
||||||
$(P If the function is nested, the parameters returned are those of the
|
|
||||||
inner function, not the outer one.)
|
|
||||||
|
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
---
|
---
|
||||||
|
alias AliasSeq(A...) = A;
|
||||||
|
|
||||||
|
void f(int n, char c)
|
||||||
|
{
|
||||||
|
alias PS = __traits(parameters);
|
||||||
|
PS[0]++; // increment n
|
||||||
|
static assert(is(typeof(PS) == AliasSeq!(int, char)));
|
||||||
|
|
||||||
|
// output parameter names
|
||||||
|
static foreach (i, p; PS)
|
||||||
|
{
|
||||||
|
pragma(msg, __traits(identifier, p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int add(int x, int y)
|
int add(int x, int y)
|
||||||
{
|
{
|
||||||
return x + y;
|
return x + y;
|
||||||
|
|
@ -1627,7 +1828,13 @@ int forwardToAdd(int x, int y)
|
||||||
// equivalent to;
|
// equivalent to;
|
||||||
//return add(x, y);
|
//return add(x, y);
|
||||||
}
|
}
|
||||||
|
---
|
||||||
|
)
|
||||||
|
|
||||||
|
$(P If the function is nested, the parameters returned are those of the
|
||||||
|
inner function, not the outer one.)
|
||||||
|
|
||||||
|
---
|
||||||
int nestedExample(int x)
|
int nestedExample(int x)
|
||||||
{
|
{
|
||||||
// outer function's parameters
|
// outer function's parameters
|
||||||
|
|
@ -1642,7 +1849,8 @@ int nestedExample(int x)
|
||||||
|
|
||||||
return add(x, x);
|
return add(x, x);
|
||||||
}
|
}
|
||||||
|
---
|
||||||
|
---
|
||||||
class C
|
class C
|
||||||
{
|
{
|
||||||
int opApply(int delegate(size_t, C) dg)
|
int opApply(int delegate(size_t, C) dg)
|
||||||
|
|
|
||||||
|
|
@ -493,5 +493,5 @@ $(SPEC_SUBNAV_PREV_NEXT attribute, Attributes, expression, Expressions)
|
||||||
)
|
)
|
||||||
|
|
||||||
Macros:
|
Macros:
|
||||||
CHAPTER=9
|
CHAPTER=10
|
||||||
TITLE=Pragmas
|
TITLE=Pragmas
|
||||||
|
|
|
||||||
|
|
@ -49,12 +49,17 @@ $(GNAME TraitsKeyword):
|
||||||
$(RELATIVE_LINK2 isZeroInit, $(D isZeroInit))
|
$(RELATIVE_LINK2 isZeroInit, $(D isZeroInit))
|
||||||
$(RELATIVE_LINK2 isModule, $(D isModule))
|
$(RELATIVE_LINK2 isModule, $(D isModule))
|
||||||
$(RELATIVE_LINK2 isPackage, $(D isPackage))
|
$(RELATIVE_LINK2 isPackage, $(D isPackage))
|
||||||
|
$(RELATIVE_LINK2 isCOMClass, $(D isCOMClass))
|
||||||
$(RELATIVE_LINK2 hasMember, $(D hasMember))
|
$(RELATIVE_LINK2 hasMember, $(D hasMember))
|
||||||
$(RELATIVE_LINK2 hasCopyConstructor, $(D hasCopyConstructor))
|
$(RELATIVE_LINK2 hasCopyConstructor, $(D hasCopyConstructor))
|
||||||
|
$(RELATIVE_LINK2 hasMoveConstructor, $(D hasMoveConstructor))
|
||||||
$(RELATIVE_LINK2 hasPostblit, $(D hasPostblit))
|
$(RELATIVE_LINK2 hasPostblit, $(D hasPostblit))
|
||||||
$(RELATIVE_LINK2 identifier, $(D identifier))
|
$(RELATIVE_LINK2 identifier, $(D identifier))
|
||||||
|
$(RELATIVE_LINK2 fullyQualifiedName, $(D fullyQualifiedName))
|
||||||
$(RELATIVE_LINK2 getAliasThis, $(D getAliasThis))
|
$(RELATIVE_LINK2 getAliasThis, $(D getAliasThis))
|
||||||
$(RELATIVE_LINK2 getAttributes, $(D getAttributes))
|
$(RELATIVE_LINK2 getAttributes, $(D getAttributes))
|
||||||
|
$(RELATIVE_LINK2 getBitfieldOffset, $(D getBitfieldOffset))
|
||||||
|
$(RELATIVE_LINK2 getBitfieldWidth, $(D getBitfieldWidth))
|
||||||
$(RELATIVE_LINK2 getFunctionAttributes, $(D getFunctionAttributes))
|
$(RELATIVE_LINK2 getFunctionAttributes, $(D getFunctionAttributes))
|
||||||
$(RELATIVE_LINK2 getFunctionVariadicStyle, $(D getFunctionVariadicStyle))
|
$(RELATIVE_LINK2 getFunctionVariadicStyle, $(D getFunctionVariadicStyle))
|
||||||
$(RELATIVE_LINK2 getLinkage, $(D getLinkage))
|
$(RELATIVE_LINK2 getLinkage, $(D getLinkage))
|
||||||
|
|
@ -82,6 +87,7 @@ $(GNAME TraitsKeyword):
|
||||||
$(RELATIVE_LINK2 toType, $(D toType))
|
$(RELATIVE_LINK2 toType, $(D toType))
|
||||||
$(RELATIVE_LINK2 initSymbol, $(D initSymbol))
|
$(RELATIVE_LINK2 initSymbol, $(D initSymbol))
|
||||||
$(RELATIVE_LINK2 parameters, $(D parameters))
|
$(RELATIVE_LINK2 parameters, $(D parameters))
|
||||||
|
$(RELATIVE_LINK2 fullyQualifiedName, $(D fullyQualifiedName))
|
||||||
|
|
||||||
$(GNAME TraitsArguments):
|
$(GNAME TraitsArguments):
|
||||||
$(GLINK TraitsArgument)
|
$(GLINK TraitsArgument)
|
||||||
|
|
@ -346,7 +352,7 @@ static assert(!__traits(isCopyable, T));
|
||||||
$(H3 $(GNAME isPOD))
|
$(H3 $(GNAME isPOD))
|
||||||
|
|
||||||
$(P Takes one argument, which must be a type. It returns
|
$(P Takes one argument, which must be a type. It returns
|
||||||
$(D true) if the type is a $(DDSUBLINK glossary, pod, POD) type, otherwise $(D false).)
|
$(D true) if the type is a $(DDSUBLINK spec/glossary, pod, POD) type, otherwise $(D false).)
|
||||||
|
|
||||||
$(H3 $(GNAME toType))
|
$(H3 $(GNAME toType))
|
||||||
|
|
||||||
|
|
@ -404,7 +410,45 @@ static assert(__traits(isZeroInit, void));
|
||||||
|
|
||||||
$(H3 $(GNAME hasCopyConstructor))
|
$(H3 $(GNAME hasCopyConstructor))
|
||||||
|
|
||||||
$(P The argument is a type. If it is a struct with a copy constructor, returns $(D true). Otherwise, return $(D false). Note that a copy constructor is distinct from a postblit.
|
$(P The argument is a type.
|
||||||
|
If it is a struct with a copy constructor, returns $(D true). Otherwise, return $(D false).
|
||||||
|
A copy constructor is distinct from a move constructor or a postblit.
|
||||||
|
)
|
||||||
|
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
|
---
|
||||||
|
|
||||||
|
import std.stdio;
|
||||||
|
|
||||||
|
struct S { }
|
||||||
|
|
||||||
|
class C { }
|
||||||
|
|
||||||
|
struct P
|
||||||
|
{
|
||||||
|
this(ref P rhs) {} // copy constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
struct B
|
||||||
|
{
|
||||||
|
this(this) {} // postblit
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
writeln(__traits(hasCopyConstructor, S)); // false
|
||||||
|
writeln(__traits(hasCopyConstructor, C)); // false
|
||||||
|
writeln(__traits(hasCopyConstructor, P)); // true
|
||||||
|
writeln(__traits(hasCopyConstructor, B)); // false, this is a postblit
|
||||||
|
}
|
||||||
|
---
|
||||||
|
)
|
||||||
|
|
||||||
|
$(H3 $(GNAME hasMoveConstructor))
|
||||||
|
|
||||||
|
$(P The argument is a type.
|
||||||
|
If it is a struct with a move constructor, returns $(D true). Otherwise, return $(D false).
|
||||||
|
A move constructor is distinct from a copy constructor or a postblit.
|
||||||
)
|
)
|
||||||
|
|
||||||
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
|
|
@ -414,28 +458,27 @@ import std.stdio;
|
||||||
|
|
||||||
struct S
|
struct S
|
||||||
{
|
{
|
||||||
|
this(S rhs) {} // move constructor
|
||||||
}
|
}
|
||||||
|
|
||||||
class C
|
class C { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
struct P
|
struct P
|
||||||
{
|
{
|
||||||
this(ref P rhs) {}
|
this(ref P rhs) {} // copy constructor
|
||||||
}
|
}
|
||||||
|
|
||||||
struct B
|
struct B
|
||||||
{
|
{
|
||||||
this(this) {}
|
this(this) {} // postblit
|
||||||
}
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
writeln(__traits(hasCopyConstructor, S)); // false
|
writeln(__traits(hasMoveConstructor, S)); // true
|
||||||
writeln(__traits(hasCopyConstructor, C)); // false
|
writeln(__traits(hasMoveConstructor, C)); // false
|
||||||
writeln(__traits(hasCopyConstructor, P)); // true
|
writeln(__traits(hasMoveConstructor, P)); // false
|
||||||
writeln(__traits(hasCopyConstructor, B)); // false, this is a postblit
|
writeln(__traits(hasMoveConstructor, B)); // false, this is a postblit
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
)
|
)
|
||||||
|
|
@ -633,13 +676,13 @@ $(H3 $(GNAME initSymbol))
|
||||||
$(P Takes a single argument, which must evaluate to a `class`, `struct` or `union` type.
|
$(P Takes a single argument, which must evaluate to a `class`, `struct` or `union` type.
|
||||||
Returns a `const(void)[]` that holds the initial state of any instance of the supplied type.
|
Returns a `const(void)[]` that holds the initial state of any instance of the supplied type.
|
||||||
The slice is constructed for any type `T` as follows:
|
The slice is constructed for any type `T` as follows:
|
||||||
|
)
|
||||||
|
|
||||||
- `ptr` points to either the initializer symbol of `T`
|
- `ptr` points to either the initializer symbol of `T`
|
||||||
or `null` if `T` is a zero-initialized struct / unions.
|
or `null` if `T` is a $(RELATIVE_LINK2 isZeroInit, zero-initialized) struct/union.
|
||||||
|
|
||||||
- `length` is equal to the size of an instance, i.e. `T.sizeof` for structs / unions and
|
- `length` is equal to the size of an instance, i.e. `T.sizeof` for a struct/union and
|
||||||
$(RELATIVE_LINK2 classInstanceSize, $(D __traits(classInstanceSize, T)`)) for classes.
|
$(RELATIVE_LINK2 classInstanceSize, $(D __traits(classInstanceSize, T))) for a class.
|
||||||
)
|
|
||||||
|
|
||||||
$(P
|
$(P
|
||||||
This trait matches the behaviour of `TypeInfo.initializer()` but can also be used when
|
This trait matches the behaviour of `TypeInfo.initializer()` but can also be used when
|
||||||
|
|
@ -647,11 +690,14 @@ $(H3 $(GNAME initSymbol))
|
||||||
)
|
)
|
||||||
|
|
||||||
$(P
|
$(P
|
||||||
This traits is not available during $(DDSUBLINK glossary, ctfe, CTFE) because the actual address
|
This trait is not available during $(DDSUBLINK spec/glossary, ctfe, CTFE) because the actual address
|
||||||
of the initializer symbol will be set by the linker and hence is not available at compile time.
|
of the initializer symbol will be set by the linker and hence is not available at compile time.
|
||||||
)
|
)
|
||||||
|
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_RUN
|
||||||
---
|
---
|
||||||
|
import core.stdc.stdlib;
|
||||||
|
|
||||||
class C
|
class C
|
||||||
{
|
{
|
||||||
int i = 4;
|
int i = 4;
|
||||||
|
|
@ -665,12 +711,14 @@ $(H3 $(GNAME initSymbol))
|
||||||
void* ptr = malloc(initSym.length);
|
void* ptr = malloc(initSym.length);
|
||||||
scope (exit) free(ptr);
|
scope (exit) free(ptr);
|
||||||
|
|
||||||
ptr[0..initSym.length] = initSym[];
|
// Note: allocated memory will only be written to through `c`, so cast is safe
|
||||||
|
ptr[0..initSym.length] = cast(void[]) initSym[];
|
||||||
|
|
||||||
C c = cast(C) ptr;
|
C c = cast(C) ptr;
|
||||||
assert(c.i == 4);
|
assert(c.i == 4);
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
$(H2 $(LNAME2 functions, Function Traits))
|
$(H2 $(LNAME2 functions, Function Traits))
|
||||||
|
|
@ -693,8 +741,8 @@ static assert(!__traits(isDisabled, Foo.bar));
|
||||||
---
|
---
|
||||||
)
|
)
|
||||||
|
|
||||||
$(P For any other declaration even if `@disable` is a syntactically valid
|
$(P For any other declaration, even if `@disable` is a syntactically valid
|
||||||
attribute `false` is returned because the annotation has no effect.)
|
attribute, `false` is returned because the annotation has no effect.)
|
||||||
|
|
||||||
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
---
|
---
|
||||||
|
|
@ -1076,12 +1124,26 @@ static assert(__traits(getParameterStorageClasses, foo(p, a, b, c), 3)[0] == "la
|
||||||
$(H3 $(GNAME parameters))
|
$(H3 $(GNAME parameters))
|
||||||
|
|
||||||
$(P May only be used inside a function. Takes no arguments, and returns
|
$(P May only be used inside a function. Takes no arguments, and returns
|
||||||
a sequence of the enclosing function's parameters.)
|
an $(DDSUBLINK spec/template, lvalue-sequences, lvalue sequence) of the
|
||||||
|
enclosing function's parameters.)
|
||||||
$(P If the function is nested, the parameters returned are those of the
|
|
||||||
inner function, not the outer one.)
|
|
||||||
|
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
---
|
---
|
||||||
|
alias AliasSeq(A...) = A;
|
||||||
|
|
||||||
|
void f(int n, char c)
|
||||||
|
{
|
||||||
|
alias PS = __traits(parameters);
|
||||||
|
PS[0]++; // increment n
|
||||||
|
static assert(is(typeof(PS) == AliasSeq!(int, char)));
|
||||||
|
|
||||||
|
// output parameter names
|
||||||
|
static foreach (i, p; PS)
|
||||||
|
{
|
||||||
|
pragma(msg, __traits(identifier, p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int add(int x, int y)
|
int add(int x, int y)
|
||||||
{
|
{
|
||||||
return x + y;
|
return x + y;
|
||||||
|
|
@ -1093,7 +1155,13 @@ $(H3 $(GNAME parameters))
|
||||||
// equivalent to;
|
// equivalent to;
|
||||||
//return add(x, y);
|
//return add(x, y);
|
||||||
}
|
}
|
||||||
|
---
|
||||||
|
)
|
||||||
|
|
||||||
|
$(P If the function is nested, the parameters returned are those of the
|
||||||
|
inner function, not the outer one.)
|
||||||
|
|
||||||
|
---
|
||||||
int nestedExample(int x)
|
int nestedExample(int x)
|
||||||
{
|
{
|
||||||
// outer function's parameters
|
// outer function's parameters
|
||||||
|
|
@ -1108,7 +1176,8 @@ $(H3 $(GNAME parameters))
|
||||||
|
|
||||||
return add(x, x);
|
return add(x, x);
|
||||||
}
|
}
|
||||||
|
---
|
||||||
|
---
|
||||||
class C
|
class C
|
||||||
{
|
{
|
||||||
int opApply(int delegate(size_t, C) dg)
|
int opApply(int delegate(size_t, C) dg)
|
||||||
|
|
@ -1135,6 +1204,22 @@ $(H3 $(GNAME parameters))
|
||||||
|
|
||||||
$(H2 $(LNAME2 symbols, Symbol Traits))
|
$(H2 $(LNAME2 symbols, Symbol Traits))
|
||||||
|
|
||||||
|
$(H3 $(GNAME fullyQualifiedName))
|
||||||
|
|
||||||
|
$(P Gets the fully qualified name of a type or symbol.)
|
||||||
|
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
|
-----------------
|
||||||
|
module myModule;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
static assert(__traits(fullyQualifiedName, i) == "myModule.i");
|
||||||
|
|
||||||
|
struct MyStruct {}
|
||||||
|
static assert(__traits(fullyQualifiedName, const MyStruct[]) == "const(myModule.MyStruct[])");
|
||||||
|
-----------------
|
||||||
|
)
|
||||||
|
|
||||||
$(H3 $(GNAME isNested))
|
$(H3 $(GNAME isNested))
|
||||||
|
|
||||||
$(P Takes one argument.
|
$(P Takes one argument.
|
||||||
|
|
@ -1147,14 +1232,34 @@ $(H3 $(GNAME isNested))
|
||||||
$(H3 $(GNAME isFuture))
|
$(H3 $(GNAME isFuture))
|
||||||
|
|
||||||
$(P Takes one argument. It returns `true` if the argument is a symbol
|
$(P Takes one argument. It returns `true` if the argument is a symbol
|
||||||
marked with the `@future` keyword, otherwise `false`. Currently, only
|
marked with the $(DDSUBLINK spec/attribute, future, `@__future` attribute),
|
||||||
functions and variable declarations have support for the `@future` keyword.)
|
otherwise `false`. Currently, only
|
||||||
|
functions and variable declarations have support for the `@__future` keyword.)
|
||||||
|
|
||||||
$(H3 $(GNAME isDeprecated))
|
$(H3 $(GNAME isDeprecated))
|
||||||
|
|
||||||
$(P Takes one argument. It returns `true` if the argument is a symbol
|
$(P Takes one argument. It returns `true` if the argument is a symbol
|
||||||
marked with the `deprecated` keyword, otherwise `false`.)
|
marked with the `deprecated` keyword, otherwise `false`.)
|
||||||
|
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
|
---
|
||||||
|
deprecated("No longer supported")
|
||||||
|
int i;
|
||||||
|
|
||||||
|
struct A
|
||||||
|
{
|
||||||
|
int foo() { return 1; }
|
||||||
|
|
||||||
|
deprecated("please use foo")
|
||||||
|
int bar() { return 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
static assert(__traits(isDeprecated, i));
|
||||||
|
static assert(!__traits(isDeprecated, A.foo));
|
||||||
|
static assert(__traits(isDeprecated, A.bar));
|
||||||
|
---
|
||||||
|
)
|
||||||
|
|
||||||
$(H3 $(GNAME isTemplate))
|
$(H3 $(GNAME isTemplate))
|
||||||
|
|
||||||
$(P Takes one argument. If that argument or any of its overloads is a template
|
$(P Takes one argument. If that argument or any of its overloads is a template
|
||||||
|
|
@ -1164,9 +1269,9 @@ $(H3 $(GNAME isTemplate))
|
||||||
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
---
|
---
|
||||||
void foo(T)(){}
|
void foo(T)(){}
|
||||||
static assert(__traits(isTemplate,foo));
|
static assert(__traits(isTemplate, foo));
|
||||||
static assert(!__traits(isTemplate,foo!int()));
|
static assert(!__traits(isTemplate, foo!int()));
|
||||||
static assert(!__traits(isTemplate,"string"));
|
static assert(!__traits(isTemplate, "string"));
|
||||||
---
|
---
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1201,12 +1306,20 @@ $(H3 $(GNAME isPackage))
|
||||||
otherwise $(D false).
|
otherwise $(D false).
|
||||||
)
|
)
|
||||||
|
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
---
|
---
|
||||||
import std.algorithm.sorting;
|
import std.algorithm.sorting;
|
||||||
static assert(__traits(isPackage, std));
|
static assert(__traits(isPackage, std));
|
||||||
static assert(__traits(isPackage, std.algorithm));
|
static assert(__traits(isPackage, std.algorithm));
|
||||||
static assert(!__traits(isPackage, std.algorithm.sorting));
|
static assert(!__traits(isPackage, std.algorithm.sorting));
|
||||||
---
|
---
|
||||||
|
)
|
||||||
|
|
||||||
|
$(H3 $(GNAME isCOMClass))
|
||||||
|
$(P Takes one argument. If that argument is a symbol that refers to a
|
||||||
|
$(DDSUBLINK spec/class, ClassDeclaration, class declaration) and is a COM class then $(D true) is retuned,
|
||||||
|
otherwise $(D false).
|
||||||
|
)
|
||||||
|
|
||||||
$(H3 $(GNAME hasMember))
|
$(H3 $(GNAME hasMember))
|
||||||
|
|
||||||
|
|
@ -1230,11 +1343,12 @@ void main()
|
||||||
{
|
{
|
||||||
S s;
|
S s;
|
||||||
|
|
||||||
writeln(__traits(hasMember, S, "m")); // true
|
static assert(__traits(hasMember, S, "m"));
|
||||||
writeln(__traits(hasMember, s, "m")); // true
|
static assert(__traits(hasMember, s, "m"));
|
||||||
writeln(__traits(hasMember, S, "y")); // false
|
static assert(!__traits(hasMember, S, "y"));
|
||||||
writeln(__traits(hasMember, S, "write")); // false, but callable like a member via UFCS
|
static assert(!__traits(hasMember, S, "write")); // false, but callable like a member via UFCS
|
||||||
writeln(__traits(hasMember, int, "sizeof")); // true
|
static assert(__traits(hasMember, int, "sizeof"));
|
||||||
|
static assert(__traits(hasMember, 5, "sizeof"));
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
)
|
)
|
||||||
|
|
@ -1244,13 +1358,10 @@ $(H3 $(GNAME identifier))
|
||||||
$(P Takes one argument, a symbol. Returns the identifier
|
$(P Takes one argument, a symbol. Returns the identifier
|
||||||
for that symbol as a string literal.
|
for that symbol as a string literal.
|
||||||
)
|
)
|
||||||
$(SPEC_RUNNABLE_EXAMPLE_RUN
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
---
|
---
|
||||||
int var = 123;
|
int var = 123;
|
||||||
pragma(msg, typeof(var)); // int
|
static assert(__traits(identifier, var) == "var");
|
||||||
pragma(msg, typeof(__traits(identifier, var))); // string
|
|
||||||
writeln(var); // 123
|
|
||||||
writeln(__traits(identifier, var)); // "var"
|
|
||||||
---
|
---
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1287,6 +1398,53 @@ tuple((Foo))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
$(SECTION3 $(GNAME getBitfieldOffset),
|
||||||
|
$(P Takes one argument, a qualified name that resolve to a field in a struct or class.
|
||||||
|
)
|
||||||
|
$(P If the field is a bitfield, it returns as a `uint` the bit number of the least significant
|
||||||
|
bit in the field. The rightmost bit is at offset 0, the leftmost bit is at offset 31 (for
|
||||||
|
32 bit int fields).
|
||||||
|
)
|
||||||
|
$(P If the field is a not bitfield, it returns as a `uint` the number 0.
|
||||||
|
)
|
||||||
|
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
|
---
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
int a,b;
|
||||||
|
int :2, c:3;
|
||||||
|
}
|
||||||
|
|
||||||
|
static assert(__traits(getBitfieldOffset, S.b) == 0);
|
||||||
|
static assert(__traits(getBitfieldOffset, S.c) == 2);
|
||||||
|
---
|
||||||
|
)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
$(SECTION3 $(GNAME getBitfieldWidth),
|
||||||
|
$(P Takes one argument, a qualified name that resolve to a field in a struct or class.
|
||||||
|
)
|
||||||
|
$(P If the field is a bitfield, it returns as a `uint` the width of the bit field as
|
||||||
|
a number of bits.
|
||||||
|
)
|
||||||
|
$(P If the field is a not bitfield, it returns the number of bits in the type.
|
||||||
|
)
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
|
---
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
int a,b;
|
||||||
|
int :2, c:3;
|
||||||
|
}
|
||||||
|
|
||||||
|
static assert(__traits(getBitfieldWidth, S.b) == 32);
|
||||||
|
static assert(__traits(getBitfieldWidth, S.c) == 3);
|
||||||
|
---
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
$(H3 $(GNAME getLinkage))
|
$(H3 $(GNAME getLinkage))
|
||||||
|
|
||||||
$(P Takes one argument, which is a declaration symbol, or the type of a function, delegate,
|
$(P Takes one argument, which is a declaration symbol, or the type of a function, delegate,
|
||||||
|
|
@ -1363,13 +1521,13 @@ void main()
|
||||||
|
|
||||||
$(H3 $(GNAME getOverloads))
|
$(H3 $(GNAME getOverloads))
|
||||||
|
|
||||||
$(P The first argument is an aggregate (e.g. struct/class/module).
|
* The first argument is an aggregate type or instance, or a module.
|
||||||
The second argument is a `string` that matches the name of
|
* The second argument is a `string` that matches the name of
|
||||||
the member(s) to return.
|
the member(s) to return.
|
||||||
The third argument is a `bool`, and is optional. If `true`, the
|
* The third argument is a `bool`, and is optional. If `true`, the
|
||||||
result will also include template overloads.
|
result will also include template overloads.
|
||||||
The result is a symbol sequence of all the overloads of the supplied name.
|
* The result is a $(DDSUBLINK spec/template, homogeneous_sequences, symbol sequence)
|
||||||
)
|
of all the overloads of the supplied name.
|
||||||
|
|
||||||
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
---
|
---
|
||||||
|
|
@ -1377,8 +1535,6 @@ import std.stdio;
|
||||||
|
|
||||||
class D
|
class D
|
||||||
{
|
{
|
||||||
this() { }
|
|
||||||
~this() { }
|
|
||||||
void foo() { }
|
void foo() { }
|
||||||
int foo(int) { return 2; }
|
int foo(int) { return 2; }
|
||||||
void bar(T)() { return T.init; }
|
void bar(T)() { return T.init; }
|
||||||
|
|
@ -1389,18 +1545,24 @@ void main()
|
||||||
{
|
{
|
||||||
D d = new D();
|
D d = new D();
|
||||||
|
|
||||||
foreach (t; __traits(getOverloads, D, "foo"))
|
alias fooOverloads = __traits(getOverloads, D, "foo");
|
||||||
writeln(typeid(typeof(t)));
|
foreach (o; fooOverloads)
|
||||||
|
writeln(typeid(typeof(o)));
|
||||||
|
|
||||||
alias b = typeof(__traits(getOverloads, D, "foo"));
|
// typeof on a symbol sequence gives a type sequence
|
||||||
foreach (t; b)
|
foreach (T; typeof(fooOverloads))
|
||||||
writeln(typeid(t));
|
writeln(typeid(T));
|
||||||
|
|
||||||
auto i = __traits(getOverloads, d, "foo")[1](1);
|
// calls d.foo(3)
|
||||||
writeln(i);
|
auto i = __traits(getOverloads, d, "foo")[1](3);
|
||||||
|
assert(i == 2);
|
||||||
|
|
||||||
foreach (t; __traits(getOverloads, D, "bar", true))
|
// pass true to include templates
|
||||||
writeln(t.stringof);
|
// calls std.stdio.writeln(i)
|
||||||
|
__traits(getOverloads, std.stdio, "writeln", true)[0](i);
|
||||||
|
|
||||||
|
foreach (o; __traits(getOverloads, D, "bar", true))
|
||||||
|
writeln(o.stringof);
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
)
|
)
|
||||||
|
|
@ -1408,10 +1570,10 @@ void main()
|
||||||
Prints:
|
Prints:
|
||||||
|
|
||||||
$(CONSOLE
|
$(CONSOLE
|
||||||
void()
|
void function()
|
||||||
int()
|
int function(int)
|
||||||
void()
|
void function()
|
||||||
int()
|
int function(int)
|
||||||
2
|
2
|
||||||
bar(T)()
|
bar(T)()
|
||||||
bar(int n)
|
bar(int n)
|
||||||
|
|
@ -1473,6 +1635,43 @@ export
|
||||||
public
|
public
|
||||||
)
|
)
|
||||||
|
|
||||||
|
$(H3 $(GNAME fullyQualifiedName))
|
||||||
|
|
||||||
|
$(P Takes one argument, which can be a type, expression, or symbol, and returns a string.)
|
||||||
|
|
||||||
|
$(UL
|
||||||
|
$(LI A $(D type) returns a string representing the type.)
|
||||||
|
$(LI A $(D expression) returns a string representing the type of the expression.)
|
||||||
|
$(LI A $(D symbol) returns a string representing the fully qualified name of the symbol.)
|
||||||
|
)
|
||||||
|
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
|
---
|
||||||
|
module plugh;
|
||||||
|
import std.stdio;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
auto s = __traits(fullyQualifiedName, int);
|
||||||
|
writeln(s);
|
||||||
|
|
||||||
|
auto t = __traits(fullyQualifiedName, 1.0);
|
||||||
|
writeln(t);
|
||||||
|
|
||||||
|
auto u = __traits(fullyQualifiedName, t);
|
||||||
|
writeln(u);
|
||||||
|
}
|
||||||
|
---
|
||||||
|
)
|
||||||
|
|
||||||
|
Prints:
|
||||||
|
|
||||||
|
$(CONSOLE
|
||||||
|
int
|
||||||
|
double
|
||||||
|
plugh.main.t
|
||||||
|
)
|
||||||
|
|
||||||
$(H3 $(GNAME getProtection))
|
$(H3 $(GNAME getProtection))
|
||||||
|
|
||||||
$(P A backward-compatible alias for $(GLINK getVisibility).)
|
$(P A backward-compatible alias for $(GLINK getVisibility).)
|
||||||
|
|
@ -1507,15 +1706,13 @@ $(H3 $(GNAME getUnitTests))
|
||||||
Takes one argument, a symbol of an aggregate (e.g. struct/class/module).
|
Takes one argument, a symbol of an aggregate (e.g. struct/class/module).
|
||||||
The result is a symbol sequence of all the unit test functions of that aggregate.
|
The result is a symbol sequence of all the unit test functions of that aggregate.
|
||||||
The functions returned are like normal nested static functions,
|
The functions returned are like normal nested static functions,
|
||||||
$(DDSUBLINK glossary, ctfe, CTFE) will work and
|
$(DDSUBLINK spec/glossary, ctfe, CTFE) will work and
|
||||||
$(DDSUBLINK spec/attribute, uda, UDAs) will be accessible.
|
$(DDSUBLINK spec/attribute, uda, UDAs) will be accessible.
|
||||||
)
|
)
|
||||||
|
|
||||||
$(H4 Note:)
|
$(NOTE
|
||||||
|
The `-unittest` flag needs to be passed to the compiler. If the flag
|
||||||
$(P
|
is not passed, $(CODE __traits(getUnitTests)) will always return an
|
||||||
The -unittest flag needs to be passed to the compiler. If the flag
|
|
||||||
is not passed $(CODE __traits(getUnitTests)) will always return an
|
|
||||||
empty sequence.
|
empty sequence.
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1639,7 +1836,8 @@ $(H3 $(GNAME allMembers))
|
||||||
$(P Takes a single argument, which must evaluate to either
|
$(P Takes a single argument, which must evaluate to either
|
||||||
a module, a struct, a union, a class, an interface, an enum, or a
|
a module, a struct, a union, a class, an interface, an enum, or a
|
||||||
template instantiation.
|
template instantiation.
|
||||||
|
)
|
||||||
|
$(P
|
||||||
A sequence of string literals is returned, each of which
|
A sequence of string literals is returned, each of which
|
||||||
is the name of a member of that argument combined with all
|
is the name of a member of that argument combined with all
|
||||||
of the members of its base classes (if the argument is a class).
|
of the members of its base classes (if the argument is a class).
|
||||||
|
|
@ -1730,6 +1928,30 @@ static assert(__traits(isSame, object, object));
|
||||||
alias daz = foo;
|
alias daz = foo;
|
||||||
static assert(__traits(isSame, foo, daz));
|
static assert(__traits(isSame, foo, daz));
|
||||||
---
|
---
|
||||||
|
)
|
||||||
|
$(P isSame matches against non-instantiated templates.)
|
||||||
|
|
||||||
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
|
---
|
||||||
|
struct Foo(T){
|
||||||
|
T x;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Bar(T){
|
||||||
|
T x;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Point(T){
|
||||||
|
T x;
|
||||||
|
T y;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum isFooOrBar(alias FB) = __traits(isSame, FB, Foo) || __traits(isSame, FB, Bar);
|
||||||
|
|
||||||
|
static assert(isFooOrBar!(Foo));
|
||||||
|
static assert(isFooOrBar!(Bar));
|
||||||
|
static assert(!isFooOrBar!(Point));
|
||||||
|
---
|
||||||
)
|
)
|
||||||
|
|
||||||
$(P The result is `true` if the two arguments are expressions
|
$(P The result is `true` if the two arguments are expressions
|
||||||
|
|
@ -1845,14 +2067,27 @@ $(H3 $(GNAME compiles))
|
||||||
compile (are semantically correct).
|
compile (are semantically correct).
|
||||||
The arguments can be symbols, types, or expressions that
|
The arguments can be symbols, types, or expressions that
|
||||||
are syntactically correct.
|
are syntactically correct.
|
||||||
The arguments cannot be statements or declarations.
|
The arguments cannot be statements or declarations - instead
|
||||||
|
these can be wrapped in a $(DDSUBLINK spec/expression, function_literals,
|
||||||
|
function literal) expression.
|
||||||
)
|
)
|
||||||
|
|
||||||
$(P If there are no arguments, the result is $(D false).)
|
$(P If there are no arguments, the result is $(D false).)
|
||||||
|
|
||||||
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
|
||||||
---
|
---
|
||||||
import std.stdio;
|
static assert(!__traits(compiles));
|
||||||
|
static assert(__traits(compiles, 1 + 1)); // expression
|
||||||
|
static assert(__traits(compiles, typeof(1))); // type
|
||||||
|
static assert(__traits(compiles, object)); // symbol
|
||||||
|
static assert(__traits(compiles, 1, 2, 3, int, long));
|
||||||
|
static assert(!__traits(compiles, 3[1])); // semantic error
|
||||||
|
static assert(!__traits(compiles, 1, 2, 3, int, long, 3[1]));
|
||||||
|
|
||||||
|
enum n = 3;
|
||||||
|
// wrap a declaration/statement in a function literal
|
||||||
|
static assert(__traits(compiles, { int[n] arr; }));
|
||||||
|
static assert(!__traits(compiles, { foreach (e; n) {} }));
|
||||||
|
|
||||||
struct S
|
struct S
|
||||||
{
|
{
|
||||||
|
|
@ -1860,29 +2095,23 @@ struct S
|
||||||
int s2;
|
int s2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int foo();
|
static assert(__traits(compiles, S.s1 = 0));
|
||||||
int bar();
|
static assert(!__traits(compiles, S.s2 = 0));
|
||||||
|
static assert(!__traits(compiles, S.s3));
|
||||||
|
|
||||||
void main()
|
int foo();
|
||||||
{
|
|
||||||
writeln(__traits(compiles)); // false
|
static assert(__traits(compiles, foo));
|
||||||
writeln(__traits(compiles, foo)); // true
|
static assert(__traits(compiles, foo + 1)); // call foo with optional parens
|
||||||
writeln(__traits(compiles, foo + 1)); // true
|
static assert(!__traits(compiles, &foo + 1));
|
||||||
writeln(__traits(compiles, &foo + 1)); // false
|
|
||||||
writeln(__traits(compiles, typeof(1))); // true
|
|
||||||
writeln(__traits(compiles, S.s1)); // true
|
|
||||||
writeln(__traits(compiles, S.s3)); // false
|
|
||||||
writeln(__traits(compiles, 1,2,3,int,long,std)); // true
|
|
||||||
writeln(__traits(compiles, 3[1])); // false
|
|
||||||
writeln(__traits(compiles, 1,2,3,int,long,3[1])); // false
|
|
||||||
}
|
|
||||||
---
|
---
|
||||||
)
|
)
|
||||||
|
|
||||||
$(P This is useful for:)
|
$(P This is useful for:)
|
||||||
|
|
||||||
$(UL
|
$(UL
|
||||||
$(LI Giving better error messages inside generic code than
|
$(LI Giving better error messages (using $(DDSUBLINK spec/version, static-assert,
|
||||||
|
`static assert`)) inside generic code than
|
||||||
the sometimes hard to follow compiler ones.)
|
the sometimes hard to follow compiler ones.)
|
||||||
$(LI Doing a finer grained specialization than template
|
$(LI Doing a finer grained specialization than template
|
||||||
partial specialization allows for.)
|
partial specialization allows for.)
|
||||||
|
|
@ -1891,5 +2120,5 @@ void main()
|
||||||
$(SPEC_SUBNAV_PREV_NEXT version, Conditional Compilation, errors, Error Handling)
|
$(SPEC_SUBNAV_PREV_NEXT version, Conditional Compilation, errors, Error Handling)
|
||||||
|
|
||||||
Macros:
|
Macros:
|
||||||
CHAPTER=25
|
CHAPTER=26
|
||||||
TITLE=Traits
|
TITLE=Traits
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,11 @@ classInstanceAlignment k
|
||||||
classInstanceSize k
|
classInstanceSize k
|
||||||
compiles k
|
compiles k
|
||||||
derivedMembers k
|
derivedMembers k
|
||||||
|
fullyQualifiedName k
|
||||||
getAliasThis k
|
getAliasThis k
|
||||||
getAttributes k
|
getAttributes k
|
||||||
|
getBitfieldOffset k
|
||||||
|
getBitfieldWidth k
|
||||||
getCppNamespaces k
|
getCppNamespaces k
|
||||||
getFunctionAttributes k
|
getFunctionAttributes k
|
||||||
getFunctionVariadicStyle k
|
getFunctionVariadicStyle k
|
||||||
|
|
@ -25,6 +28,7 @@ getVirtualMethods k
|
||||||
getVisibility k
|
getVisibility k
|
||||||
hasCopyConstructor k
|
hasCopyConstructor k
|
||||||
hasMember k
|
hasMember k
|
||||||
|
hasMoveConstructor k
|
||||||
hasPostblit k
|
hasPostblit k
|
||||||
identifier k
|
identifier k
|
||||||
initSymbol k
|
initSymbol k
|
||||||
|
|
@ -32,6 +36,7 @@ isAbstractClass k
|
||||||
isAbstractFunction k
|
isAbstractFunction k
|
||||||
isArithmetic k
|
isArithmetic k
|
||||||
isAssociativeArray k
|
isAssociativeArray k
|
||||||
|
isCOMClass k
|
||||||
isCopyable k
|
isCopyable k
|
||||||
isDeprecated k
|
isDeprecated k
|
||||||
isDisabled k
|
isDisabled k
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue