1 /******************************************************************************* 2 3 Templates to define types with modified qualifiers based on some input 4 types. 5 6 Many of helper templates here have been added because of D1 to D2 migration 7 to hide behind them qualifiers not supported in D1 (const, immutable, 8 inout). Others, like `Unqual`, are generally useful even outside of 9 migration context. 10 11 NB: because this module is often used as purely compile-time dependency it 12 used built-in asserts instead of `ocean.core.Test` to reduce amount of 13 cyclic imports. `ocean.meta` modules in general are not supposed to 14 import anything outside of `ocean.meta`. 15 16 Copyright: 17 Copyright (C) 2017 dunnhumby Germany GmbH. All rights reserved. 18 19 License: 20 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details. 21 Alternatively, this file may be distributed under the terms of the Tango 22 3-Clause BSD License (see LICENSE_BSD.txt for details). 23 24 *******************************************************************************/ 25 26 module ocean.meta.types.Qualifiers; 27 28 /******************************************************************************* 29 30 Convenience string type aliases. 31 32 Initially defined to help with D2 migration but proved themselves as useful 33 shortcuts to reduce visual code clutter. 34 35 *******************************************************************************/ 36 37 alias Immut!(char)[] istring; 38 alias Const!(char)[] cstring; 39 alias char[] mstring; 40 41 /******************************************************************************* 42 43 Helper template to be used instead of plain types in function parameter 44 list when one will need to be const-qualified in D2 world - usually this is 45 necessary if function needs to handle string literals. 46 47 This should be used instead of istring/cstring aliases in generic array 48 processing functions as opposed to string-specific code. 49 50 Example: 51 52 --- 53 void foo(Element)(Const!(Element)[] buf) 54 { 55 } 56 57 foo!(char)("aaa"); // will work in both D1 and D2 58 --- 59 60 *******************************************************************************/ 61 62 template Const(T) 63 { 64 alias const(T) Const;; 65 } 66 67 unittest 68 { 69 alias Const!(int[]) Int; 70 71 static assert (is(Int)); 72 73 static assert (is(Int == const)); 74 } 75 76 /******************************************************************************* 77 78 Same as Const!(T) but for immutable 79 80 Example: 81 82 --- 83 Immut!(char)[] foo() 84 { 85 return "aaa"; // ok, immutable 86 return new char[]; // error, mutable 87 } 88 --- 89 90 *******************************************************************************/ 91 92 template Immut(T) 93 { 94 alias immutable(T) Immut; 95 } 96 97 unittest 98 { 99 alias Immut!(int[]) Int; 100 101 static assert (is(Int)); 102 103 static assert (is(Int == immutable)); 104 } 105 106 /******************************************************************************* 107 108 Same as Const!(T) but for inout 109 110 Example: 111 112 --- 113 Inout!(char[]) foo(Inout!(char[]) arg) 114 { 115 return arg; 116 } 117 118 mstring = foo("aaa"); // error 119 istring = foo("aaa"); // ok 120 mstring = foo("aaa".dup); // ok 121 --- 122 123 *******************************************************************************/ 124 125 template Inout(T) 126 { 127 alias inout(T) Inout; 128 } 129 130 unittest 131 { 132 alias Inout!(char[]) Str; 133 134 Str foo ( Str arg ) { return arg; } 135 136 char[] s1 = foo("aaa".dup); 137 Immut!(char)[] s2 = foo("aaa"); 138 } 139 140 /******************************************************************************* 141 142 In D1 does nothing. In D2 strips top-most type qualifier. 143 144 This is a small helper useful for adapting templated code where template 145 parameter can possibly be deduced as const or immutable. Using this type 146 directly in implementation will result in unmodifiable variables which isn't 147 always wanted. 148 149 Example: 150 151 --- 152 void foo(Element)(Element[] buf) 153 { 154 // this causes an error with D2 if element 155 // gets deduced as const 156 Element tmp; 157 tmp = Element.init; 158 159 // this is ok in both d1 and D2 160 Unqual!(Element) tmp; 161 tmp = Element.init; 162 } 163 --- 164 165 *******************************************************************************/ 166 167 template Unqual(T) 168 { 169 static if (is(T U == const U)) 170 { 171 alias U Unqual; 172 } 173 else static if (is(T U == immutable U)) 174 { 175 alias U Unqual; 176 } 177 else 178 { 179 alias T Unqual; 180 } 181 } 182 183 unittest 184 { 185 static assert (is(Unqual!(typeof("a"[0])) == char)); 186 }