-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathutil.d
112 lines (98 loc) · 1.97 KB
/
util.d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
module util;
import std.ascii : isDigit;
import std.stdio : stderr;
public:
enum TypeName
{
INT,
POINTER,
ARRAY,
CHAR,
}
struct Type
{
TypeName type;
Type* pointer_to;
// 配列
Type* array_of;
size_t array_length;
}
/// strtolの代わり
int nextInt(string s, ref size_t i)
{
int result;
while (i < s.length && s[i].isDigit())
{
result = (result * 10) + (s[i] - '0');
i++;
}
return result;
}
/// Cみたいにどこでもexit()するための例外
class ExitException : Exception
{
/// 終了コード
int rc;
this(int return_code = 0, string file = __FILE__, size_t line = __LINE__)
{
super(null, file, line);
this.rc = return_code;
}
}
void error(A...)(string msg, A args)
{
stderr.writefln(msg, args);
throw new ExitException(-1);
}
// Enumの番号を表示
mixin template debugEnum(E)
{
import std.traits : EnumMembers;
pragma(msg, E, ":");
static foreach (e; EnumMembers!E)
static if (e <= char.max)
{
pragma(msg, "\t", cast(char) e, "\t= ", cast(int) e);
}
else
{
pragma(msg, "\t", cast(int) e, "\t= ", cast(int) e);
}
}
long size_of(Type t)
{
with (TypeName) switch (t.type)
{
case CHAR:
return 1;
case INT:
return 4;
case ARRAY:
return size_of(*t.array_of) * t.array_length;
default:
assert(t.type == TypeName.POINTER);
return 8;
}
}
long align_of(Type t)
{
with (TypeName) switch (t.type)
{
case CHAR:
return 1;
case INT:
return 4;
case POINTER:
return 8;
default:
assert(t.type == TypeName.ARRAY);
return align_of(*t.array_of);
}
}
size_t roundup(size_t x, size_t alignment)
{
// alignmentは2の倍数。
// (x + alignment - 1) - ((x + alignment -1) % alignment) と等価。
size_t tmp = (alignment - 1);
return (x + tmp) & ~tmp;
}