英語版
このページの英語版を見る
std.experimental.allocator
アロケータ用の高レベルインターフェース。バンドルされたデータの割り当て/作成
struct、classを含むデータの一括割り当て/作成、破棄/割り当て解除を実装する、
また、アロケーションに関連する配列プリミティブも実装する。このモジュールは
このモジュールは、アロケータを利用したり、そのドキュメントを作成したりするための入り口である。
概要
// Allocate an int, initialize it with 42 int* p = theAllocator.make!int(42); assert(*p == 42); // Destroy and deallocate it theAllocator.dispose(p); // Allocate using the global process allocator p = processAllocator.make!int(100); assert(*p == 100); // Destroy and deallocate processAllocator.dispose(p);
// Create an array of 50 doubles initialized to -1.0 double[] arr = theAllocator.makeArray!double(50, -1.0); // Append two zeros to it theAllocator.expandArray(arr, 2, 0.0); // On second thought, take that back theAllocator.shrinkArray(arr, 2); // Destroy and deallocate theAllocator.dispose(arr);
層構造
Dのアロケータは、実装とドキュメントの両面でレイヤー構造になっている:- 高レベルの動的型付けレイヤー(このモジュールの後半で説明する)。 モジュールで後述する)。と呼ばれるインターフェイスで構成される。 IAllocatorと呼ばれるインターフェイスで構成されている。 と呼ばれるインターフェイスで構成される。インターフェース・プリミティブ自身は、割り当てられるオブジェクトの型には無頓着である。 void[]インターフェイス・プリミティブ自体は、アロケートされるオブジェクトの型には無頓着である。 を扱うだけである。インターフェイスが(型パラメタライズドではなく)ダイナミックである必然性がある。 各スレッドはデフォルトで使用する現在のアロケータを持つ。 型の変数 theAllocator型である。 IAllocator.プロセスは というグローバル・アロケータがある。 processAllocatorと呼ばれるグローバル・アロケータがある。 IAllocator.新しいスレッドが作成されると processAllocatorにコピーされる。 にコピーされる。 theAllocator.アプリケーションは、これらの 参照を指すオブジェクトを変更できる。デフォルトでは、アプリケーション起動時に processAllocator はDのガベージコレクションされたヒープを使用するオブジェクトを参照する。このレイヤーはまた のような高レベル関数を含む。 makeや disposeなどの高レベル関数も含まれる。 などの高レベル関数も含まれる。この このレイヤーは、アロケーション・プリミティブをカジュアルに使う場合に必要なものだ。
- 中レベルの静的型付けレイヤーは、複数のアロケータをひとつにまとめるためのものだ。 を1つにまとめる。作成されるオブジェクトの"@型"のプロパティを使用して、アロケーション要求を、場合によっては特殊化されたアロケータにルーティングする。 にルーティングする。このレイヤーは比較的薄い。 モジュールで実装され、文書化されている。 std.experimental.allocator.typedモジュールに実装されている。このレイヤーは比較的薄く、モジュールに実装され文書化されている。 アロケータを使い分けることができる。 全体的なパフォーマンスが向上する。
- 高度に汎用的なヒープ・ビルディング・ブロックの低レベル・コレクション
である。 レゴブロックのようなもので、アプリケーション固有のアロケータを組み立てるのに使うことができる。 本当のアロケーションの賢さはこのレベルで発揮される。このレイヤーは このレイヤーは、独自のアロケータを構成したい高度なアプリケーションにとって興味深いものだ。 これらのビルディング・ブロックの典型的な使い方をよく表しているのが、モジュールである。 std.experimental.allocator.showcaseである。 モジュールである。実装とドキュメントの入り口は である。 std.experimental.allocator.building_blocks.設計上 プリミティブと同じシグネチャを持つ。 IAllocatorプリミティブと同じシグネチャを持つが、ほとんどの部分はオプションであり、静的イントロスペクションによって駆動される。 によって駆動される。パラメータ化されたクラス CAllocatorImplは の実装に静的な低レベルアロケータをパッケージ化するための即時かつ有用な手段を提供する。 の実装にパッケージ化することができる。 IAllocator. - Coreアロケータ・オブジェクトは、D'sガベージコレクション・ヒープとのインターフェイスを持つ。 (std.experimental.allocator.gc_allocator)、Cのmalloc ファミリー (std.experimental.allocator.mallocator)、OS (std.experimental.allocator.mmap_allocator).ほとんどのカスタム・アロケータは ほとんどのカスタム・アロケータは、最終的にこれらのコア・アロケータのいずれかからメモリを取得する。
慣用的な std.experimental.allocator
現時点では std.experimental.allocator
は、D言語の
newの組み込み演算子とは統合されていない。
配列連結演算子など、メモリを確保するD言語の組み込み演算子とは統合されていない。つまり std.experimental.allocator
は
オプトインvoid fun(size_t n) { // Use the current allocator int[] a1 = theAllocator.makeArray!int(n); scope(exit) theAllocator.dispose(a1); ... }代替のアロケータを試すには theAllocatorを設定する。 に設定する。例えば、多くの8バイト・オブジェクトを割り当てるアプリケーションを考えてみよう。 オブジェクトを多数割り当てるアプリケーションを考えてみよう。これらはデフォルトのアロケータではうまくサポートされていない。 フリー・リスト・アロケータを推奨する。 mainそのため、フリー・リスト・アロケータを使用することを推奨する:
void main() { import std.experimental.allocator.building_blocks.free_list : FreeList; theAllocator = allocatorObject(FreeList!8()); ... }
IAllocator リファレンスを後で使うために保存する
他のグローバルリソースと同様に、theAllocator とprocessAllocator を頻繁に、そして気軽に設定すべきではない。特に 特に、あるアロケータでメモリを確保し、別のアロケータで メモリを解放すると、未定義の動作を引き起こす。 一般的に、これらの変数はアプリケーションの初期化段階で設定され、アプリケーションの間中、設定され続ける。 アプリケーションの最後まで続く。 これを避けるために、割り当てや再割り当て、割り当て解除を比較的頻繁に行う必要がある長寿命オブジェクトは、このような変数を使用しない方がよいだろう、 アロケーション、再アロケーション、デアロケーションを比較的頻繁に実行する必要がある長寿命オブジェクトは、これを避けるため への参照を保存しておくといいだろう。その場合 を使う代わりに、theAllocator 。 を使うことになる。例えば、ユーザー定義のハッシュ・テーブルを考えてみよう:struct HashTable { private IAllocator allocator; this(size_t buckets, IAllocator allocator = theAllocator) { this.allocator = allocator; ... } // Getter and setter IAllocator allocator() { return allocator; } void allocator(IAllocator a) { assert(empty); allocator = a; } }初期化後、HashTable 。
allocator
オブジェクトを使用する。さらに
HashTable.allocator
を別のアロケータを指すように設定することは合法でなければならない。
そうでなければ、オブジェクトは既存の状態をデアロケートすることができない。
そうでなければ、オブジェクトは既存の状態をデアロケートできない。
を使わずにアロケータを使うIAllocator
ヒープ・ビルディング・ブロックから組み立てられたアロケータは、ヒープ・ビルディング・ブロックを経由しなくても使える。 IAllocator を通す必要はない。アロケータはIAllocator と同じプリミティブを持っている。 で動作する。 make, makeArray, disposeなどで動作する。だから アロケータ・オブジェクトを適当に作り、適切に使用すれば十分なのだ:void fun(size_t n) { // Use a stack-installed allocator for up to 64KB StackFront!65536 myAllocator; int[] a2 = myAllocator.makeArray!int(n); scope(exit) myAllocator.dispose(a2); ... }この場合、myAllocator はIAllocator インターフェースには従わない。 プリミティブを実装しているので、ダック型付けによってmakeArray 。 型 "を使用する。 このセットアップで注意すべき重要な点は、静的に型付けされたアセンブルされたアロケータは、ダック型付けを経由するアロケータよりもほとんど常に高速であるということである。 を経由するアロケータよりも速いということだ。 IAllocator.重要な経験則は、「アセンブル・アロケータが先で、 に適応するのは後」である。 IAllocator 。優れたアロケータは、テンプレート・アセンブリによって複雑なロジックを実装している。 テンプレート・アセンブリによって複雑なロジックを実装し、IAllocator (通常は allocatorObject)でラップされるのは、クライアント・レベルで一度だけだ。
License:
Authors:
- interface
IAllocator
; - 動的アロケータ・インターフェース。アロケータを定義するコードは最終的にこのインターフェイスを実装する。 このインターフェイスを実装する。これは、様々なアロケータ実装をカプセル化するために統一された型が必要な場合に使用される。 これは、様々なアロケータ実装をカプセル化するために統一された型が必要な場合に使用されるべきである。アロケータをこのレベルで合成することは推奨されない。 動的インターフェースの柔軟性に欠け、カスケードされた多重呼び出しによる非効率性があるためである。 による非効率性のためである。その代わり、アロケータは で定義されている std.experimental.allocator.building_blocks, で定義された静的インターフェースを使ってアロケータを構成し、構成された アロケータを
IAllocator
(に適合させる。 CAllocatorImplに適応させる。) Ternary を返すメソッドは、成功するとTernary.yes を返す、 Ternary.no プリミティブがアロケータ・インスタンスに実装されていない場合はTernary.unknown を返す。 を返す。- abstract nothrow @property uint
alignment
(); - 提供されたアライメントを返す。
- abstract nothrow size_t
goodAllocSize
(size_ts
); - 内部の断片化がゼロであることを保証するアロケーションサイズを返す。 を返す。
- abstract nothrow void[]
allocate
(size_t, TypeInfoti
= null); - n バイトのメモリを割り当てる。
- abstract nothrow void[]
alignedAllocate
(size_tn
, uinta
); - 指定されたアラインメントで
n
バイトのメモリを指定されたアラインメントで割り当てる。a
.このプリミティブをサポートしていない このプリミティブをサポートしていない実装は、常にnull を返すべきである。 - abstract nothrow void[]
allocateAll
(); - このアロケータが利用可能なすべてのメモリを割り当てて返す。 このプリミティブをサポートしていない実装は、常に null.
- abstract nothrow bool
expand
(ref void[], size_t); - メモリブロックをその場で展開し、成功すればtrue を返す。 このプリミティブをサポートしない実装は、常に以下を返すべきである。 false.
- abstract nothrow bool
reallocate
(ref void[], size_t); - メモリ・ブロックの再割り当てを行う。
- abstract nothrow bool
alignedReallocate
(ref void[]b
, size_tsize
, uintalignment
); - 指定されたアラインメントでメモリブロックを再割り当てする。
- abstract nothrow Ternary
owns
(void[]b
); - Ternary.yes 指定されたアラインメントでメモリブロックを再割り当てする。
b
アロケータが所有している場合はTernary.no を返し、アロケータが所有していない場合は を返す。 アロケータが所有していない場合はb
所有者がわからない場合はTernary.unknown を返す。 を返す。このプリミティブをサポートしていない実装では をサポートしていない実装は、常にTernary.unknown を返すべきである。 - abstract nothrow Ternary
resolveInternalPointer
(const void*p
, ref void[]result
); - 割り当てられたフルブロックへの内部ポインタを解決する。このプリミティブをサポートしていない は常にTernary.unknown を返すべきである。
- abstract nothrow bool
deallocate
(void[]b
); - メモリブロックを解放する。このプリミティブをサポートしない実装は、常に を返すべきである。 プリミティブは常にfalse を返すべきである。アロケータが を呼び出すことである。
deallocate
(null). - abstract nothrow bool
deallocateAll
(); - を呼び出すことである。このプリミティブをサポートしていない実装は、常に を返すべきである。 をサポートしていない実装は、常にfalse を返すべきである。
- abstract nothrow Ternary
empty
(); - このアロケータから現在メモリが割り当てられていない場合はTernary.yes を返す。 Ternary.no を返す。 Ternary.unknown を返す。
- abstract pure nothrow @nogc @safe void
incRef
(); - このインターフェイスを実装する具象クラスの参照カウントを増やす。 インタフェースを実装する具象クラスの参照カウントを増やす。ステートレスアロケータでは、これは何もしない。
- abstract pure nothrow @nogc @safe bool
decRef
(); - このインタフェースを実装する具象クラスの参照カウントを減少させる。 このインタフェースを実装する具象クラスの参照カウントを減少させる。 参照カウントが0 になると、オブジェクトは自己破壊する。Returns:true 参照カウントが と より大きい場合、オブジェクトは自滅する。 になると、 を返す。ステートレスアロケータでは、常に を返す。0 false 0 true
- struct
RCIAllocator
; - 動的アロケータ・インターフェースをラップする参照カウント構造体。 様々なアロケータ実装をカプセル化するために統一された型が必要な場合は、これを使うべきである。 これは、様々なアロケータ実装をカプセル化するために統一された型が必要な場合に使用されるべきである。アロケータを定義するコードは、最終的に動的アロケータ・インターフェースを実装する。 IAllocator インターフェイスを実装する。 CAllocatorImplインターフェイスを実装し
RCIAllocator
を構築する。 このレベルでは、アロケーターの合成は推奨されない。 動的インターフェイスの柔軟性の欠如と、カスケードされた多重呼び出しによる非効率性のためである。 による非効率性のためである。代わりに、アロケータは で定義された std.experimental.allocator.building_blocksで定義された静的インターフェースを使ってアロケータを合成し、合成された アロケータをRCIAllocator
(に適合させる。 allocatorObjectに適応させる。) - interface
ISharedAllocator
; - 動的共有アロケータ・インターフェース。スレッド間で共有可能なアロケータを定義するコードは を定義するコードは、最終的にこのインターフェイスを実装することになる。これは 様々なアロケータをカプセル化するために統一された型が必要な場合に使用される。 の実装をカプセル化するために統一された型が必要な場合に使用されるべきである。アロケータをこのレベルで合成することは推奨されない。 動的インターフェースの柔軟性に欠け、カスケードされた多重呼び出しによる非効率性があるためだ。 による非効率性のためである。その代わり、アロケータは で定義されている std.experimental.allocator.building_blocks, で定義された静的インターフェースを使ってアロケータを構成し、構成された アロケータを
ISharedAllocator
(に適合させる。 CSharedAllocatorImplに適応させる。) Ternary を返すメソッドは、成功するとTernary.yes を返す、 Ternary.no プリミティブがアロケータ・インスタンスに実装されていない場合はTernary.unknown を返す。 を返す。- abstract shared nothrow @property uint
alignment
(); - 提供されたアライメントを返す。
- abstract shared nothrow size_t
goodAllocSize
(size_ts
); - 内部の断片化がゼロであることを保証するアロケーションサイズを返す。 を返す。
- abstract shared nothrow void[]
allocate
(size_t, TypeInfoti
= null); - n バイトのメモリを割り当てる。
- abstract shared nothrow void[]
alignedAllocate
(size_tn
, uinta
); - 指定されたアラインメントで
n
バイトのメモリを指定されたアラインメントで割り当てる。a
.このプリミティブをサポートしていない このプリミティブをサポートしていない実装は、常にnull を返すべきである。 - abstract shared nothrow void[]
allocateAll
(); - このアロケータが利用可能なすべてのメモリを割り当てて返す。 このプリミティブをサポートしていない実装は、常に null.
- abstract shared nothrow bool
expand
(ref void[], size_t); - メモリブロックをその場で展開し、成功すればtrue を返す。 このプリミティブをサポートしない実装は、常に以下を返すべきである。 false.
- abstract shared nothrow bool
reallocate
(ref void[], size_t); - メモリ・ブロックの再割り当てを行う。
- abstract shared nothrow bool
alignedReallocate
(ref void[]b
, size_tsize
, uintalignment
); - 指定されたアラインメントでメモリブロックを再割り当てする。
- abstract shared nothrow Ternary
owns
(void[]b
); - Ternary.yes 指定されたアラインメントでメモリブロックを再割り当てする。
b
アロケータが所有している場合はTernary.no を返し、アロケータが所有していない場合は を返す。 アロケータが所有していない場合はb
所有者がわからない場合はTernary.unknown を返す。 を返す。このプリミティブをサポートしていない実装では をサポートしていない実装は、常にTernary.unknown を返すべきである。 - abstract shared nothrow Ternary
resolveInternalPointer
(const void*p
, ref void[]result
); - 割り当てられたフルブロックへの内部ポインタを解決する。このプリミティブをサポートしていない は常にTernary.unknown を返すべきである。
- abstract shared nothrow bool
deallocate
(void[]b
); - メモリブロックを解放する。このプリミティブをサポートしない実装は、常に を返すべきである。 プリミティブは常にfalse を返すべきである。アロケータが を呼び出すことである。
deallocate
(null). - abstract shared nothrow bool
deallocateAll
(); - を呼び出すことである。このプリミティブをサポートしていない実装は、常に を返すべきである。 をサポートしていない実装は、常にfalse を返すべきである。
- abstract shared nothrow Ternary
empty
(); - このアロケータから現在メモリが割り当てられていない場合はTernary.yes を返す。 Ternary.no を返す。 Ternary.unknown を返す。
- abstract shared pure nothrow @nogc @safe void
incRef
(); - このインターフェイスを実装する具象クラスの参照カウントを増やす。 インタフェースを実装する具象クラスの参照カウントを増やす。ステートレスアロケータでは、これは何もしない。
- abstract shared pure nothrow @nogc @safe bool
decRef
(); - このインタフェースを実装する具象クラスの参照カウントを減少させる。 このインタフェースを実装する具象クラスの参照カウントを減少させる。 参照カウントが0 になると、オブジェクトは自己破壊する。ステートレスアロケータでは、これは何もしない。Returns:true 参照カウントが および より大きい場合、 にぶつかる。 に当たった場合、 を返す。ステートレスアロケータでは、常に を返す。0 false 0 true
- struct
RCISharedAllocator
; - 動的共有アロケータ・インターフェースをラップする参照カウント構造体。 様々なアロケータ実装をカプセル化するために統一された型が必要な場合は、これを使うべきである。 これは、様々なアロケータ実装をカプセル化するために統一された型が必要な場合に使用されるべきである。スレッド間で共有可能なアロケータを定義するコードは、最終的に、動的共有アロケータ・インターフェイスの ISharedAllocatorインターフェイスを実装する。 CSharedAllocatorImplインターフェイスを実装し
RCISharedAllocator
を構築する。 を構築する。 このレベルでは、アロケーターの合成は推奨されない。 動的インターフェイスの柔軟性の欠如と、カスケードされた多重呼び出しによる非効率性のためである。 による非効率性のためである。代わりに、アロケータは で定義されている std.experimental.allocator.building_blocksで定義された静的インターフェースを使ってアロケータを合成し、合成されたアロケータを をRCISharedAllocator
(に適合させる。 sharedAllocatorObjectに適応させる。) - nothrow @nogc @property ref @safe RCIAllocator
theAllocator
();
nothrow @nogc @property @system voidtheAllocator
(RCIAllocatora
); - 現在のスレッドのアロケータを取得/設定する。これはデフォルトのアロケータである。 で、スレッドローカルメモリの割り当てに使われる。スレッド間で共有される を割り当てる場合は、processAllocator (下記)を使用する。デフォルトでは
theAllocator
processAllocatorからメモリをフェッチする。 を使用する。Examples:// Install a new allocator that is faster for 128-byte allocations. import std.experimental.allocator.building_blocks.free_list : FreeList; import std.experimental.allocator.gc_allocator : GCAllocator; auto oldAllocator = theAllocator; scope(exit) theAllocator = oldAllocator; theAllocator = allocatorObject(FreeList!(GCAllocator, 128)()); // Use the now changed allocator to allocate an array const ubyte[] arr = theAllocator.makeArray!ubyte(128); assert(arr.ptr); //...
- nothrow @nogc @property ref @trusted RCISharedAllocator
processAllocator
();
nothrow @nogc @property @system voidprocessAllocator
(ref RCISharedAllocatora
); - 現在のプロセスのアロケータを取得/設定する。このアロケータは を使わなければならない。この オブジェクトはshared にキャストできる。
- auto
make
(T, Allocator, A...)(auto ref Allocatoralloc
, auto ref Aargs
); - を使用して)動的にアロケートする。
alloc
を使用して) 動的に割り当て、割り当てられたメモリに を使用してT 型のオブジェクトを作成する。args
(を使用する。 を使って初期化する。初期化は割り当てられたメモリ内で行われ、それ以外は と意味的には同じである。 T(args
). (と同じである。alloc
.make
!(T[])を使うと、配列ではなく(空の)配列へのポインタが作成されることに注意されたい)。 Tへのポインタを作成することに注意。アロケータを使って を使う。alloc
.makeArray!Tを使う。)Parameters:T 作成されるオブジェクトの型。 Allocator alloc
必要なメモリを確保するためのアロケータ。これは、アロケータ用の静的インターフェイスを実装した アロケータ用の静的インターフェイスを実装したオブジェクト、あるいはIAllocator 参照である。 A args
作成されたオブジェクトの初期化に使われるオプションの引数。もし 存在しない場合、オブジェクトはデフォルトで構築される。 Returns:T がクラス型の場合、作成されたオブジェクトへの参照を返す。T オブジェクトへの参照を返す。そうでない場合は、作成されたオブジェクトを指すT* を返す。すべての場合において 割り当てに失敗した場合は、null を返す。Throws:T のコンストラクタがスローした場合、割り当てられたメモリを解放し、例外を伝搬する。 例外を伝播する。Examples:// Dynamically allocate one integer const int* p1 = theAllocator.make!int; // It's implicitly initialized with its .init value writeln(*p1); // 0 // Dynamically allocate one double, initialize to 42.5 const double* p2 = theAllocator.make!double(42.5); writeln(*p2); // 42.5 // Dynamically allocate a struct static struct Point { int x, y, z; } // Use the generated constructor taking field values in order const Point* p = theAllocator.make!Point(1, 2); assert(p.x == 1 && p.y == 2 && p.z == 0); // Dynamically allocate a class object static class Customer { uint id = uint.max; this() {} this(uint id) { this.id = id; } // ... } Customer cust = theAllocator.make!Customer; assert(cust.id == uint.max); // default initialized cust = theAllocator.make!Customer(42); writeln(cust.id); // 42 // explicit passing of outer pointer static class Outer { int x = 3; class Inner { auto getX() { return x; } } } auto outer = theAllocator.make!Outer(); auto inner = theAllocator.make!(Outer.Inner)(outer); writeln(outer.x); // inner.getX
- T[]
makeArray
(T, Allocator)(auto ref Allocatoralloc
, size_tlength
);
T[]makeArray
(T, Allocator)(auto ref Allocatoralloc
, size_tlength
, Tinit
);
Unqual!(ElementEncodingType!R)[]makeArray
(Allocator, R)(auto ref Allocatoralloc
, Rrange
)
if (isInputRange!R && !isInfinite!R);
T[]makeArray
(T, Allocator, R)(auto ref Allocatoralloc
, Rrange
)
if (isInputRange!R && !isInfinite!R); - 要素を持つT の配列を作成する。
length
要素の配列を作成する。alloc
.配列は、デフォルトで初期化されるか、あるいはinit
から取得した値で初期化される。range
.Parameters:T 作成される配列の要素型。 Allocator alloc
メモリの確保に使われるアロケータ size_t length
新しく作成される配列の長さ T init
配列を埋めるために使われる要素 R range
配列要素の初期化に使われる範囲 Returns:null 新しく作成された配列。length
が0 、あるいは 割り当てに失敗した場合はThrows:最初の2つのオーバーロードは、以下の場合にのみスローする。alloc
をスローする。最初の2つのオーバーロードは コピー初期化を含むオーバーロードは、メモリを解放し、コピー操作がスローした場合に例外を伝播する。 例外を伝播する。Examples:import std.algorithm.comparison : equal; static void test(T)() { T[] a = theAllocator.makeArray!T(2); assert(a.equal([0, 0])); a = theAllocator.makeArray!T(3, 42); assert(a.equal([42, 42, 42])); import std.range : only; a = theAllocator.makeArray!T(only(42, 43, 44)); assert(a.equal([42, 43, 44])); } test!int(); test!(shared int)(); test!(const int)(); test!(immutable int)();
- bool
expandArray
(T, Allocator)(auto ref Allocatoralloc
, ref T[]array
, size_tdelta
);
boolexpandArray
(T, Allocator)(auto ref Allocatoralloc
, ref T[]array
, size_tdelta
, auto ref Tinit
);
boolexpandArray
(T, Allocator, R)(auto ref Allocatoralloc
, ref T[]array
, Rrange
)
if (isInputRange!R); - 成長する
array
より多くの要素を追加することでdelta
要素が追加される。必要なメモリは を使用して割り当てられる。alloc
.追加された要素は、デフォルトの のコピーで満たされるかinit
のコピーで埋められるか、次の値で初期化される。 から取得した値で初期化される。range
.Parameters:T 作成される配列の要素型 Allocator alloc
メモリの確保に使われるアロケータ T[] array
増やされる配列への参照 size_t delta
追加する要素数(成功すると、新しい長さの array
である)。 array.length + delta)T init
配列の要素を埋める R range
配列要素の初期化に使用する範囲 Returns:true 成功した場合は、 。後者の場合 後者の場合falsearray
は影響を受けない。Throws:最初の2つのオーバーロードは、以下の場合にのみスローする。alloc
をスローする。最初の2つのオーバーロードは コピー初期化を含むオーバーロードは、メモリを解放し、コピー操作がスローした場合に例外を伝播する。 例外を伝播する。Examples:auto arr = theAllocator.makeArray!int([1, 2, 3]); assert(theAllocator.expandArray(arr, 2)); writeln(arr); // [1, 2, 3, 0, 0] import std.range : only; assert(theAllocator.expandArray(arr, only(4, 5))); writeln(arr); // [1, 2, 3, 0, 0, 4, 5]
- bool
shrinkArray
(T, Allocator)(auto ref Allocatoralloc
, ref T[]array
, size_tdelta
); - 要素分だけ配列を縮小する。
delta
要素だけ縮小する。array.length < delta の場合は何もせず、false を返す。そうでなければ 配列の最後のarray.length - delta 要素を破棄する。 配列のバッファを再割り当てする。再割り当てに失敗した場合は、デフォルトで初期化されたデータで配列を埋める。 で埋める。Parameters:T 作成される配列の要素型 Allocator alloc
メモリの確保に使われるアロケータ T[] array
縮小される配列への参照。 size_t delta
削除する要素数(成功すると、新しい長さの array
はarray.length - delta)Returns:true 成功時、メモリを再割り当てできなかった場合は となる。後者の場合 後者の場合、スライス はデフォルトで初期化された 要素が残る。 false array[$ - delta .. $]Throws:最初の2つのオーバーロードは、以下の場合にのみスローする。alloc
をスローする。最初の2つのオーバーロードは コピー初期化を含むオーバーロードは、メモリを解放し、コピー操作がスローした場合に例外を伝播する。 例外を伝播する。Examples:int[] a = theAllocator.makeArray!int(100, 42); writeln(a.length); // 100 assert(theAllocator.shrinkArray(a, 98)); writeln(a.length); // 2 writeln(a); // [42, 42]
- void
dispose
(A, T)(auto ref Aalloc
, auto ref T*p
);
voiddispose
(A, T)(auto ref Aalloc
, auto ref Tp
)
if (is(T == class) || is(T == interface));
voiddispose
(A, T)(auto ref Aalloc
, auto ref T[]array
); - が指すオブジェクトを破壊し、その後(次のようにして)デアロケートする。
alloc
を使用して)オブジェクトを破壊し、その後デアロケートする。 ポインタが指すオブジェクト、class またはinterface 参照によって参照されるクラス・オブジェクト、または配列全体を破棄する。それぞれの実体は同じアロケータで割り当てられたものとする。 同じアロケータで割り当てられたものとする。 - auto
makeMultidimensionalArray
(T, Allocator, size_t N)(auto ref Allocatoralloc
, size_t[N]lengths
...); - T型の要素からなる多次元配列を確保する。Parameters:
N 次元数 T 多次元配列の要素の型。 Allocator alloc
メモリの確保に使用されるアロケータ size_t[N] lengths
各次元のサイズを含む静的配列 Returns:T型の要素を持つN次元配列。Examples:import std.experimental.allocator.mallocator : Mallocator; auto mArray = Mallocator.instance.makeMultidimensionalArray!int(2, 3, 6); // deallocate when exiting scope scope(exit) { Mallocator.instance.disposeMultidimensionalArray(mArray); } writeln(mArray.length); // 2 foreach (lvl2Array; mArray) { writeln(lvl2Array.length); // 3 foreach (lvl3Array; lvl2Array) writeln(lvl3Array.length); // 6 }
- void
disposeMultidimensionalArray
(T, Allocator)(auto ref Allocatoralloc
, auto ref T[]array
); - 多次元配列がmakeMultidimensionalArrayで作成され、同じアロケータが使われたと仮定して、多次元配列を破棄し、その後デアロケートする。 makeMultidimensionalArrayで作成され、同じアロケータが使われたと仮定する。Parameters:
T 多次元配列の要素の型。 Allocator alloc
メモリの確保に使われたアロケータ T[] array
解放される多次元配列。 Examples:struct TestAllocator { import std.experimental.allocator.common : platformAlignment; import std.experimental.allocator.mallocator : Mallocator; alias allocator = Mallocator.instance; private static struct ByteRange { void* ptr; size_t length; } private ByteRange[] _allocations; enum uint alignment = platformAlignment; void[] allocate(size_t numBytes) { auto ret = allocator.allocate(numBytes); _allocations ~= ByteRange(ret.ptr, ret.length); return ret; } bool deallocate(void[] bytes) { import std.algorithm.mutation : remove; import std.algorithm.searching : canFind; bool pred(ByteRange other) { return other.ptr == bytes.ptr && other.length == bytes.length; } assert(_allocations.canFind!pred); _allocations = _allocations.remove!pred; return allocator.deallocate(bytes); } ~this() { assert(!_allocations.length); } } TestAllocator allocator; auto mArray = allocator.makeMultidimensionalArray!int(2, 3, 5, 6, 7, 2); allocator.disposeMultidimensionalArray(mArray);
- RCIAllocator
allocatorObject
(A)(auto ref Aa
)
if (!isPointer!A);
RCIAllocatorallocatorObject
(A)(A*pa
); - 与えられた静的型付けのアロケータを中心に構築された、動的型付けのCAllocator を返す。 型アロケータを中心に構築された動的に型付けされた
a
を中心に構築された動的型A を返す。アロケータへのポインタを渡すと へのポインタを渡すと、そのポインタが指すアロケータを中心に動的アロケータが作られる、 を作成する。アロケータを "値"または "参照"で渡すと、以下のように動作する。 参照でアロケータを渡すと、次のように動作する。- A "がステートを持っていない場合、結果のオブジェクトは静的共有ストレージに割り当てられる。 共有ストレージに割り当てられる。
- A に状態がある場合、結果は std.algorithm.mutation.move 内のアロケータA a 。結果自体は、それ自身の静的に型付けされたアロケータ 自身の静的に型付けされたアロケータに割り当てられる。
Examples:import std.experimental.allocator.mallocator : Mallocator; RCIAllocator a = allocatorObject(Mallocator.instance); auto b = a.allocate(100); writeln(b.length); // 100 assert(a.deallocate(b)); // The in-situ region must be used by pointer import std.experimental.allocator.building_blocks.region : InSituRegion; auto r = InSituRegion!1024(); a = allocatorObject(&r); b = a.allocate(200); writeln(b.length); // 200 // In-situ regions can deallocate the last allocation assert(a.deallocate(b));
- nothrow RCISharedAllocator
sharedAllocatorObject
(A)(auto ref Aa
)
if (!isPointer!A);
RCISharedAllocatorsharedAllocatorObject
(A)(A*pa
); - 与えられた静的型付けのアロケータを中心に構築された、動的型付けのCSharedAllocator を返す。 型アロケータを中心に構築された動的に型付けされた
a
を中心に構築された動的型A を返す。アロケータへのポインタを渡すと へのポインタを渡すと、そのポインタが指すアロケータを中心に動的アロケータが作られる、 を作成する。アロケータを "値"または "参照"で渡すと、次のように動作する。 参照でアロケータを渡すと、次のように動作する。- A "がステートを持っていない場合、結果のオブジェクトは静的共有ストレージに割り当てられる。 共有ストレージに割り当てられる。
- A 、状態がありコピー可能な場合、結果は以下のようになる。 std.algorithm.mutation.move内の提供されたアロケータA a 。 結果自身は、静的に型付けされたアロケータに割り当てられる。
- A が状態を持ち、コピー可能でない場合、結果は渡された引数を結果の中に移動する。 渡された引数は結果の中に移動される。結果自体は、それ自身の に割り当てられる。
- class
CAllocatorImpl
(Allocator, Flag!"indirect" indirect = No.indirect): IAllocator; - Allocator を使ったIAllocator の実装。これは 静的に構築されたアロケータ型をIAllocator に適応させる。 非テンプレート・コードで直接使用できる。通常
CAllocatorImpl
を呼び出すことで間接的に使われる。 theAllocator.- pure @nogc ref @safe Allocator
impl
(); - 実装はパブリック・メンバーとして利用できる。
- pure @nogc @safe this(Allocator*
pa
); - 実装はパブリック・メンバーとして利用可能である。
- @property uint
alignment
(); - 戻り値 impl.
alignment
. - size_t
goodAllocSize
(size_ts
); - 戻り値 impl.
goodAllocSize
(s
). - void[]
allocate
(size_ts
, TypeInfoti
= null); - 戻り値 impl.
allocate
(s
). - void[]
alignedAllocate
(size_ts
, uinta
); - を返す。 impl.
alignedAllocate
が存在すれば、それを呼び出して結果を返す。 そうでない場合は、常にnull を返す。 - Ternary
owns
(void[]b
); - もしAllocator が
owns
を実装していれば、それに転送する。そうでない場合は Ternary.unknown. - bool
expand
(ref void[]b
, size_ts
); - 定義されていればimpl.expand(b, s) を返し、そうでなければfalse を返す。
- bool
reallocate
(ref void[]b
, size_ts
); - impl.reallocate(b, s) を返す。
- bool
alignedReallocate
(ref void[]b
, size_ts
, uinta
); - に転送する。 impl.
alignedReallocate
false に転送する。 - bool
deallocate
(void[]b
); - もし impl.
deallocate
が定義されていない場合、false を返す。そうでない場合は に転送する。 - bool
deallocateAll
(); - を呼び出す。 impl.
deallocateAll
()を呼び出し、定義されていればその結果を返す、 そうでない場合はfalse を返す。 - Ternary
empty
(); - に転送する。 impl.
empty
()Ternary.unknownに転送する。 - void[]
allocateAll
(); - を返す。 impl.
allocateAll
()null を返す。
- class
CSharedAllocatorImpl
(Allocator, Flag!"indirect" indirect = No.indirect): ISharedAllocator; - Allocator を使ったISharedAllocator の実装。これは 静的に構築され、スレッド間で共有可能なアロケータ型を、非テンプレーテッド・コードで直接使用できるISharedAllocator に適応させる。通常
CSharedAllocatorImpl
を呼び出すことで間接的に使われる。 processAllocator.- shared pure @nogc ref @safe Allocator
impl
(); - 実装はパブリック・メンバーとして利用できる。
- shared pure @nogc @safe this(Allocator*
pa
); - 実装はパブリック・メンバーとして利用可能である。
- shared @property uint
alignment
(); - 戻り値 impl.
alignment
. - shared size_t
goodAllocSize
(size_ts
); - 戻り値 impl.
goodAllocSize
(s
). - shared void[]
allocate
(size_ts
, TypeInfoti
= null); - 戻り値 impl.
allocate
(s
). - shared void[]
alignedAllocate
(size_ts
, uinta
); - を返す。 impl.
alignedAllocate
が存在すれば、それを呼び出して結果を返す。 そうでない場合は、常にnull を返す。 - shared Ternary
owns
(void[]b
); - もしAllocator が
owns
を実装していれば、それに転送する。そうでない場合は Ternary.unknown. - shared bool
expand
(ref void[]b
, size_ts
); - 定義されていればimpl.expand(b, s) を返し、そうでなければfalse を返す。
- shared bool
reallocate
(ref void[]b
, size_ts
); - impl.reallocate(b, s) を返す。
- shared bool
alignedReallocate
(ref void[]b
, size_ts
, uinta
); - に転送する。 impl.
alignedReallocate
false に転送する。 - shared bool
deallocate
(void[]b
); - もし impl.
deallocate
が定義されていない場合、false を返す。そうでない場合は に転送する。 - shared bool
deallocateAll
(); - を呼び出す。 impl.
deallocateAll
()を呼び出し、定義されていればその結果を返す、 そうでない場合はfalse を返す。 - shared Ternary
empty
(); - に転送する。 impl.
empty
()Ternary.unknownに転送する。 - shared void[]
allocateAll
(); - を返す。 impl.
allocateAll
()null を返す。
- struct
ThreadLocal
(A); - スレッドローカルストレージにアロケータオブジェクトを格納する(つまり、shared Dではない)。 グローバル)に格納する。
ThreadLocal
!AはA のサブタイプである。 Aのアロケータ・プリミティブを実装しているように見える。A 状態を保持しなければならない。ThreadLocal
!Aはインスタンス化を拒否する。これは というのは、例えばThreadLocal
!MallocatorMallocatorは動作しない。 の状態は、Mallocator のメンバとして格納されているのではなく、Cライブラリの実装に隠されているからだ。 Cライブラリの実装に隠されているからだ。Examples:import std.experimental.allocator.building_blocks.free_list : FreeList; import std.experimental.allocator.gc_allocator : GCAllocator; import std.experimental.allocator.mallocator : Mallocator; static assert(!is(ThreadLocal!Mallocator)); static assert(!is(ThreadLocal!GCAllocator)); alias Allocator = ThreadLocal!(FreeList!(GCAllocator, 0, 8)); auto b = Allocator.instance.allocate(5); static assert(__traits(hasMember, Allocator, "allocate"));
- static A
instance
; - アロケータ・インスタンス。
- this();
- ThreadLocal はすべてのコンストラクタを無効にする。意図した使い方は .ThreadLocal!A.instance
Copyright © 1999-2024 by the D Language Foundation
DEEPL APIにより翻訳、ところどころ修正。
このページの最新版(英語)
このページの原文(英語)
翻訳時のdmdのバージョン: 2.108.0
ドキュメントのdmdのバージョン: 2.109.1
翻訳日付 :
HTML生成日時:
編集者: dokutoku