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