Phần này là ví dụ tuyệt vời cho khả năng sinh mã lúc biên dịch với mixin. Đó là việc xử lý các bit thông tin.
D có các hàm cơ bản để xử lý bit:
&
phép và
(and)
|
phép hoặc
(or)
~
phép phủ định (negative)
<<
phép dịch trái có dấu
>>
phép dịch phải có dấu (giữ nguyên dấu của bit cao)
>>>
phép dịch phải không dấu
Ví dụ phổ biến là đọc giá trị của một bit. Dù D có thư viện core.bitop.bt
cho hầu hết các nhu cầu, nhưng ta hãy tự bắt đầu theo cách riêng để làm
quên với việc xử lý theo bit
enum posA = 1;
enum maskA = (1 << posA);
bool getFieldA()
{
return _data & maskA;
}
Tổng quát hơn, ta có thể kiểm tra một khối gồm nhiều hơn một bit. Ta sẽ cần biết chiều dài của khối, và đầu vào sẽ dịch chuyển tương ứng trước khi gài mặt nạ bit:
enum posA = 1;
enum lenA = 3;
enum maskA = (1 << lenA) - 1; // ...0111
uint getFieldA()
{
return (_data >> posA) & maskA;
}
Cài giá trị cho một khối có thể hiểu là dùng mặt nạ phủ định và chỉ cho phép thay đổi giá trị trong khối chỉ định:
void setFieldA(bool b);
{
return (_data & ~maskAWrite) | ((b << aPos) & maskAWrite);
}
std.bitmanip
có hết mọi thứThư viện của D cung cấp mọi thứ để bạn xử lý các bit một cách hứng thú.
Nhưng trong hầu hết trường hợp, bạn không muốn chép và dán những phép
xử lý như trong ví dụ ở trên, vì cách đó dễ dẫn tới sai sót.
Hãy sử dụng thư viện std.bitmapip
để viết các phép xử lý bit theo cách
đơn giản, dễ bảo trì, mà còn có thể dùng với mixin và không giảm đi hiệu năng
chương trình.
Hãy xem ví dụ ở phần sau. Một BitVector
được định nghĩa, nhưng nó chỉ sử
dụng một số X bit, và hầu như không thể phân biệt với các cấu trúc thường.
Thư viện std.bitmanip
và core.bitop
gồm nhiều hàm tiện ích cho các
ứng dụng được viết với chủ đích giảm tối thiểu việc dùng bộ nhớ.
Vì trình biên dịch thêm vào các biến một số bit để khớp với kiến trúc bộ
nhớ trên hệ thống (size_t.sizeof
), ví dụ các biến kiểu bool
, byte
, char
,
bạn được khuyên bắt đầu với các trường ở ngăn xếp cao (fields of high alignments.)