Yeni bir sürüm ile karşınızdayım!
Tataaaa...:)
Alıntı:
>
> module sdb.ikibinoniki.stacks;
>
> /****************************************************/
> class Stack(T) {
> /****************************************************/
> int index;
> T[] stack;
> /* #1: */
> void push (T data) @property {
> stack ~= data;
> this.index++;
> }
> /* #2: */
> T pop () @property {
> return stack[--this.index];
> }
> /* #3: */
> int size () @property {
> return this.index;
> }
> /* #4: */
> bool empty () const @property {
> return this.index == 0;
> }
> }
> ```
unittest { /* Class Stack Tests */
auto myStack = new Stack!int;
int sum, i = 11;
foreach(data; 0..i) {
myStack.push(data); // #1.
}
assert (i == myStack.size); // #3.
while(!myStack.empty()) { // #4.
sum += myStack.pop(); // #2.
}
assert (sum == 55);
assert (myStack.size == 0);
}
debug void main() {
/* Compile parameters:
- dmd sdb/ikibinoniki/stacks.d -debug -unittest
*/
}
Evet, görüldüğü gibi gelişeceğine kırpılmış bir sürümü ile karşılaştınız...:)
Dış görünüş aldatıcı çünkü bu sadece modülün bir parçası. Bu hale dönüşmesine, ne zamandır düşündüğüm derleme çalışması sebep oldu. Baktım; yığıtlar ile ilgili birbirine benzer çok şey yapmışım. Öyleyse, pekala temel bir sınıftan bunları türetebilirdik. Örneğin şurada (<http://ddili.org/forum/thread/1030>) değindiğim yığıt, artık yukarıdaki modülden türemiş olarak şu şekilde kullanılabilir:
import sdb.ikibinoniki.stacks;
//
class BoolStack(T) : Stack!T {
//
public:
/***********/
immutable length_t = (T.sizeof * 8);
this (size_t size) {
size_t lenOverflow = size % length_t ? 1 : 0;
super.stack = new T[(size / length_t) + lenOverflow];
}
/* #b1: /
void clear () @property {
foreach(ref cell; stack) {
cell = 0;
}
super.index = 0;
}
/ #b2: */
auto length () const @property {
return (stack.length * T.sizeof) + index.sizeof;
}
private
/***********/
bool bitTest (size_t bit) {
T xCell = stack[bit / length_t];
T xMask = cast(T)1 << bit % length_t;
return (xCell & xMask) != 0;
}
override:
/***********/
/* #b3: */
void push (T data) @property {
immutable index = super.index / length_t;
immutable xMask = super.index % length_t;
if(index >= stack.length) {
throw new Exception("Stack is full!");
}
stack[index] |= data << xMask;
super.index++;
}
/* #b4: /
T pop () @property {
if(!super.index) {
throw new Exception("Stack is empty!");
}
return cast(T)bitTest(--super.index);
}
/ #b5: */
string toString () @property {
string result = "[";
foreach(i; 0..super.index) {
result ~= bitTest(i) ? "1" : "0";
}
return result ~ "]";
}
}
unittest { /* Class BoolStack Tests */
auto data = [ false, true, false, false, true, false, true, true,
true ]; //<-- 2/1 byte ---------------------------^
auto test = new BoolStack!ubyte(data.length);
// 4(int) + 2(ubyte) = 6
assert (test.length == 6 ); // #b2.
assert (test.empty); // #s4.
test.push (false);
assert (!test.empty);
test.push (true);
assert (test.size == 2); // #s3.
test.clear; // #b1.
assert (test.empty);
foreach(d; data) {
test.push(d); // #b3.
}
assert (!test.empty);
assert (test.toString ==
"[010010111]"); // #b5.
foreach_reverse(d; data) {
assert (d == test.pop); // #b4.
}
assert (test.empty);
}
Bir de bu temelden, yeni bir sınıf (örn. RangeStack) türetilip iki aralık işlevi de (popFront(), front() işlevleri) eklenirse, görünürde çok karışmayan/şişmeyen ama aralıklarla da kullanılabilen yeni bir sınıfımız olabilir.
Kolay gelsin...
--
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]