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 }