1 module foundation.wasm; 2 3 import core.bitop : bsf, bsr; 4 public import core.bitop : popcnt; 5 import std.traits; 6 7 @safe: 8 9 nothrow { 10 T clz(T)(T val) if (isIntegral!T) { 11 if (val == 0) { 12 return T.sizeof * 8; 13 } 14 return 31 - bsr(val); 15 } 16 17 T ctz(T)(T val) if (isIntegral!T) { 18 if (val == 0) { 19 return T.sizeof * 8; 20 } 21 return bsf(val); 22 } 23 } 24 25 T div(T)(T x, T y) if (isIntegral!T) { 26 static if (isSigned!T) { 27 error(!(x == T.min && y == -1), "Overflow"); 28 } 29 error(y != 0, "Division with zero"); 30 31 return x / y; 32 } 33 34 T rem(T)(T x, T y) if (isIntegral!T) { 35 static if (isSigned!T) { 36 error(!(x == T.min && y == -1), "Overflow"); 37 } 38 error(y != 0, "Division with zero"); 39 40 return x % y; 41 } 42 43 void error(const bool flag, string msg, string file = __FILE__, size_t line = __LINE__) { 44 import std.exception; 45 46 if (!flag) { 47 throw new Exception(msg, file, line); 48 } 49 } 50 51 void assert_trap(E)(lazy E expression, string msg = null, string file = __FILE__, size_t line = __LINE__) { 52 import std.exception : assertThrown; 53 54 assertThrown(expression, msg, file, line); 55 }