1 // 2 // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. 3 // Copyright (C) 2013 LunarG, Inc. 4 // 5 // All rights reserved. 6 // 7 // Redistribution and use in source and binary forms, with or without 8 // modification, are permitted provided that the following conditions 9 // are met: 10 // 11 // Redistributions of source code must retain the above copyright 12 // notice, this list of conditions and the following disclaimer. 13 // 14 // Redistributions in binary form must reproduce the above 15 // copyright notice, this list of conditions and the following 16 // disclaimer in the documentation and/or other materials provided 17 // with the distribution. 18 // 19 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its 20 // contributors may be used to endorse or promote products derived 21 // from this software without specific prior written permission. 22 // 23 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 // POSSIBILITY OF SUCH DAMAGE. 35 // 36 37 #ifndef _CONSTANT_UNION_INCLUDED_ 38 #define _CONSTANT_UNION_INCLUDED_ 39 40 namespace glslang { 41 42 class TConstUnion { 43 public: 44 POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) 45 46 TConstUnion() : iConst(0), type(EbtInt) { } 47 48 void setIConst(int i) 49 { 50 iConst = i; 51 type = EbtInt; 52 } 53 54 void setUConst(unsigned int u) 55 { 56 uConst = u; 57 type = EbtUint; 58 } 59 60 void setI64Const(long long i64) 61 { 62 i64Const = i64; 63 type = EbtInt64; 64 } 65 66 void setU64Const(unsigned long long u64) 67 { 68 u64Const = u64; 69 type = EbtUint64; 70 } 71 72 void setDConst(double d) 73 { 74 dConst = d; 75 type = EbtDouble; 76 } 77 78 void setBConst(bool b) 79 { 80 bConst = b; 81 type = EbtBool; 82 } 83 84 void setSConst(const TString* s) 85 { 86 sConst = s; 87 type = EbtString; 88 } 89 90 int getIConst() const { return iConst; } 91 unsigned int getUConst() const { return uConst; } 92 long long getI64Const() const { return i64Const; } 93 unsigned long long getU64Const() const { return u64Const; } 94 double getDConst() const { return dConst; } 95 bool getBConst() const { return bConst; } 96 const TString* getSConst() const { return sConst; } 97 98 bool operator==(const int i) const 99 { 100 if (i == iConst) 101 return true; 102 103 return false; 104 } 105 106 bool operator==(const unsigned int u) const 107 { 108 if (u == uConst) 109 return true; 110 111 return false; 112 } 113 114 bool operator==(const long long i64) const 115 { 116 if (i64 == i64Const) 117 return true; 118 119 return false; 120 } 121 122 bool operator==(const unsigned long long u64) const 123 { 124 if (u64 == u64Const) 125 return true; 126 127 return false; 128 } 129 130 bool operator==(const double d) const 131 { 132 if (d == dConst) 133 return true; 134 135 return false; 136 } 137 138 bool operator==(const bool b) const 139 { 140 if (b == bConst) 141 return true; 142 143 return false; 144 } 145 146 bool operator==(const TConstUnion& constant) const 147 { 148 if (constant.type != type) 149 return false; 150 151 switch (type) { 152 case EbtInt: 153 if (constant.iConst == iConst) 154 return true; 155 156 break; 157 case EbtUint: 158 if (constant.uConst == uConst) 159 return true; 160 161 break; 162 case EbtInt64: 163 if (constant.i64Const == i64Const) 164 return true; 165 166 break; 167 case EbtUint64: 168 if (constant.u64Const == u64Const) 169 return true; 170 171 break; 172 case EbtDouble: 173 if (constant.dConst == dConst) 174 return true; 175 176 break; 177 case EbtBool: 178 if (constant.bConst == bConst) 179 return true; 180 181 break; 182 default: 183 assert(false && "Default missing"); 184 } 185 186 return false; 187 } 188 189 bool operator!=(const int i) const 190 { 191 return !operator==(i); 192 } 193 194 bool operator!=(const unsigned int u) const 195 { 196 return !operator==(u); 197 } 198 199 bool operator!=(const long long i) const 200 { 201 return !operator==(i); 202 } 203 204 bool operator!=(const unsigned long long u) const 205 { 206 return !operator==(u); 207 } 208 209 bool operator!=(const float f) const 210 { 211 return !operator==(f); 212 } 213 214 bool operator!=(const bool b) const 215 { 216 return !operator==(b); 217 } 218 219 bool operator!=(const TConstUnion& constant) const 220 { 221 return !operator==(constant); 222 } 223 224 bool operator>(const TConstUnion& constant) const 225 { 226 assert(type == constant.type); 227 switch (type) { 228 case EbtInt: 229 if (iConst > constant.iConst) 230 return true; 231 232 return false; 233 case EbtUint: 234 if (uConst > constant.uConst) 235 return true; 236 237 return false; 238 case EbtInt64: 239 if (i64Const > constant.i64Const) 240 return true; 241 242 return false; 243 case EbtUint64: 244 if (u64Const > constant.u64Const) 245 return true; 246 247 return false; 248 case EbtDouble: 249 if (dConst > constant.dConst) 250 return true; 251 252 return false; 253 default: 254 assert(false && "Default missing"); 255 return false; 256 } 257 } 258 259 bool operator<(const TConstUnion& constant) const 260 { 261 assert(type == constant.type); 262 switch (type) { 263 case EbtInt: 264 if (iConst < constant.iConst) 265 return true; 266 267 return false; 268 case EbtUint: 269 if (uConst < constant.uConst) 270 return true; 271 272 return false; 273 case EbtInt64: 274 if (i64Const < constant.i64Const) 275 return true; 276 277 return false; 278 case EbtUint64: 279 if (u64Const < constant.u64Const) 280 return true; 281 282 return false; 283 case EbtDouble: 284 if (dConst < constant.dConst) 285 return true; 286 287 return false; 288 default: 289 assert(false && "Default missing"); 290 return false; 291 } 292 } 293 294 TConstUnion operator+(const TConstUnion& constant) const 295 { 296 TConstUnion returnValue; 297 assert(type == constant.type); 298 switch (type) { 299 case EbtInt: returnValue.setIConst(iConst + constant.iConst); break; 300 case EbtInt64: returnValue.setI64Const(i64Const + constant.i64Const); break; 301 case EbtUint: returnValue.setUConst(uConst + constant.uConst); break; 302 case EbtUint64: returnValue.setU64Const(u64Const + constant.u64Const); break; 303 case EbtDouble: returnValue.setDConst(dConst + constant.dConst); break; 304 default: assert(false && "Default missing"); 305 } 306 307 return returnValue; 308 } 309 310 TConstUnion operator-(const TConstUnion& constant) const 311 { 312 TConstUnion returnValue; 313 assert(type == constant.type); 314 switch (type) { 315 case EbtInt: returnValue.setIConst(iConst - constant.iConst); break; 316 case EbtInt64: returnValue.setI64Const(i64Const - constant.i64Const); break; 317 case EbtUint: returnValue.setUConst(uConst - constant.uConst); break; 318 case EbtUint64: returnValue.setU64Const(u64Const - constant.u64Const); break; 319 case EbtDouble: returnValue.setDConst(dConst - constant.dConst); break; 320 default: assert(false && "Default missing"); 321 } 322 323 return returnValue; 324 } 325 326 TConstUnion operator*(const TConstUnion& constant) const 327 { 328 TConstUnion returnValue; 329 assert(type == constant.type); 330 switch (type) { 331 case EbtInt: returnValue.setIConst(iConst * constant.iConst); break; 332 case EbtInt64: returnValue.setI64Const(i64Const * constant.i64Const); break; 333 case EbtUint: returnValue.setUConst(uConst * constant.uConst); break; 334 case EbtUint64: returnValue.setU64Const(u64Const * constant.u64Const); break; 335 case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break; 336 default: assert(false && "Default missing"); 337 } 338 339 return returnValue; 340 } 341 342 TConstUnion operator%(const TConstUnion& constant) const 343 { 344 TConstUnion returnValue; 345 assert(type == constant.type); 346 switch (type) { 347 case EbtInt: returnValue.setIConst(iConst % constant.iConst); break; 348 case EbtInt64: returnValue.setI64Const(i64Const % constant.i64Const); break; 349 case EbtUint: returnValue.setUConst(uConst % constant.uConst); break; 350 case EbtUint64: returnValue.setU64Const(u64Const % constant.u64Const); break; 351 default: assert(false && "Default missing"); 352 } 353 354 return returnValue; 355 } 356 357 TConstUnion operator>>(const TConstUnion& constant) const 358 { 359 TConstUnion returnValue; 360 switch (type) { 361 case EbtInt: 362 switch (constant.type) { 363 case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break; 364 case EbtUint: returnValue.setIConst(iConst >> constant.uConst); break; 365 case EbtInt64: returnValue.setIConst(iConst >> constant.i64Const); break; 366 case EbtUint64: returnValue.setIConst(iConst >> constant.u64Const); break; 367 default: assert(false && "Default missing"); 368 } 369 break; 370 case EbtUint: 371 switch (constant.type) { 372 case EbtInt: returnValue.setUConst(uConst >> constant.iConst); break; 373 case EbtUint: returnValue.setUConst(uConst >> constant.uConst); break; 374 case EbtInt64: returnValue.setUConst(uConst >> constant.i64Const); break; 375 case EbtUint64: returnValue.setUConst(uConst >> constant.u64Const); break; 376 default: assert(false && "Default missing"); 377 } 378 break; 379 case EbtInt64: 380 switch (constant.type) { 381 case EbtInt: returnValue.setI64Const(i64Const >> constant.iConst); break; 382 case EbtUint: returnValue.setI64Const(i64Const >> constant.uConst); break; 383 case EbtInt64: returnValue.setI64Const(i64Const >> constant.i64Const); break; 384 case EbtUint64: returnValue.setI64Const(i64Const >> constant.u64Const); break; 385 default: assert(false && "Default missing"); 386 } 387 break; 388 case EbtUint64: 389 switch (constant.type) { 390 case EbtInt: returnValue.setU64Const(u64Const >> constant.iConst); break; 391 case EbtUint: returnValue.setU64Const(u64Const >> constant.uConst); break; 392 case EbtInt64: returnValue.setU64Const(u64Const >> constant.i64Const); break; 393 case EbtUint64: returnValue.setU64Const(u64Const >> constant.u64Const); break; 394 default: assert(false && "Default missing"); 395 } 396 break; 397 default: assert(false && "Default missing"); 398 } 399 400 return returnValue; 401 } 402 403 TConstUnion operator<<(const TConstUnion& constant) const 404 { 405 TConstUnion returnValue; 406 switch (type) { 407 case EbtInt: 408 switch (constant.type) { 409 case EbtInt: returnValue.setIConst(iConst << constant.iConst); break; 410 case EbtUint: returnValue.setIConst(iConst << constant.uConst); break; 411 case EbtInt64: returnValue.setIConst(iConst << constant.i64Const); break; 412 case EbtUint64: returnValue.setIConst(iConst << constant.u64Const); break; 413 default: assert(false && "Default missing"); 414 } 415 break; 416 case EbtUint: 417 switch (constant.type) { 418 case EbtInt: returnValue.setUConst(uConst << constant.iConst); break; 419 case EbtUint: returnValue.setUConst(uConst << constant.uConst); break; 420 case EbtInt64: returnValue.setUConst(uConst << constant.i64Const); break; 421 case EbtUint64: returnValue.setUConst(uConst << constant.u64Const); break; 422 default: assert(false && "Default missing"); 423 } 424 break; 425 case EbtInt64: 426 switch (constant.type) { 427 case EbtInt: returnValue.setI64Const(i64Const << constant.iConst); break; 428 case EbtUint: returnValue.setI64Const(i64Const << constant.uConst); break; 429 case EbtInt64: returnValue.setI64Const(i64Const << constant.i64Const); break; 430 case EbtUint64: returnValue.setI64Const(i64Const << constant.u64Const); break; 431 default: assert(false && "Default missing"); 432 } 433 break; 434 case EbtUint64: 435 switch (constant.type) { 436 case EbtInt: returnValue.setU64Const(u64Const << constant.iConst); break; 437 case EbtUint: returnValue.setU64Const(u64Const << constant.uConst); break; 438 case EbtInt64: returnValue.setU64Const(u64Const << constant.i64Const); break; 439 case EbtUint64: returnValue.setU64Const(u64Const << constant.u64Const); break; 440 default: assert(false && "Default missing"); 441 } 442 break; 443 default: assert(false && "Default missing"); 444 } 445 446 return returnValue; 447 } 448 449 TConstUnion operator&(const TConstUnion& constant) const 450 { 451 TConstUnion returnValue; 452 assert(type == constant.type); 453 switch (type) { 454 case EbtInt: returnValue.setIConst(iConst & constant.iConst); break; 455 case EbtUint: returnValue.setUConst(uConst & constant.uConst); break; 456 case EbtInt64: returnValue.setI64Const(i64Const & constant.i64Const); break; 457 case EbtUint64: returnValue.setU64Const(u64Const & constant.u64Const); break; 458 default: assert(false && "Default missing"); 459 } 460 461 return returnValue; 462 } 463 464 TConstUnion operator|(const TConstUnion& constant) const 465 { 466 TConstUnion returnValue; 467 assert(type == constant.type); 468 switch (type) { 469 case EbtInt: returnValue.setIConst(iConst | constant.iConst); break; 470 case EbtUint: returnValue.setUConst(uConst | constant.uConst); break; 471 case EbtInt64: returnValue.setI64Const(i64Const | constant.i64Const); break; 472 case EbtUint64: returnValue.setU64Const(u64Const | constant.u64Const); break; 473 default: assert(false && "Default missing"); 474 } 475 476 return returnValue; 477 } 478 479 TConstUnion operator^(const TConstUnion& constant) const 480 { 481 TConstUnion returnValue; 482 assert(type == constant.type); 483 switch (type) { 484 case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break; 485 case EbtUint: returnValue.setUConst(uConst ^ constant.uConst); break; 486 case EbtInt64: returnValue.setI64Const(i64Const ^ constant.i64Const); break; 487 case EbtUint64: returnValue.setU64Const(u64Const ^ constant.u64Const); break; 488 default: assert(false && "Default missing"); 489 } 490 491 return returnValue; 492 } 493 494 TConstUnion operator~() const 495 { 496 TConstUnion returnValue; 497 switch (type) { 498 case EbtInt: returnValue.setIConst(~iConst); break; 499 case EbtUint: returnValue.setUConst(~uConst); break; 500 case EbtInt64: returnValue.setI64Const(~i64Const); break; 501 case EbtUint64: returnValue.setU64Const(~u64Const); break; 502 default: assert(false && "Default missing"); 503 } 504 505 return returnValue; 506 } 507 508 TConstUnion operator&&(const TConstUnion& constant) const 509 { 510 TConstUnion returnValue; 511 assert(type == constant.type); 512 switch (type) { 513 case EbtBool: returnValue.setBConst(bConst && constant.bConst); break; 514 default: assert(false && "Default missing"); 515 } 516 517 return returnValue; 518 } 519 520 TConstUnion operator||(const TConstUnion& constant) const 521 { 522 TConstUnion returnValue; 523 assert(type == constant.type); 524 switch (type) { 525 case EbtBool: returnValue.setBConst(bConst || constant.bConst); break; 526 default: assert(false && "Default missing"); 527 } 528 529 return returnValue; 530 } 531 532 TBasicType getType() const { return type; } 533 534 private: 535 union { 536 int iConst; // used for ivec, scalar ints 537 unsigned int uConst; // used for uvec, scalar uints 538 long long i64Const; // used for i64vec, scalar int64s 539 unsigned long long u64Const; // used for u64vec, scalar uint64s 540 bool bConst; // used for bvec, scalar bools 541 double dConst; // used for vec, dvec, mat, dmat, scalar floats and doubles 542 const TString* sConst; // string constant 543 }; 544 545 TBasicType type; 546 }; 547 548 // Encapsulate having a pointer to an array of TConstUnion, 549 // which only needs to be allocated if its size is going to be 550 // bigger than 0. 551 // 552 // One convenience is being able to use [] to go inside the array, instead 553 // of C++ assuming it as an array of pointers to vectors. 554 // 555 // General usage is that the size is known up front, and it is 556 // created once with the proper size. 557 // 558 class TConstUnionArray { 559 public: 560 POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) 561 562 TConstUnionArray() : unionArray(nullptr) { } 563 virtual ~TConstUnionArray() { } 564 565 explicit TConstUnionArray(int size) 566 { 567 if (size == 0) 568 unionArray = nullptr; 569 else 570 unionArray = new TConstUnionVector(size); 571 } 572 TConstUnionArray(const TConstUnionArray& a) : unionArray(a.unionArray) { } 573 TConstUnionArray(const TConstUnionArray& a, int start, int size) 574 { 575 unionArray = new TConstUnionVector(size); 576 for (int i = 0; i < size; ++i) 577 (*unionArray)[i] = a[start + i]; 578 } 579 580 // Use this constructor for a smear operation 581 TConstUnionArray(int size, const TConstUnion& val) 582 { 583 unionArray = new TConstUnionVector(size, val); 584 } 585 586 int size() const { return unionArray ? (int)unionArray->size() : 0; } 587 TConstUnion& operator[](size_t index) { return (*unionArray)[index]; } 588 const TConstUnion& operator[](size_t index) const { return (*unionArray)[index]; } 589 bool operator==(const TConstUnionArray& rhs) const 590 { 591 // this includes the case that both are unallocated 592 if (unionArray == rhs.unionArray) 593 return true; 594 595 if (! unionArray || ! rhs.unionArray) 596 return false; 597 598 if (! unionArray || ! rhs.unionArray) 599 return false; 600 601 return *unionArray == *rhs.unionArray; 602 } 603 bool operator!=(const TConstUnionArray& rhs) const { return ! operator==(rhs); } 604 605 double dot(const TConstUnionArray& rhs) 606 { 607 assert(rhs.unionArray->size() == unionArray->size()); 608 double sum = 0.0; 609 610 for (size_t comp = 0; comp < unionArray->size(); ++comp) 611 sum += (*this)[comp].getDConst() * rhs[comp].getDConst(); 612 613 return sum; 614 } 615 616 bool empty() const { return unionArray == nullptr; } 617 618 protected: 619 typedef TVector<TConstUnion> TConstUnionVector; 620 TConstUnionVector* unionArray; 621 }; 622 623 } // end namespace glslang 624 625 #endif // _CONSTANT_UNION_INCLUDED_ 626