

//
// bit manipulation
//

alignUp(x, align) = bitand(x+align-1, bitnot(align-1));

alignDown(x, align) = bitand(x, bitnot(align-1));

higherPower2(x) {
    assert(x <= bitshl(SizeT(1), TypeSize(SizeT)*8-1), "higherPower2");
    var y = SizeT(1);
    while (x > y)
        y *= 2;
    return y;
}

lowerPower2(x) {
    assert(x >= 1, "lowerPower2");
    var y = SizeT(1);
    while (x/2 >= y)
        y *= 2;
    return y;
}

floorLog2(n_) {
    var n = n_;
    assert(n > 0, "floorLog2");
    var x = 0;
    while (n > 1) {
        n /= 2;
        x += 1;
    }
    return x;
}

[T]
ceilLog2(n:T) {
    var x = floorLog2(n);
    if (bitshl(T(1), x) != n)
        return x+1;
    return x;
}



//
// resizeFile
//

resizeFile(file, newSize) {
    assert(fileSize(file) < newSize, "resizeFile");
    seek(file, newSize-1);
    write(file, 0);
}
