Spec-Zone.ru › D

std.traits

Шаблоны, которые извлекают информацию о типах и символах во время компиляции.

Категория Шаблоны
Свойства имени символа fullyQualifiedName moduleName packageName
Свойства функции isFunction arity functionAttributes hasFunctionAttributes functionLinkage FunctionTypeOf isSafe isUnsafe isFinal ParameterDefaults ParameterIdentifierTuple ParameterStorageClassTuple Parameters ReturnType SetFunctionAttributes variadicFunctionStyle
Свойства агрегатного типа BaseClassesTuple BaseTypeTuple classInstanceAlignment EnumMembers FieldNameTuple Fields hasAliasing hasElaborateAssign hasElaborateCopyConstructor hasElaborateDestructor hasElaborateMove hasIndirections hasMember hasStaticMember hasNested hasUnsharedAliasing InterfacesTuple isInnerClass isNested MemberFunctionsTuple RepresentationTypeTuple TemplateArgsOf TemplateOf TransitiveBaseTypeTuple
Преобразование типов CommonType ImplicitConversionTargets CopyTypeQualifiers CopyConstness isAssignable isCovariantWith isImplicitlyConvertible
SomethingTypeOf rvalueOf lvalueOf InoutOf ConstOf SharedOf SharedInoutOf SharedConstOf ImmutableOf QualifierOf
Категории типов allSameType ifTestable isType isAggregateType isArray isAssociativeArray isAutodecodableString isBasicType isBoolean isBuiltinType isCopyable isDynamicArray isEqualityComparable isFloatingPoint isIntegral isNarrowString isConvertibleToString isNumeric isOrderingComparable isPointer isScalarType isSigned isSIMDVector isSomeChar isSomeString isStaticArray isUnsigned
Поведение типов isAbstractClass isAbstractFunction isCallable isDelegate isExpressions isFinalClass isFinalFunction isFunctionPointer isInstanceOf isIterable isMutable isSomeFunction isTypeTuple
Общие типы ForeachType KeyType Largest mostNegative OriginalType PointerTarget Signed Unconst Unqual Unsigned ValueType Promoted
Разное mangledName Select select
Пользовательские атрибуты hasUDA getUDAs getSymbolsByUDA
Лицензия:
Лицензия Boost 1.0.
Авторы:
Walter Bright, Tomasz Stachowiak (isExpressions), Andrei Alexandrescu, Shin Fujishiro, Robert Clipsham, David Nadlinger, Kenji Hara, Shoichi Kato
Исходный код
std/traits.d
END_OF_DOCUMENT_MARKER
template InoutOf(T)
Параметры:
T Тип для квалификации
Возвращает:
T с добавленным квалификатором inout.
Примеры:
static assert(is(InoutOf!(int) == inout int));
static assert(is(InoutOf!(inout int) == inout int));
static assert(is(InoutOf!(const int) == inout const int));
static assert(is(InoutOf!(shared int) == inout shared int));
template ConstOf(T)
Параметры:
T Тип для квалификации
Возвращает:
T с добавленным квалификатором const.
Примеры:
static assert(is(ConstOf!(int) == const int));
static assert(is(ConstOf!(const int) == const int));
static assert(is(ConstOf!(inout int) == const inout int));
static assert(is(ConstOf!(shared int) == const shared int));
template SharedOf(T)
Параметры:
T Тип для квалификации
Возвращает:
T с добавленным квалификатором shared.
Примеры:
static assert(is(SharedOf!(int) == shared int));
static assert(is(SharedOf!(shared int) == shared int));
static assert(is(SharedOf!(inout int) == shared inout int));
static assert(is(SharedOf!(immutable int) == shared immutable int));
template SharedInoutOf(T)
Параметры:
T Тип для квалификации
Возвращает:
T с добавленными квалификаторами inout и shared.
Примеры:
static assert(is(SharedInoutOf!(int) == shared inout int));
static assert(is(SharedInoutOf!(int) == inout shared int));

static assert(is(SharedInoutOf!(const int) == shared inout const int));
static assert(is(SharedInoutOf!(immutable int) == shared inout immutable int));
template SharedConstOf(T)
Параметры:
T Тип для квалификации
Возвращает:
T с добавленными квалификаторами const и shared.
Примеры:
static assert(is(SharedConstOf!(int) == shared const int));
static assert(is(SharedConstOf!(int) == const shared int));

static assert(is(SharedConstOf!(inout int) == shared inout const int));
// immutable variables are implicitly shared and const
static assert(is(SharedConstOf!(immutable int) == immutable int));
template ImmutableOf(T)
Параметры:
T Тип для квалификации
Возвращает:
T с добавленным квалификатором immutable.
Примеры:
static assert(is(ImmutableOf!(int) == immutable int));
static assert(is(ImmutableOf!(const int) == immutable int));
static assert(is(ImmutableOf!(inout int) == immutable int));
static assert(is(ImmutableOf!(shared int) == immutable int));
template QualifierOf(T)

Предоставляет шаблон, который можно использовать для применения тех же атрибутов, что и к данному типу T. Например, передавая inout shared int будет возвращено SharedInoutOf.

Параметры:
T тип, из которого нужно проверить квалификаторы
Возвращает:
Шаблон квалификатора из заданного типа T
Примеры:
static assert(__traits(isSame, QualifierOf!(immutable int), ImmutableOf));
static assert(__traits(isSame, QualifierOf!(shared int), SharedOf));
static assert(__traits(isSame, QualifierOf!(shared inout int), SharedInoutOf));
template packageName(alias T)

Получить полное имя пакета для данного символа.

Примеры:
static assert(packageName!packageName == "std");
Примеры:
static assert(packageName!moduleName == "std");
template moduleName(alias T)

Получить имя модуля (включая пакет) для данного символа.

Примеры:
static assert(moduleName!moduleName == "std.traits");
template fullyQualifiedName(T...) if (T.length == 1)

Получить полное квалифицированное имя типа или символа. Может выступать в роли интеллектуального преобразователя типа/символа в строку.

Пример
module myModule;
struct MyStruct {}
static assert(fullyQualifiedName!(const MyStruct[]) == "const(myModule.MyStruct[])");
Примеры:
static assert(fullyQualifiedName!fullyQualifiedName == "std.traits.fullyQualifiedName");
template ReturnType(func...) if (func.length == 1 && isCallable!func)

Получить тип возвращаемого значения из функции, указателя на функцию, делегата, структуры с opCall, указателя на структуру с opCall или класса с opCall. Обратите внимание, что ref не является частью типа, а атрибутом функции (см. шаблон functionAttributes).

Примеры:
int foo();
ReturnType!foo x;   // x is declared as int
template Parameters(func...) if (func.length == 1 && isCallable!func)

Получить, как кортеж, типы параметров функции, указателя на функцию, делегата, структуры с opCall, указателя на структуру с opCall, или класса с opCall.

Примеры:
int foo(int, long);
void bar(Parameters!foo);      // declares void bar(int, long);
void abc(Parameters!foo[1]);   // declares void abc(long);
alias ParameterTypeTuple = Parameters(func...) if (func.length == 1 && isCallable!func);

Альтернативное имя для Parameters, сохранено для совместимости со старыми версиями.

template arity(func...) if (func.length == 1 && isCallable!func && (variadicFunctionStyle!func == Variadic.no))

Возвращает количество аргументов функции func. arity не определено для функций с переменным числом аргументов.

Примеры:
void foo(){}
static assert(arity!foo == 0);
void bar(uint){}
static assert(arity!bar == 1);
void variadicFoo(uint...){}
static assert(!__traits(compiles, arity!variadicFoo));
enum ParameterStorageClass: uint;

template ParameterStorageClassTuple(func...) if (func.length == 1 && isCallable!func)

Получить кортеж, по одному на каждый параметр функции, классов хранения параметров.

Параметры:
func символ функции или тип функции, делегата или указателя на функцию
Возвращает:
Кортеж битов ParameterStorageClass
Примеры:
alias STC = ParameterStorageClass; // shorten the enum name

void func(ref int ctx, out real result, in real param, void* ptr)
{
}
alias pstc = ParameterStorageClassTuple!func;
static assert(pstc.length == 4); // number of parameters
static assert(pstc[0] == STC.ref_);
static assert(pstc[1] == STC.out_);
version (none)
{
    // TODO: When the DMD PR (dlang/dmd#11474) gets merged,
    // remove the versioning and the second test
    static assert(pstc[2] == STC.in_);
    // This is the current behavior, before `in` is fixed to not be an alias
    static assert(pstc[2] == STC.scope_);
}
static assert(pstc[3] == STC.none);
none

in_

ref_

out_

lazy_

scope_

return_

Эти флаги могут быть побитово объединены для представления сложного класса хранения.

enum ParameterStorageClass extractParameterStorageClassFlags(Attribs...);

Преобразовать результат __traits(getParameterStorageClasses) в ParameterStorageClass enum.

Параметры:
Attribs Возвращаемое значение __traits(getParameterStorageClasses)
Возвращает:
Побитовое ИЛИ эквивалентных ParameterStorageClass enum.
Примеры:
static void func(ref int ctx, out real result);

enum param1 = extractParameterStorageClassFlags!(
    __traits(getParameterStorageClasses, func, 0)
);
static assert(param1 == ParameterStorageClass.ref_);

enum param2 = extractParameterStorageClassFlags!(
    __traits(getParameterStorageClasses, func, 1)
);
static assert(param2 == ParameterStorageClass.out_);

enum param3 = extractParameterStorageClassFlags!(
    __traits(getParameterStorageClasses, func, 0),
    __traits(getParameterStorageClasses, func, 1)
);
static assert(param3 == (ParameterStorageClass.ref_ | ParameterStorageClass.out_));
template ParameterIdentifierTuple(func...) if (func.length == 1 && isCallable!func)

Получить, как кортеж, идентификаторы параметров к символу функции.

Примеры:
int foo(int num, string name, int);
static assert([ParameterIdentifierTuple!foo] == ["num", "name", ""]);
template ParameterDefaults(func...) if (func.length == 1 && isCallable!func)

Получить, как кортеж, значение по умолчанию параметров к символу функции. Если параметр не имеет значения по умолчанию, возвращается void.

Примеры:
int foo(int num, string name = "hello", int[] = [1,2,3], lazy int x = 0);
static assert(is(ParameterDefaults!foo[0] == void));
static assert(   ParameterDefaults!foo[1] == "hello");
static assert(   ParameterDefaults!foo[2] == [1,2,3]);
static assert(   ParameterDefaults!foo[3] == 0);
alias ParameterDefaultValueTuple = ParameterDefaults(func...) if (func.length == 1 && isCallable!func);

Альтернативное имя для ParameterDefaults, сохранено для совместимости со старыми версиями.

enum FunctionAttribute: uint;

template functionAttributes(func...) if (func.length == 1 && isCallable!func)

Возвращает маску FunctionAttribute для функции func.

См. также:
hasFunctionAttributes
Примеры:
alias FA = FunctionAttribute; // shorten the enum name

real func(real x) pure nothrow @safe
{
    return x;
}
static assert(functionAttributes!func & FA.pure_);
static assert(functionAttributes!func & FA.safe);
static assert(!(functionAttributes!func & FA.trusted)); // not @trusted
none

pure_

nothrow_

ref_

property

trusted

safe

nogc

system

const_

immutable_

inout_

shared_

return_

scope_

live

Эти флаги могут быть побитово объединены для представления сложного атрибута.

template hasFunctionAttributes(args...) if (args.length > 0 && isCallable!(args[0]) && allSatisfy!(isSomeString, typeof(args[1..$])))

Проверяет, имеет ли функция заданные атрибуты.

Параметры:
args Функция для проверки, за которым следует переменное число атрибутов функции в виде строк
Возвращает:
true, если функция имеет указанный список атрибутов, и false в противном случае.
См. также:
functionAttributes
Примеры:
real func(real x) pure nothrow @safe;
static assert(hasFunctionAttributes!(func, "@safe", "pure"));
static assert(!hasFunctionAttributes!(func, "@trusted"));

// for templates attributes are automatically inferred
bool myFunc(T)(T b)
{
    return !b;
}
static assert(hasFunctionAttributes!(myFunc!bool, "@safe", "pure", "@nogc", "nothrow"));
static assert(!hasFunctionAttributes!(myFunc!bool, "shared"));
template isSafe(alias func) if (isCallable!func)

true если func является @safe или @trusted.

Примеры:
@safe    int add(int a, int b) {return a+b;}
@trusted int sub(int a, int b) {return a-b;}
@system  int mul(int a, int b) {return a*b;}

static assert( isSafe!add);
static assert( isSafe!sub);
static assert(!isSafe!mul);
enum auto isUnsafe(alias func);

true если func является @system.

Примеры:
@safe    int add(int a, int b) {return a+b;}
@trusted int sub(int a, int b) {return a-b;}
@system  int mul(int a, int b) {return a*b;}

static assert(!isUnsafe!add);
static assert(!isUnsafe!sub);
static assert( isUnsafe!mul);
template functionLinkage(func...) if (func.length == 1 && isCallable!func)

Определите атрибут связи функции.

Параметры:
func символ функции или тип функции, делегата или указателя на функцию
Возвращает:
одну из строк "D", "C", "C++", "Windows", "Objective-C" или "System".
Примеры:
extern(D) void Dfunc() {}
extern(C) void Cfunc() {}
static assert(functionLinkage!Dfunc == "D");
static assert(functionLinkage!Cfunc == "C");

string a = functionLinkage!Dfunc;
writeln(a); // "D"

auto fp = &Cfunc;
string b = functionLinkage!fp;
writeln(b); // "C"
enum Variadic: int;

template variadicFunctionStyle(func...) if (func.length == 1 && isCallable!func)

Определяет, какой тип параметров с переменным числом аргументов имеет функция.

Параметры:
func символ функции или тип функции, делегата или указателя на функцию
Возвращает:
перечисление Variadic
Примеры:
void func() {}
static assert(variadicFunctionStyle!func == Variadic.no);

extern(C) int printf(in char*, ...);
static assert(variadicFunctionStyle!printf == Variadic.c);
no

Функция не является функцией с переменным числом аргументов.

c

Функция является функцией с переменным числом аргументов в стиле C, которая использует core.stdc.stdarg

d

Функция является функцией с переменным числом аргументов в стиле D, которая использует __argptr и __arguments.

typesafe

Функция является безопасной функцией с переменным числом аргументов.

template FunctionTypeOf(func...) if (func.length == 1 && isCallable!func)

Получить тип функции из вызываемого объекта func.

Использование встроенной функции typeof для функции свойства возвращает типы значения свойства, а не самой функции свойства. Тем не менее, FunctionTypeOf может получить типы функций свойств.

Примечание
Не путайте типы функций с типами указателей на функции; типы функций обычно используются для целей рефлексии на этапе компиляции.
Примеры:
class C
{
    int value() @property { return 0; }
}
static assert(is( typeof(C.value) == int ));
static assert(is( FunctionTypeOf!(C.value) == function ));
template SetFunctionAttributes(T, string linkage, uint attrs) if (isFunctionPointer!T || isDelegate!T)

template SetFunctionAttributes(T, string linkage, uint attrs) if (is(T == function))

Создает новый тип функции или делегата с той же базовой сигнатурой, что и заданный, но с другими атрибутами (включая связь).

Это особенно полезно для добавления/удаления атрибутов из типов в обобщенном коде, где имя фактического типа нельзя указать.

Параметры:
T Базовый тип.
linkage Желаемая связь результата типа.
attrs Желаемые FunctionAttribute результата типа.
Примеры:
alias ExternC(T) = SetFunctionAttributes!(T, "C", functionAttributes!T);

auto assumePure(T)(T t)
if (isFunctionPointer!T || isDelegate!T)
{
    enum attrs = functionAttributes!T | FunctionAttribute.pure_;
    return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t;
}

int f()
{
    import core.thread : getpid;
    return getpid();
}

int g() pure @trusted
{
    auto pureF = assumePure(&f);
    return pureF();
}
assert(g() > 0);
template isInnerClass(T) if (is(T == class))

Определяет, является ли T классом, вложенным внутри другого класса, и что T.outer является неявной ссылкой на внешний класс (т.е. outer не использовался в качестве имени поля или метода)

Параметры:
T тип для проверки
Возвращает:
true если T является вложенным классом внутри другого с описанными выше условиями; false в противном случае
Примеры:
class C
{
    int outer;
}
static assert(!isInnerClass!C);

class Outer1
{
    class Inner1 { }
    class Inner2
    {
        int outer;
    }
}
static assert(isInnerClass!(Outer1.Inner1));
static assert(!isInnerClass!(Outer1.Inner2));

static class Outer2
{
    static class Inner
    {
        int outer;
    }
}
static assert(!isInnerClass!(Outer2.Inner));
template isNested(T) if (is(T == class) || is(T == struct) || is(T == union))

Определяет, имеет ли T собственный указатель контекста. T должен быть либо class, либо struct, либо union.

Примеры:
static struct S { }
static assert(!isNested!S);

int i;
struct NestedStruct { void f() { ++i; } }
static assert(isNested!NestedStruct);
template hasNested(T)

Определяет, имеет ли T или любой из его типов представления указатель контекста.

Примеры:
static struct S { }

int i;
struct NS { void f() { ++i; } }

static assert(!hasNested!(S[2]));
static assert(hasNested!(NS[2]));
template Fields(T)

Получить в виде кортежа типы полей структуры, класса или объединения. Это включает поля, занимающие место в памяти, исключая скрытые поля, такие как указатель таблицы виртуальных функций или указатель контекста для вложенных типов. Если T не является структурой, классом или объединением, возвращает кортеж с одним элементом T.

Примеры:
import std.meta : AliasSeq;
struct S { int x; float y; }
static assert(is(Fields!S == AliasSeq!(int, float)));
alias FieldTypeTuple = Fields(T);

Альтернативное имя для Fields, сохранено для обратной совместимости.

template FieldNameTuple(T)

Получить в виде выражения кортежа имена полей структуры, класса или объединения. Это включает поля, занимающие место в памяти, исключая скрытые поля, такие как указатель таблицы виртуальных функций или указатель контекста для вложенных типов. Не включаются унаследованные поля (для классов). Если T не является структурой, классом или объединением, возвращается кортеж выражений с пустой строкой.

Примеры:
import std.meta : AliasSeq;
struct S { int x; float y; }
static assert(FieldNameTuple!S == AliasSeq!("x", "y"));
static assert(FieldNameTuple!int == AliasSeq!"");
template RepresentationTypeTuple(T)

Получить примитивные типы полей структуры или класса в топологическом порядке.

Примеры:
struct S1 { int a; float b; }
struct S2 { char[] a; union { S1 b; S1 * c; } }
alias R = RepresentationTypeTuple!S2;
assert(R.length == 4
    && is(R[0] == char[]) && is(R[1] == int)
    && is(R[2] == float) && is(R[3] == S1*));
enum auto hasAliasing(T...);

Возвращает true тогда и только тогда, когда представление T содержит хотя бы одно из следующих:

  1. сырой указатель U* и U не является неизменяемым;
  2. массив U[] и U не является неизменяемым;
  3. ссылка на тип класса или интерфейса C и C не является неизменяемым.
  4. ассоциативный массив, который не является неизменяемым.
  5. делегат.

Примеры:
struct S1 { int a; Object b; }
struct S2 { string a; }
struct S3 { int a; immutable Object b; }
struct S4 { float[3] vals; }
static assert( hasAliasing!S1);
static assert(!hasAliasing!S2);
static assert(!hasAliasing!S3);
static assert(!hasAliasing!S4);
template hasIndirections(T)

Возвращает true тогда и только тогда, когда представление T содержит хотя бы одно из следующих:

  1. сырой указатель U*;
  2. массив U[];
  3. ссылка на тип класса C;
  4. ассоциативный массив;
  5. делегат;
  6. a context pointer.

Примеры:
static assert( hasIndirections!(int[string]));
static assert( hasIndirections!(void delegate()));
static assert( hasIndirections!(void delegate() immutable));
static assert( hasIndirections!(immutable(void delegate())));
static assert( hasIndirections!(immutable(void delegate() immutable)));

static assert(!hasIndirections!(void function()));
static assert( hasIndirections!(void*[1]));
static assert(!hasIndirections!(byte[1]));
enum auto hasUnsharedAliasing(T...);

Возвращает true тогда и только тогда, когда представление T содержит хотя бы одно из следующих:

  1. сырой указатель U* и U не является неизменяемым или общим;
  2. массив U[] и U не является неизменяемым или общим;
  3. ссылка на тип класса C и C не является неизменяемым или общим.
  4. ассоциативный массив, который не является неизменяемым или общим.
  5. делегат, который не является общим.

Примеры:
struct S1 { int a; Object b; }
struct S2 { string a; }
struct S3 { int a; immutable Object b; }
static assert( hasUnsharedAliasing!S1);
static assert(!hasUnsharedAliasing!S2);
static assert(!hasUnsharedAliasing!S3);

struct S4 { int a; shared Object b; }
struct S5 { char[] a; }
struct S6 { shared char[] b; }
struct S7 { float[3] vals; }
static assert(!hasUnsharedAliasing!S4);
static assert( hasUnsharedAliasing!S5);
static assert(!hasUnsharedAliasing!S6);
static assert(!hasUnsharedAliasing!S7);
template hasElaborateCopyConstructor(S)

Истина, если S или любой тип, встроенный непосредственно в представление S, определяет сложный конструктор копирования. Сложные конструкторы копирования вводятся путем определения this(this) для struct.

Классы и объединения никогда не имеют сложных конструкторов копирования.

Примеры:
static assert(!hasElaborateCopyConstructor!int);

static struct S1 { }
static struct S2 { this(this) {} }
static struct S3 { S2 field; }
static struct S4 { S3[1] field; }
static struct S5 { S3[] field; }
static struct S6 { S3[0] field; }
static struct S7 { @disable this(); S3 field; }
static assert(!hasElaborateCopyConstructor!S1);
static assert( hasElaborateCopyConstructor!S2);
static assert( hasElaborateCopyConstructor!(immutable S2));
static assert( hasElaborateCopyConstructor!S3);
static assert( hasElaborateCopyConstructor!(S3[1]));
static assert(!hasElaborateCopyConstructor!(S3[0]));
static assert( hasElaborateCopyConstructor!S4);
static assert(!hasElaborateCopyConstructor!S5);
static assert(!hasElaborateCopyConstructor!S6);
static assert( hasElaborateCopyConstructor!S7);
template hasElaborateAssign(S)

Истина, если S или любой тип, непосредственно встроенный в представление S, определяет сложное присваивание. Сложные присваивания вводятся путем определения opAssign(typeof(this)) или opAssign(ref typeof(this)) для struct, или когда существует сгенерированное компилятором opAssign.

Тип S получает сгенерированное компилятором opAssign если у него есть сложный деструктор.

Классы и объединения никогда не имеют сложных присваиваний.

Примечание
Структуры с оператором(ами) постблит (возможно вложенными) будут иметь скрытый, но сложный сгенерированный компилятором оператор присваивания (если его явно не отключить).
Примеры:
static assert(!hasElaborateAssign!int);

static struct S  { void opAssign(S) {} }
static assert( hasElaborateAssign!S);
static assert(!hasElaborateAssign!(const(S)));

static struct S1 { void opAssign(ref S1) {} }
static struct S2 { void opAssign(int) {} }
static struct S3 { S s; }
static assert( hasElaborateAssign!S1);
static assert(!hasElaborateAssign!S2);
static assert( hasElaborateAssign!S3);
static assert( hasElaborateAssign!(S3[1]));
static assert(!hasElaborateAssign!(S3[0]));
template hasElaborateDestructor(S)

Истина, если S или любой тип, непосредственно встроенный в представление S, определяет сложный деструктор. Сложные деструкторы вводятся путем определения ~this() для struct.

Классы и объединения никогда не имеют сложных деструкторов, даже если классы могут определять ~this().

Примеры:
static assert(!hasElaborateDestructor!int);

static struct S1 { }
static struct S2 { ~this() {} }
static struct S3 { S2 field; }
static struct S4 { S3[1] field; }
static struct S5 { S3[] field; }
static struct S6 { S3[0] field; }
static struct S7 { @disable this(); S3 field; }
static assert(!hasElaborateDestructor!S1);
static assert( hasElaborateDestructor!S2);
static assert( hasElaborateDestructor!(immutable S2));
static assert( hasElaborateDestructor!S3);
static assert( hasElaborateDestructor!(S3[1]));
static assert(!hasElaborateDestructor!(S3[0]));
static assert( hasElaborateDestructor!S4);
static assert(!hasElaborateDestructor!S5);
static assert(!hasElaborateDestructor!S6);
static assert( hasElaborateDestructor!S7);
template hasElaborateMove(S)

Истина, если S или любой тип, встроенный непосредственно в представление S, определяет сложные семантики перемещения. Сложные семантики перемещения вводятся путем определения opPostMove(ref typeof(this)) для struct.

Классы и объединения никогда не имеют сложных семантик перемещения.

Примеры:
static assert(!hasElaborateMove!int);

static struct S1 { }
static struct S2 { void opPostMove(ref S2) {} }
static struct S3 { void opPostMove(inout ref S3) inout {} }
static struct S4 { void opPostMove(const ref S4) {} }
static struct S5 { void opPostMove(S5) {} }
static struct S6 { void opPostMove(int) {} }
static struct S7 { S3[1] field; }
static struct S8 { S3[] field; }
static struct S9 { S3[0] field; }
static struct S10 { @disable this(); S3 field; }
static assert(!hasElaborateMove!S1);
static assert( hasElaborateMove!S2);
static assert( hasElaborateMove!S3);
static assert( hasElaborateMove!(immutable S3));
static assert( hasElaborateMove!S4);
static assert(!hasElaborateMove!S5);
static assert(!hasElaborateMove!S6);
static assert( hasElaborateMove!S7);
static assert(!hasElaborateMove!S8);
static assert(!hasElaborateMove!S9);
static assert( hasElaborateMove!S10);
enum auto hasMember(T, string name);

Возвращает true тогда и только тогда, когда T является агрегатом, который определяет символ, называемый name.

Примеры:
static assert(!hasMember!(int, "blah"));
struct S1 { int blah; }
struct S2 { int blah(){ return 0; } }
class C1 { int blah; }
class C2 { int blah(){ return 0; } }
static assert(hasMember!(S1, "blah"));
static assert(hasMember!(S2, "blah"));
static assert(hasMember!(C1, "blah"));
static assert(hasMember!(C2, "blah"));
template hasStaticMember(T, string member)

Указывает, существует ли символ, представленный строкой или членом, и является ли он статическим членом T.

Параметры:
T Тип, содержащий символ member.
member Имя символа для проверки, который находится в T.
Возвращает:
true если member существует и является статическим.
Примеры:
static struct S
{
    static void sf() {}
    void f() {}

    static int si;
    int i;
}

static assert( hasStaticMember!(S, "sf"));
static assert(!hasStaticMember!(S, "f"));

static assert( hasStaticMember!(S, "si"));
static assert(!hasStaticMember!(S, "i"));

static assert(!hasStaticMember!(S, "hello"));
template EnumMembers(E) if (is(E == enum))

Возвращает члены перечисления типа enum E.

Параметры:
E Тип перечисления. E может иметь дублирующиеся значения.
Возвращает:
Статический кортеж, составленный из членов перечисления типа E. Члены упорядочены так же, как они объявлены в E. Имя перечисления можно найти, запросив у компилятора имя идентификатора, т. е. __traits(identifier, EnumMembers!MyEnum[i]). Для перечислений с уникальными значениями также можно использовать std.conv.to.
Примечание
Перечисление может иметь несколько членов с одинаковым значением. Если вы хотите использовать EnumMembers для генерации, например, операторов switch во время компиляции, вы должны использовать шаблон std.meta.NoDuplicates, чтобы избежать генерации дублирующих операторов switch.
Примечание
Возвращаемые значения строго типизированы с помощью E. Таким образом, следующий код не работает без явного приведения типа:
enum E : int { a, b, c }
int[] abc = cast(int[]) [ EnumMembers!E ];
Приведение типа не требуется, если тип переменной определяется неявно. Смотрите пример ниже.
Примеры:
Создайте массив значений перечисления
enum Sqrts : real
{
    one = 1,
    two = 1.41421,
    three = 1.73205
}
auto sqrts = [EnumMembers!Sqrts];
writeln(sqrts); // [Sqrts.one, Sqrts.two, Sqrts.three]
Примеры:
Обобщенная функция rank(v) в следующем примере использует этот шаблон для поиска члена e в типе перечисления E.
// Returns i if e is the i-th enumerator of E.
static size_t rank(E)(E e)
if (is(E == enum))
{
    static foreach (i, member; EnumMembers!E)
    {
        if (e == member)
            return i;
    }
    assert(0, "Not an enum member");
}

enum Mode
{
    read = 1,
    write = 2,
    map = 4
}
writeln(rank(Mode.read)); // 0
writeln(rank(Mode.write)); // 1
writeln(rank(Mode.map)); // 2
Примеры:
Используйте EnumMembers для генерации оператора switch с использованием static foreach.
import std.conv : to;
class FooClass
{
    string calledMethod;
    void foo() @safe { calledMethod = "foo"; }
    void bar() @safe { calledMethod = "bar"; }
    void baz() @safe { calledMethod = "baz"; }
}

enum FooEnum { foo, bar, baz }

auto var = FooEnum.bar;
auto fooObj = new FooClass();
s: final switch (var)
{
    static foreach (member; EnumMembers!FooEnum)
    {
        case member: // Generate a case for each enum value.
            // Call fooObj.{name of enum value}().
            __traits(getMember, fooObj, to!string(member))();
            break s;
    }
}
// As we pass in FooEnum.bar, the bar() method gets called.
writeln(fooObj.calledMethod); // "bar"
template BaseTypeTuple(A)

Получить AliasSeq базового класса и базовых интерфейсов этого класса или интерфейса. BaseTypeTuple!Object возвращает пустой кортеж типов.

Примеры:
import std.meta : AliasSeq;

interface I1 { }
interface I2 { }
interface I12 : I1, I2 { }
static assert(is(BaseTypeTuple!I12 == AliasSeq!(I1, I2)));

interface I3 : I1 { }
interface I123 : I1, I2, I3 { }
static assert(is(BaseTypeTuple!I123 == AliasSeq!(I1, I2, I3)));
template BaseClassesTuple(T) if (is(T == class))

Получить AliasSeq всех базовых классов этого класса в порядке убывания. Интерфейсы не включаются. BaseClassesTuple!Object возвращает пустой кортеж типов.

Примеры:
import std.meta : AliasSeq;

class C1 { }
class C2 : C1 { }
class C3 : C2 { }
static assert(!BaseClassesTuple!Object.length);
static assert(is(BaseClassesTuple!C1 == AliasSeq!(Object)));
static assert(is(BaseClassesTuple!C2 == AliasSeq!(C1, Object)));
static assert(is(BaseClassesTuple!C3 == AliasSeq!(C2, C1, Object)));
template InterfacesTuple(T)
Параметры:
T Проверяемый class или interface.
Возвращает:
std.meta.AliasSeq всех интерфейсов, прямо или косвенно унаследованных этим классом или интерфейсом. Интерфейсы не повторяются при множественном имплементировании. InterfacesTuple!Object возвращает пустой AliasSeq.
Примеры:
interface I1 {}
interface I2 {}
class A : I1, I2 {}
class B : A, I1 {}
class C : B {}

alias TL = InterfacesTuple!C;
static assert(is(TL[0] == I1) && is(TL[1] == I2));
template TransitiveBaseTypeTuple(T)

Получить AliasSeq всех базовых классов T в порядке убывания, за которыми следуют интерфейсы T. TransitiveBaseTypeTuple!Object возвращает пустой кортеж типов.

Примеры:
interface J1 {}
interface J2 {}
class B1 {}
class B2 : B1, J1, J2 {}
class B3 : B2, J1 {}
alias TL = TransitiveBaseTypeTuple!B3;
writeln(TL.length); // 5
assert(is (TL[0] == B2));
assert(is (TL[1] == B1));
assert(is (TL[2] == Object));
assert(is (TL[3] == J1));
assert(is (TL[4] == J2));

writeln(TransitiveBaseTypeTuple!Object.length); // 0
template MemberFunctionsTuple(C, string name) if (is(C == class) || is(C == interface))

Возвращает кортеж нестатических функций с именем name объявленных в классе или интерфейсе C. Ковариантные дубликаты сворачиваются в наиболее производный.

Примеры:
interface I { I foo(); }
class B
{
    real foo(real v) { return v; }
}
class C : B, I
{
    override C foo() { return this; } // covariant overriding of I.foo()
}
alias foos = MemberFunctionsTuple!(C, "foo");
static assert(foos.length == 2);
static assert(__traits(isSame, foos[0], C.foo));
static assert(__traits(isSame, foos[1], B.foo));
template TemplateOf(alias T : Base!Args, alias Base, Args...)

template TemplateOf(T : Base!Args, alias Base, Args...)

template TemplateOf(T)

Возвращает псевдоним шаблона, экземпляром которого является T. Вернет void если передан символ без шаблона.

Примеры:
struct Foo(T, U) {}
static assert(__traits(isSame, TemplateOf!(Foo!(int, real)), Foo));
template TemplateArgsOf(alias T : Base!Args, alias Base, Args...)

template TemplateArgsOf(T : Base!Args, alias Base, Args...)

Возвращает AliasSeq аргументов шаблона, используемых для экземпляризации T.

Примеры:
import std.meta : AliasSeq;

struct Foo(T, U) {}
static assert(is(TemplateArgsOf!(Foo!(int, real)) == AliasSeq!(int, real)));
template classInstanceAlignment(T) if (is(T == class))

Возвращает выравнивание экземпляра класса.

Примеры:
class A { byte b; }
class B { long l; }

// As class instance always has a hidden pointer
static assert(classInstanceAlignment!A == (void*).alignof);
static assert(classInstanceAlignment!B == long.alignof);
template CommonType(T...)

Получить тип, к которому все типы могут быть неявно приведены. Полезно, например, для определения типа массива по нескольким значениям инициализации. Возвращает void, если передан пустой список или если типы не имеют общего типа.

Примеры:
alias X = CommonType!(int, long, short);
assert(is(X == long));
alias Y = CommonType!(int, char[], short);
assert(is(Y == void));
Примеры:
static assert(is(CommonType!(3) == int));
static assert(is(CommonType!(double, 4, float) == double));
static assert(is(CommonType!(string, char[]) == const(char)[]));
static assert(is(CommonType!(3, 3U) == uint));
static assert(is(CommonType!(double, int) == double));
template ImplicitConversionTargets(T)
Параметры:
T Проверяемый тип
Возвращает:
An std.meta.AliasSeq со всеми возможными целевыми типами неявного преобразования T. Если T является классом, производным от Object, возвращается результат TransitiveBaseTypeTuple. Если тип не является встроенным скалярным типом или классом, производным от Object, возвращается пустой std.meta.AliasSeq.
Примечание
Возможные цели вычисляются более консервативно, чем это позволяет язык, исключая все опасные преобразования. Например, ImplicitConversionTargets!double не включает float.
См. также:
isImplicitlyConvertible
Примеры:
import std.meta : AliasSeq;

static assert(is(ImplicitConversionTargets!(ulong) == AliasSeq!(float, double, real)));
static assert(is(ImplicitConversionTargets!(int) == AliasSeq!(long, ulong, float, double, real)));
static assert(is(ImplicitConversionTargets!(float) == AliasSeq!(double, real)));
static assert(is(ImplicitConversionTargets!(double) == AliasSeq!(real)));

static assert(is(ImplicitConversionTargets!(char) == AliasSeq!(
    wchar, dchar, byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real
)));
static assert(is(ImplicitConversionTargets!(wchar) == AliasSeq!(
    dchar, short, ushort, int, uint, long, ulong, float, double, real
)));
static assert(is(ImplicitConversionTargets!(dchar) == AliasSeq!(
    int, uint, long, ulong, float, double, real
)));

static assert(is(ImplicitConversionTargets!(string) == AliasSeq!(const(char)[])));
static assert(is(ImplicitConversionTargets!(void*) == AliasSeq!(void*)));

interface A {}
interface B {}
class C : A, B {}

static assert(is(ImplicitConversionTargets!(C) == AliasSeq!(Object, A, B)));
static assert(is(ImplicitConversionTargets!(const C) == AliasSeq!(const Object, const A, const B)));
static assert(is(ImplicitConversionTargets!(immutable C) == AliasSeq!(
    immutable Object, immutable A, immutable B
)));
enum bool isImplicitlyConvertible(From, To);

Является ли From неявно преобразуемым к To?

Примеры:
static assert( isImplicitlyConvertible!(immutable(char), char));
static assert( isImplicitlyConvertible!(const(char), char));
static assert( isImplicitlyConvertible!(char, wchar));
static assert(!isImplicitlyConvertible!(wchar, char));

static assert(!isImplicitlyConvertible!(const(ushort), ubyte));
static assert(!isImplicitlyConvertible!(const(uint), ubyte));
static assert(!isImplicitlyConvertible!(const(ulong), ubyte));

static assert(!isImplicitlyConvertible!(const(char)[], string));
static assert( isImplicitlyConvertible!(string, const(char)[]));
enum auto isAssignable(Lhs, Rhs = Lhs);

Возвращает true если значение типа Rhs может быть присвоено переменной типа Lhs.

isAssignable возвращает, можно ли присвоить как lvalue, так и rvalue.

Если вы опустите Rhs, isAssignable проверит идентичность присваиваемого Lhs.

Примеры:
static assert( isAssignable!(long, int));
static assert(!isAssignable!(int, long));
static assert( isAssignable!(const(char)[], string));
static assert(!isAssignable!(string, char[]));

// int is assignable to int
static assert( isAssignable!int);

// immutable int is not assignable to immutable int
static assert(!isAssignable!(immutable int));
enum auto isRvalueAssignable(Lhs, Rhs = Lhs);

Возвращает true если rvalue типа Rhs может быть присвоено переменной типа Lhs

enum auto isLvalueAssignable(Lhs, Rhs = Lhs);

Возвращает true если lvalue типа Rhs может быть присвоено переменной типа Lhs

template isCovariantWith(F, G) if (is(F == function) && is(G == function) || is(F == delegate) && is(G == delegate) || isFunctionPointer!F && isFunctionPointer!G)

Определяет, является ли тип функции F ковариантным с G, т. е. функции типа F могут переопределять функции типа G.

Примеры:
interface I { I clone(); }
interface J { J clone(); }
class C : I
{
    override C clone()   // covariant overriding of I.clone()
    {
        return new C;
    }
}

// C.clone() can override I.clone(), indeed.
static assert(isCovariantWith!(typeof(C.clone), typeof(I.clone)));

// C.clone() can't override J.clone(); the return type C is not implicitly
// convertible to J.
static assert(!isCovariantWith!(typeof(C.clone), typeof(J.clone)));
@property T rvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init);

@property ref T lvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init);

Создает lvalue или rvalue типа T для typeof(...) и __traits(compiles, ...) целей. Фактическое значение не возвращается.

Параметры:
T Тип для преобразования
Примечание
Попытка использовать возвращенное значение приведет к ошибке "Символ не определен" во время компоновки.
Примеры:
static int f(int);
static assert(is(typeof(f(rvalueOf!int)) == int));
Примеры:
static bool f(ref int);
static assert(is(typeof(f(lvalueOf!int)) == bool));
enum bool isBoolean(T);

Обнаружить, является ли T встроенным булевым типом.

Примеры:
static assert( isBoolean!bool);
enum EB : bool { a = true }
static assert( isBoolean!EB);
static assert(!isBoolean!(SubTypeOf!bool));
enum bool isIntegral(T);

Обнаружить, является ли T встроенным целочисленным типом. Типы bool, char, wchar, и dchar не считаются целочисленными.

Примеры:
static assert(
    isIntegral!byte &&
    isIntegral!short &&
    isIntegral!int &&
    isIntegral!long &&
    isIntegral!(const(long)) &&
    isIntegral!(immutable(long))
);

static assert(
    !isIntegral!bool &&
    !isIntegral!char &&
    !isIntegral!double
);

// types which act as integral values do not pass
struct S
{
    int val;
    alias val this;
}

static assert(!isIntegral!S);
enum bool isFloatingPoint(T);

Обнаружить, является ли T встроенным типом с плавающей точкой.

Примеры:
static assert(
    isFloatingPoint!float &&
    isFloatingPoint!double &&
    isFloatingPoint!real &&
    isFloatingPoint!(const(real)) &&
    isFloatingPoint!(immutable(real))
);

static assert(!isFloatingPoint!int);

// complex and imaginary numbers do not pass
static assert(
    !isFloatingPoint!cfloat &&
    !isFloatingPoint!ifloat
);

// types which act as floating point values do not pass
struct S
{
    float val;
    alias val this;
}

static assert(!isFloatingPoint!S);
enum bool isNumeric(T);

Определить, является ли T встроенным числовым типом (целочисленным или с плавающей точкой).

Примеры:
static assert(
    isNumeric!byte &&
    isNumeric!short &&
    isNumeric!int &&
    isNumeric!long &&
    isNumeric!float &&
    isNumeric!double &&
    isNumeric!real &&
    isNumeric!(const(real)) &&
    isNumeric!(immutable(real))
);

static assert(
    !isNumeric!void &&
    !isNumeric!bool &&
    !isNumeric!char &&
    !isNumeric!wchar &&
    !isNumeric!dchar
);

// types which act as numeric values do not pass
struct S
{
    int val;
    alias val this;
}

static assert(!isIntegral!S);
enum bool isScalarType(T);

Определить, является ли T скалярным типом (встроенным числовым, символьным или булевым типом).

Примеры:
static assert(!isScalarType!void);
static assert( isScalarType!(immutable(byte)));
static assert( isScalarType!(immutable(ushort)));
static assert( isScalarType!(immutable(int)));
static assert( isScalarType!(ulong));
static assert( isScalarType!(shared(float)));
static assert( isScalarType!(shared(const bool)));
static assert( isScalarType!(const(char)));
static assert( isScalarType!(wchar));
static assert( isScalarType!(const(dchar)));
static assert( isScalarType!(const(double)));
static assert( isScalarType!(const(real)));
enum bool isBasicType(T);

Определить, является ли T базовым типом (скалярный тип или void).

Примеры:
static assert(isBasicType!void);
static assert(isBasicType!(const(void)));
static assert(isBasicType!(shared(void)));
static assert(isBasicType!(immutable(void)));
static assert(isBasicType!(shared const(void)));
static assert(isBasicType!(shared inout(void)));
static assert(isBasicType!(shared inout const(void)));
static assert(isBasicType!(inout(void)));
static assert(isBasicType!(inout const(void)));
static assert(isBasicType!(immutable(int)));
static assert(isBasicType!(shared(float)));
static assert(isBasicType!(shared(const bool)));
static assert(isBasicType!(const(dchar)));
enum bool isUnsigned(T);

Определить, является ли T встроенным беззнаковым числовым типом.

Примеры:
static assert(
    isUnsigned!uint &&
    isUnsigned!ulong
);

static assert(
    !isUnsigned!char &&
    !isUnsigned!int &&
    !isUnsigned!long &&
    !isUnsigned!char &&
    !isUnsigned!wchar &&
    !isUnsigned!dchar
);
enum bool isSigned(T);

Определить, является ли T встроенным знаковым числовым типом.

Примеры:
static assert(
    isSigned!int &&
    isSigned!long
);

static assert(
    !isSigned!uint &&
    !isSigned!ulong
);
enum bool isSomeChar(T);

Определить, является ли T одним из встроенных символьных типов.

Встроенные символьные типы — это любой из char, wchar или dchar, с квалификаторами или без них.

Примеры:
//Char types
static assert( isSomeChar!char);
static assert( isSomeChar!wchar);
static assert( isSomeChar!dchar);
static assert( isSomeChar!(typeof('c')));
static assert( isSomeChar!(immutable char));
static assert( isSomeChar!(const dchar));

//Non char types
static assert(!isSomeChar!int);
static assert(!isSomeChar!byte);
static assert(!isSomeChar!string);
static assert(!isSomeChar!wstring);
static assert(!isSomeChar!dstring);
static assert(!isSomeChar!(char[4]));
enum bool isSomeString(T);

Определить, является ли T одним из встроенных строковых типов.

Встроенные строковые типы — это Char[], где Char — это любой из char, wchar или dchar, с квалификаторами или без них.

Статические массивы символов (например, char[80]) не считаются встроенными строковыми типами.

Примеры:
//String types
static assert( isSomeString!string);
static assert( isSomeString!(wchar[]));
static assert( isSomeString!(dchar[]));
static assert( isSomeString!(typeof("aaa")));
static assert( isSomeString!(const(char)[]));

//Non string types
static assert(!isSomeString!int);
static assert(!isSomeString!(int[]));
static assert(!isSomeString!(byte[]));
static assert(!isSomeString!(typeof(null)));
static assert(!isSomeString!(char[4]));

enum ES : string { a = "aaa", b = "bbb" }
static assert(!isSomeString!ES);

static struct Stringish
{
    string str;
    alias str this;
}
static assert(!isSomeString!Stringish);
enum bool isNarrowString(T);

Определить, является ли тип T узкой строкой.

Все массивы, использующие char, wchar и их квалифицированные версии, являются узкими строками (включая string и wstring).

Примеры:
static assert(isNarrowString!string);
static assert(isNarrowString!wstring);
static assert(isNarrowString!(char[]));
static assert(isNarrowString!(wchar[]));

static assert(!isNarrowString!dstring);
static assert(!isNarrowString!(dchar[]));

static assert(!isNarrowString!(typeof(null)));
static assert(!isNarrowString!(char[4]));

enum ES : string { a = "aaa", b = "bbb" }
static assert(!isNarrowString!ES);

static struct Stringish
{
    string str;
    alias str this;
}
static assert(!isNarrowString!Stringish);
enum bool isOrderingComparable(T);

enum bool isEqualityComparable(T);

Определяет, является ли T сопоставимым типом. Базовые типы, структуры и классы, реализующие opCmp, являются сопоставимыми по порядку.

Примеры:
static assert(isOrderingComparable!int);
static assert(isOrderingComparable!string);
static assert(!isOrderingComparable!creal);

static struct Foo {}
static assert(!isOrderingComparable!Foo);

static struct Bar
{
    int a;
    auto opCmp(Bar b1) const { return a - b1.a; }
}

Bar b1 = Bar(5);
Bar b2 = Bar(7);
assert(isOrderingComparable!Bar && b2 > b1);
enum auto isConvertibleToString(T);

Предупреждение: Этот признак будет устаревшим, как только он перестанет использоваться в Phobos. Для того, чтобы параметр функции безопасно принимал тип, неявным образом преобразуемый в строку, как строку, преобразование должно происходить в месте вызова; в противном случае преобразование выполняется внутри функции, и во многих случаях это означает, что локальная память срезвается (например, если в функцию передается статический массив, то он копируется, а полученный динамический массив будет срезом локальной переменной). Таким образом, если результирующая строка выходит за пределы функции, строка ссылается на недопустимую память, и доступ к ней означал бы доступ к недопустимой памяти. Таким образом, единственный безопасный способ для функции принять типы, которые неявно преобразуются в строку, заключается в том, чтобы неявное преобразование происходило в месте вызова, и это может произойти только в том случае, если параметр явно типизируется как массив, тогда как использование isConvertibleToString в ограничении шаблона приведет к преобразованию внутри функции. Таким образом, isConvertibleToString по своей природе небезопасен и будет устаревшим.

Определить, является ли T структурой, статическим массивом или перечислением, неявно преобразуемым в строку.

Примеры:
static struct AliasedString
{
    string s;
    alias s this;
}

enum StringEnum { a = "foo" }

assert(!isConvertibleToString!string);
assert(isConvertibleToString!AliasedString);
assert(isConvertibleToString!StringEnum);
assert(isConvertibleToString!(char[25]));
assert(!isConvertibleToString!(char[]));
enum auto isAutodecodableString(T);

Определить, является ли тип T строкой, которая будет автоматически декодирована.

Учитывая тип S, который является одним из:

  1. const(char)[]
  2. const(wchar)[]
Тип T может быть одним из:
  1. S
  2. неявно преобразуется в T
  3. перечисление с базовым типом T
  4. агрегат с базовым типом T
с оговоркой, что T не может быть статическим массивом.

Параметры:
T тип для проверки
Возвращает:
true, если T представляет строку, которая подвергается автоматическому декодированию. См. также: isNarrowString
Примеры:
static struct Stringish
{
    string s;
    alias s this;
}
static assert(isAutodecodableString!wstring);
static assert(isAutodecodableString!Stringish);
static assert(!isAutodecodableString!dstring);

enum E : const(char)[3] { X = "abc" }
enum F : const(char)[] { X = "abc" }
enum G : F { X = F.init }

static assert(isAutodecodableString!(char[]));
static assert(!isAutodecodableString!(E));
static assert(isAutodecodableString!(F));
static assert(isAutodecodableString!(G));

struct Stringish2
{
    Stringish s;
    alias s this;
}

enum H : Stringish { X = Stringish() }
enum I : Stringish2 { X = Stringish2() }

static assert(isAutodecodableString!(H));
static assert(isAutodecodableString!(I));
enum bool isStaticArray(T);

Определить, является ли тип T статическим массивом.

Примеры:
static assert( isStaticArray!(int[3]));
static assert( isStaticArray!(const(int)[5]));
static assert( isStaticArray!(const(int)[][5]));

static assert(!isStaticArray!(const(int)[]));
static assert(!isStaticArray!(immutable(int)[]));
static assert(!isStaticArray!(const(int)[4][]));
static assert(!isStaticArray!(int[]));
static assert(!isStaticArray!(int[char]));
static assert(!isStaticArray!(int[1][]));
static assert(!isStaticArray!(int[int]));
static assert(!isStaticArray!int);
enum bool isDynamicArray(T);

Определить, является ли тип T динамическим массивом.

Примеры:
static assert( isDynamicArray!(int[]));
static assert( isDynamicArray!(string));
static assert( isDynamicArray!(long[3][]));

static assert(!isDynamicArray!(int[5]));
static assert(!isDynamicArray!(typeof(null)));
enum bool isArray(T);

Определить, является ли тип T массивом (статическим или динамическим; для ассоциативных массивов см. isAssociativeArray).

Примеры:
static assert( isArray!(int[]));
static assert( isArray!(int[5]));
static assert( isArray!(string));

static assert(!isArray!uint);
static assert(!isArray!(uint[uint]));
static assert(!isArray!(typeof(null)));
enum bool isAssociativeArray(T);

Определить, является ли T типом ассоциативного массива

enum bool isBuiltinType(T);

Определить, является ли тип T встроенным типом.

Примеры:
class C;
union U;
struct S;
interface I;

static assert( isBuiltinType!void);
static assert( isBuiltinType!string);
static assert( isBuiltinType!(int[]));
static assert( isBuiltinType!(C[string]));
static assert(!isBuiltinType!C);
static assert(!isBuiltinType!U);
static assert(!isBuiltinType!S);
static assert(!isBuiltinType!I);
static assert(!isBuiltinType!(void delegate(int)));
enum bool isSIMDVector(T);

Определить, является ли тип T типом вектора SIMD.

enum bool isPointer(T);

Определить, является ли тип T указателем.

template PointerTarget(T : T*)

Возвращает целевой тип указателя.

Примеры:
static assert(is(PointerTarget!(int*) == int));
static assert(is(PointerTarget!(void*) == void));
enum bool isAggregateType(T);

Определить, является ли тип T агрегатным типом.

Примеры:
class C;
union U;
struct S;
interface I;

static assert( isAggregateType!C);
static assert( isAggregateType!U);
static assert( isAggregateType!S);
static assert( isAggregateType!I);
static assert(!isAggregateType!void);
static assert(!isAggregateType!string);
static assert(!isAggregateType!(int[]));
static assert(!isAggregateType!(C[string]));
static assert(!isAggregateType!(void delegate(int)));
enum bool isIterable(T);

Возвращает true если T может быть итерирован с помощью цикла foreach с единственной переменной цикла автоматически выведенного типа, независимо от того, как реализован цикл foreach. Это включает диапазоны, структуры/классы, которые определяют opApply с одной переменной цикла, и встроенные динамические, статические и ассоциативные массивы.

Примеры:
struct OpApply
{
    int opApply(scope int delegate(ref uint) dg) { assert(0); }
}

struct Range
{
    @property uint front() { assert(0); }
    void popFront() { assert(0); }
    enum bool empty = false;
}

static assert( isIterable!(uint[]));
static assert( isIterable!OpApply);
static assert( isIterable!(uint[string]));
static assert( isIterable!Range);

static assert(!isIterable!uint);
enum bool isMutable(T);

Возвращает true, если T не const или неизменяемый. Обратите внимание, что isMutable true для string или immutable(char)[], потому что "головка" изменяема.

Примеры:
static assert( isMutable!int);
static assert( isMutable!string);
static assert( isMutable!(shared int));
static assert( isMutable!(shared const(int)[]));

static assert(!isMutable!(const int));
static assert(!isMutable!(inout int));
static assert(!isMutable!(shared(const int)));
static assert(!isMutable!(shared(inout int)));
static assert(!isMutable!(immutable string));
enum bool isInstanceOf(alias S, T);

enum auto isInstanceOf(alias S, alias T);

Возвращает true, если T является экземпляром шаблона S.

Примеры:
static struct Foo(T...) { }
static struct Bar(T...) { }
static struct Doo(T) { }
static struct ABC(int x) { }
static void fun(T)() { }
template templ(T) { }

static assert(isInstanceOf!(Foo, Foo!int));
static assert(!isInstanceOf!(Foo, Bar!int));
static assert(!isInstanceOf!(Foo, int));
static assert(isInstanceOf!(Doo, Doo!int));
static assert(isInstanceOf!(ABC, ABC!1));
static assert(!isInstanceOf!(Foo, Foo));
static assert(isInstanceOf!(fun, fun!int));
static assert(isInstanceOf!(templ, templ!int));
Примеры:
Для использования isInstanceOf для проверки идентичности шаблона внутри данного шаблона, используйте TemplateOf.
static struct A(T = void)
{
    // doesn't work as expected, only accepts A when T = void
    void func(B)(B b) if (isInstanceOf!(A, B)) {}

    // correct behavior
    void method(B)(B b) if (isInstanceOf!(TemplateOf!(A), B)) {}
}

A!(void) a1;
A!(void) a2;
A!(int) a3;

static assert(!__traits(compiles, a1.func(a3)));
static assert( __traits(compiles, a1.method(a2)));
static assert( __traits(compiles, a1.method(a3)));
template isExpressions(T...)

Проверить, является ли кортеж T кортежем выражений. Кортеж выражений содержит только выражения.

См. также:
isTypeTuple.
Примеры:
static assert(isExpressions!(1, 2.0, "a"));
static assert(!isExpressions!(int, double, string));
static assert(!isExpressions!(int, 2.0, "a"));
alias isExpressionTuple = isExpressions(T...);

Альтернативное имя для isExpressions, сохранено для совместимости со старыми версиями.

template isTypeTuple(T...)

Проверить, является ли кортеж T кортежем типов. Кортеж типов содержит только типы.

См. также:
isExpressions.
Примеры:
static assert(isTypeTuple!(int, float, string));
static assert(!isTypeTuple!(1, 2.0, "a"));
static assert(!isTypeTuple!(1, double, string));
template isFunctionPointer(T...) if (T.length == 1)

Определить, является ли символ или тип T указателем на функцию.

Примеры:
static void foo() {}
void bar() {}

auto fpfoo = &foo;
static assert( isFunctionPointer!fpfoo);
static assert( isFunctionPointer!(void function()));

auto dgbar = &bar;
static assert(!isFunctionPointer!dgbar);
static assert(!isFunctionPointer!(void delegate()));
static assert(!isFunctionPointer!foo);
static assert(!isFunctionPointer!bar);

static assert( isFunctionPointer!((int a) {}));
template isDelegate(T...) if (T.length == 1)

Определить, является ли символ или тип T делегатом.

Примеры:
static void sfunc() { }
int x;
void func() { x++; }

int delegate() dg;
assert(isDelegate!dg);
assert(isDelegate!(int delegate()));
assert(isDelegate!(typeof(&func)));

int function() fp;
assert(!isDelegate!fp);
assert(!isDelegate!(int function()));
assert(!isDelegate!(typeof(&sfunc)));
template isSomeFunction(T...) if (T.length == 1)

Определить, является ли символ или тип T функцией, указателем на функцию или делегатом.

Параметры:
T Тип для проверки
Возвращает:
bool
Примеры:
static real func(ref int) { return 0; }
static void prop() @property { }
class C
{
    real method(ref int) { return 0; }
    real prop() @property { return 0; }
}
auto c = new C;
auto fp = &func;
auto dg = &c.method;
real val;

static assert( isSomeFunction!func);
static assert( isSomeFunction!prop);
static assert( isSomeFunction!(C.method));
static assert( isSomeFunction!(C.prop));
static assert( isSomeFunction!(c.prop));
static assert( isSomeFunction!(c.prop));
static assert( isSomeFunction!fp);
static assert( isSomeFunction!dg);

static assert(!isSomeFunction!int);
static assert(!isSomeFunction!val);
template isCallable(alias callable)

Определить, является ли T вызываемым объектом, который можно вызвать с оператором вызова функции (...).

Примеры:
Функции, лямбда-выражения и агрегатные типы с (статическим) opCall.
void f() { }
int g(int x) { return x; }

static assert( isCallable!f);
static assert( isCallable!g);

class C { int opCall(int) { return 0; } }
auto c = new C;
struct S { static int opCall(int) { return 0; } }
interface I { real value() @property; }

static assert( isCallable!c);
static assert( isCallable!(c.opCall));
static assert( isCallable!S);
static assert( isCallable!(I.value));
static assert( isCallable!((int a) { return a; }));

static assert(!isCallable!I);
Примеры:
Шаблоны
void f()() { }
T g(T = int)(T x) { return x; }

static assert( isCallable!f);
static assert( isCallable!g);
Примеры:
Перегруженные функции и шаблоны функций.
static struct Wrapper
{
    void f() { }
    int f(int x) { return x; }

    void g()() { }
    T g(T = int)(T x) { return x; }
}

static assert(isCallable!(Wrapper.f));
static assert(isCallable!(Wrapper.g));
template isAbstractFunction(T...) if (T.length == 1)

Определить, является ли T абстрактной функцией.

Параметры:
T Тип для проверки
Возвращает:
A bool
Примеры:
struct S { void foo() { } }
class C { void foo() { } }
class AC { abstract void foo(); }
static assert(!isAbstractFunction!(int));
static assert(!isAbstractFunction!(S.foo));
static assert(!isAbstractFunction!(C.foo));
static assert( isAbstractFunction!(AC.foo));
template isFinalFunction(T...) if (T.length == 1)

Определить, является ли T конечной функцией.

Примеры:
struct S { void bar() { } }
final class FC { void foo(); }
class C
{
    void bar() { }
    final void foo();
}
static assert(!isFinalFunction!(int));
static assert(!isFinalFunction!(S.bar));
static assert( isFinalFunction!(FC.foo));
static assert(!isFinalFunction!(C.bar));
static assert( isFinalFunction!(C.foo));
enum auto isNestedFunction(alias f);

Определяет, является ли f функцией, которая требует указателя на контекст.

Параметры:
f Тип для проверки Возвращает A bool
Примеры:
static void f() {}
static void fun()
{
    int i;
    int f() { return i; }

    static assert(isNestedFunction!(f));
}

static assert(!isNestedFunction!f);
template isAbstractClass(T...) if (T.length == 1)

Определить, является ли T абстрактным классом.

Примеры:
struct S { }
class C { }
abstract class AC { }
static assert(!isAbstractClass!S);
static assert(!isAbstractClass!C);
static assert( isAbstractClass!AC);
C c;
static assert(!isAbstractClass!c);
AC ac;
static assert( isAbstractClass!ac);
template isFinalClass(T...) if (T.length == 1)

Определить, является ли T конечным классом.

Примеры:
class C { }
abstract class AC { }
final class FC1 : C { }
final class FC2 { }
static assert(!isFinalClass!C);
static assert(!isFinalClass!AC);
static assert( isFinalClass!FC1);
static assert( isFinalClass!FC2);
C c;
static assert(!isFinalClass!c);
FC1 fc1;
static assert( isFinalClass!fc1);
template Unconst(T)

Удаляет const, inout и immutable квалификаторы, если они есть, из типа T.

Примеры:
static assert(is(Unconst!int == int));
static assert(is(Unconst!(const int) == int));
static assert(is(Unconst!(immutable int) == int));
static assert(is(Unconst!(shared int) == shared int));
static assert(is(Unconst!(shared(const int)) == shared int));
template Unqual(T)

Удаляет все квалификаторы, если они есть, из типа T.

Примеры:
static assert(is(Unqual!int == int));
static assert(is(Unqual!(const int) == int));
static assert(is(Unqual!(immutable int) == int));
static assert(is(Unqual!(shared int) == int));
static assert(is(Unqual!(shared(const int)) == int));
template CopyTypeQualifiers(FromType, ToType)

Копирует квалификаторы типа из FromType в ToType.

Поддерживаемые квалификаторы типа:

  • const
  • inout
  • immutable
  • shared

Примеры:
static assert(is(CopyTypeQualifiers!(inout const real, int) == inout const int));
template CopyConstness(FromType, ToType)

Возвращает тип ToType с «константностью» FromType . Константность типа относится к тому, является ли он const, immutable, или inout . Если FromType не имеет константности, возвращаемый тип будет таким же, как ToType.

Примеры:
const(int) i;
CopyConstness!(typeof(i), float) f;
assert( is(typeof(f) == const float));

CopyConstness!(char, uint) u;
assert( is(typeof(u) == uint));

//The 'shared' qualifier will not be copied
assert(!is(CopyConstness!(shared bool, int) == shared int));

//But the constness will be
assert( is(CopyConstness!(shared const real, double) == const double));

//Careful, const(int)[] is a mutable array of const(int)
alias MutT = CopyConstness!(const(int)[], int);
assert(!is(MutT == const(int)));

//Okay, const(int[]) applies to array and contained ints
alias CstT = CopyConstness!(const(int[]), int);
assert( is(CstT == const(int)));
template ForeachType(T)

Возвращает тип, выведенный для цикла, когда переменная типа T итерируется с помощью цикла foreach с одной переменной цикла и автоматически выведенным типом возврата. Обратите внимание, что это может отличаться от std.range.ElementType!Range в случае узких строк или если T имеет как opApply, так и интерфейс диапазона.

Примеры:
static assert(is(ForeachType!(uint[]) == uint));
static assert(is(ForeachType!string == immutable(char)));
static assert(is(ForeachType!(string[string]) == string));
static assert(is(ForeachType!(inout(int)[]) == inout(int)));
template OriginalType(T)

Удаляет все enum из типа T.

Примеры:
enum E : real { a = 0 } // NOTE: explicit initialization to 0 required during Enum init deprecation cycle
enum F : E    { a = E.a }
alias G = const(F);
static assert(is(OriginalType!E == real));
static assert(is(OriginalType!F == real));
static assert(is(OriginalType!G == const real));
template KeyType(V : V[K], K)

Получить тип ключа ассоциативного массива.

Примеры:
alias Hash = int[string];
static assert(is(KeyType!Hash == string));
static assert(is(ValueType!Hash == int));
KeyType!Hash str = "a"; // str is declared as string
ValueType!Hash num = 1; // num is declared as int
template ValueType(V : V[K], K)

Получить тип значения ассоциативного массива.

Примеры:
alias Hash = int[string];
static assert(is(KeyType!Hash == string));
static assert(is(ValueType!Hash == int));
KeyType!Hash str = "a"; // str is declared as string
ValueType!Hash num = 1; // num is declared as int
template Unsigned(T)
Параметры:
T Встроенный целочисленный или векторный тип.
Возвращает:
Соответствующий беззнаковый числовой тип для T с теми же квалификаторами типа. Если T не является целочисленным или векторным типом, выдается ошибка времени компиляции.
Примеры:
static assert(is(Unsigned!(int) == uint));
static assert(is(Unsigned!(long) == ulong));
static assert(is(Unsigned!(const short) == const ushort));
static assert(is(Unsigned!(immutable byte) == immutable ubyte));
static assert(is(Unsigned!(inout int) == inout uint));
Примеры:
Беззнаковые типы передаются
static assert(is(Unsigned!(uint) == uint));
static assert(is(Unsigned!(const uint) == const uint));

static assert(is(Unsigned!(ubyte) == ubyte));
static assert(is(Unsigned!(immutable uint) == immutable uint));
template Largest(T...) if (T.length >= 1)

Возвращает наибольший тип, т.е. T, такой что T.sizeof является наибольшим. Если более одного типа имеют одинаковый размер, возвращается левое аргумент из этих типов.

Примеры:
static assert(is(Largest!(uint, ubyte, ushort, real) == real));
static assert(is(Largest!(ulong, double) == ulong));
static assert(is(Largest!(double, ulong) == double));
static assert(is(Largest!(uint, byte, double, short) == double));
static if (is(ucent))
    static assert(is(Largest!(uint, ubyte, ucent, ushort) == ucent));
template Signed(T)

Возвращает соответствующий знаковый тип для T. T должен быть числовым целочисленным типом; в противном случае возникает ошибка времени компиляции.

Примеры:
alias S1 = Signed!uint;
static assert(is(S1 == int));
alias S2 = Signed!(const(uint));
static assert(is(S2 == const(int)));
alias S3 = Signed!(immutable(uint));
static assert(is(S3 == immutable(int)));
static if (is(ucent))
{
    alias S4 = Signed!ucent;
    static assert(is(S4 == cent));
}
template mostNegative(T) if (isNumeric!T || isSomeChar!T || isBoolean!T)

Возвращает наименьшее отрицательное значение числового типа T.

Примеры:
static assert(mostNegative!float == -float.max);
static assert(mostNegative!double == -double.max);
static assert(mostNegative!real == -real.max);
static assert(mostNegative!bool == false);
Примеры:
import std.meta : AliasSeq;

static foreach (T; AliasSeq!(bool, byte, short, int, long))
    static assert(mostNegative!T == T.min);

static foreach (T; AliasSeq!(ubyte, ushort, uint, ulong, char, wchar, dchar))
    static assert(mostNegative!T == 0);
template Promoted(T) if (isScalarType!T)

Получить тип, к которому скалярный тип T будет промотирован в выражениях многотерминой арифметики.

Примеры:
ubyte a = 3, b = 5;
static assert(is(typeof(a * b) == Promoted!ubyte));
static assert(is(Promoted!ubyte == int));

static assert(is(Promoted!(shared(bool)) == shared(int)));
static assert(is(Promoted!(const(int)) == const(int)));
static assert(is(Promoted!double == double));
template mangledName(sth...) if (sth.length == 1)

Возвращает изменённое имя символа или типа sth.

mangledName равно встроенному свойству .mangleof, но может быть более удобным в обобщённом коде, например, в качестве шаблона аргумента при вызове staticMap.

Примеры:
import std.meta : AliasSeq;
alias TL = staticMap!(mangledName, int, const int, immutable int);
static assert(TL == AliasSeq!("i", "xi", "yi"));
template Select(bool condition, T...) if (T.length == 2)

Присваивает себе T[0] , если булевое condition является true , и T[1] в противном случае.

Примеры:
// can select types
static assert(is(Select!(true, int, long) == int));
static assert(is(Select!(false, int, long) == long));
static struct Foo {}
static assert(is(Select!(false, const(int), const(Foo)) == const(Foo)));

// can select symbols
int a = 1;
int b = 2;
alias selA = Select!(true, a, b);
alias selB = Select!(false, a, b);
writeln(selA); // 1
writeln(selB); // 2

// can select (compile-time) expressions
enum val = Select!(false, -4, 9 - 6);
static assert(val == 3);
A select(bool cond : true, A, B)(A a, lazy B b);

B select(bool cond : false, A, B)(lazy A a, B b);

Выбрать одну из двух функций для выполнения через шаблонный параметр.

Параметры:
cond Булево значение, определяющее, какая функция выполняется
A a Первая функция
B b Вторая функция
Возвращает:
a без вычисления b , если cond является true . В противном случае возвращает b без вычисления a.
Примеры:
real run() { return 0; }
int fail() { assert(0); }
auto a = select!true(run(), fail());
auto b = select!false(fail(), run());
static assert(is(typeof(a) == real));
static assert(is(typeof(b) == real));
enum auto hasUDA(alias symbol, alias attribute);

Определить, имеет ли символ заданный пользовательский атрибут.

См. также:
getUDAs
Примеры:
enum E;
struct S {}

@("alpha") int a;
static assert(hasUDA!(a, "alpha"));
static assert(!hasUDA!(a, S));
static assert(!hasUDA!(a, E));

@(E) int b;
static assert(!hasUDA!(b, "alpha"));
static assert(!hasUDA!(b, S));
static assert(hasUDA!(b, E));

@E int c;
static assert(!hasUDA!(c, "alpha"));
static assert(!hasUDA!(c, S));
static assert(hasUDA!(c, E));

@(S, E) int d;
static assert(!hasUDA!(d, "alpha"));
static assert(hasUDA!(d, S));
static assert(hasUDA!(d, E));

@S int e;
static assert(!hasUDA!(e, "alpha"));
static assert(hasUDA!(e, S));
static assert(!hasUDA!(e, S()));
static assert(!hasUDA!(e, E));

@S() int f;
static assert(!hasUDA!(f, "alpha"));
static assert(hasUDA!(f, S));
static assert(hasUDA!(f, S()));
static assert(!hasUDA!(f, E));

@(S, E, "alpha") int g;
static assert(hasUDA!(g, "alpha"));
static assert(hasUDA!(g, S));
static assert(hasUDA!(g, E));

@(100) int h;
static assert(hasUDA!(h, 100));

struct Named { string name; }

@Named("abc") int i;
static assert(hasUDA!(i, Named));
static assert(hasUDA!(i, Named("abc")));
static assert(!hasUDA!(i, Named("def")));

struct AttrT(T)
{
    string name;
    T value;
}

@AttrT!int("answer", 42) int j;
static assert(hasUDA!(j, AttrT));
static assert(hasUDA!(j, AttrT!int));
static assert(!hasUDA!(j, AttrT!string));

@AttrT!string("hello", "world") int k;
static assert(hasUDA!(k, AttrT));
static assert(!hasUDA!(k, AttrT!int));
static assert(hasUDA!(k, AttrT!string));

struct FuncAttr(alias f) { alias func = f; }
static int fourtyTwo() { return 42; }
static size_t getLen(string s) { return s.length; }

@FuncAttr!getLen int l;
static assert(hasUDA!(l, FuncAttr));
static assert(!hasUDA!(l, FuncAttr!fourtyTwo));
static assert(hasUDA!(l, FuncAttr!getLen));
static assert(!hasUDA!(l, FuncAttr!fourtyTwo()));
static assert(!hasUDA!(l, FuncAttr!getLen()));

@FuncAttr!getLen() int m;
static assert(hasUDA!(m, FuncAttr));
static assert(!hasUDA!(m, FuncAttr!fourtyTwo));
static assert(hasUDA!(m, FuncAttr!getLen));
static assert(!hasUDA!(m, FuncAttr!fourtyTwo()));
static assert(hasUDA!(m, FuncAttr!getLen()));
template getUDAs(alias symbol, alias attribute)

Получить соответствующие пользовательские атрибуты от данного символа.

Если UDA — это тип, то любые UDA того же типа у символа будут соответствовать. Если UDA — шаблон для типа, то любая UDA, являющаяся экземпляром этого шаблона, будет соответствовать. А если UDA — значение, то любые UDA у символа, равные этому значению, будут соответствовать.

См. также:
hasUDA
Примеры:
struct Attr
{
    string name;
    int value;
}

@Attr("Answer", 42) int a;
static assert(getUDAs!(a, Attr).length == 1);
static assert(getUDAs!(a, Attr)[0].name == "Answer");
static assert(getUDAs!(a, Attr)[0].value == 42);

@(Attr("Answer", 42), "string", 9999) int b;
static assert(getUDAs!(b, Attr).length == 1);
static assert(getUDAs!(b, Attr)[0].name == "Answer");
static assert(getUDAs!(b, Attr)[0].value == 42);

@Attr("Answer", 42) @Attr("Pi", 3) int c;
static assert(getUDAs!(c, Attr).length == 2);
static assert(getUDAs!(c, Attr)[0].name == "Answer");
static assert(getUDAs!(c, Attr)[0].value == 42);
static assert(getUDAs!(c, Attr)[1].name == "Pi");
static assert(getUDAs!(c, Attr)[1].value == 3);

static assert(getUDAs!(c, Attr("Answer", 42)).length == 1);
static assert(getUDAs!(c, Attr("Answer", 42))[0].name == "Answer");
static assert(getUDAs!(c, Attr("Answer", 42))[0].value == 42);

static assert(getUDAs!(c, Attr("Answer", 99)).length == 0);

struct AttrT(T)
{
    string name;
    T value;
}

@AttrT!uint("Answer", 42) @AttrT!int("Pi", 3) @AttrT int d;
static assert(getUDAs!(d, AttrT).length == 2);
static assert(getUDAs!(d, AttrT)[0].name == "Answer");
static assert(getUDAs!(d, AttrT)[0].value == 42);
static assert(getUDAs!(d, AttrT)[1].name == "Pi");
static assert(getUDAs!(d, AttrT)[1].value == 3);

static assert(getUDAs!(d, AttrT!uint).length == 1);
static assert(getUDAs!(d, AttrT!uint)[0].name == "Answer");
static assert(getUDAs!(d, AttrT!uint)[0].value == 42);

static assert(getUDAs!(d, AttrT!int).length == 1);
static assert(getUDAs!(d, AttrT!int)[0].name == "Pi");
static assert(getUDAs!(d, AttrT!int)[0].value == 3);

struct SimpleAttr {}

@SimpleAttr int e;
static assert(getUDAs!(e, SimpleAttr).length == 1);
static assert(is(getUDAs!(e, SimpleAttr)[0] == SimpleAttr));

@SimpleAttr() int f;
static assert(getUDAs!(f, SimpleAttr).length == 1);
static assert(is(typeof(getUDAs!(f, SimpleAttr)[0]) == SimpleAttr));

struct FuncAttr(alias f) { alias func = f; }
static int add42(int v) { return v + 42; }
static string concat(string l, string r) { return l ~ r; }

@FuncAttr!add42 int g;
static assert(getUDAs!(g, FuncAttr).length == 1);
static assert(getUDAs!(g, FuncAttr)[0].func(5) == 47);

static assert(getUDAs!(g, FuncAttr!add42).length == 1);
static assert(getUDAs!(g, FuncAttr!add42)[0].func(5) == 47);

static assert(getUDAs!(g, FuncAttr!add42()).length == 0);

static assert(getUDAs!(g, FuncAttr!concat).length == 0);
static assert(getUDAs!(g, FuncAttr!concat()).length == 0);

@FuncAttr!add42() int h;
static assert(getUDAs!(h, FuncAttr).length == 1);
static assert(getUDAs!(h, FuncAttr)[0].func(5) == 47);

static assert(getUDAs!(h, FuncAttr!add42).length == 1);
static assert(getUDAs!(h, FuncAttr!add42)[0].func(5) == 47);

static assert(getUDAs!(h, FuncAttr!add42()).length == 1);
static assert(getUDAs!(h, FuncAttr!add42())[0].func(5) == 47);

static assert(getUDAs!(h, FuncAttr!concat).length == 0);
static assert(getUDAs!(h, FuncAttr!concat()).length == 0);

@("alpha") @(42) int i;
static assert(getUDAs!(i, "alpha").length == 1);
static assert(getUDAs!(i, "alpha")[0] == "alpha");

static assert(getUDAs!(i, 42).length == 1);
static assert(getUDAs!(i, 42)[0] == 42);

static assert(getUDAs!(i, 'c').length == 0);
template getSymbolsByUDA(alias symbol, alias attribute)
Параметры:
symbol Агрегатный тип или модуль для поиска
attribute Пользовательский атрибут для поиска
Возвращает:
Все символы в symbol , которые имеют заданный UDA attribute.
Примечание
Это не рекурсивно; оно не будет искать символы внутри символов, таких как вложенные структуры или объединения.
Примеры:
enum Attr;
struct A
{
    @Attr int a;
    int b;
}

static assert(getSymbolsByUDA!(A, Attr).length == 1);
static assert(hasUDA!(getSymbolsByUDA!(A, Attr)[0], Attr));
Примеры:
enum Attr;

static struct A
{
    @Attr int a;
    int b;
    @Attr void doStuff() {}
    void doOtherStuff() {}
    static struct Inner
    {
        // Not found by getSymbolsByUDA
        @Attr int c;
    }
}

// Finds both variables and functions with the attribute, but
// doesn't include the variables and functions without it.
static assert(getSymbolsByUDA!(A, Attr).length == 2);
// Can access attributes on the symbols returned by getSymbolsByUDA.
static assert(hasUDA!(getSymbolsByUDA!(A, Attr)[0], Attr));
static assert(hasUDA!(getSymbolsByUDA!(A, Attr)[1], Attr));
Примеры:
Находит несколько атрибутов
static struct UDA { string name; }

static struct B
{
    @UDA("X")
    int x;
    @UDA("Y")
    int y;
    @(100)
    int z;
}

// Finds both UDA attributes.
static assert(getSymbolsByUDA!(B, UDA).length == 2);
// Finds one `100` attribute.
static assert(getSymbolsByUDA!(B, 100).length == 1);
// Can get the value of the UDA from the return value
static assert(getUDAs!(getSymbolsByUDA!(B, UDA)[0], UDA)[0].name == "X");
Примеры:
Проверяет UDA на самом агрегатном символе
static struct UDA { string name; }

@UDA("A")
static struct C
{
    @UDA("B")
    int d;
}

static assert(getSymbolsByUDA!(C, UDA).length == 2);
static assert(getSymbolsByUDA!(C, UDA)[0].stringof == "C");
static assert(getSymbolsByUDA!(C, UDA)[1].stringof == "d");
Примеры:
Не находит ничего, если нет члена со специфическим UDA
static struct UDA { string name; }

static struct D
{
    int x;
}

static assert(getSymbolsByUDA!(D, UDA).length == 0);
template allSameType(T...)
Возвращает:
true , если все типы T одинаковые.
Примеры:
static assert(allSameType!(int, int));
static assert(allSameType!(int, int, int));
static assert(allSameType!(float, float, float));
static assert(!allSameType!(int, double));
static assert(!allSameType!(int, float, double));
static assert(!allSameType!(int, float, double, real));
static assert(!allSameType!(short, int, float, double, real));
enum auto ifTestable(T, alias pred = (a) => a);
Возвращает:
true , если тип T можно проверить в выражении if , то есть если if (pred(T.init)) {} поддается компиляции.
template isType(X...) if (X.length == 1)

Определить, является ли X типом. Аналогично is(X). Это полезно при совместном использовании с другими шаблонами, например, allSatisfy!(isType, X).

Возвращает:
true если X является типом, false в противном случае
Примеры:
struct S {
    template Test() {}
}
class C {}
interface I {}
union U {}
static assert(isType!int);
static assert(isType!string);
static assert(isType!(int[int]));
static assert(isType!S);
static assert(isType!C);
static assert(isType!I);
static assert(isType!U);

int n;
void func(){}
static assert(!isType!n);
static assert(!isType!func);
static assert(!isType!(S.Test));
static assert(!isType!(S.Test!()));
template isFunction(X...) if (X.length == 1)

Определить, является ли символ или тип X функцией. Это отличается от проверки, является ли символ вызываемым или удовлетворяет is(X == function), оно определяет, представляет ли символ обычное объявление функции, а не делегат или указатель на функцию.

Возвращает:
true если X является функцией, false в противном случае
См. также:
Используйте isFunctionPointer или isDelegate для определения этих типов соответственно.
Примеры:
static void func(){}
static assert(isFunction!func);

struct S
{
    void func(){}
}
static assert(isFunction!(S.func));
template isFinal(X...) if (X.length == 1)

Определить, является ли X финальным методом или классом.

Возвращает:
true если X является финальным, false в противном случае
Примеры:
class C
{
    void nf() {}
    static void sf() {}
    final void ff() {}
}
final class FC { }

static assert(!isFinal!(C));
static assert( isFinal!(FC));

static assert(!isFinal!(C.nf));
static assert(!isFinal!(C.sf));
static assert( isFinal!(C.ff));
enum auto isCopyable(S);

Определяет, можно ли скопировать тип S. Если тип не может быть скопирован, то код, подобный MyStruct x; auto y = x;, не будет компилироваться. Копирование для структур можно отключить, используя @disable this(this).

Параметры:
S Тип для проверки.
Возвращает:
true если S можно скопировать. false в противном случае.
Примеры:
struct S1 {}                        // Fine. Can be copied
struct S2 {         this(this) {}}  // Fine. Can be copied
struct S3 {@disable this(this);  }  // Not fine. Copying is disabled.
struct S4 {S3 s;}                   // Not fine. A field has copying disabled.

class C1 {}

static assert( isCopyable!S1);
static assert( isCopyable!S2);
static assert(!isCopyable!S3);
static assert(!isCopyable!S4);

static assert(isCopyable!C1);
static assert(isCopyable!int);
static assert(isCopyable!(int[]));

© 1999–2021 The D Language Foundation
Licensed under the Boost License 1.0.
https://dlang.org/phobos/std_traits.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API