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 }