1 /** 2 * This module is contains utility templates used by the other modules in 3 * $(CALIB_ABSTRACT). 4 * 5 * Take a look the various modules in $(CALIB_ABSTRACT) for usage examples. 6 */ 7 8 module caLib_abstract.util; 9 10 11 12 /** 13 * return `true` if `T` has an `alias` named `CellStateType`. `False` if not 14 */ 15 template hasCellStateType(T) 16 { 17 enum hasCellStateType = 18 is(T.CellStateType) && 19 is(T.init.CellStateType); 20 } 21 22 /// 23 unittest 24 { 25 struct Foo { 26 alias CellStateType = void; 27 } 28 29 static assert( hasCellStateType!Foo); 30 static assert(!hasCellStateType!string); 31 } 32 33 34 35 /** 36 * Return true all of the given arguments are types that can be impliciltly 37 * converted to one-another 38 * 39 * It is unclear if it behaves the way it should in all cases and should 40 * not be used . 41 */ 42 deprecated template isCellStateTypesCompatible(T...) 43 { 44 static assert(T.length != 0); 45 46 static if(T.length == 1) 47 { 48 enum isCellStateTypesCompatible = true; 49 } 50 else 51 { 52 enum isCellStateTypesCompatible = 53 __traits(compiles, (() { 54 static assert(is(T[0] : T[1])); 55 })() ) && 56 isDimensionsCompatible!(T[1..$]); 57 } 58 } 59 60 /// 61 unittest 62 { 63 static assert( isCellStateTypesCompatible!(int)); 64 static assert( isCellStateTypesCompatible!(int, uint)); 65 static assert(!isCellStateTypesCompatible!(int, string)); 66 } 67 68 69 70 /** 71 * return `true` if `T` has an `alias` named `DisplayValueType`. `False` if not 72 */ 73 template hasDisplayValueType(T) 74 { 75 enum hasDisplayValueType = 76 is(T.DisplayValueType) && 77 is(T.init.DisplayValueType); 78 } 79 80 /// 81 unittest 82 { 83 struct Foo { 84 alias DisplayValueType = uint; 85 } 86 87 static assert( hasDisplayValueType!Foo); 88 static assert(!hasDisplayValueType!string); 89 } 90 91 92 93 /** 94 * Return true all of the given arguments are types that can be impliciltly 95 * converted to one-another 96 * 97 * It is unclear if it behaves the way it should in all cases and should 98 * not be used . 99 */ 100 deprecated template isDisplayValueTypesCompatible(T...) 101 { 102 static assert(T.length != 0); 103 104 static if(T.length == 1) 105 { 106 enum isCellStateTypesCompatible = true; 107 } 108 else 109 { 110 enum isCellStateTypesCompatible = 111 __traits(compiles, (() { 112 static assert(is(T[0] : T[1])); 113 })() ) && 114 isDimensionsCompatible!(T[1..$]); 115 } 116 } 117 118 /// 119 unittest 120 { 121 static assert( isCellStateTypesCompatible!(int)); 122 static assert( isCellStateTypesCompatible!(int, uint)); 123 static assert(!isCellStateTypesCompatible!(int, string)); 124 } 125 126 127 128 /** 129 * return `true` if `T` has an `enum uint` named `Dimension`. `False` if not 130 */ 131 template hasDimension(T) 132 { 133 enum hasDimension = 134 is(typeof(T.Dimension) : int) && 135 is(typeof(T.init.Dimension) : int); 136 } 137 138 /// 139 unittest 140 { 141 struct Foo { 142 static immutable int Dimension = 0; 143 } 144 145 static assert( hasDimension!Foo); 146 static assert(!hasDimension!int); 147 } 148 149 150 151 /** 152 * Return true all of the given arguments are types that can be impliciltly 153 * converted to one-another 154 * 155 * It is unclear if it behaves the way it should in all cases and should 156 * not be used . 157 */ 158 deprecated template isDimensionsCompatible(T...) 159 { 160 static assert(T.length != 0); 161 162 static if(T.length == 1) 163 { 164 enum isDimensionsCompatible = true; 165 } 166 else 167 { 168 enum isDimensionsCompatible = 169 __traits(compiles, (() { 170 static assert(T[0] == T[1]); 171 })() ) && 172 isDimensionsCompatible!(T[1..$]); 173 174 } 175 } 176 177 /// 178 unittest 179 { 180 static assert( isDimensionsCompatible!(0)); 181 static assert( isDimensionsCompatible!(0, 0u)); 182 static assert( isDimensionsCompatible!(0, 0u, byte(0))); 183 static assert(!isDimensionsCompatible!(0, 0.1f)); 184 } 185 186 187 188 /** 189 * return `true` if `T` has an `alias` named `NeighbourhoodType`. `False` if not 190 * 191 * return `true` if `T` has an `alias` named `NeighbourhoodType`. `False` if not. 192 * $(B Note) that `NeighbourhoodType` need not actually be a neighbourhood. 193 * It can be any type 194 */ 195 template hasNeighbourhoodType(T) 196 { 197 enum hasNeighbourhoodType = 198 is(T.NeighbourhoodType) && 199 is(T.init.NeighbourhoodType); 200 } 201 202 /// 203 unittest 204 { 205 struct Foo { 206 alias NeighbourhoodType = char; //car is is not a neighbourhood 207 } 208 209 static assert( hasNeighbourhoodType!Foo); //but this return true anyways 210 static assert(!hasNeighbourhoodType!int); 211 }