ビット操作

mixinによりコンパイル時にコードを生成するDの能力の好例がビット操作です。

シンプルなビット操作

Dはビット操作のために以下の演算子を提供します:

  • & ビット単位論理積
  • | ビット単位論理和
  • ~ ビット反転
  • << ビット符号あり左シフト
  • >> ビット符号あり右シフト (上位ビットの符号が保持されます)
  • >>> ビット符号なし右シフト

実践例

ビット操作の一般的な例はビットの値を読むことです。Dは最も一般的なタスクのために core.bitop.btを提供しますが、ビット操作に慣れ親しむためには、 ビットのテストの冗長な実装をしてみましょう。:

enum posA = 1;
enum maskA = (1 << posA);
bool getFieldA()
{
    return _data & maskA;
}

一般化は1より長いブロックのテストをすることです。そのためブロックの長さの特殊な リードマスクが必要で、データブロックはマスクが適用される前にシフトされます:

enum posA = 1;
enum lenA = 3;
enum maskA = (1 << lenA) - 1; // ...0111
uint getFieldA()
{
    return (_data >> posA) & maskA;
}

そのようなブロックの設定は等しくマスクの否定によって定義し、特定のブロック内のみに書込みできます:

void setFieldA(bool b);
{
    return (_data & ~maskAWrite) | ((b << aPos) & maskAWrite);
}

助けになるstd.bitmanip

カスタムビット操作コードを書くことは非常に面白く、Dはそのための完全なツールボックスを提供します。 しかし非常にエラーを引き起こしやすく保守がしづらいため大抵の場合そのようなビット操作はコピー&ペーストはしたくありません。 したがってDではstd.bitmanipが保守性のあり、読みやすいビット操作を書くことをstd.bitmanipとmixinの力で 助けます - パフォーマンスは犠牲になりません。

エクササイズのセクションをご覧ください。BitVectorは定義されていますが、まだXビットを使い、 普通の構造体とほとんど見分けがつきません。

std.bitmanipcore.bitop少ないメモリ消費を必要とする アプリケーションのための非常に有用な更に多くのヘルパがあります。

パディングとアライメント

コンパイラは、bool, byte, char のようなOSのメモリレイアウト (size_t.sizeof) よりも小さいサイズの変数に対してパディングを挿入するため、アライメントの大きいフィールドから書くと良いでしょう。

掘り下げる

rdmd playground.d