D 1.0   D 2.0
About Japanese Translation

Last update Thu Feb 17 14:20:21 2011

std.traits

コンパイル時に、 型とシンボルの情報を取り出すためのテンプレートです。

Source:
std/traits.d

License:
Boost License 1.0.

Authors:
Walter Bright, Tomasz Stachowiak (isExpressionTuple), Andrei Alexandrescu Shin Fujishiro

template ReturnType(func...) if (staticLength!(func) == 1)
関数か、関数ポインタ、デリゲート、 opCallメソッドを持つ構造体、opCallメソッドを持つ構造体へのポインタ、 あるいはopCallメソッドを持つクラス から返値の型を取得します。

Example:
 import std.traits;
 int foo();
 ReturnType!(foo) x;   // x は int 型

template ParameterTypeTuple(dg...) if (staticLength!(dg) == 1)
関数か、関数ポインタ、デリゲート、 あるいは 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); の宣言

enum ParameterStorageClass;
template ParameterStorageClassTuple(func...) if (staticLength!(func) == 1)
関数 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);

NONE
SCOPE
OUT
REF
LAZY
これらのフラグは、 ビットORして複雑な記憶域クラスを表現するのにも使われます。

enum FunctionAttribute;
template functionAttributes(func...) if (staticLength!(func) == 1)
関数 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 でない

NONE
PURE
NOTHROW
REF
PROPERTY
TRUSTED
SAFE
これらのフラグは、ビットORして複雑な属性を表現するのにも使われます。

template isSafe(alias func)
関数が @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);

template areAllSafe(funcs...) if (funcs.length > 0)
全ての関数が @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);

template isUnsafe(alias func)
関数が @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);

template functionLinkage(func...) if (staticLength!(func) == 1)
関数の呼び出し規約を文字列で返します。

Example:
string a = functionLinkage!(writeln!(string, int));
assert(a == "D"); // extern(D)

auto fp = &printf;
string b = functionLinkage!(fp);
assert(b == "C"); // extern(C)

enum Variadic;
template variadicFunctionStyle(func...) if (staticLength!(func) == 1)
関数の可変個引数タイプを判定します。

Example:
void func() {}
static assert(variadicFunctionStyle!(func) == Variadic.NO);

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

NO
可変個引数でない

C
C形式の可変個引数

D
D形式の、 _argptr と _arguments を使う可変個引数

TYPESAFE
関数は型安全可変個引数

template FunctionTypeOf(func...) if (staticLength!(func) == 1)
呼び出し可能オブジェクト func から関数型を取り出します。

組み込みの typeof をプロパティ関数に使うと、 プロパティ値の型が求まり、これは関数そのものの型ではありません。しかし、 FunctionTypeOf はプロパティ関数の型を求めることができます。
class C {
    int value() @property;
}
static assert(is( typeof(C.value) == int ));
static assert(is( FunctionTypeOf!(C.value) == function ));

Note:
関数型と関数ポインタ型を混同しないようにご注意ください。 関数型は通常はコンパイル時リフレクションの用途に使われます。

template FieldTypeTuple(S)
構造体かクラスをフィールドのタプルに変換したときの型を取得します。 これは、仮想関数テーブルへのポインタのような隠しフィールドを除いた、 メモリ空間を消費するフィールドのみで構成される タプルとなります。

template RepresentationTypeTuple(T)
構造体やクラスのフィールドのプリミティブな型のタプルを 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*));

template hasAliasing(T...)
T の表現に以下のいずれかが含まれているときに、true を返します:
  1. 生のポインタ U*U がimmutableでないもの
  2. 配列 U[]U が immutable でないもの
  3. クラスやインターフェイス参照 CC が immutable でないもの
  4. 連想配列でimmutableでないもの
  5. delegate

template hasIndirections(T)
T の表現が少なくとも以下の1つを含んでいると true になります:
  1. 生ポインタ U*
  2. 配列 U[]
  3. クラスへの参照型 C
  4. 連想配列
  5. delegate

template hasUnsharedAliasing(T...)
T の表現が少なくとも以下の1つを含んでいると true になります:
  1. 生ポインタ U*U がimmutableやsharedでないもの
  2. 配列 U[]U が immutable や shared でないもの
  3. クラスへの参照型 CC が immutable や shared でないもの
  4. immutable や shared でない連想配列
  5. shared でない delegate

template hasElaborateCopyConstructor(S)
SS の表現に直接埋め込まれた型が単純でないコピーコンストラクタを定義していると true となります。単純でないコピーコンストラクタとは this(this) が構造体に定義されていることを言います。 (構造体以外には単純でないコピーコンストラクタはありません)

template hasElaborateAssign(S)
SS の表現に直接埋め込まれた型が単純でない代入を定義していると true となります。単純でない代入とは 構造体に opAssign(typeof(this)) または opAssign(ref typeof(this)) が定義されていることをいいます。(構造体以外には単純でない代入はありません)

template hasElaborateDestructor(S)
S か、その表現に直接埋め込まれている型が 単純でないデストラクタを定義していると true となります。単純でないデストラクタとは、 ~this() が構造体に定義されていることを言います。 (構造体以外には、~this() が定義されていても、単純でないデストラクタはありません)

template hasMember(T,string name)
Tstructclassname という名前のメンバを持つ時に true となります

template EnumMembers(E) if (is(E == enum))
列挙型 enum E のメンバ一覧を取得します

Parameters:
E 列挙型。E には値が重複するメンバがあっても構いません。

Returns:
列挙型 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);

template BaseTypeTuple(A)
指定したクラスやインターフェイスの基底型と基底インターフェイスからなる 型タプルを返します。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) を表示
 }

template BaseClassesTuple(T)
このクラスの全ての基底クラスを、降順の型タプルとして返します。 インターフェイスは含まれません。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) を表示
 }

template InterfacesTuple(T)
このクラスや基底クラスの実装する全てのインターフェイスを並べた 型タプルを返します。複数回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) を表示
 }

template TransitiveBaseTypeTuple(T)
クラス 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) を表示
 }

template MemberFunctionsTuple(C,string name) if (is(C == class) || is(C == interface))
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));

template CommonType(T...)
指定した型全ての暗黙変換先となれる型を返します。 例えば、さまざまな初期化値から配列を生成する場合などに役に立ちます。 空リストを渡したときや、共通の型が存在しない場合は void を返します。

Example:
alias CommonType!(int, long, short) X;
assert(is(X == long));
alias CommonType!(int, char[], short) Y;
assert(is(Y == void));

template ImplicitConversionTargets(T)
T. からの暗黙変換先となりうる型全てのタプルを返します。

Important note:

このテンプレートが返す型のリストは、危険な変換を除いているため D 2.005 コンパイラが認めるものより保守的になっています。 例えば ImplicitConversionTargets!(double) には float は含まれません。

template isImplicitlyConvertible(From,To)
FromTo に暗黙変換可能か?

template isAssignable(Lhs,Rhs)
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[]));

template isCovariantWith(F,G) if (is(F == function) && is(G == function))
関数型 F に対して G が covariant であるか、 つまり、FG 型の関数でオーバーライドできるか、を判定します。

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)));

template isIntegral(T)
T が組み込みの整数型かどうかを判定します。bool, char, wchar, dchar は整数型とは見なされません。

template isFloatingPoint(T)
T が組み込みの浮動小数点数型かどうかを判定します。

template isNumeric(T)
T が組み込みの数値型(整数あるいは 浮動小数点数)かどうかを判定します。

template isUnsigned(T)
T が組み込みの符号無し数値型かどうかを判定します。

template isSigned(T)
T が組み込みの符号付き数値型かどうかを判定します。

template isSomeString(T)
T が組み込みの文字列型かどうかを判定します。

template isSomeChar(T)
T が組み込みの文字型かどうかを判定します。

template isAssociativeArray(T)
T が組み込みの連想配列型かどうかを判定します。

template isStaticArray(T : U[N],U,size_t N)
Tが静的配列かどうかを判定します。

template isDynamicArray(T,U = void)
型 T が動的配列型かどうかを判定します。

template isArray(T)
型 T が配列型かどうかを判定します。

template isPointer(T)
T がポインタ型かどうかを判定します。

template pointerTarget(T : T*)
ポインタ型の指す型を返します。

template isIterable(T)
T が foreach ループを auto 型の1個のループ変数で回せるならば true を返します。 foreach の実装には依存せず、レンジ、 opApply を持つ構造体/クラス、 組み込みの動的配列や静的配列、連想配列でtrueになります。

template isExpressionTuple(T...)
タプル T が式タプルかどうか判定します。

template isTypeTuple(T...)
タプル T が型タプルかどうか判定します。

template isFunctionPointer(T...) if (staticLength!(T) == 1)
シンボルまたは型 T が関数ポインタかどうか判定します

template isDelegate(T...) if (staticLength!(T) == 1)
T が delegate かどうか判定します。

template isSomeFunction(T...) if (staticLength!(T) == 1)
シンボルまたは型 T が関数、関数ポインタ、delegateのどれかであるか判定します。

template isCallable(T...) if (staticLength!(T) == 1)
T が呼び出し可能オブジェクト、つまり (...) 演算子が使えるか判定します。

template isAbstractFunction(method...) if (staticLength!(method) == 1)
組み込みtraitsと同じ意味です: __traits(isAbstractFunction, method).

template Unqual(T)
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));

template ForeachType(T)
型 T の値を foreach でループ変数1個でループするときに、 その変数の型は何になるかを返します。これは std.range.ElementType!(Range) とは一致しないことがあります: char/wchar文字列や、 opApplyとレンジインターフェイスを両方実装している場合など。

template OriginalType(T)
全ての typedef (enum も含む) を型 T から取り除きます。

Example:
enum E : int { a }
typedef E F;
typedef const F G;
static assert(is(OriginalType!G == const int));

template Unsigned(T)
T に対する unsigned 型を返します。 Tが整数型ではないばあい、コンパイルエラーになります。
template Largest(T...) if (T.length >= 1)
引数のタプルのうち T.sizeof が最大になる型を返します。 複数の型が同じサイズで最大の時は、 最左のものが返されます。

template Signed(T)
T に対する signed 型を返します。 Tが整数型ではないばあい、コンパイルエラーになります。
template mostNegative(T)
数値型Tの負の最小値を返します。
template mangledName(sth...) if (staticLength!(sth) == 1)
シンボルまたは型 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" と表示

template Select(bool condition,T,F)
真偽値 conditiontrue なら T への alias、そうでなければ F への alias となります。

Example:
alias Select!(size_t.sizeof == 4, int, long) Int;

A select(bool cond : true, A, B)(A a, lazy B b);
B select(bool cond : false, A, B)(lazy A a, B b);
condtrue ならば b を評価せずに a を返します。逆に false ならば a を評価せずに b を返します。