1 module d.common.qualifier;
2 
3 enum Visibility {
4 	Private,
5 	Package,
6 	Protected,
7 	Public,
8 	Export,
9 }
10 
11 enum Linkage {
12 	D,
13 	C,
14 	Cpp,
15 	Windows,
16 	System,
17 	Pascal,
18 	Java,
19 }
20 
21 enum Storage {
22 	Local,
23 	Capture,
24 	Static,
25 	Enum,
26 }
27 
28 @property
29 bool isGlobal(Storage s) {
30 	return s > Storage.Capture;
31 }
32 
33 @property
34 bool isLocal(Storage s) {
35 	return !isGlobal(s);
36 }
37 
38 unittest {
39 	with (Storage) {
40 		assert(Local.isGlobal == false);
41 		assert(Local.isLocal == true);
42 		assert(Capture.isGlobal == false);
43 		assert(Capture.isLocal == true);
44 		assert(Static.isGlobal == true);
45 		assert(Static.isLocal == false);
46 		assert(Enum.isGlobal == true);
47 		assert(Enum.isLocal == false);
48 	}
49 }
50 
51 enum TypeQualifier {
52 	Mutable,
53 	Inout,
54 	Const,
55 	Shared,
56 	ConstShared,
57 	Immutable,
58 }
59 
60 // XXX: operator overloading ?
61 auto add(TypeQualifier actual, TypeQualifier added) {
62 	if ((actual == TypeQualifier.Shared && added == TypeQualifier.Const)
63 		    || (added == TypeQualifier.Shared
64 			    && actual == TypeQualifier.Const)) {
65 		return TypeQualifier.ConstShared;
66 	}
67 
68 	import std.algorithm;
69 	return max(actual, added);
70 }
71 
72 unittest {
73 	import std.traits;
74 	foreach (q1; EnumMembers!TypeQualifier) {
75 		assert(TypeQualifier.Mutable.add(q1) == q1);
76 		assert(TypeQualifier.Immutable.add(q1) == TypeQualifier.Immutable);
77 
78 		foreach (q2; EnumMembers!TypeQualifier) {
79 			assert(q1.add(q2) == q2.add(q1));
80 		}
81 	}
82 
83 	with (TypeQualifier) {
84 		assert(Const.add(Immutable) == Immutable);
85 		assert(Const.add(Inout) == Const);
86 		assert(Const.add(Shared) == ConstShared);
87 		assert(Const.add(ConstShared) == ConstShared);
88 
89 		assert(Immutable.add(Inout) == Immutable);
90 		assert(Immutable.add(Shared) == Immutable);
91 		assert(Immutable.add(ConstShared) == Immutable);
92 
93 		// assert(Inout.add(Shared) == ConstShared);
94 		assert(Inout.add(ConstShared) == ConstShared);
95 
96 		assert(Shared.add(ConstShared) == ConstShared);
97 	}
98 }
99 
100 bool canConvert(TypeQualifier from, TypeQualifier to) {
101 	if (from == to) {
102 		return true;
103 	}
104 
105 	final switch (to) with (TypeQualifier) {
106 		case Mutable, Inout, Shared, Immutable:
107 			// Some qualifier are not safely castable to.
108 			return false;
109 
110 		case Const:
111 			return from == Mutable || from == Immutable || from == Inout;
112 
113 		case ConstShared:
114 			return from == Shared || from == Immutable;
115 	}
116 }
117 
118 enum ParamKind {
119 	/// Regular parameter. A slot on the stack will be allocated and value
120 	/// copied in it when calling the function.
121 	Regular,
122 	/// Final parameter. No slot on the stack is created for it, and the
123 	/// parameter cannot be written to, even when mutable.
124 	Final,
125 	/// Ref parameter. The address of the argument is passed instead of the
126 	/// argument itself and is used as if it was a regular slot on the stack.
127 	Ref,
128 }