Konu biraz mixin'lere kaymış...:)
İster istemez neler yapılabilir diye biraz kafa yordum. Öncelikle; evet, C'deki define komutuyla (önişleç sanırım) parametreler yerleştirilip kod olduğu gibi çağrıldığı yere yerleştiriliyor. Sakıncaları hakkında ve C++'da neden kurtulamadığımızı bilmiyorum. Ama biz mixin'e gelelim çünkü define'dan çok daha güçlü bir olanak D'de hali hazırda mevcut...
Şöyle düşündüm; biz eğer bir bit'in 1 olup olmadığını öğrendikten sonra onun üzerinde işlem gerçekleştireceksek, her iki işleve de aynı parametreleri göndermek zorunda kalırız. Gerçi bu işlevleri yapı içerisine alma ve/veya tek merkezden besleme mümkün ama farz edelim ki bu örnekleri, kodu fazla değiştirmeden sürdürmek zorundayız. Ancak defalarca parametreler ile kafayı yemek istemiyoruz!
En azından yazılım kararlılığını/bütünlüğünü sağlamak için bunu yapmalıyız. Çünkü insan hata yapar ve bir yerde A değerini yazarken, diğer tarafa B değerini yazdığında işler karışabilir.
Aşağıda bunu kodlarla ifade etmeye çalıştım. İlk olarak bit isminde ortak bir parametre tanımlayarak çalıştırdım ve her şey yolunda gitti. Hazır elimi atmışken '(T)'ür şablonu kullanarak işlevleri daha akıllı hale getirdim. Hoş template içine alınca bunu başaramadım ama lütfen her ikisini de deneyin. Çünkü her ikisi de çalışıyor ve farkı görmek için sadece '//' işaretini kaldırmanız yeterli:
import std.stdio;
struct MemoryBlock(T) {
T[] searchmask;
string toString() const {
enum bitSize = format("%%.%sb ", T.sizeof * 8);
string printOut;
foreach_reverse(s; searchmask) {
printOut ~= format(bitSize, s);
}
return printOut;
}
}
bool isInSearch(T)(ref MemoryBlock!T mb, size_t offset) {
enum bitSize = T.sizeof * 8;
return ( mb.searchmask[offset / bitSize] &
( 1 << (offset % bitSize)) ) != 0;
}
void removeFromSearch(T)(ref MemoryBlock!T mb, size_t offset) {
enum bitSize = T.sizeof * 8;
mb.searchmask[offset / bitSize] &=
~( 1 << (offset % bitSize));
}
mixin template bitOp(alias mb, alias offset) {
bool isInSearch() {
return ( mb.searchmask[offset / 8] &
( 1 << (offset % 8)) ) != 0;
}
void removeFromSearch() {
mb.searchmask[offset / 8] &=
~( 1 << (offset % 8));
}
}
void main(){
auto mb = MemoryBlock!ubyte([0b1111_0000, 0b0000_1111]);
// bits: 7---^ ^---8
size_t bit = 8; assert(isInSearch(mb, bit));
mb.writeln;
//removeFromSearch(mb, bit); /*
mixin bitOp!(mb, bit) op;
if(op.isInSearch) op.removeFromSearch; //*/
mb.writeln;
}
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]