システムヘッダー<functional>、<new>、<cstddef>、<cstdlib>、<exception>をインクルードしている。
Boost ヘッダー "detail/ct_gcd_lcm.hpp" (ct_gcd_lcm.html を見よ)、"detail/gcd_lcm.hpp" (gcd_lcm.htmlを見よ)、"simple_segregated_storage.hpp" をインクルードしている。( simple_segregated_storage.htmlを見よ)。
namespace details { template <typename SizeType> class PODptr { public: typedef SizeType size_type; PODptr(char * ptr, size_type size); PODptr(); // コピーコンストラクタ、代入演算子、デストラクターを許可 bool valid() const; void invalidate(); char * & begin(); char * begin() const; char * end() const; size_type total_size() const; size_type element_size() const; size_type & next_size() const; char * & next_ptr() const; PODptr next() const; void next(const PODptr & arg) const; }; } // namespace details template <typename UserAllocator = default_user_allocator_new_delete> class pool: protected simple_segregated_storage<typename UserAllocator::size_type> { ... // 公開インターフェース protected: details::PODptr<size_type> list; simple_segregated_storage<size_type> & store(); const simple_segregated_storage<size_type> & store() const; const size_type requested_size; size_type next_size; details::PODptr<size_type> find_POD(void * chunk) const; static bool is_from(void * chunk, char * i, size_type sizeof_i); size_type alloc_size() const; public: // 公開インターフェースの拡張 pool(size_type requested_size, size_type next_size); size_type get_next_size() const; void set_next_size(size_type); };
pool がシステムからメモリーを必要とするときはいつでも、テンプレートパラメータである UserAllocator からシステムへ要求が出される。 システムにリクエストする量はダブリングアルゴリズムによって決定される。 言い換えると、追加でシステムメモリーを確保するときは、要求する量を2倍にするということである。 ユーザーは以下に述べる拡張によってダブリングアルゴリズムを管理することができる。
ユーザーは pool のコンストラクターに追加のパラメータを渡すことができる。 このパラメーターは size_type 型で、そのオブジェクトがシステムメモリーを初めて必要とするときに要求するチャンクの数である。 既定値は 32 である。このパラメーターは 0 であってはならない。
関数 size_type get_next_size() const; と void set_next_size(size_type); のペアはユーザーに明示的な next_size への読み書きを許す。 この値はオブジェクトが次にシステムメモリーからの割り当てが必要になったときに要求するチャンクの数である。 この値を 0 に設定してはならない。
PODptr は現実には存在しない異なるクラス型へのポインタであるかのように振舞うクラスである。 それは、それが指す "object" の "data" にアクセスするメンバー関数を提供する。 これらの "class" 型はサイズが異なり、メモリーの最後に何か情報を持っているため、PODptrは、この "class" のサイズを知っている必要がある。 まるで "class" へのポインタと同様に。
PODptr はシステムから割り当てられたメモリーブロックの場所とサイズを保持している。 個々のメモリーブロックは論理的に3つのセクションに分かれている。
PODptr クラスは生のメモリーブロックを扱うよりはクリーンな方法を提供するのみである。
PODptr は valid もしくは invalid のいずれかである。 invalid な PODptr は null ポインタのアナロジーである。
PODptr のデフォルトコンストラクタは無効な(invalid)なオブジェクトを作る。 メンバー関数 invalidate の呼び出しは、そのオブジェクトを無効にする。 メンバー関数 valid は、有効・無効性のテストに使用することができる。
PODptr は、コンストラクタにメモリーブロックのアドレスとサイズを渡すことでメモリーブロックを指すように作られることもある。 この方法で生成された PODptr は有効(valid)である。
PODptr はメンバー関数 next の呼び出しによって生成されることもある。 このメンバー関数は、メモリーブロックリストの中の次のメモリーブロックを指す PODptr を返す。もしくは、次のブロックが存在しないならば無効な PODptr を返す。
個々の PODptr は、そのメモリーブロックのアドレスとサイズを保持している。 このアドレスはメンバー関数 begin で、読み書きされる。 メモリーブロックのサイズはメンバー関数 total_size による読みのみが許されている。
チャンク領域は element_size と連携して、メンバー関数< SPAN CLASS="code">begin と end によってアクセスすることができる。 end によって返される値は、つねに begin によって返される値に element_size を加えた値である。 begin のみが書き込み可能である。 end は past-the-end 値(末尾の要素の次)である。 begin に始まりend の前で終わるポインタの使用はメモリーブロックのチャンクを通しで反復することができる。
メンバー関数 next_ptr によって次ポインタ領域にアクセスすることができる。 メンバー関数next_sizeによって次サイズ領域にアクセスすることができる。 両者とも書き込み可能である。 両者とも、メンバー関数 next を使って、同時に読むまたは変更ができる。
これは、このPoolオブジェクトによって割り当てられたメモリーブロックのリストである。 (first として単純分離記憶域によって開示された)未使用のメモリーチャンクのリストと同じものではない。
基底クラスである単純分離記憶域オブジェクトを返すのに使われる、便宜関数がある。
最初の引数はコンストラクタへ渡される。 ユーザーによって要求されたチャンクのバイト数を表現している。 チャンクの実際のサイズは異なっているかもしれない。 下記の alloc_size を見よ。
我々が次にシステムメモリーを割り当てるとき UserAllocator が要求するチャンクの数。 上記の拡張の説明を見よ。
メモリーブロックリストを通しで調べて、その chunk がそこから割り当てられている、または将来割り当てられことがあり得るブロックを探す。 もし見つかれば、そのブロックを返す。chunk が他の Pool から割り当てられている、もしくは将来他の Pool から割り当てられことがあり得る場合は無効な値を返す。 それ以外の chunk の値は、不正な結果を招く。
chunk が 要素サイズが sizeof_i のメモリーチャンク i から割り当てられていると見える(思われる)かどうかをテストする。 sizeof_i はそのブロックのチャンク領域のサイズであり、ブロックのトータルサイズではないことに注意せよ。
chunk がそのメモリーブロックから割り当てられているか、将来そのメモリーブロックから割り当てられることがあり得る場合に true を返す。 chunk が他のブロックから割り当てられているか、将来他のブロックから割り当てられることがあり得る場合には false を返す。 それ以外の chunk の値は不正な結果を招く。
この Pool によって割り当てられるメモリーチャンクの計算されたサイズを返す。 アラインメントの都合で、lcm(requested_size, sizeof(void *), sizeof(size_type)) と定義されている。
Copyright © 2000, 2001 Stephen Cleary (shammah@voyager.net)
This file can be redistributed and/or modified under the terms found in copyright.html
This software and its documentation is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.