1 // 2 // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 #ifndef _CONSTANT_UNION_INCLUDED_ 8 #define _CONSTANT_UNION_INCLUDED_ 9 10 #include <assert.h> 11 12 class ConstantUnion { 13 public: 14 POOL_ALLOCATOR_NEW_DELETE(); 15 ConstantUnion() 16 { 17 iConst = 0; 18 type = EbtVoid; 19 } 20 21 bool cast(TBasicType newType, const ConstantUnion &constant) 22 { 23 switch (newType) 24 { 25 case EbtFloat: 26 switch (constant.type) 27 { 28 case EbtInt: setFConst(static_cast<float>(constant.getIConst())); break; 29 case EbtUInt: setFConst(static_cast<float>(constant.getUConst())); break; 30 case EbtBool: setFConst(static_cast<float>(constant.getBConst())); break; 31 case EbtFloat: setFConst(static_cast<float>(constant.getFConst())); break; 32 default: return false; 33 } 34 break; 35 case EbtInt: 36 switch (constant.type) 37 { 38 case EbtInt: setIConst(static_cast<int>(constant.getIConst())); break; 39 case EbtUInt: setIConst(static_cast<int>(constant.getUConst())); break; 40 case EbtBool: setIConst(static_cast<int>(constant.getBConst())); break; 41 case EbtFloat: setIConst(static_cast<int>(constant.getFConst())); break; 42 default: return false; 43 } 44 break; 45 case EbtUInt: 46 switch (constant.type) 47 { 48 case EbtInt: setUConst(static_cast<unsigned int>(constant.getIConst())); break; 49 case EbtUInt: setUConst(static_cast<unsigned int>(constant.getUConst())); break; 50 case EbtBool: setUConst(static_cast<unsigned int>(constant.getBConst())); break; 51 case EbtFloat: setUConst(static_cast<unsigned int>(constant.getFConst())); break; 52 default: return false; 53 } 54 break; 55 case EbtBool: 56 switch (constant.type) 57 { 58 case EbtInt: setBConst(constant.getIConst() != 0); break; 59 case EbtUInt: setBConst(constant.getUConst() != 0); break; 60 case EbtBool: setBConst(constant.getBConst()); break; 61 case EbtFloat: setBConst(constant.getFConst() != 0.0f); break; 62 default: return false; 63 } 64 break; 65 case EbtStruct: // Struct fields don't get cast 66 switch (constant.type) 67 { 68 case EbtInt: setIConst(constant.getIConst()); break; 69 case EbtUInt: setUConst(constant.getUConst()); break; 70 case EbtBool: setBConst(constant.getBConst()); break; 71 case EbtFloat: setFConst(constant.getFConst()); break; 72 default: return false; 73 } 74 break; 75 default: 76 return false; 77 } 78 79 return true; 80 } 81 82 void setIConst(int i) {iConst = i; type = EbtInt; } 83 void setUConst(unsigned int u) { uConst = u; type = EbtUInt; } 84 void setFConst(float f) {fConst = f; type = EbtFloat; } 85 void setBConst(bool b) {bConst = b; type = EbtBool; } 86 87 int getIConst() const { return iConst; } 88 unsigned int getUConst() const { return uConst; } 89 float getFConst() const { return fConst; } 90 bool getBConst() const { return bConst; } 91 92 bool operator==(const int i) const 93 { 94 return i == iConst; 95 } 96 97 bool operator==(const unsigned int u) const 98 { 99 return u == uConst; 100 } 101 102 bool operator==(const float f) const 103 { 104 return f == fConst; 105 } 106 107 bool operator==(const bool b) const 108 { 109 return b == bConst; 110 } 111 112 bool operator==(const ConstantUnion& constant) const 113 { 114 if (constant.type != type) 115 return false; 116 117 switch (type) { 118 case EbtInt: 119 return constant.iConst == iConst; 120 case EbtUInt: 121 return constant.uConst == uConst; 122 case EbtFloat: 123 return constant.fConst == fConst; 124 case EbtBool: 125 return constant.bConst == bConst; 126 default: 127 return false; 128 } 129 } 130 131 bool operator!=(const int i) const 132 { 133 return !operator==(i); 134 } 135 136 bool operator!=(const unsigned int u) const 137 { 138 return !operator==(u); 139 } 140 141 bool operator!=(const float f) const 142 { 143 return !operator==(f); 144 } 145 146 bool operator!=(const bool b) const 147 { 148 return !operator==(b); 149 } 150 151 bool operator!=(const ConstantUnion& constant) const 152 { 153 return !operator==(constant); 154 } 155 156 bool operator>(const ConstantUnion& constant) const 157 { 158 assert(type == constant.type); 159 switch (type) { 160 case EbtInt: 161 return iConst > constant.iConst; 162 case EbtUInt: 163 return uConst > constant.uConst; 164 case EbtFloat: 165 return fConst > constant.fConst; 166 default: 167 return false; // Invalid operation, handled at semantic analysis 168 } 169 } 170 171 bool operator<(const ConstantUnion& constant) const 172 { 173 assert(type == constant.type); 174 switch (type) { 175 case EbtInt: 176 return iConst < constant.iConst; 177 case EbtUInt: 178 return uConst < constant.uConst; 179 case EbtFloat: 180 return fConst < constant.fConst; 181 default: 182 return false; // Invalid operation, handled at semantic analysis 183 } 184 } 185 186 ConstantUnion operator+(const ConstantUnion& constant) const 187 { 188 ConstantUnion returnValue; 189 assert(type == constant.type); 190 switch (type) { 191 case EbtInt: returnValue.setIConst(iConst + constant.iConst); break; 192 case EbtUInt: returnValue.setUConst(uConst + constant.uConst); break; 193 case EbtFloat: returnValue.setFConst(fConst + constant.fConst); break; 194 default: assert(false && "Default missing"); 195 } 196 197 return returnValue; 198 } 199 200 ConstantUnion operator-(const ConstantUnion& constant) const 201 { 202 ConstantUnion returnValue; 203 assert(type == constant.type); 204 switch (type) { 205 case EbtInt: returnValue.setIConst(iConst - constant.iConst); break; 206 case EbtUInt: returnValue.setUConst(uConst - constant.uConst); break; 207 case EbtFloat: returnValue.setFConst(fConst - constant.fConst); break; 208 default: assert(false && "Default missing"); 209 } 210 211 return returnValue; 212 } 213 214 ConstantUnion operator*(const ConstantUnion& constant) const 215 { 216 ConstantUnion returnValue; 217 assert(type == constant.type); 218 switch (type) { 219 case EbtInt: returnValue.setIConst(iConst * constant.iConst); break; 220 case EbtUInt: returnValue.setUConst(uConst * constant.uConst); break; 221 case EbtFloat: returnValue.setFConst(fConst * constant.fConst); break; 222 default: assert(false && "Default missing"); 223 } 224 225 return returnValue; 226 } 227 228 ConstantUnion operator%(const ConstantUnion& constant) const 229 { 230 ConstantUnion returnValue; 231 assert(type == constant.type); 232 switch (type) { 233 case EbtInt: returnValue.setIConst(iConst % constant.iConst); break; 234 case EbtUInt: returnValue.setUConst(uConst % constant.uConst); break; 235 default: assert(false && "Default missing"); 236 } 237 238 return returnValue; 239 } 240 241 ConstantUnion operator>>(const ConstantUnion& constant) const 242 { 243 ConstantUnion returnValue; 244 assert(type == constant.type); 245 switch (type) { 246 case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break; 247 case EbtUInt: returnValue.setUConst(uConst >> constant.uConst); break; 248 default: assert(false && "Default missing"); 249 } 250 251 return returnValue; 252 } 253 254 ConstantUnion operator<<(const ConstantUnion& constant) const 255 { 256 ConstantUnion returnValue; 257 assert(type == constant.type); 258 switch (type) { 259 case EbtInt: returnValue.setIConst(iConst << constant.iConst); break; 260 case EbtUInt: returnValue.setUConst(uConst << constant.uConst); break; 261 default: assert(false && "Default missing"); 262 } 263 264 return returnValue; 265 } 266 267 ConstantUnion operator&(const ConstantUnion& constant) const 268 { 269 ConstantUnion returnValue; 270 assert(type == constant.type); 271 switch (type) { 272 case EbtInt: returnValue.setIConst(iConst & constant.iConst); break; 273 case EbtUInt: returnValue.setUConst(uConst & constant.uConst); break; 274 default: assert(false && "Default missing"); 275 } 276 277 return returnValue; 278 } 279 280 ConstantUnion operator|(const ConstantUnion& constant) const 281 { 282 ConstantUnion returnValue; 283 assert(type == constant.type); 284 switch (type) { 285 case EbtInt: returnValue.setIConst(iConst | constant.iConst); break; 286 case EbtUInt: returnValue.setUConst(uConst | constant.uConst); break; 287 default: assert(false && "Default missing"); 288 } 289 290 return returnValue; 291 } 292 293 ConstantUnion operator^(const ConstantUnion& constant) const 294 { 295 ConstantUnion returnValue; 296 assert(type == constant.type); 297 switch (type) { 298 case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break; 299 case EbtUInt: returnValue.setUConst(uConst ^ constant.uConst); break; 300 default: assert(false && "Default missing"); 301 } 302 303 return returnValue; 304 } 305 306 ConstantUnion operator&&(const ConstantUnion& constant) const 307 { 308 ConstantUnion returnValue; 309 assert(type == constant.type); 310 switch (type) { 311 case EbtBool: returnValue.setBConst(bConst && constant.bConst); break; 312 default: assert(false && "Default missing"); 313 } 314 315 return returnValue; 316 } 317 318 ConstantUnion operator||(const ConstantUnion& constant) const 319 { 320 ConstantUnion returnValue; 321 assert(type == constant.type); 322 switch (type) { 323 case EbtBool: returnValue.setBConst(bConst || constant.bConst); break; 324 default: assert(false && "Default missing"); 325 } 326 327 return returnValue; 328 } 329 330 TBasicType getType() const { return type; } 331 private: 332 333 union { 334 int iConst; // used for ivec, scalar ints 335 unsigned int uConst; // used for uvec, scalar uints 336 bool bConst; // used for bvec, scalar bools 337 float fConst; // used for vec, mat, scalar floats 338 } ; 339 340 TBasicType type; 341 }; 342 343 #endif // _CONSTANT_UNION_INCLUDED_ 344