The OpenD Programming Language

1 /++
2 Const and Immutable qualifiers helpers for Mir Type System.
3 
4 License: $(HTTP www.apache.org/licenses/LICENSE-2.0, Apache-2.0)
5 Authors:   Ilia Ki
6 
7 Macros:
8 NDSLICE = $(REF_ALTTEXT $(TT $2), $2, mir, ndslice, $1)$(NBSP)
9 +/
10 module mir.qualifier;
11 
12 import std.traits;
13 
14 /++
15 +/
16 template LightScopeOf(T)
17 {
18     static if (isPointer!T)
19     {
20         alias LightScopeOf = T;
21     }
22     else
23     {
24         static if (__traits(hasMember, T, "lightScope"))
25             alias LightScopeOf = typeof(T.init.lightScope());
26         else
27         static if (is(T == immutable))
28             alias LightScopeOf = LightImmutableOf!T;
29         else
30         static if (is(T == const))
31             alias LightScopeOf = LightConstOf!T;
32         else
33             alias LightScopeOf = T;
34     }
35 }
36 
37 /++
38 +/
39 template LightConstOf(T)
40 {
41     static if (isPointer!T)
42     {
43         alias LightConstOf = const(PointerTarget!T)*;
44     }
45     else
46     {
47         alias LightConstOf = typeof(const(T).init.lightConst());
48     }
49 }
50 
51 /// ditto
52 template LightImmutableOf(T)
53 {
54     static if (isPointer!T)
55     {
56         alias LightImmutableOf = immutable(PointerTarget!T)*;
57     }
58     else
59     {
60         alias LightImmutableOf = typeof(immutable(T).init.lightImmutable());
61     }
62 }
63 
64 @property:
65 
66 /++
67 Tries to strip a reference counting handles from the value.
68 This funciton should be used only when the result never skips the current scope.
69 
70 This function is used by some algorithms to optimise work with reference counted types.
71 +/
72 auto ref lightScope(T)(auto ref return scope T v)
73     if (!is(T : P*, P) && __traits(hasMember, T, "lightScope"))
74 {
75     return v.lightScope;
76 }
77 
78 /// ditto
79 auto ref lightScope(T)(auto return ref T v)
80     if (!is(T : P*, P) && !__traits(hasMember, T, "lightScope"))
81 {
82     static if (is(T == immutable))
83         return lightImmutable(v);
84     else
85     static if (is(T == const))
86         return lightConst(v);
87     else
88         return v;
89 }
90 
91 /// ditto
92 auto lightScope(T)(return T v)
93     if (is(T : P*, P))
94 {
95     return cast(typeof(*v)*) v;
96 }
97 
98 ///
99 auto lightImmutable(T)(auto ref immutable T v)
100     if (!is(T : P*, P) && __traits(hasMember, immutable T, "lightImmutable"))
101 {
102     return v.lightImmutable;
103 }
104 
105 /// ditto
106 T lightImmutable(T)(auto ref immutable T e)
107     if (!isDynamicArray!T && isImplicitlyConvertible!(immutable T, T) && !__traits(hasMember, immutable T, "lightImmutable"))
108 {
109     return e;
110 }
111 
112 /// ditto
113 auto lightImmutable(T)(immutable(T)[] e)
114 {
115     return e;
116 }
117 
118 /// ditto
119 auto lightImmutable(T)(immutable(T)* e)
120 {
121     return e;
122 }
123 
124 ///
125 auto lightConst(T)(auto ref const T v)
126     if (!is(T : P*, P) && __traits(hasMember, const T, "lightConst"))
127 {
128     return v.lightConst;
129 }
130 
131 /// ditto
132 auto lightConst(T)(auto ref immutable T v)
133     if (!is(T : P*, P) && __traits(hasMember, immutable T, "lightConst"))
134 {
135     return v.lightConst;
136 }
137 
138 /// ditto
139 T lightConst(T)(auto ref const T e)
140     if (!isDynamicArray!T && isImplicitlyConvertible!(const T, T) && !__traits(hasMember, const T, "lightConst"))
141 {
142     return e;
143 }
144 
145 /// ditto
146 T lightConst(T)(auto ref immutable T e)
147     if (!isDynamicArray!T && isImplicitlyConvertible!(immutable T, T) && !__traits(hasMember, immutable T, "lightConst"))
148 {
149     return e;
150 }
151 
152 /// ditto
153 auto lightConst(T)(const(T)[] e)
154 {
155     return e;
156 }
157 
158 /// ditto
159 auto lightConst(T)(immutable(T)[] e)
160 {
161     return e;
162 }
163 
164 /// ditto
165 auto lightConst(T)(const(T)* e)
166 {
167     return e;
168 }
169 
170 /// ditto
171 auto lightConst(T)(immutable(T)* e)
172 {
173     return e;
174 }
175 
176 ///
177 auto trustedImmutable(T)(auto ref const T e) @trusted
178 {
179     return lightImmutable(*cast(immutable) &e);
180 }