英語版
このページの英語版を見る

std.typecons

このモジュールはさまざまな型コンストラクター、つまりテンプレートを実装している。 を実装しており、新しい有用な汎用型を構築することができる。

ソース std/typecons.d

Authors:
Andrei Alexandrescu, Bartosz Milewski, Don Clugston, Shin Fujishiro, Kenji Hara
Examples:
値のタプル
alias Coord = Tuple!(int, "x", int, "y", int, "z");
Coord c;
c[1] = 1;       // インデックスによるアクセス
c.z = 1;        // 指定された名前によるアクセス
writeln(c); // Coord(0, 1, 1)

// 名前は省略可、型は混合可
alias DictEntry = Tuple!(string, int);
auto dict = DictEntry("seven", 7);

// 要素の型を推測することができる
writeln(tuple(2, 3, 4)[1]); // 3
// 型推論は名前でも機能する
auto tup = tuple!("x", "y", "z")(2, 3, 4);
writeln(tup.y); // 3
Examples:
定数オブジェクトと不変オブジェクトへのリバインド可能な参照
class Widget
{
    void foo() const @safe {}
}
const w1 = new Widget, w2 = new Widget;
w1.foo();
// w1 = w2は機能しない; constオブジェクトをリバインドできない

auto r = Rebindable!(const Widget)(w1);
// rがWidgetオブジェクトであるかのようにメソッドを呼び出す
r.foo();
// 別のオブジェクトを参照するようにrをリバインドする
r = w2;
struct Unique(T);
リソースの一意な所有権をカプセル化する。
Unique!Tdestroy T を呼び出す。 destroy の重要な結果の1つは、 のデストラクタを呼び出すことである。 Tのデストラクタを呼び出すことである。 GCで管理されている参照は、デストラクタの間 の他のメンバは、デストラクタ呼び出し中も有効であることが保証されない。 Tの他のメンバ(ファイルハンドルやmalloc メモリへのポインタなど)は、デストラクタ呼び出し中も有効である。 の他のメンバは、デストラクタ呼び出し中も有効である。 これにより、リソース T の非GCリソースの割り当て解除やクリーンアップができる。
もしUnique!T を元のスコープの外でも保持したい場合は、それを転送することができる。 スコープ外で永続化することが望ましい場合は、それを転送することができる。 この転送は、 を呼び出すことで 明示的に行うこともできるし、暗黙的に行うこともできる。 releaseを呼び出すことで明示的に行うことも、関数からUniqueを返すときに暗黙的に行うこともできる。 関数からUniqueを返す場合などである。リソースT は、ポリモーフィックなクラスオブジェクトか、インターフェースのインスタンスである。 その場合、Uniqueは多相的に振る舞う。 も多相的に振る舞う。
T が値型の場合、Unique!T は への参照として実装される。 Tへの参照として実装される。
Examples:
struct S
{
    int i;
    this(int i){this.i = i;}
}
Unique!S produce()
{
    // ヒープ上にSの一意なインスタンスを構築する
    Unique!S ut = new S(5);
    // 暗黙の所有権移転
    return ut;
}
// 参照によってユニークなリソースを借りる
void increment(ref Unique!S ur)
{
    ur.i++;
}
void consume(Unique!S u2)
{
    writeln(u2.i); // 6
    // リソースはここで自動的に削除される
}
Unique!S u1;
assert(u1.isEmpty);
u1 = produce();
writeln(u1.i); // 5
increment(u1);
writeln(u1.i); // 6
//consume(u1); // エラー: u1はコピーできない
// リソースの所有権を譲渡する
consume(u1.release);
assert(u1.isEmpty);
alias RefT = T;
T への参照を表す。T が値型の場合はT* に解決する。
Unique!T create(A...)(auto ref A args)
if (__traits(compiles, new T(args)));
Unique を安全に構築できるようにする。 のエイリアスをT が公開しない限り)。 this).

注釈 入れ子の構造体/クラスは作成できない。

Parameters:
A args T のコンストラクタに渡す引数
static class C {}
auto u = Unique!(C).create();
this(RefT p);
r値を取るコンストラクタ
r値が単なるl値のビュー(キャスト)でない限り、一意性が保証される。 が単なるl値のビュー(キャストなど)でない限り、一意性が保証される。 典型的な使用法だ:
Unique!Foo f = new Foo;
this(ref RefT p);
l値を取るコンストラクタ
これはそのソースをNULLにする。 NULL化により、ソースに以前のエイリアスがない限り、一意性が保証される。 ソースのエイリアスが存在しない限り、一意性が保証される。
this(U)(Unique!U u)
if (is(u.RefT : RefT));
コンストラクタ。こちらの型に変換可能な型のUnique を取る?
?
通常、派生型のUnique r値を基本型の 。 Unique

例:

class C : Object {}

Unique!C uc = new C;
Unique!Object uo = uc.release;

void opAssign(U)(Unique!U u)
if (is(u.RefT : RefT));
当方の型に転換可能な型のUnique から所有権を移転する。
const @property bool isEmpty();
リソースが存在するかどうかを返す
Unique release();
Unique r値に所有権を移す。現在のコンテンツをナル化する。 std.algorithm.moveを呼び出すのと同じ。
struct Tuple(Specs...) if (distinctFieldNames!Specs);
値のタプル、例えばTuple!(int, string) は、 と を格納するレコードである。 int string Tuple は、値を束ねるために使われる。 特に、関数から複数の値を返すときなどである。 関数" から複数の値を返すときなどである。 が の場合、個々のメンバには、 の構文でアクセスできる。 である場合、個々のメンバには、最初のフィールドは という構文でアクセスできる、 でアクセスできる。obj Tuple obj[0] obj[1]
See Also:
Parameters:
Specs Tuple に含まれる型(オプションでメンバ名)のリスト。
Examples:
Tuple!(int, int) point;
// 座標を割り当てる
point[0] = 5;
point[1] = 6;
// 座標を読み込む
auto x = point[0];
auto y = point[1];
Examples:
Tuple メンバには名前を
付けることができる。
名前付きと名前なしの メンバを混在させることは合法である。上記の方法はすべてのフィールドに適用できる。
alias Entry = Tuple!(int, "index", string, "value");
Entry e;
e.index = 4;
e.value = "Hello";
writeln(e[1]); // "Hello"
writeln(e[0]); // 4
Examples:
名前付きフィールドを持つ は、名前なしフィールドを持つ とは別の型Tuple Tuple
である。
すなわち、それぞれの命名が、 に別個の型を与える。 名前だけが異なる2つのフィールドは、たとえ同じ構造を持っていたとしても、やはり別個のものである。 たとえ同じ構造であってもである。 Tuple Tuple
Tuple!(int, "x", int, "y") point1;
Tuple!(int, int) point2;
assert(!is(typeof(point1) == typeof(point2)));
Examples:
タプルを範囲として使う
import std.algorithm.iteration : sum;
import std.range : only;
auto t = tuple(1, 2);
writeln(t.expand.only.sum); // 3
Examples:
タプルを連結する
import std.meta : AliasSeq;
auto t = tuple(1, "2") ~ tuple(ushort(42), true);
static assert(is(t.Types == AliasSeq!(int, string, ushort, bool)));
writeln(t[1]); // "2"
writeln(t[2]); // 42
writeln(t[3]); // true
alias Types = staticMap!(extractType, fieldSpecs);
Tuple の構成要素の型。
alias fieldNames = staticMap!(extractName, fieldSpecs);
Tuple の構成要素の名前。名前のないフィールドは空の名前を持つ。
Examples:
import std.meta : AliasSeq;
alias Fields = Tuple!(int, "id", string, float);
static assert(Fields.fieldNames == AliasSeq!("id", "", ""));
Types expand;
Tuple を構成要素に展開するには を使うt t.expand
に展開する。 の結果は、あたかも の構成要素が値のリストとして列挙されているかのように動作する。 が値のリストであるかのように動作する。(通常、 は単一の値として動作する。 として動作する)。expand Tuple Tuple
Examples:
auto t1 = tuple(1, " hello ", 'a');
writeln(t1.toString()); // `Tuple!(int, string, char)(1, " hello ", 'a')`

void takeSeveralTypes(int n, string s, bool b)
{
    assert(n == 4 && s == "test" && b == false);
}

auto t2 = tuple(4, "test", false);
//t.expandは値のリストとして機能する
takeSeveralTypes(t2.expand);
this(Types values);
各フィールドに1つの値を取るコンストラクタ
Parameters:
Types values 。 で与えられる値と同じ型である値のリスト。 で与えられる型と同じか、暗黙のうちに変換できる値のリストである。 に暗黙的に変換できる値のリスト。これらは、 に現れるのと同じ順序でなければならない。 に現れるのと同じ順序でなければならない。Types Tuple Types
Examples:
alias ISD = Tuple!(int, string, double);
auto tup = ISD(1, "test", 3.2);
writeln(tup.toString()); // `Tuple!(int, string, double)(1, "test", 3.2)`
this(U, size_t n)(U[n] values)
if (n == Types.length && allSatisfy!(isBuildableFrom!U, Types));
互換性のある配列を取るコンストラクタ。
Parameters:
U[n] values Tuple を構築するための互換性のある静的配列。 配列スライスはサポートされていない。
Examples:
int[2] ints;
Tuple!(int, int) t = ints;
this(U)(U another)
if (areBuildCompatibleTuples!(typeof(this), U) && (noMemberHasCopyCtor!(typeof(this)) || !is(Unqual!U == Unqual!(typeof(this)))));
互換性のある を取るコンストラクタTuple
2つの は互換性がある。 二つの は互換性がある。 左辺の各型 に対して、右辺の対応する型 は暗黙的に に変換できる。 に暗黙的に変換できる。Tuple iff T U T
Parameters:
U another 互換性のある 。その型は次のものでなければならない。 の型と互換性がなければならない。Tuple Tuple
Examples:
alias IntVec = Tuple!(int, int, int);
alias DubVec = Tuple!(double, double, double);

IntVec iv = tuple(1, 1, 1);

// OK、intは暗黙的にdoubleに変換できる
DubVec dv = iv;
//エラー: doubleは暗黙的にintに変換できない
//IntVec iv2 = dv;
bool opEquals(R)(R rhs)
if (areCompatibleTuples!(typeof(this), R, "=="));

const bool opEquals(R)(R rhs)
if (areCompatibleTuples!(typeof(this), R, "=="));

bool opEquals(R...)(auto ref R rhs)
if (R.length > 1 && areCompatibleTuples!(typeof(this), Tuple!R, "=="));
等しいかどうかの比較。2つの は等しいとみなされる。 それらは以下の条件を満たす:Tuple iff
  • 各 は同じ長さであTuple
  • る。 左辺の各型 と右辺の各型 について、T
  • 以下の条件を満たす。
  • について、 型の値をU T
  • 型の値と比較することができる。
U
    • の値と比較できる。 左辺の各値 と右辺の各値 について、式 は、右辺の各値 と左辺の各値v1
    • を比較することができる。
    • に対して、式 は真である。 となる。v2 v1 == v2
    Parameters:
    R rhs 比較する 。これは を満たしていなければならない。Tuple Tuple
    Returns:
    両方の が等しければ真、そうでなければ偽Tuple
    Examples:
    Tuple!(int, string) t1 = tuple(1, "test");
    Tuple!(double, string) t2 =  tuple(1.0, "test");
    //OK、intはdoubleと比較でき、
    //どちらも値は1である
    writeln(t1); // t2
    
    auto opCmp(R)(R rhs)
    if (areCompatibleTuples!(typeof(this), R, "<"));

    const auto opCmp(R)(R rhs)
    if (areCompatibleTuples!(typeof(this), R, "<"));
    順序の比較。
    Parameters:
    R rhs Tuple と比較する。それは以下の基準を満たさなければならない。 でなければならない。Tuple
    Returns:
    左辺のタプルに含まれる値 と、右辺のタプルに含まれる値 について、v1
    次のようにする。
    右辺に含まれる値 : すべてのメンバに対して 、あるいは、最初の位置に対して以下の値が指定された場合は0とする。 を指定する: v2
    v1 == v2
    • オペランドのいずれかが NaN の場合は NaN
    • 式 が真の場合は負の数。v1 < v2
    • 式 が真の場合は正の数。v1 > v2
    Examples:
    v1 > v2 が真である最初の が結果を決定するv1
    が結果を決定する。これは予期せぬ動作につながる可能性がある。
    auto tup1 = tuple(1, 1, 1);
    auto tup2 = tuple(1, 100, 100);
    assert(tup1 < tup2);
    
    //比較に重要なのは最初の結果だけである
    tup1[0] = 2;
    assert(tup1 > tup2);
    
    auto opBinary(string op, T)(auto ref T t)
    if (op == "~" && !(is(T : U[], U) && isTuple!U));

    auto opBinaryRight(string op, T)(auto ref T t)
    if (op == "~" && !(is(T : U[], U) && isTuple!U));
    タプルを連結する。 タプルの連結は、すべての名前付きフィールドが異なる場合にのみ許可される(このタプルの名前付きフィールドが および の名前付きフィールドがこのタプルに存在しない)。t t
    Parameters:
    T t で連結する 。Tuple
    Returns:
    このタプルと
    t
    ref Tuple opAssign(R)(auto ref R rhs)
    if (areCompatibleTuples!(typeof(this), R, "="));
    別の からの代入。Tuple
    Parameters:
    R rhs Tuple から割り当てる。の各要素は ソース の各要素は、ターゲット の各要素に暗黙的に割り当て可能でなければならない。 の各要素に暗黙的に割り当て可能でなければならない。Tuple Tuple
    inout ref auto rename(names...)() return
    if (names.length == 0 || allSatisfy!(isSomeString, typeof(names)));
    Tuple の要素名を変更する
    rename 渡された 。 を返す。 は変更されない。 渡された名前が、 のメンバ数より少ない場合 のメンバの数より少ない名前が渡された場合、それらの末尾のメンバは変更されない。 空文字列は、そのメンバーの名前を削除する。 を超える名前を渡すことはコンパイル時のエラーである。 を超える名前を渡すのはコンパイル時のエラーである。names Tuple Tuple Tuple
    Examples:
    auto t0 = tuple(4, "hello");
    
    auto t0Named = t0.rename!("val", "tag");
    writeln(t0Named.val); // 4
    writeln(t0Named.tag); // "hello"
    
    Tuple!(float, "dat", size_t[2], "pos") t1;
    t1.pos = [2, 1];
    auto t1Named = t1.rename!"height";
    t1Named.height = 3.4f;
    writeln(t1Named.height); // 3.4f
    writeln(t1Named.pos); // [2, 1]
    t1Named.rename!"altitude".altitude = 5;
    writeln(t1Named.height); // 5
    
    Tuple!(int, "a", int, int, "c") t2;
    t2 = tuple(3,4,5);
    auto t2Named = t2.rename!("", "b");
    // "a"にはもはや名前がない
    static assert(!__traits(hasMember, typeof(t2Named), "a"));
    writeln(t2Named[0]); // 3
    writeln(t2Named.b); // 4
    writeln(t2Named.c); // 5
    
    // タプルのメンバ数以上の名前を指定できない
    static assert(!__traits(compiles, t2.rename!("a","b","c","d")));
    
    // レンジパイプラインで使用する
    import std.range : iota, zip;
    import std.algorithm.iteration : map, sum;
    auto res = zip(iota(1, 4), iota(10, 13))
        .map!(t => t.rename!("a", "b"))
        .map!(t => t.a * t.b)
        .sum;
    writeln(res); // 68
    
    const tup = Tuple!(int, "a", int, "b")(2, 3);
    const renamed = tup.rename!("c", "d");
    writeln(renamed.c + renamed.d); // 5
    
    inout ref auto rename(alias translate)()
    if (is(typeof(translate) : V[K], V, K) && isSomeString!V && (isSomeString!K || is(K : size_t)));
    rename のオーバーロード。 をテンプレートパラメータとして受け取る。 キーが変更されるメンバの名前またはインデックスであり 新しい名前は対応する値である。 、すべてのキーは . 空文字列のルールは、"可変長"の場合と同じである。 のテンプレート・オーバーロードと同じルールが適用される。translate translate tuple rename
    Examples:
    // 名前を現在の名前に置き換える
    
    Tuple!(float, "dat", size_t[2], "pos") t1;
    t1.pos = [2, 1];
    auto t1Named = t1.rename!(["dat": "height"]);
    t1Named.height = 3.4;
    writeln(t1Named.pos); // [2, 1]
    t1Named.rename!(["height": "altitude"]).altitude = 5;
    writeln(t1Named.height); // 5
    
    Tuple!(int, "a", int, "b") t2;
    t2 = tuple(3, 4);
    auto t2Named = t2.rename!(["a": "b", "b": "c"]);
    writeln(t2Named.b); // 3
    writeln(t2Named.c); // 4
    
    const t3 = Tuple!(int, "a", int, "b")(3, 4);
    const t3Named = t3.rename!(["a": "b", "b": "c"]);
    writeln(t3Named.b); // 3
    writeln(t3Named.c); // 4
    
    Examples:
    // ポジションで名前を置き換える
    
    Tuple!(float, "dat", size_t[2], "pos") t1;
    t1.pos = [2, 1];
    auto t1Named = t1.rename!([0: "height"]);
    t1Named.height = 3.4;
    writeln(t1Named.pos); // [2, 1]
    t1Named.rename!([0: "altitude"]).altitude = 5;
    writeln(t1Named.height); // 5
    
    Tuple!(int, "a", int, "b", int, "c") t2;
    t2 = tuple(3, 4, 5);
    auto t2Named = t2.rename!([0: "c", 2: "a"]);
    writeln(t2Named.a); // 5
    writeln(t2Named.b); // 4
    writeln(t2Named.c); // 3
    
    inout @property ref @trusted inout(Tuple!(sliceSpecs!(from, to))) slice(size_t from, size_t to)()
    if (from <= to && (to <= Types.length));
    この の参照スライスを取るTuple
    Parameters:
    from スライスの開始位置を指定する 。size_t
    to スライスの終了位置(排他的)を指定する 。size_t
    Returns:
    元の からのスライスである新しい[from, to) Tuple
    元の の範囲と同じ型と値を持つ。 と同じ型と値を持つ。[from, to)
    Examples:
    Tuple!(int, string, float, double) a;
    a[1] = "abc";
    a[2] = 4.5;
    auto s = a.slice!(1, 3);
    static assert(is(typeof(s) == Tuple!(string, float)));
    assert(s[0] == "abc" && s[1] == 4.5);
    
    // https://issues.dlang.org/show_bug.cgi?id=15645
    Tuple!(int, short, bool, double) b;
    static assert(!__traits(compiles, b.slice!(2, 4)));
    
    const nothrow @safe size_t toHash();
    この のハッシュを作成Tuple
    する。
    Returns:
    この のハッシュを表す 。Tuple size_t
    const string toString()();
    文字列に変換す
    る。
    Returns:
    この の文字列表現。Tuple
    const void toString(DG)(scope DG sink);

    const void toString(DG, Char)(scope DG sink, ref scope const FormatSpec!Char fmt);
    Tuple を 、 、 のいずれかでフォーマット%s %(inner%) %(inner%|sep%)
    する。
    タプルがサポートするフォーマット
    。 れる。れる。
    FormatDescription

    %s

    Tuple!(types)(elements formatted with %s each) のようなフォーマット

    %(inner%)

    フォーマット は、展開された に適用さinner Tuple

    、フィールドの数だけ書式を含むことができるTuple

    %(inner%|sep%)

    フォーマット は1つのフォーマットであり、 のすべてのフィールドに適用さinner

    フォーマット は、 のすべてのフィールドに適用される1つのフォーマットである。 に互換性がなければならない。Tuple

    Parameters:
    DG sink char 、デリゲートを受け入れる
    FormatSpec!Char fmt A
    std.format.FormatSpec
    Examples:
    import std.format : format;
    
    Tuple!(int, double)[3] tupList = [ tuple(1, 1.0), tuple(2, 4.0), tuple(3, 9.0) ];
    
    // デフォルトのフォーマット
    writeln(format("%s", tuple("a", 1))); // `Tuple!(string, int)("a", 1)`
    
    // 各コンポーネントに1つのフォーマット
    writeln(format("%(%#x v %.4f w %#x%)", tuple(1, 1.0, 10))); // `0x1 v 1.0000 w 0xa`
    writeln(format("%#x v %.4f w %#x", tuple(1, 1.0, 10).expand)); // `0x1 v 1.0000 w 0xa`
    
    // すべてのコンポーネントに1つのフォーマット
    // `>abc< & >1< & >2.3< & >[4, 5]<`
    writeln(format("%(>%s<%| & %)", tuple("abc", 1, 2.3, [4, 5])));
    
    // タプルの配列
    writeln(format("%(%(f(%d) = %.1f%);  %)", tupList)); // `f(1) = 1.0;  f(2) = 4.0;  f(3) = 9.0`
    
    Examples:
    import std.exception : assertThrown;
    import std.format : format, FormatException;
    
    // エラー: %( %)が見つからない。
    assertThrown!FormatException(
        format("%d, %f", tuple(1, 2.0)) == `1, 2.0`
    );
    
    // エラー: %( %| %)が見つからない。
    assertThrown!FormatException(
        format("%d", tuple(1, 2)) == `1, 2`
    );
    
    // エラー: %dがdoubleに不適切である
    assertThrown!FormatException(
        format("%(%d%|, %)", tuple(1, 2.0)) == `1, 2.0`
    );
    
    auto reverse(T)(T t)
    if (isTuple!T);
    Tuple のフィールドを逆順に並べたコピーを作成する。
    Parameters:
    T t コピーするTuple
    Returns:
    新しいTuple
    Examples:
    auto tup = tuple(1, "2");
    writeln(tup.reverse); // tuple("2", 1)
    
    template tuple(Names...)
    与えられた引数に従ってインスタンス化され、初期化されたTuple オブジェクトを構築する。 オブジェクトを構築する。
    Parameters:
    )。
    Names の連続する各フィールドを示す文字列のリスト(オプション Tuple または、要素がキャストされる型のリスト。 名前のリストの場合、 Args の対応するフィールドと一致する。 すべてのフィールドに名前をつける必要はないが 名前は順番に進まなければならないので、あるフィールドをスキップして、そのフィールドの後に次のフィールドの名前を付けることはできない。 を飛ばして次のフィールドに名前をつけることはできない。 型のリストの場合、 型のリストでは、パラメータと同じ数の型がなければならない。
    Examples:
    auto value = tuple(5, 6.7, "hello");
    writeln(value[0]); // 5
    writeln(value[1]); // 6.7
    writeln(value[2]); // "hello"
    
    // フィールド名を指定できる。
    auto entry = tuple!("index", "value")(4, "Hello");
    writeln(entry.index); // 4
    writeln(entry.value); // "Hello"
    
    auto tuple(Args...)(Args args);
    Parameters:
    Args args Tuple を初期化する値。Tuple の"型 "は、与えられた値の型から推測される。 の型は、与えられた値の型から推測される。
    Returns:
    与えられた引数から型が推測された新しいTuple
    enum auto isTuple(T);
    Tstd.typecons.Tuple のインスタンスである場合に限り、true を返す。
    Parameters:
    T チェックする型
    Returns:
    TTuple 型であれば true、そうでなければ false
    を返す。
    Examples:
    static assert(isTuple!(Tuple!()));
    static assert(isTuple!(Tuple!(int)));
    static assert(isTuple!(Tuple!(int, real, string)));
    static assert(isTuple!(Tuple!(int, "x", real, "y")));
    static assert(isTuple!(Tuple!(int, Tuple!(real), string)));
    
    template Rebindable(T) if (is(T == class) || is(T == interface) || isDynamicArray!T || isAssociativeArray!T)

    struct Rebindable(T) if (!is(T == class) && !is(T == interface) && !isDynamicArray!T && !isAssociativeArray!T);
    Rebindable!(T) はシンプルで効率的なラッパーである。 T 、別のオブジェクトを参照するために再割り当てできることを除けば、 型のオブジェクトと同じように振る舞うシンプルで効率的なラッパーである。 型のオブジェクトと同じように動作するシンプルで効率的なラッパーである。完全を期すため、Rebindable!(T) は、 が非定数オブジェクト型である場合、 にエイリアスする。 TT にエイリアスす
    る。 Rebindable 。 例えば、const オブジェクトを参照するストレージを持ちたい場合、 を使いたいかもしれない。 を参照する変更可能なストレージを持ちたい場合、Rebindable を使いたいかもしれない。 Dの型システムの健全性を壊すことはなく、。 通常、cast に伴うリスクはない。
    Parameters:
    よい。
    T どの型でも
    Examples:
    通常の オブジェクト参照の再割り当てはできないconst
    class Widget { int x; int y() @safe const { return x; } }
    const a = new Widget;
    // Fine
    a.y();
    // エラー!const aを変更できない
    // a.x = 5;
    // エラー!const aを変更できない
    // a = new Widget;
    
    Examples:
    しかし、 では再割り当てが可能Rebindable!(Widget)
    である、
    それ以外は とまったく同じように振る舞う。 const Widget
    class Widget { int x; int y() const @safe { return x; } }
    auto a = Rebindable!(const Widget)(new Widget);
    // Fine
    a.y();
    // エラー!const aを変更できない
    // a.x = 5;
    // Fine
    a = new Widget;
    
    Examples:
    一般的なアルゴリズムでRebindableを使う
    :
    import std.range.primitives : front, popFront;
    
    // std.algorithm.searching.maxElementのシンプルなバージョン
    typeof(R.init.front) maxElement(R)(R r)
    {
        auto max = rebindable(r.front);
        r.popFront;
        foreach (e; r)
            if (e > max)
                max = e; // Rebindableはconst-correctの再割り当てを可能にする
        return max;
    }
    struct S
    {
        char[] arr;
        alias arr this; // 比較のために
    }
    // ミュータブルに変換できない
    const S cs;
    static assert(!__traits(compiles, { S s = cs; }));
    
    alias CS = const S;
    CS[] arr = [CS("harp"), CS("apple"), CS("pot")];
    CS ms = maxElement(arr);
    writeln(ms.arr); // "pot"
    
    Examples:
    static struct S
    {
        int* ptr;
    }
    S s = S(new int);
    
    const cs = s;
    // s.ptrをcs.ptrに代入できない
    static assert(!__traits(compiles, {s = cs;}));
    
    Rebindable!(const S) rs = s;
    assert(rs.ptr is s.ptr);
    // rs.ptrはconstである
    static assert(!__traits(compiles, {rs.ptr = null;}));
    
    // s.ptrをrs.ptrに代入できない
    static assert(!__traits(compiles, {s = rs;}));
    
    const S cs2 = rs;
    // rsをリバインドする
    rs = cs2;
    rs = S();
    assert(rs.ptr is null);
    
    Rebindable!T rebindable(T)(T obj)
    if (is(T == class) || is(T == interface) || isDynamicArray!T || isAssociativeArray!T);

    Rebindable!T rebindable(T)(T value)
    if (!is(T == class) && !is(T == interface) && !isDynamicArray!T && !isAssociativeArray!T && !is(T : Rebindable!U, U));
    自動型推論を用いてRebindable を作成するための便利な関数である。 を作成するための便利な関数である。
    Parameters:
    T obj Rebindable を初期化する値への参照。
    Returns:
    与えられた参照で初期化された、新しく構築されたRebindable
    Examples:
    class C
    {
        int payload;
        this(int p) { payload = p; }
    }
    const c = new C(1);
    
    auto c2 = c.rebindable;
    writeln(c2.payload); // 1
    // Rebindableをrebindableに渡す
    c2 = c2.rebindable;
    
    c2 = new C(2);
    writeln(c2.payload); // 2
    
    const c3 = c2.get;
    writeln(c3.payload); // 2
    
    Examples:
    immutable struct S
    {
        int[] array;
    }
    auto s1 = [3].idup.rebindable;
    s1 = [4].idup.rebindable;
    writeln(s1); // [4]
    
    Rebindable!T rebindable(T)(Rebindable!T obj);
    この関数は、単純に渡されたRebindable オブジェクトを返す。 これは 一般的なプログラミングの場合、与えられたオブジェクトが通常の class またはRebindable のどちらかである場合に有用である。
    Parameters:
    である。
    Rebindable!T obj Rebindable!Tのインスタンス
    Returns:
    obj のインスタンスであ
    Examples:
    class C
    {
        int payload;
        this(int p) { payload = p; }
    }
    const c = new C(1);
    
    auto c2 = c.rebindable;
    writeln(c2.payload); // 1
    // rebindableをrebindableに渡す
    c2 = c2.rebindable;
    writeln(c2.payload); // 1
    
    template UnqualRef(T) if (is(T == class) || is(T == interface))
    Rebindable!(T) と似ているが、参照からすべての修飾子を取り除く。 不変性だけでなく、すべての修飾子を除去する。主な使用例としては 共有(共有クラスデータへのスレッドローカル参照を持つ)
    Parameters:
    T クラスまたはインターフェイス型。
    Examples:
    class Data {}
    
    static shared(Data) a;
    static UnqualRef!(shared Data) b;
    
    import core.thread;
    
    auto thread = new core.thread.Thread({
        a = new shared Data();
        b = new shared Data();
    });
    
    thread.start();
    thread.join();
    
    assert(a !is null);
    assert(b is null);
    
    string alignForSize(E...)(const char[][] names...);
    提供されたメンバを順番に並べ、アライメントを保ちながらサイズを最小にする。 アラインメントは、80ビットの実数や、align(1)として宣言された構造体では、必ずしも最適ではない。 としても最適ではない。
    Parameters:
    E アラインメントされる型のリスト。 struct class のような集合体のフィールドを表す。
    char[][] names 整列されるフィールドの名前。
    Returns:
    structclass のような集約に混ぜる文字列。
    Examples:
    struct Banner {
        mixin(alignForSize!(byte[6], double)(["name", "height"]));
    }
    
    struct Nullable(T);

    auto nullable(T)(T t);
    値がないことを示す特徴的な "null"状態と対になる値を定義する。 を定義する。デフォルトで構築された場合、Nullable!T オブジェクトはヌル状態から始まる。これを代入すると 非NULLになる。nullify を呼び出すと、再びヌル状態になる。
    実質的にNullable!TTbool を格納する
    こちらも参照のこと: apply ペイロードを使用する別の方法。
    Examples:
    struct CustomerRecord
    {
        string name;
        string address;
        int customerNum;
    }
    
    Nullable!CustomerRecord getByName(string name)
    {
        //毛むくじゃらの束
    
        return Nullable!CustomerRecord.init;
    }
    
    auto queryResult = getByName("Doe, John");
    if (!queryResult.isNull)
    {
        //Mr.Doeの顧客記録を処理する
        auto address = queryResult.get.address;
        auto customerNum = queryResult.get.customerNum;
    
        //この顧客情報を使っていくつかの処理を行う
    }
    else
    {
        //顧客をデータベースに追加する
    }
    
    Examples:
    import std.exception : assertThrown;
    
    auto a = 42.nullable;
    assert(!a.isNull);
    writeln(a.get); // 42
    
    a.nullify();
    assert(a.isNull);
    assertThrown!Throwable(a.get);
    
    Examples:
    import std.algorithm.iteration : each, joiner;
    Nullable!int a = 42;
    Nullable!int b;
    // 各値を配列に追加する
    int[] arr;
    a.each!((n) => arr ~= n);
    writeln(arr); // [42]
    b.each!((n) => arr ~= n);
    writeln(arr); // [42]
    // Nullableの配列から最初の値を取り出す
    Nullable!int[] c = new Nullable!int[](10);
    c[7] = Nullable!int(42);
    writeln(c.joiner.front); // 42
    
    inout this(inout T value);
    valuethis を初期化するコンストラクタ .
    Parameters:
    T value このNullable を初期化する値。
    bool opEquals(this This, Rhs)(auto ref Rhs rhs)
    if (!is(CommonType!(This, Rhs) == void));

    bool opEquals(this This, Rhs)(auto ref Rhs rhs)
    if (is(CommonType!(This, Rhs) == void) && is(typeof(this.get == rhs)));
    両方がNULLの場合は等しい。一方がNULLで、もう一方がNULLでない場合 がnullでない場合、両者は等しくない。両方がnullでない場合、値が等しければ等しい。 値が等しければ等しい。
    Examples:
    Nullable!int empty;
    Nullable!int a = 42;
    Nullable!int b = 42;
    Nullable!int c = 27;
    
    writeln(empty); // empty
    writeln(empty); // Nullable!int.init
    assert(empty != a);
    assert(empty != b);
    assert(empty != c);
    
    writeln(a); // b
    assert(a != c);
    
    assert(empty != 42);
    writeln(a); // 42
    assert(c != 42);
    
    string toString();

    const string toString();

    void toString(W)(ref W writer, ref scope const FormatSpec!char fmt)
    if (isOutputRange!(W, char));

    const void toString(W)(ref W writer, ref scope const FormatSpec!char fmt)
    if (isOutputRange!(W, char));
    isNulltrue の場合、文字列"Nullable.null" を返す
    そうでなければ std.format.formattedWrite を呼び出すのと同じである。 を呼び出すのと同じである。
    Parameters:
    W writer char出力範囲
    FormatSpec!char fmt std.format.FormatSpec 。 このNullableがNULLでない場合の値を表す。
    Returns:
    writerfmt が設定されていない場合はstring 、そうでない場合はvoid
    const pure nothrow @property @safe bool isNull();
    this がヌル状態かどうかをチェック
    する。
    Returns:
    trueiff this がヌル状態かどうか、そうでなければ false
    Examples:
    Nullable!int ni;
    assert(ni.isNull);
    
    ni = 0;
    assert(!ni.isNull);
    
    void nullify()();
    this を強制的にヌル状態
    にする。
    Examples:
    Nullable!int ni = 0;
    assert(!ni.isNull);
    
    ni.nullify();
    assert(ni.isNull);
    
    ref Nullable opAssign()(T value) return;
    value を内部保持状態に割り当てる
    割り当てが成功すると this が非NULLになる。
    Parameters:
    T value このNullable に割り当て
    T
    型の値。
    Examples:
    この が、すでにNULL値を持つ型(ポインタなNullable
    ど)をラップしている場合、この にNULL値を代入する。
    (ポインタなど)をラップしている場合、NULL値をこの の他の値を代入するのと変わらない。 を代入するのと変わらない。その結果、コードは非常に奇妙に見えることになる。 を使用することで、これを避けることを強く推奨する。 を使用することを強く推奨する。 テンプレート引数を取る Nullable T Nullable nullValue
    //Passes
    Nullable!(int*) npi;
    assert(npi.isNull);
    
    //Passes?!
    npi = null;
    assert(!npi.isNull);
    
    inout pure nothrow @property ref @safe inout(T) get();

    inout @property inout(T) get()(inout(T) fallback);

    inout @property auto get(U)(inout(U) fallback);
    nullでなければ値を取得する
    this がNULLの状態で、オプションの パラメータ が指定されていれば、それが返される。 がない場合、 ヌル状態で を呼び出すことは無効である。fallback fallback get
    フォールバック型がNullable型と異なる場合、 。 を返す。 get(T)
    Parameters:
    inout(T) fallback Nullable が NULL の場合に返す値。
    Returns:
    この が内部的に保持する値Nullable
    である。
    alias empty = isNull;

    alias popFront = nullify;

    alias popBack = nullify;

    inout pure nothrow @property ref @safe inout(T) front();

    alias back = front;

    inout @property inout(typeof(this)) save();

    inout inout(typeof(this)) opIndex(size_t[2] dim);

    const size_t[2] opSlice(size_t dim : 0)(size_t from, size_t to);

    const pure nothrow @property @safe size_t length();

    template opDollar(size_t dim : 0)

    inout pure nothrow ref @safe inout(T) opIndex(size_t index);
    auto opSlice(this This)();
    Nullable を範囲に変換する
    含まれる型が の場合でも動作する。immutable
    struct Nullable(T, T nullValue);

    auto nullable(alias nullValue, T)(T t)
    if (is(typeof(nullValue) == T));
    Nullable!T と同じだが、ヌル状態は特定の値として定義されている。 と同じである。例えば、Nullable!(uint, uint.max) は「」である。 uint であり、ヌル状態を表す値としてuint.max を設定する。 Nullable!(T, nullValue) は、余分なbool を格納する必要がないため、Nullable!T よりもストレージ効率が高い。
    Parameters:
    T Nullableがヌル値を提供するラップ型。
    nullValue のヌル状態を示すヌル値である。 Nullable.T 型でなければならない。
    Examples:
    Nullable!(size_t, size_t.max) indexOf(string[] haystack, string needle)
    {
        //Find the needle, returning -1 if not found
    
        return Nullable!(size_t, size_t.max).init;
    }
    
    void sendLunchInvite(string name)
    {
    }
    
    //Cよりは安全だ...
    auto coworkers = ["Jane", "Jim", "Marry", "Fred"];
    auto pos = indexOf(coworkers, "Bob");
    if (!pos.isNull)
    {
        //ボブにランチの招待状を送る
        sendLunchInvite(coworkers[pos]);
    }
    else
    {
        //ボブが見つからない; report the error
    }
    
    //そしてオーバーヘッドはない
    static assert(Nullable!(size_t, size_t.max).sizeof == size_t.sizeof);
    
    Examples:
    import std.exception : assertThrown;
    
    Nullable!(int, int.min) a;
    assert(a.isNull);
    assertThrown!Throwable(a.get);
    a = 5;
    assert(!a.isNull);
    writeln(a); // 5
    static assert(a.sizeof == int.sizeof);
    
    Examples:
    auto a = nullable!(int.min)(8);
    writeln(a); // 8
    a.nullify();
    assert(a.isNull);
    
    this(T value);
    valuethis を初期化するコンストラクタ .
    Parameters:
    T value このNullable を初期化する値。
    const @property bool isNull();
    this がヌル状態かどうかをチェック
    する。
    Returns:
    trueiff this がヌル状態、そうでなければ false。
    Examples:
    Nullable!(int, -1) ni;
    //"null"状態に初期化される
    assert(ni.isNull);
    
    ni = 0;
    assert(!ni.isNull);
    
    void nullify()();
    this を強制的にヌル状態
    にする。
    Examples:
    Nullable!(int, -1) ni = 0;
    assert(!ni.isNull);
    
    ni = -1;
    assert(ni.isNull);
    
    void opAssign()(T value);
    value を内部保持状態に割り当てる
    割り当てが成功すると this が非NULLになる。ヌルチェックは行われない。注釈: 代入が成功すると、this はヌル状態になる。
    Parameters:
    T value このNullable に代入するT 型の値。 それがnullvalue の場合、この の内部状態はnullに設定される。 Nullable
    内部状態はヌルに設定される。
    Examples:
    この が、すでにnull値を持つ型(ポインタなど)をラップしており、そのnull値がこの に与えNullable
    られていない場合、この の内部状態はnullに設定される。
    (ポインタなど)をラップし、そのヌル値が にヌル値が与えられていない場合、ヌル値をこの にnull値を代入しても、 、 にNULL値が与えられていない場合、これにNULL値を代入することは、他の型の値を代入するのと変わらない。これは非常に奇妙なコードになる。 の"組み込み"のヌル値を使うことで、これを避けることを強く推奨する。 の"内蔵"値である を使用することを強く推奨する。 nullValue Nullable T T nullValue
    //Passes
    enum nullVal = cast(int*) 0xCAFEBABE;
    Nullable!(int*, nullVal) npi;
    assert(npi.isNull);
    
    //Passes?!
    npi = null;
    assert(!npi.isNull);
    
    inout @property ref inout(T) get();
    this がヌル状態であってはならない。 この関数は、 への暗黙の変換の際にも呼び出される。T

    事前条件 は でなければならない。 isNull false

    Returns:
    この が内部的に保持する値Nullable
    Examples:
    import std.exception : assertThrown, assertNotThrown;
    
    Nullable!(int, -1) ni;
    //`get`は暗黙的に呼び出される。非リリースモードでは
    //エラーをスローする
    assertThrown!Throwable(ni == 0);
    
    ni = 0;
    assertNotThrown!Throwable(ni == 0);
    
    template apply(alias fun)
    Nullable の内容を解凍し、操作を実行し、再度梱包する。isNullの場合は何もしない。
    Nullable で呼び出されると、applyNullable に含まれる値をアンパック
    する、
    それを指定された関数に渡し、その結果を別のNullable で包む(必要な場合)。 Nullable がNULLの場合、apply はNULL自身を返す。
    Parameters:
    T t a
    Nullable
    fun nullableの内容を操作する関数である。
    Returns:
    fun(t.get).nullable if!t.isNull, elseNullable.init.
    こちらも参照のこと: Maybe モナド
    Examples:
    alias toFloat = i => cast(float) i;
    
    Nullable!int sample;
    
    // apply(null)は関数の戻り値の型をnullの`Nullable`にする。
    Nullable!float f = sample.apply!toFloat;
    assert(sample.isNull && f.isNull);
    
    sample = 3;
    
    // apply(non-null)は関数を呼び出し、その結果を`Nullable`で囲む。
    f = sample.apply!toFloat;
    assert(!sample.isNull && !f.isNull);
    writeln(f.get); // 3.0f
    
    Examples:
    alias greaterThree = i => (i > 3) ? i.nullable : Nullable!(typeof(i)).init;
    
    Nullable!int sample;
    
    // 関数が既に`Nullable`を返している場合、その`Nullable`はラップされない。
    auto result = sample.apply!greaterThree;
    assert(sample.isNull && result.isNull);
    
    // 関数は`Nullable`を返すことにしてもよい。
    sample = 3;
    result = sample.apply!greaterThree;
    assert(!sample.isNull && result.isNull);
    
    // あるいは、既に`Nullable`でラップされた値を返すかもしれない。
    sample = 4;
    result = sample.apply!greaterThree;
    assert(!sample.isNull && !result.isNull);
    writeln(result.get); // 4
    
    struct NullableRef(T);

    auto nullableRef(T)(T* t);
    Nullable!T 、オブジェクトがメモリの別の場所にある値を参照することを除けば、同じである。 を参照する。これにより、代入は最初に代入された値を上書きする。 を上書きする。内部的には、NullableRef!T は (つまり )へのポインタを格納するだけである。 T Nullable!T.sizeof == (T*).sizeofへのポインタを格納するだけである。
    Examples:
    import std.exception : assertThrown;
    
    int x = 5, y = 7;
    auto a = nullableRef(&x);
    assert(!a.isNull);
    writeln(a); // 5
    writeln(x); // 5
    a = 42;
    writeln(x); // 42
    assert(!a.isNull);
    writeln(a); // 42
    a.nullify();
    writeln(x); // 42
    assert(a.isNull);
    assertThrown!Throwable(a.get);
    assertThrown!Throwable(a = 71);
    a.bind(&y);
    writeln(a); // 7
    y = 135;
    writeln(a); // 135
    
    pure nothrow @safe this(T* value);
    コンストラクタはthisvalue にバインドする
    Parameters:
    T* value バインドする値
    pure nothrow @safe void bind(T* value);
    value に内部状態をバインド
    する。
    Parameters:
    T* value このNullableRef をバインドするT 型の値へのポインタ。
    Examples:
    NullableRef!int nr = new int(42);
    writeln(nr); // 42
    
    int* n = new int(1);
    nr.bind(n);
    writeln(nr); // 1
    
    const pure nothrow @property @safe bool isNull();
    this がヌル状態の場合のみ、true を返す。
    Returns:
    this がヌル状態の場合は真、そうでない場合は偽を
    返す。
    Examples:
    NullableRef!int nr;
    assert(nr.isNull);
    
    int* n = new int(42);
    nr.bind(n);
    assert(!nr.isNull && nr == 42);
    
    pure nothrow @safe void nullify();
    this を強制的にヌル状態
    にする。
    Examples:
    NullableRef!int nr = new int(42);
    assert(!nr.isNull);
    
    nr.nullify();
    assert(nr.isNull);
    
    void opAssign()(T value)
    if (isAssignable!T);
    value を内部保持状態に割り当てる
    Parameters:
    T value このNullableRef に割り当てるT 型の値。 このNullableRef の内部状態が初期化されていない場合 この の内部状態が初期化されていない場合、非リリース・モードではエラーがスローされる。 エラーが投げられる。
    Examples:
    import std.exception : assertThrown, assertNotThrown;
    
    NullableRef!int nr;
    assert(nr.isNull);
    assertThrown!Throwable(nr = 42);
    
    nr.bind(new int(0));
    assert(!nr.isNull);
    assertNotThrown!Throwable(nr = 42);
    writeln(nr); // 42
    
    inout pure nothrow @property ref @safe inout(T) get();
    this がヌル状態であってはならない。 この関数は、T への暗黙の変換の際にも呼び出される。
    Examples:
    import std.exception : assertThrown, assertNotThrown;
    
    NullableRef!int nr;
    //`get`は暗黙的に呼び出される。
    //非リリースモードではエラーをスローする
    assertThrown!Throwable(nr == 0);
    
    nr.bind(new int(0));
    assertNotThrown!Throwable(nr == 0);
    
    template BlackHole(Base)
    BlackHole!BaseBase のサブクラスであり、 の抽象メンバ関数をすべてドゥ・ナッシング関数として自動的に実装する。 のサブクラスであり、Base のすべての抽象メンバ関数を何もしない関数として自動的に実装する。 自動実装された各 自動実装された関数は、何もせずに戻り値の型のデフォルト値を返すだけである。 のデフォルト値を返すだけである。
    名前の由来は クラス::ブラックホール Sean M. BurkeによるPerlモジュールである。
    Parameters:
    Base BlackHole 、継承する非最終クラス。
    Examples:
    import std.math.traits : isNaN;
    
    static abstract class C
    {
        int m_value;
        this(int v) { m_value = v; }
        int value() @property { return m_value; }
    
        abstract real realValue() @property;
        abstract void doSomething();
    }
    
    auto c = new BlackHole!C(42);
    writeln(c.value); // 42
    
    // NaNであるreal.initを返す
    assert(c.realValue.isNaN);
    // 抽象関数は何もしないものとして実装される
    c.doSomething();
    
    template WhiteHole(Base)
    WhiteHole!Base は、Base のサブクラスである。 のサブクラスであり、抽象メンバ関数を常に失敗する関数として自動的に実装する。これらの関数は単に。 Error Whitehole は、実装されていないクラス・メンバ関数の使用をトラップするのに便利である。 実装されていないクラス・メンバ関数の使用をトラップするのに便利である。
    名前の由来は クラス::ホワイトホール Michael G SchwernのPerlモジュールに由来する。
    Parameters:
    Base WhiteHole 、継承する非最終クラス。
    Examples:
    import std.exception : assertThrown;
    
    static class C
    {
        abstract void notYetImplemented();
    }
    
    auto c = new WhiteHole!C;
    assertThrown!NotImplementedError(c.notYetImplemented()); // エラーをスローする
    
    class AutoImplement(Base, alias how, alias what = isAbstractFunction) if (!is(how == class)): Base;

    class AutoImplement(Interface, BaseClass, alias how, alias what = isAbstractFunction) if (is(Interface == interface) && is(BaseClass == class)): BaseClass, Interface;
    AutoImplement クラスまたはインターフェイス のすべての抽象メンバ関数を、指定された方法で自動的に(デフォルトで)実装する。 Base 、指定された方法で自動的に実装される。
    AutoImplementInterface BaseClassを自動的に実装する。
    Parameters:
    れるかを指定する。する。
    how テンプレート化された関数" は、関数がどのように実装/上書きさ
    how Base 、2つの引数が渡される。 実装された関数へのエイリアスである。 そしてhow 、実装された関数本体を文字列として返さなければならない。 関数本体を文字列として返さなければならない。
    生成された関数本体には、以下のキーワードを使用することができる:
    • a0 a1 関数に渡される引数;
    • args 引数のタプル;
    • self 関数自体のエイリアス;
    • parent オーバーライドされた関数のエイリアス(もしあれば)
    複雑な関数を生成するために、(暗黙的な "テンプレート・プロパティ"の代わりに)テンプレート化された関数を使いたいかもしれない。 の代わりに)テンプレート化された関数を使って複雑な関数を生成することができる:
    // オーバーライドされた関数を呼び出すたびにログメッセージを表示する。
    string generateLogger(C, alias fun)() @property
    {
        import std.traits;
        enum qname = C.stringof ~ "." ~ __traits(identifier, fun);
        string stmt;
    
        stmt ~= q{ struct Importer { import std.stdio; } };
        stmt ~= `Importer.writeln("Log: ` ~ qname ~ `(", args, ")");`;
        static if (!__traits(isAbstractFunction, fun))
        {
            static if (is(ReturnType!fun == void))
                stmt ~= q{ parent(args); };
            else
                stmt ~= q{
                    auto r = parent(args);
                    Importer.writeln("--> ", r);
                    return r;
                };
        }
        return stmt;
    }
    
    what テンプレート化された関数" は、どの関数を実装/オーバーライドすべきかを決定 を決定するテンプレートである。
    引数はwhat に渡される。 Base 関数へのエイリアスである。 what はブール値を返さなければならない。 渡された関数が実装/上書きされるべきことを示すために、true を返す。 を返す。
    // funが何かを返すかどうかを見る。
    enum bool hasValue(alias fun) = !is(ReturnType!(fun) == void);
    

    注釈

    : 生成されたコードは、 モジュールのスコープに挿入される。

    生成されたコードは、std.typecons モジュールのスコープに挿入される。 したがって のスコープに挿入される。したがって、std.typecons の外の有用な関数は、生成されたコードでは使用できない。 コードでは使えない。 この問題を回避するには、importgenerateLogger() ローカル構造体にしておく。 のテンプレートのようにする。

    Bugs:
    • コンストラクタへの可変長引数はスーパーに転送されない。
    • 深いインターフェース継承は、次のようなメッセージでコンパイルエラーを引き起こす
    • Error: function std.typecons.AutoImplement!(Foo).AutoImplement.bar" のようなメッセージが表示される。 は関数をオーバーライドしていません" といったメッセージが表示される。 [Bugzilla 2525]
    • parent キーワードは実際にはスーパークラスの対応するメンバ関数へのデリゲート
    • である。
    • 対応するメンバ関数へのデリゲートである。 [Bugzilla 2540] でエイリアステンプレートパラメータを使用する。
    • how および/またはwhat でエイリアス テンプレート パラメータを使用すると、奇妙なコンパイル エラーが発生することがある
    • 奇妙なコンパイルエラーを引き起こす可能性がある。 この問題を回避するには、代わりにテンプレート・タプル・パラメータを使用する。 この問題を回避する。 [Bugzilla 4217] この問題を回避する。
    Examples:
    interface PackageSupplier
    {
        int foo();
        int bar();
    }
    
    static abstract class AbstractFallbackPackageSupplier : PackageSupplier
    {
        protected PackageSupplier default_, fallback;
    
        this(PackageSupplier default_, PackageSupplier fallback)
        {
            this.default_ = default_;
            this.fallback = fallback;
        }
    
        abstract int foo();
        abstract int bar();
    }
    
    template fallback(T, alias func)
    {
        import std.format : format;
        // 実装されているすべてのメソッドについて:
        // - まずデフォルトを試す
        // - 失敗した場合のみ実行し、フォールバックを返す
        enum fallback = q{
            try
            {
                return default_.%1$s(args);
            }
            catch (Exception)
            {
                return fallback.%1$s(args);
            }
        }.format(__traits(identifier, func));
    }
    
    // 2つのクラスを組み合わせ、2番目のクラスをフォールバックとして使う
    alias FallbackPackageSupplier = AutoImplement!(AbstractFallbackPackageSupplier, fallback);
    
    class FailingPackageSupplier : PackageSupplier
    {
        int foo(){ throw new Exception("failure"); }
        int bar(){ return 2;}
    }
    
    class BackupPackageSupplier : PackageSupplier
    {
        int foo(){ return -1; }
        int bar(){ return -1;}
    }
    
    auto registry = new FallbackPackageSupplier(new FailingPackageSupplier(), new BackupPackageSupplier());
    
    writeln(registry.foo()); // -1
    writeln(registry.bar()); // 2
    
    template generateEmptyFunction(C, func...)

    enum string generateAssertTrap(C, func...);
    AutoImplement 用の定義済みハウポリシー。 これらのテンプレートは BlackHole およびWhiteHole でもそれぞれ使用される。
    Examples:
    alias BlackHole(Base) = AutoImplement!(Base, generateEmptyFunction);
    
    interface I
    {
        int foo();
        string bar();
    }
    
    auto i = new BlackHole!I();
    // generateEmptyFunctionは、何もせずに戻り値の型のデフォルト値を返す
    writeln(i.foo); // 0
    assert(i.bar is null);
    
    Examples:
    import std.exception : assertThrown;
    
    alias WhiteHole(Base) = AutoImplement!(Base, generateAssertTrap);
    
    interface I
    {
        int foo();
        string bar();
    }
    
    auto i = new WhiteHole!I();
    // generateAssertTrapはインターフェースの未実装関数ごとに例外をスローする
    assertThrown!NotImplementedError(i.foo);
    assertThrown!NotImplementedError(i.bar);
    
    template wrap(Targets...) if (Targets.length >= 1 && allSatisfy!(isMutable, Targets))

    template wrap(Targets...) if (Targets.length >= 1 && !allSatisfy!(isMutable, Targets))

    template unwrap(Target) if (isMutable!Target)

    template unwrap(Target) if (!isMutable!Target)
    構造ベースのタイプセーフ変換をサポートする。
    Sourceinterface Targets に構造適合している場合、 wrapは、Targets を継承する内部ラッパークラスを作成し、 オブジェクトをラップして返す。 src オブジェクトをラップし、それを返す。
    unwrap は、wrap によってラップされたオブジェクトを取り出すために使用できる。
    Examples:
    interface Quack
    {
        int quack();
        @property int height();
    }
    interface Flyer
    {
        @property int height();
    }
    class Duck : Quack
    {
        int quack() { return 1; }
        @property int height() { return 10; }
    }
    class Human
    {
        int quack() { return 2; }
        @property int height() { return 20; }
    }
    
    Duck d1 = new Duck();
    Human h1 = new Human();
    
    interface Refleshable
    {
        int reflesh();
    }
    
    // 構造適合性を持たない
    static assert(!__traits(compiles, d1.wrap!Refleshable));
    static assert(!__traits(compiles, h1.wrap!Refleshable));
    
    // strict upcast
    Quack qd = d1.wrap!Quack;
    assert(qd is d1);
    assert(qd.quack() == 1);    // Duck.quackを呼び出す
    // strict downcast
    Duck d2 = qd.unwrap!Duck;
    assert(d2 is d1);
    
    // structural upcast
    Quack qh = h1.wrap!Quack;
    assert(qh.quack() == 2);    // Human.quackを呼び出す
    // 構造的なダウンキャスト
    Human h2 = qh.unwrap!Human;
    assert(h2 is h1);
    
    // 構造物アップキャスト(2段階)
    Quack qx = h1.wrap!Quack;   // Human -> Quack
    Flyer fx = qx.wrap!Flyer;   // Quack -> Flyer
    assert(fx.height == 20);    // Human.heightを呼び出す
    // 構造的ダウンキャスト(2段階)
    Quack qy = fx.unwrap!Quack; // Flyer -> Quack
    Human hy = qy.unwrap!Human; // Quack -> Human
    assert(hy is h1);
    // 構造的ダウンキャスト(1段階)
    Human hz = fx.unwrap!Human; // Flyer -> Human
    assert(hz is h1);
    
    Examples:
    import std.traits : FunctionAttribute, functionAttributes;
    interface A { int run(); }
    interface B { int stop(); @property int status(); }
    class X
    {
        int run() { return 1; }
        int stop() { return 2; }
        @property int status() { return 3; }
    }
    
    auto x = new X();
    auto ab = x.wrap!(A, B);
    A a = ab;
    B b = ab;
    writeln(a.run()); // 1
    writeln(b.stop()); // 2
    writeln(b.status); // 3
    static assert(functionAttributes!(typeof(ab).status) & FunctionAttribute.property);
    
    enum RefCountedAutoInitialize: int;
    SafeRefCounted オブジェクトの自動初期化に関するオプション(以下の定義を参照のこと)。 SafeRefCounted )の自動初期化に関するオプション。
    Examples:
    import core.exception : AssertError;
    import std.exception : assertThrown;
    
    struct Foo
    {
        int a = 42;
    }
    
    SafeRefCounted!(Foo, RefCountedAutoInitialize.yes) rcAuto;
    SafeRefCounted!(Foo, RefCountedAutoInitialize.no) rcNoAuto;
    
    writeln(rcAuto.refCountedPayload.a); // 42
    
    assertThrown!AssertError(rcNoAuto.refCountedPayload);
    rcNoAuto.refCountedStore.ensureInitialized;
    writeln(rcNoAuto.refCountedPayload.a); // 42
    
    no
    オブジェクトを自動初期
    化しない
    yes
    オブジェクトを自動
    初期
    する
    struct SafeRefCounted(T, RefCountedAutoInitialize autoInit = RefCountedAutoInitialize.yes) if (!is(T == class) && !is(T == interface));
    ペイロードとしてT の値を含む参照カウント・オブジェクトを定義する。 として定義する。
    のインスタンスは、構造体への参照である。 SafeRefCountedのインスタンスは構造体への参照である、 のインスタンスは、構造体への参照である 構造体への参照である。 ストアには、参照カウント とT ペイロードが含まれる。 SafeRefCountedmalloc 。 を使う。 のインスタンスがコピーされたり SafeRefCountedのインスタンスがコピーされたり のインスタンスがコピーされたりスコープから外れたりすると、自動的に参照カウントが増減する。 参照カウントは自動的に増減する。 参照カウントがゼロになると SafeRefCounted free がペイロードに対してdestroy 。 を呼び出す。 T 、ペイロードがGCで割り当てられたメモリへの参照を含んでいる場合は、 。 が含まれていれば、それをGCメモリに追加する。 SafeRefCountedがGCメモリに追加する。 に追加され、ストアに呼び出される前にGCスキャンから削除される。 free がストアで呼び出される前に、GCスキャンから削除する。
    destroy の重要な結果の1つは、 ペイロードのデストラクタを呼び出すことである。 T のデストラクタを呼び出すことである。 GCで管理された参照は、デストラクタ呼び出しの間 の他のメンバは有効である。 Tの他のメンバ(ファイルハンドルやmalloc メモリへのポインタなど)は、デストラクタ呼び出し中も有効である。 の他のメンバは、デストラクタ呼び出し中も有効である。 これにより、T 。 の他のメンバ、たとえばファイルハンドルや メモリへのポインタは、デストラクタ呼び出し中も有効である。 参照カウントがゼロになった直後に、GC以外のリソースをデアロケートまたはクリーンアップすることができる。
    preview=dip1000を指定しない、 SafeRefCountedは安全ではないので を注意深く使うべきである。ペイロードへの参照は オブジェクトの外側で SafeRefCountedオブジェクトの外側にエスケープしてはならない。
    preview=dip1000とする、 SafeRefCountedの場合、ペイロードへのアクセスが を持つ borrow関数のみでアクセスされれば安全である。スコープのセマンティクスは、誤って refCountedPayloadのエスケープを防ぐこともできる。 しかし、ペイロードの使用中に最後にカウントされた参照を破棄しないかどうかは、ユーザー次第である。そのため refCountedPayload へのアクセスは、@system のコードでのみ可能である。
    autoInit オプションは、ストアが自動的に初期化されることをオブジェクトに保証させる。 が自動的に初期化されるようにする。autoInit == RefCountedAutoInitialize.yes (デフォルトのオプション)のままにしておくと便利だが、ペイロードにアクセスするたびにテストが必要になる。 にすると、ペイロードにアクセスするたびにテストが必要になる。autoInit == RefCountedAutoInitialize.no の場合、ユーザーコードは refCountedStore.isInitialized またはrefCountedStore.ensureInitialized のいずれかを呼び出さなければならない。そうしないと、NULL ポインタの非参照となる。
    T.this()@disable でアノテーションされている場合、コンパイルするにはautoInit が必要である。 RefCountedAutoInitialize.no でなければならない。
    See Also:
    Examples:
    // `int`と`size_t`のペア - the latter being the
    // reference count - が動的に確保される
    auto rc1 = SafeRefCounted!int(5);
    writeln(rc1); // 5
    // アロケーションは不要で、参照カウントを1つ追加するだけでよい
    auto rc2 = rc1;
    // 参照セマンティクス
    rc2 = 42;
    writeln(rc1); // 42
    // rc1とrc2がスコープ外に出たとき、ペアは解放される
    
    struct RefCountedStore;
    SafeRefCounted ストレージの実装である。
    const pure nothrow @nogc @property @safe bool isInitialized();
    基礎となるストアが割り当てられ、初期化された場合のみ、true を返す。 を返す。
    const pure nothrow @nogc @property @safe size_t refCount();
    基礎となるストアが割り当てられ、初期化されている場合は、基礎となる参照カウントを返す。 (正の整数)、そうでなければ0 を返す。
    pure nothrow @safe void ensureInitialized()();
    ペイロードが適切に初期化されたことを確認する。このような このような呼び出しは、通常、ペイロードを使用する前に挿入される。
    がアノテーションされている場合、この関数は使用できない。 T.this()アノテーションが @disable.
    inout nothrow @property ref @safe inout(RefCountedStore) refCountedStore();
    ストレージ実装構造体を返す。
    this(A...)(auto ref A args)
    if (A.length > 0);

    this(return scope T val);
    ペイロードを初期化するコンストラクタ。

    ポストコンディション refCountedStore.isInitialized

    void opAssign(typeof(this) rhs);

    void opAssign(T rhs);
    代入演算子。

    注意 自動初期化がオフの場合、初期化されていない SafeRefCounted に新しいペイロードを割り当てることはできない。 自動初期化がオフの場合。別のカウントされた参照を代入することはできる。

    @property ref @system T refCountedPayload() return;

    inout pure nothrow @nogc @property ref @system inout(T) refCountedPayload() return;
    ペイロードへの参照を返す。if (autoInit ==) RefCountedAutoInitialize.yes)の場合、 refCountedStore.ensureInitialized を呼び出す。そうでない場合は、 assert(refCountedStore.isInitialized) を発行する。alias refCountedPayload this; と共に使用される。SafeRefCounted オブジェクトをT として使用できる。
    最初のオーバーロードは、autoInit == RefCountedAutoInitialize.yes の場合のみ存在する。 だから、もしautoInit == RefCountedAutoInitialize.no が定数または不変オブジェクトに対して呼び出された場合は、次のようになる。 refCountedPayloadも "nothrow"となる(ただし、初期化されていない場合はアサートされる)。 (としても修飾される(ただし、初期化されていない場合はアサートされる)。
    template borrow(alias fun)
    のペイロードを借用する。 SafeRefCountedfunのペイロードを借用する。@safe fun@safe であり、ペイロードへの参照をエスケープしていない場合。 操作の間、参照カウントはインクリメントされる、 最後の参照を破棄しても fun.
    Parameters:
    fun 値または参照によってペイロードを受け入れる callable。
    RC refCount ペイロードへのカウントされた参照。
    Returns:
    fun の戻り値(もしあれば)。戻り値のref は転送される。 が転送される。

    問題点 理由はまだ不明だが、この関数をUFCS構文で使用したコードは、。 を使ったコードは、@safe として推論されない。コードが明示的に @safe fun 、それを妨げるものは何もない。

    Examples:
    この例は-preview=dip1000@safe とマークすることができる。
    auto rcInt = safeRefCounted(5);
    writeln(rcInt.borrow!(theInt => theInt)); // 5
    auto sameInt = rcInt;
    writeln(sameInt.borrow!"a"); // 5
    
    // 関数の中で`ref`を使っている
    auto arr = [0, 1, 2, 3, 4, 5, 6];
    sameInt.borrow!(ref (x) => arr[x]) = 10;
    writeln(arr); // [0, 1, 2, 3, 4, 10, 6]
    
    // エイリアスを使ってペイロードを変更する
    sameInt.borrow!"a*=2";
    writeln(rcInt.borrow!"a"); // 10
    
    SafeRefCounted!(T, RefCountedAutoInitialize.no) safeRefCounted(T)(T val);
    SafeRefCounted を初期化する。 val.で初期化する。 T SafeRefCounted のテンプレート・パラメータは val. この関数は、コピー不可能な値をヒープに移動するために使用できる。 また、SafeRefCountedautoInit オプションも無効にする。
    Parameters:
    T val 参照カウントされる値
    Returns:
    初期化されたSafeRefCountedval.
    Examples:
    static struct File
    {
        static size_t nDestroyed;
        string name;
        @disable this(this); // コピーできない
        ~this() { name = null; ++nDestroyed; }
    }
    
    auto file = File("name");
    writeln(file.name); // "name"
    // ファイルをコピーできず、一意の所有権を持つ
    static assert(!__traits(compiles, {auto file2 = file;}));
    
    writeln(File.nDestroyed); // 0
    
    // 所有権を共有するために、ファイルを参照カウントする
    // 注意:
    //   すべての`SafeRefCounted!File`ハンドルが作成され、削除される複合ステートメント(中括弧で区切られたスコープ)を書く。
    //   これにより、すべてのハンドルが破棄された後に何が起こるかを(スコープの後で)見ることができる。
    {
        // `file`の内容を別の(ヒープに割り当てられた)`File`オブジェクトに移動し、
        // 1つまたは複数の(最初は1つの)`SafeRefCounted!File`オブジェクト("ハンドル")を使って管理・アクセスする。
        // This "moving":
        //   (1) `file`のデストラクタを起動する(=>`File.nDestroyed`が0から1にインクリメントされ、`file.name`が`null`になる);
        //   (2) `file`を`File.init`で上書きする(=>`file.name`が`null`になる)。
        // デストラクタに`name = null;`と書くのは冗長に見えるが、
        // (2)は`File`がデストラクタ(またはポストブリット演算子)を定義している場合にのみ実行され、
        // `nDestroyed`インストルメンテーションがなければデストラクタを定義する理由はないことに注意してほしい。
        import std.algorithm.mutation : move;
        auto rcFile = safeRefCounted(move(file));
        writeln(rcFile.name); // "name"
        writeln(File.nDestroyed); // 1
        writeln(file.name); // null
    
        // 同じ別の`File`オブジェクトに対して、別の`SafeRefCounted!File`ハンドルを作成する。
        // いずれかのハンドルが生きている間、`File`オブジェクトは生き続ける(=>`File.nDestroyed`は変更されない)。
        auto rcFile2 = rcFile;
        writeln(rcFile.refCountedStore.refCount); // 2
        writeln(File.nDestroyed); // 1
    }
    // 最後の`SafeRefCounted!File`ハンドルが破棄されると、別の`File`オブジェクトは削除される
    // (i.e. つまり、上記の複合文の閉じ中括弧で、`rcFile`と`rcFile2`の両方のハンドルが破棄される: `rcFile`と`rcFile2`)
    // (=> `File.nDestroyed`が1から2まで再びインクリメントされる):
    writeln(File.nDestroyed); // 2
    
    template Proxy(alias a)
    暗黙の変換を無効にしながら、すべての操作を転送するa のプロキシを作成する。 のプロキシを作成する。エイリアスされた項目a は でなければならない。 lvalue これは、"基本"型から新しい型を生成するのに便利である。 これは、"基本"型から新しい型を生成するのに便利である。 新しい型は古い型とは何の関係もない、 設計上)。
    新しい型は、基底型が行うすべての操作をサポートする、 +--<[] などのすべての演算子を含む。
    Parameters:
    a すべての操作のプロキシとして機能する値。l値でなければならない。 l値でなければならない。
    Examples:
    struct MyInt
    {
        private int value;
        mixin Proxy!value;
    
        this(int n){ value = n; }
    }
    
    MyInt n = 10;
    
    // 元の型が持つ操作を有効にする。
    ++n;
    writeln(n); // 11
    writeln(n * 2); // 22
    
    void func(int n) { }
    
    // 元の型への暗黙の変換を無効にする。
    //int x = n;
    //func(n);
    
    Examples:
    プロキシ値はlvalue でなければならない。
    struct NewIntType
    {
        //Won't work; リテラル'1'はr値であり、
        //l値ではない
        //mixin Proxy!1;
    
        //OK、nはl値である
        int n;
        mixin Proxy!n;
    
        this(int n) { this.n = n; }
    }
    
    NewIntType nit = 0;
    nit++;
    writeln(nit); // 1
    
    
    struct NewObjectType
    {
        Object obj;
        //OK、objはl値である
        mixin Proxy!obj;
    
        this (Object o) { obj = o; }
    }
    
    NewObjectType not = new Object();
    assert(__traits(compiles, not.toHash()));
    
    Examples:
    新しい型が古い型と関係ないという事実には、1つ例外がある。 とは関係がない。疑似メンバー 関数は新しい型でも使用できる。 に転送される。
    import std.math.traits : isInfinity;
    
    float f = 1.0;
    assert(!f.isInfinity);
    
    struct NewFloat
    {
        float _;
        mixin Proxy!_;
    
        this(float f) { _ = f; }
    }
    
    NewFloat nf = 1.0f;
    assert(!nf.isInfinity);
    
    struct Typedef(T, T init = T.init, string cookie = null);
    Typedef は、既存の型に基づいたユニークな型を作ることができる。 既存の型をベースとしたユニークな型を作成することができる。 、 とは異なり、2つの型が等しいとみなされることはない。 aliasTypedef
    Parameters:
    init 新しい型の初期値(オプション)。
    cookie 省略可能である。 同じ原点に基づく複数の一意な型を作成するために使用される。T

    注釈 ライブラリルーチンがTypedef型を扱えない場合、、 TypedefType テンプレートを使って、Typedefがラップしている 型を取り出すことができる。

    Examples:
    alias MyInt = Typedef!int;
    MyInt foo = 10;
    foo++;
    writeln(foo); // 11
    
    Examples:
    カスタム初期化値
    alias MyIntInit = Typedef!(int, 42);
    static assert(is(TypedefType!MyIntInit == int));
    static assert(MyIntInit() == 42);
    
    Examples:
    typedefは新しい型を作る。
    alias MyInt = Typedef!int;
    static void takeInt(int) {}
    static void takeMyInt(MyInt) {}
    
    int i;
    takeInt(i);    // ok
    static assert(!__traits(compiles, takeMyInt(i)));
    
    MyInt myInt;
    static assert(!__traits(compiles, takeInt(myInt)));
    takeMyInt(myInt);  // ok
    
    Examples:
    オプションの引数cookie 、同じ基本型を持つ異なる型を作成する。
    alias TypeInt1 = Typedef!int;
    alias TypeInt2 = Typedef!int;
    
    // 2つの型定義は同じ型である。
    static assert(is(TypeInt1 == TypeInt2));
    
    alias MoneyEuros = Typedef!(float, float.init, "euros");
    alias MoneyDollars = Typedef!(float, float.init, "dollars");
    
    // 二つの型定義は同じ型ではない。
    static assert(!is(MoneyEuros == MoneyDollars));
    
    string toString(this T)();

    void toString(this T, W)(ref W writer, ref scope const FormatSpec!char fmt)
    if (isOutputRange!(W, char));
    ラップされた値を人間が読める文字列に変換する。
    Examples:
    import std.conv : to;
    
    int i = 123;
    auto td = Typedef!int(i);
    writeln(i.to!string); // td.to!string
    
    template TypedefType(T)
    Typedef がラップしている基本型を取得する。 TTypedef でない場合、T にエイリアスされる。
    Examples:
    import std.conv : to;
    
    alias MyInt = Typedef!int;
    static assert(is(TypedefType!MyInt == int));
    
    /// 非Typedefでインスタンス化すると、その型が返される
    static assert(is(TypedefType!int == int));
    
    string num = "5";
    
    // 必要な型を取り出す
    MyInt myInt = MyInt( num.to!(TypedefType!MyInt) );
    writeln(myInt); // 5
    
    // 基礎となる型にキャストし、ラップされる値を得る
    int x = cast(TypedefType!MyInt) myInt;
    
    alias MyIntInit = Typedef!(int, 42);
    static assert(is(TypedefType!MyIntInit == int));
    static assert(MyIntInit() == 42);
    
    template scoped(T) if (is(T == class))
    現在のスコープ内でclass オブジェクトを割り当てる、 newこの機能は安全ではない; この機能は安全ではない。 オブジェクトへの参照をスコープ外にエスケープしないことは、ユーザーの責任である。
    オブジェクトへの参照をスコープ外に逃がさないようにするのはユーザーの責任である。 scoped()の結果が が破壊されたときに呼び出される。
    スコープされたクラス・インスタンスは、子構造体のインスタンスと同じように、親のclassstruct に埋め込むことができる、 子構造体のインスタンスと同様である。スコープされたメンバ変数は 型」でなければならない。 typeof(scoped!Class(args))を呼び出して初期化しなければならない。 を呼び出して初期化しなければならない。例を以下に示す。

    注釈 クラスのインスタンスを移動することは、たとえそのクラスへのポインタがないことが確認されていても、違法である。 クラスのインスタンスを移動することは違法である。このように、スコープされたオブジェクトを移動することは違法である。

    Examples:
    class A
    {
        int x;
        this()     {x = 0;}
        this(int i){x = i;}
        ~this()    {}
    }
    
    // 標準的な使い方、スタック上にAを構築する
    auto a1 = scoped!A();
    a1.x = 42;
    
    // `scoped`呼び出しの結果は暗黙的にクラス参照に変換される
    A aRef = a1;
    writeln(aRef.x); // 42
    
    // スコープ付き破壊
    {
        auto a2 = scoped!A(1);
        writeln(a2.x); // 1
        aRef = a2;
        // a2はここで破壊され、Aのデストラクタが呼ばれる
    }
    // aRefは現在無効な参照である
    
    // ここでは、一時的にスコープされたAは直ちに破棄される。
    // つまり、この参照は無効となる。
    version (Bug)
    {
        // Wrong、`auto`を使うべきである
        A invalid = scoped!A();
    }
    
    // 制限事項
    version (Bug)
    {
        import std.algorithm.mutation : move;
        auto invalid = a1.move; // 不正、スコープ付きオブジェクトは移動できない
    }
    static assert(!is(typeof({
        auto e1 = a1; // 不正、スコープ付きオブジェクトはコピーできない
        assert([a1][0].x == 42); // 同上
    })));
    static assert(!is(typeof({
        alias ScopedObject = typeof(a1);
        auto e2 = ScopedObject();  // illegal、scoped!Aでビルドしなければならない
        auto e3 = ScopedObject(1); // 同上
    })));
    
    // エイリアスと併用する
    alias makeScopedA = scoped!A;
    auto a3 = makeScopedA();
    auto a4 = makeScopedA(1);
    
    // メンバ変数として使用する
    struct B
    {
        typeof(scoped!A()) a; // 末尾の括弧に注意
    
        this(int i)
        {
            // メンバーを構築する
            a = scoped!A(i);
        }
    }
    
    // Stack-allocate
    auto b1 = B(5);
    aRef = b1.a;
    writeln(aRef.x); // 5
    destroy(b1); // b1.aに対してAのデストラクタを呼び出す
    // aRefは無効な参照となった
    
    // Heap-allocate
    auto b2 = new B(6);
    writeln(b2.a.x); // 6
    destroy(*b2); // b2.aに対してAのデストラクタを呼び出す
    
    @system auto scoped(Args...)(auto ref Args args);
    スコープされたオブジェクトを返す。
    Parameters:
    Args args T のコンストラクタに渡す引数。
    template Flag(string name)
    yes/noフラグを定義する。これにより フラグを受け付ける関数を、bool に頼ることなく簡単に定義できる。 列挙型を別途定義する必要もない。の代わりに Flag!"Name"の代わりにbool を使うことで、フラグの意味が呼び出し時に見えるようになる。yes/noフラグにはそれぞれ それぞれのyes/noフラグには独自の型があり、混同や取り違えが起こらない。

    例: getLine (通常はその定義から遠く離れている)を呼び出すコードは、ドキュメントを見なければ理解できない。 ドキュメントを見なければ理解できない。 APIに詳しいユーザーでも、ドキュメントを見なければ理解できない:

    string getLine(bool keepTerminator)
    {
        ...
        if (keepTerminator) ...
        ...
    }
    ...
    auto line = getLine(false);
    
    API:逆の意味(すなわち "ignoreTerminator")を仮定し、間違ったコードを挿入すると、コンパイルと実行が誤った結果になる。 のコードはコンパイルされ、誤った結果で実行される。
    booleanパラメータを Flagコード getLine 。 を呼び出すコードは、APIに精通していない人でも簡単に読んで理解することができる:
    string getLine(Flag!"keepTerminator" keepTerminator)
    {
        ...
        if (keepTerminator) ...
        ...
    }
    ...
    auto line = getLine(Yes.keepTerminator);
    
    構造体YesNo は、以下の略記法として用意されている。 Flag!"Name".yesFlag!"Name".noの省略形として提供されており、簡潔さと の省略形として提供されている。これらの便利な構造体は、通常、andのエイリアスを作成する必要がなく、逆効果であることを意味する。 のエイリアスを作成するのは非生産的である。 Flagのエイリアスを作成する必要がない。 のエイリアスを作成する必要はなく、逆効果である。
    構造化されていないパラメーターを用いてカテゴリーデータを渡すことは、スティーブによって「単純データ結合」に分類されている。bool コード・コンプリート』では、スティーブ・マコーネルが「単純データ結合」に分類している。 McConnellはCode Completeの中で、他の3種類の結合とともに「単純データ結合」に分類している。 に分類されている。著者はいくつかの研究を引用して、次のように論じている。 結合はコードの品質に悪影響を及ぼす。 Flagは は、APIにYES/NOフラグを渡すためのシンプルな構造化手法を提供している。

    Examples:
    Flag!"abc" flag;
    
    writeln(flag); // Flag!"abc".no
    writeln(flag); // No.abc
    assert(!flag);
    if (flag) assert(0);
    
    Examples:
    auto flag = Yes.abc;
    
    assert(flag);
    writeln(flag); // Yes.abc
    if (!flag) assert(0);
    if (flag) {} else assert(0);
    
    enum Flag: bool;
    no
    Flag!"Name" 型の値を作成する場合、負のオプションには Flag!"Name".no を使用する。を使用する。 Flag!"Name" 型の値を使うときは、 Flag!"Name".no と比較するか、false または0 と比較する。
    yes
    Flag!"Name" 型の値を作成するとき、肯定オプションには Flag!"Name".yes を使用する。を使用する。 Flag!"Name" Flag!"Name".yes と比較する。
    struct Yes;

    struct No;
    を使用できる便利な名前である。 Yes.encryptionの代わりに Flag!"encryption".yesNo.encryptionの代わりにFlag!"encryption".no
    Examples:
    Flag!"abc" flag;
    
    writeln(flag); // Flag!"abc".no
    writeln(flag); // No.abc
    assert(!flag);
    if (flag) assert(0);
    
    Examples:
    auto flag = Yes.abc;
    
    assert(flag);
    writeln(flag); // Yes.abc
    if (!flag) assert(0);
    if (flag) {} else assert(0);
    
    template isBitFlagEnum(E)
    列挙型が積分型で、"フラグ"値(ビット数がちょうど1の値)のみを持つかどうかを検出する。 (すなわち、ビット数がちょうど1の値)のみを持つかどうかを検出する。 さらに、"None"値を含む列挙型との互換性のためにゼロ値も許される。 "None"値を含む列挙型との互換性のために、ゼロ値も許される。
    Examples:
    enum A
    {
        None,
        A = 1 << 0,
        B = 1 << 1,
        C = 1 << 2,
        D = 1 << 3,
    }
    
    static assert(isBitFlagEnum!A);
    
    Examples:
    列挙型をデフォルト(連続)値でテストする。
    enum B
    {
        A,
        B,
        C,
        D // D == 3
    }
    
    static assert(!isBitFlagEnum!B);
    
    Examples:
    列挙型を非整数値でテストする
    enum C: double
    {
        A = 1 << 0,
        B = 1 << 1
    }
    
    static assert(!isBitFlagEnum!C);
    
    struct BitFlags(E, Flag!"unsafe" unsafe = No.unsafe) if (unsafe || isBitFlagEnum!E);
    列挙型の値の組み合わせを格納するための型安全な構造体。
    このテンプレートは、enum 値のビット OR の組み合わせを表す単純な構造体を定義する。 を表す単純な構造体を定義する。このテンプレートは、すべての列挙型値がビット数1の積分定数である場合に使用できる。 であるか、unsafe パラメータが明示的に である。 これは、列挙型自体を使用してORの組み合わせを格納するよりもはるかに安全である。 ORの組み合わせを格納するためにenumそのものを使用するよりもはるかに安全である:
    enum E
    {
        A = 1 << 0,
        B = 1 << 1
    }
    E e = E.A | E.B;
    // SwitchErrorをスローする
    final switch (e)
    {
        case E.A:
            return;
        case E.B:
            return;
    }
    
    Examples:
    演算子|で値を設定し、&でテストする。
    enum Enum
    {
        A = 1 << 0,
    }
    
    // デフォルトで構築されたBitFlagsには値が設定されていない
    immutable BitFlags!Enum flags_empty;
    assert(!flags_empty.A);
    
    // 値は|演算子で設定できる
    immutable flags_A = flags_empty | Enum.A;
    
    // and tested using property access
    assert(flags_A.A);
    
    // or the & operator
    assert(flags_A & Enum.A);
    // which commutes.
    assert(Enum.A & flags_A);
    
    Examples:
    デフォルトのBitFlagsには値が設定されていない。
    enum Enum
    {
        None,
        A = 1 << 0,
        B = 1 << 1,
        C = 1 << 2
    }
    
    immutable BitFlags!Enum flags_empty;
    assert(!(flags_empty & (Enum.A | Enum.B | Enum.C)));
    assert(!(flags_empty & Enum.A) && !(flags_empty & Enum.B) && !(flags_empty & Enum.C));
    
    Examples:
    2進演算:フラグの減算と交差
    enum Enum
    {
        A = 1 << 0,
        B = 1 << 1,
        C = 1 << 2,
    }
    immutable BitFlags!Enum flags_AB = BitFlags!Enum(Enum.A, Enum.B);
    immutable BitFlags!Enum flags_BC = BitFlags!Enum(Enum.B, Enum.C);
    
    // フラグの引き算には~演算子を使う
    immutable BitFlags!Enum flags_B = flags_AB & ~BitFlags!Enum(Enum.A);
    assert(!flags_B.A && flags_B.B && !flags_B.C);
    
    // BitFlags間の交差には&を使う
    writeln(flags_B); // (flags_BC & flags_AB)
    
    Examples:
    すべての二項演算子は、代入バージョンで動作する。
    enum Enum
    {
        A = 1 << 0,
        B = 1 << 1,
    }
    
    BitFlags!Enum flags_empty, temp, flags_AB;
    flags_AB = Enum.A | Enum.B;
    
    temp |= flags_AB;
    writeln(temp); // (flags_empty | flags_AB)
    
    temp = flags_empty;
    temp |= Enum.B;
    writeln(temp); // (flags_empty | Enum.B)
    
    temp = flags_empty;
    temp &= flags_AB;
    writeln(temp); // (flags_empty & flags_AB)
    
    temp = flags_empty;
    temp &= Enum.A;
    writeln(temp); // (flags_empty & Enum.A)
    
    Examples:
    boolとintへの変換
    enum Enum
    {
        A = 1 << 0,
        B = 1 << 1,
    }
    
    BitFlags!Enum flags;
    
    // 値が設定されていないBitFlagsはfalseに評価される
    assert(!flags);
    
    // 少なくとも1つの値が設定されているBitFlagsはtrueに評価される
    flags |= Enum.A;
    assert(flags);
    
    // これは、BitFlags間の交差をチェックするのに便利である
    BitFlags!Enum flags_AB = Enum.A | Enum.B;
    assert(flags & flags_AB);
    assert(flags & Enum.A);
    
    // もちろん、フラグから生の値を取り出すこともできる
    auto value = cast(int) flags;
    writeln(value); // Enum.A
    
    Examples:
    カスタム値を持つ列挙型には、unsafe パラメータを指定する必要がある。
    enum UnsafeEnum
    {
        A = 1,
        B = 2,
        C = 4,
        BC = B|C
    }
    static assert(!__traits(compiles, { BitFlags!UnsafeEnum flags; }));
    BitFlags!(UnsafeEnum, Yes.unsafe) flags;
    
    // プロパティアクセスは、安全でない列挙型に完全に一致するかどうかをテストする
    flags.B = true;
    assert(!flags.BC); // Bのみ
    flags.C = true;
    assert(flags.BC); // BとCの両方
    flags.B = false;
    assert(!flags.BC); // Cのみ
    
    // プロパティアクセスは、安全でない列挙型グループのすべてのビットを設定する
    flags = flags.init;
    flags.BC = true;
    assert(!flags.A && flags.B && flags.C);
    flags.A = true;
    flags.BC = false;
    assert(flags.A && !flags.B && !flags.C);
    
    template ReplaceType(From, To, T...)
    1つ以上の型TFromTo に置き換える。例えば のようにする、 ReplaceType!(int, uint, Tuple!(int, float)[string])である。 Tuple!(uint, float)[string].置換が実行される "型 置換が実行される型は、修飾子、組み込み型コンストラクタ(ポインタ、配列、連想配列、関数、デリゲート)、テンプレートなど、任意に複雑にすることができる。 (ポインタ、配列、連想配列、関数、デリゲート)、テンプレート化された関数などである。 置換は、型定義を通過して進行する。 しかし、structclassのメンバ型は置換されない。 なぜなら、置換後の型を表現する方法がないからである。
    これは高度な型操作である。 のプレースホルダ型This を置き換える場合などに必要な高度な型操作である。 std.variant.Algebraic.
    Returns:
    ReplaceTypeへのエイリアスである。 置換される。
    Examples:
    static assert(
        is(ReplaceType!(int, string, int[]) == string[]) &&
        is(ReplaceType!(int, string, int[int]) == string[string]) &&
        is(ReplaceType!(int, string, const(int)[]) == const(string)[]) &&
        is(ReplaceType!(int, string, Tuple!(int[], float))
            == Tuple!(string[], float))
    );
    
    template ReplaceTypeUnless(alias pred, From, To, T...)
    と同じである。 ReplaceTypeのような置換は行わない。 predtrue と評価される型では置換を行わない。
    Examples:
    import std.traits : isArray;
    
    static assert(
        is(ReplaceTypeUnless!(isArray, int, string, int*) == string*) &&
        is(ReplaceTypeUnless!(isArray, int, string, int[]) == int[]) &&
        is(ReplaceTypeUnless!(isArray, int, string, Tuple!(int, int[]))
            == Tuple!(string, int[]))
    );
    
    struct Ternary;
    3つの真理値を持つ3項型:
    • Ternary.yesfortrue
    • Ternary.noに対してfalse
    • Ternary.unknown未知の状態として
    トライナリー、トライバレント、トリリアンとも呼ばれる。
    Examples:
    Ternary a;
    writeln(a); // Ternary.unknown
    
    writeln(~Ternary.yes); // Ternary.no
    writeln(~Ternary.no); // Ternary.yes
    writeln(~Ternary.unknown); // Ternary.unknown
    
    enum Ternary no;

    enum Ternary yes;

    enum Ternary unknown;
    の可能な状態Ternary
    pure nothrow @nogc @safe this(bool b);

    pure nothrow @nogc @safe void opAssign(bool b);
    bool no を に、 を に受け取る。 を受け取る 。false yes true
    pure nothrow @nogc @safe this(const Ternary b);
    別の3項値から3項値を構成する
    Ternary opUnary(string s)()
    if (s == "~");

    Ternary opBinary(string s)(Ternary rhs)
    if (s == "|");

    Ternary opBinary(string s)(Ternary rhs)
    if (s == "&");

    Ternary opBinary(string s)(Ternary rhs)
    if (s == "^");

    Ternary opBinary(string s)(bool rhs)
    if (s == "|" || s == "&" || s == "^");
    論理演算の真理値表
    a b ˜a a | b a & b a ^ b
    no no yes no no no
    no yes yes no yes
    no unknown unknown no unknown
    yes no no yes no yes
    yes yes yes yes no
    yes unknown yes unknown unknown
    unknown no unknown unknown no unknown
    unknown yes yes unknown unknown
    unknown unknown unknown unknown unknown
    struct RefCounted(T, RefCountedAutoInitialize autoInit = RefCountedAutoInitialize.yes);
    の古いバージョンは SafeRefCounted以前は borrowが存在していた。 古いコードは、新しいスキームでは安全でないメンバ関数の@safetyに依存している可能性がある。 に依存している可能性がある。 SafeRefCounted 。 この型は時代遅れであり、新しいコードには推奨されない。
    Examples:
    auto rc1 = RefCounted!int(5);
    writeln(rc1); // 5
    auto rc2 = rc1;
    rc2 = 42;
    writeln(rc1); // 42
    
    RefCounted!(T, RefCountedAutoInitialize.no) refCounted(T)(T val);
    同じように safeRefCountedのようなものだが RefCounted に使われる。後方互換性のために意図されているが、そうでない場合は safeRefCounted を使う方が望ましい。
    Examples:
    static struct File
    {
        static size_t nDestroyed;
        string name;
        @disable this(this); // コピー不可
        ~this() { name = null; ++nDestroyed; }
    }
    
    auto file = File("name");
    writeln(file.name); // "name"
    static assert(!__traits(compiles, {auto file2 = file;}));
    writeln(File.nDestroyed); // 0
    
    {
        import std.algorithm.mutation : move;
        auto rcFile = refCounted(move(file));
        writeln(rcFile.name); // "name"
        writeln(File.nDestroyed); // 1
        writeln(file.name); // null
    
        auto rcFile2 = rcFile;
        writeln(rcFile.refCountedStore.refCount); // 2
        writeln(File.nDestroyed); // 1
    }
    
    writeln(File.nDestroyed); // 2