std.traits
Jump to: BaseClassesTuple BaseTypeTuple C CommonType D EnumMembers FieldTypeTuple ForeachType FunctionAttribute FunctionTypeOf ImplicitConversionTargets InterfacesTuple LAZY Largest MemberFunctionsTuple NO NONE NOTHROW OUT OriginalType PROPERTY PURE ParameterStorageClass ParameterStorageClassTuple ParameterTypeTuple REF RepresentationTypeTuple ReturnType SAFE SCOPE Select Signed TRUSTED TYPESAFE TransitiveBaseTypeTuple Unqual Unsigned Variadic areAllSafe functionAttributes functionLinkage hasAliasing hasElaborateAssign hasElaborateCopyConstructor hasElaborateDestructor hasIndirections hasMember hasUnsharedAliasing isAbstractFunction isArray isAssignable isAssociativeArray isCallable isCovariantWith isDelegate isDynamicArray isExpressionTuple isFloatingPoint isFunctionPointer isImplicitlyConvertible isIntegral isIterable isNumeric isPointer isSafe isSigned isSomeChar isSomeFunction isSomeString isStaticArray isTypeTuple isUnsafe isUnsigned mangledName mostNegative pointerTarget select signed unsigned variadicFunctionStyle
std/traits.d License:
Boost License 1.0. Authors:
Walter Bright, Tomasz Stachowiak (isExpressionTuple), Andrei Alexandrescu Shin Fujishiro
- 関数か、関数ポインタ、デリゲート、
opCallメソッドを持つ構造体、opCallメソッドを持つ構造体へのポインタ、
あるいはopCallメソッドを持つクラス
から返値の型を取得します。
Example:
import std.traits; int foo(); ReturnType!(foo) x; // x は int 型
- 関数か、関数ポインタ、デリゲート、
あるいは opCall メソッドを持つ構造体、構造体へのポインタ、クラスから
引数の型をタプルとして取得します。
Example:
import std.traits; int foo(int, long); void bar(ParameterTypeTuple!(foo)); // void bar(int, long); の宣言 void abc(ParameterTypeTuple!(foo)[1]); // void abc(long); の宣言
- 関数 func の引数の記憶域クラスからなるタプルを返します。
Example:
alias ParameterStorageClass STC; // 略記 void func(ref int ctx, out real result, real param) { } alias ParameterStorageClassTuple!(func) pstc; static assert(pstc.length == 3); // 3引数 static assert(pstc[0] == STC.REF); static assert(pstc[1] == STC.OUT); static assert(pstc[2] == STC.NONE);
- これらのフラグは、 ビットORして複雑な記憶域クラスを表現するのにも使われます。
- 関数 func の属性を返します。
Example:
alias FunctionAttribute FA; // 略記 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)); // @trusted でない
- これらのフラグは、ビットORして複雑な属性を表現するのにも使われます。
- 関数が @safe や @trusted であるかどうかを調べます。
Example:
@system int add(int a, int b) {return a+b;} @safe int sub(int a, int b) {return a-b;} @trusted int mul(int a, int b) {return a*b;} bool a = isSafe!(add); assert(a == false); bool b = isSafe!(sub); assert(b == true); bool c = isSafe!(mul); assert(c == true);
- 全ての関数が @safe か @trusted であるかどうか調べます。
Example:
@system int add(int a, int b) {return a+b;} @safe int sub(int a, int b) {return a-b;} @trusted int mul(int a, int b) {return a*b;} bool a = areAllSafe!(add, sub); assert(a == false); bool b = areAllSafe!(sub, mul); assert(b == true);
- 関数が @system かどうか調べます
Example:
@system int add(int a, int b) {return a+b;} @safe int sub(int a, int b) {return a-b;} @trusted int mul(int a, int b) {return a*b;} bool a = isUnsafe!(add); assert(a == true); bool b = isUnsafe!(sub); assert(b == false); bool c = isUnsafe!(mul); assert(c == false);
- 関数の呼び出し規約を文字列で返します。
Example:
string a = functionLinkage!(writeln!(string, int)); assert(a == "D"); // extern(D) auto fp = &printf; string b = functionLinkage!(fp); assert(b == "C"); // extern(C)
- 関数の可変個引数タイプを判定します。
Example:
void func() {} static assert(variadicFunctionStyle!(func) == Variadic.NO); extern(C) int printf(in char*, ...); static assert(variadicFunctionStyle!(printf) == Variadic.C);
- 可変個引数でない
- C形式の可変個引数
- D形式の、 _argptr と _arguments を使う可変個引数
- 関数は型安全可変個引数
- 呼び出し可能オブジェクト func から関数型を取り出します。
組み込みの typeof をプロパティ関数に使うと、
プロパティ値の型が求まり、これは関数そのものの型ではありません。しかし、
FunctionTypeOf はプロパティ関数の型を求めることができます。
class C { int value() @property; } static assert(is( typeof(C.value) == int )); static assert(is( FunctionTypeOf!(C.value) == function ));
Note:
関数型と関数ポインタ型を混同しないようにご注意ください。 関数型は通常はコンパイル時リフレクションの用途に使われます。 - 構造体かクラスをフィールドのタプルに変換したときの型を取得します。 これは、仮想関数テーブルへのポインタのような隠しフィールドを除いた、 メモリ空間を消費するフィールドのみで構成される タプルとなります。
- 構造体やクラスのフィールドのプリミティブな型のタプルを
topological order で返します。
Example:
struct S1 { int a; float b; } struct S2 { char[] a; union { S1 b; S1 * c; } } alias RepresentationTypeTuple!(S2) R; assert(R.length == 4 && is(R[0] == char[]) && is(R[1] == int) && is(R[2] == float) && is(R[3] == S1*));
- T の表現に以下のいずれかが含まれているときに、true を返します:
- 生のポインタ U* で U がimmutableでないもの
- 配列 U[] で U が immutable でないもの
- クラスやインターフェイス参照 C で C が immutable でないもの
- 連想配列でimmutableでないもの
- delegate
- T の表現が少なくとも以下の1つを含んでいると true
になります:
- 生ポインタ U*
- 配列 U[]
- クラスへの参照型 C
- 連想配列
- delegate
- T の表現が少なくとも以下の1つを含んでいると true
になります:
- 生ポインタ U* で U がimmutableやsharedでないもの
- 配列 U[] で U が immutable や shared でないもの
- クラスへの参照型 C で C が immutable や shared でないもの
- immutable や shared でない連想配列
- shared でない delegate
- S や S の表現に直接埋め込まれた型が単純でないコピーコンストラクタを定義していると true となります。単純でないコピーコンストラクタとは this(this) が構造体に定義されていることを言います。 (構造体以外には単純でないコピーコンストラクタはありません)
- S や S の表現に直接埋め込まれた型が単純でない代入を定義していると true となります。単純でない代入とは 構造体に opAssign(typeof(this)) または opAssign(ref typeof(this)) が定義されていることをいいます。(構造体以外には単純でない代入はありません)
- S か、その表現に直接埋め込まれている型が 単純でないデストラクタを定義していると true となります。単純でないデストラクタとは、 ~this() が構造体に定義されていることを言います。 (構造体以外には、~this() が定義されていても、単純でないデストラクタはありません)
- T が struct か class で name という名前のメンバを持つ時に true となります
- 列挙型 enum E のメンバ一覧を取得します
Parameters:
Returns:E 列挙型。E には値が重複するメンバがあっても構いません。
列挙型 E のメンバからなる静的タプル。 メンバは E で宣言されたのと同じ順番に並びます。 Note:
返される値は厳密に E 型を持ちます。したがって、 以下のコードは明示キャスト無しでは動きません。enum E : int { a, b, c } int[] abc = cast(int[]) [ EnumMembers!E ];
キャストは変数の型を推論するのであれば不要です。 以下の例をどうぞ。 Examples:
enum値の配列を作ります:enum Sqrts : real { one = 1, two = 1.41421, three = 1.73205, } auto sqrts = [ EnumMembers!Sqrts ]; assert(sqrts == [ Sqrts.one, Sqrts.two, Sqrts.three ]);
以下の例の汎用関数 rank(v) は、 列挙型 E からメンバ e を探すのにこのテンプレートを使っています。// e が E の i 番目の列挙子ならば i を返す size_t rank(E)(E e) if (is(E == enum)) { foreach (i, member; EnumMembers!E) { if (e == member) return i; } assert(0, "Not an enum member"); } enum Mode { read = 1, write = 2, map = 4, } assert(rank(Mode.read ) == 0); assert(rank(Mode.write) == 1); assert(rank(Mode.map ) == 2);
- 指定したクラスやインターフェイスの基底型と基底インターフェイスからなる
型タプルを返します。BaseTypeTuple!(Object)
は空の型タプルを返します。
Example:
import std.traits, std.typetuple, std.stdio; interface I { } class A { } class B : A, I { } void main() { alias BaseTypeTuple!(B) TL; writeln(typeid(TL)); // (A,I) を表示 }
- このクラスの全ての基底クラスを、降順の型タプルとして返します。
インターフェイスは含まれません。BaseClassesTuple!(Object) は空の型タプルになります。
Example:
import std.traits, std.typetuple, std.stdio; interface I { } class A { } class B : A, I { } class C : B { } void main() { alias BaseClassesTuple!(C) TL; writeln(typeid(TL)); // (B,A,Object) を表示 }
- このクラスや基底クラスの実装する全てのインターフェイスを並べた
型タプルを返します。複数回implementsされたインターフェイスでも
重複列挙されることはありません。InterfacesTuple!(Object)
は空の型タプルを返します。
Example:
import std.traits, std.typetuple, std.stdio; interface I1 { } interface I2 { } class A : I1, I2 { } class B : A, I1 { } class C : B { } void main() { alias InterfacesTuple!(C) TL; writeln(typeid(TL)); // (I1, I2) を表示 }
- クラス T の全ての基底クラスを降順に並べ、
その後ろにインターフェイスを並べた型タプルを返します。
TransitiveBaseTypeTuple!(Object)
は空の型タプルになります。
Example:
import std.traits, std.typetuple, std.stdio; interface I { } class A { } class B : A, I { } class C : B { } void main() { alias TransitiveBaseTypeTuple!(C) TL; writeln(typeid(TL)); // (B,A,Object,I) を表示 }
- name という名前の、
クラスかインターフェイスである C 型の非静的メンバ関数のタプルを返します。
共変の戻り値型による重複は、もっとも深い派生クラスのものにまとめられます。
Example:
interface I { I foo(); } class B { real foo(real v) { return v; } } class C : B, I { override C foo() { return this; } // I.foo() の共変オーバーライド } alias MemberFunctionsTuple!(C, "foo") foos; static assert(foos.length == 2); static assert(__traits(isSame, foos[0], C.foo)); static assert(__traits(isSame, foos[1], B.foo));
- 指定した型全ての暗黙変換先となれる型を返します。
例えば、さまざまな初期化値から配列を生成する場合などに役に立ちます。
空リストを渡したときや、共通の型が存在しない場合は void
を返します。
Example:
alias CommonType!(int, long, short) X; assert(is(X == long)); alias CommonType!(int, char[], short) Y; assert(is(Y == void));
- T. からの暗黙変換先となりうる型全てのタプルを返します。 Important note: このテンプレートが返す型のリストは、危険な変換を除いているため D 2.005 コンパイラが認めるものより保守的になっています。 例えば ImplicitConversionTargets!(double) には float は含まれません。
- From を To に暗黙変換可能か?
- 型 Rhs の値が
型 Lhs の変数に代入可能なら true となります。
Examples:
static assert(isAssignable!(long, int)); static assert(!isAssignable!(int, long)); static assert(isAssignable!(const(char)[], string)); static assert(!isAssignable!(string, char[]));
- 関数型 F に対して G が covariant であるか、
つまり、F を G 型の関数でオーバーライドできるか、を判定します。
Example:
interface I { I clone(); } interface J { J clone(); } class C : I { override C clone() // I.clone() の共変オーバーライド { return new C; } } // C.clone() は実際に I.clone() をオーバーライドできる static assert(isCovariantWith!(typeof(C.clone), typeof(I.clone))); // C.clone() は J.clone() をオーバーライドできない。 // 返値型 C が J に暗黙変換できないため。 static assert(isCovariantWith!(typeof(C.clone), typeof(J.clone)));
- T が組み込みの整数型かどうかを判定します。bool, char, wchar, dchar は整数型とは見なされません。
- T が組み込みの浮動小数点数型かどうかを判定します。
- T が組み込みの数値型(整数あるいは 浮動小数点数)かどうかを判定します。
- T が組み込みの符号無し数値型かどうかを判定します。
- T が組み込みの符号付き数値型かどうかを判定します。
- T が組み込みの文字列型かどうかを判定します。
- T が組み込みの文字型かどうかを判定します。
- T が組み込みの連想配列型かどうかを判定します。
- Tが静的配列かどうかを判定します。
- 型 T が動的配列型かどうかを判定します。
- 型 T が配列型かどうかを判定します。
- 型 T がポインタ型かどうかを判定します。
- ポインタ型の指す型を返します。
- T が foreach ループを auto 型の1個のループ変数で回せるならば true を返します。 foreach の実装には依存せず、レンジ、 opApply を持つ構造体/クラス、 組み込みの動的配列や静的配列、連想配列でtrueになります。
- タプル T が式タプルかどうか判定します。
- タプル T が型タプルかどうか判定します。
- シンボルまたは型 T が関数ポインタかどうか判定します
- T が delegate かどうか判定します。
- シンボルまたは型 T が関数、関数ポインタ、delegateのどれかであるか判定します。
- T が呼び出し可能オブジェクト、つまり (...) 演算子が使えるか判定します。
- 組み込みtraitsと同じ意味です: __traits(isAbstractFunction, method).
- 型 T についている修飾子があればすべて取り除きます。
Example:
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));
- 型 T の値を foreach でループ変数1個でループするときに、 その変数の型は何になるかを返します。これは std.range.ElementType!(Range) とは一致しないことがあります: char/wchar文字列や、 opApplyとレンジインターフェイスを両方実装している場合など。
- 全ての typedef (enum も含む) を型 T から取り除きます。
Example:
enum E : int { a } typedef E F; typedef const F G; static assert(is(OriginalType!G == const int));
- T に対する unsigned 型を返します。 Tが整数型ではないばあい、コンパイルエラーになります。
- 引数のタプルのうち T.sizeof が最大になる型を返します。 複数の型が同じサイズで最大の時は、 最左のものが返されます。
- T に対する signed 型を返します。 Tが整数型ではないばあい、コンパイルエラーになります。
- 数値型Tの負の最小値を返します。
- シンボルまたは型 sth のマングルされた名前文字列を返します。
Example:
mangledName は組み込みの .mangleof プロパティと基本的に同等ですが、 プロパティ関数の正しい名前が手に入ります。module test; import std.traits : mangledName; class C { int value() @property; } pragma(msg, C.value.mangleof); // "i" と表示 pragma(msg, mangledName!(C.value)); // "_D4test1C5valueMFNdZi" と表示
- 真偽値 condition が true なら
T への alias、そうでなければ F への alias となります。
Example:
alias Select!(size_t.sizeof == 4, int, long) Int;
- cond が true ならば b を評価せずに a を返します。逆に false ならば a を評価せずに b を返します。