@@ -508,6 +508,26 @@ public: \
508
508
// / A base class for custom path elements that store numeric values.
509
509
template <unsigned NumValues>
510
510
class StoredIntegerElement : public LocatorPathElt {
511
+ static constexpr unsigned valueWidth () {
512
+ switch (NumValues) {
513
+ default :
514
+ return 16 ;
515
+ case 1 :
516
+ return 64 ;
517
+ case 2 :
518
+ return 32 ;
519
+ }
520
+ }
521
+
522
+ template <unsigned Index = 0 ,
523
+ typename = typename std::enable_if<(Index < NumValues)>::type>
524
+ static uint64_t packValue (unsigned value) {
525
+ return uint64_t (value) << (valueWidth () * (NumValues - Index - 1 ));
526
+ }
527
+
528
+ static constexpr uint64_t valueMask =
529
+ valueWidth () < 64 ? (1ULL << valueWidth()) - 1 : -1ULL ;
530
+
511
531
public:
512
532
template <unsigned NumNumericInputs = NumValues,
513
533
typename = typename std::enable_if<NumNumericInputs == 1 >::type>
@@ -519,7 +539,7 @@ class StoredIntegerElement: public LocatorPathElt {
519
539
template <unsigned NumNumericInputs = NumValues,
520
540
typename = typename std::enable_if<NumNumericInputs == 2 >::type>
521
541
StoredIntegerElement (ConstraintLocator::PathElementKind kind, unsigned value0, unsigned value1)
522
- : LocatorPathElt(kind, (value0 << 16 | value1)) {
542
+ : LocatorPathElt(kind, packValue< 0 > (value0) | packValue< 1 >( value1)) {
523
543
assert (value0 == getValue<0 >() && " value0 truncated" );
524
544
assert (value1 == getValue<1 >() && " value1 truncated" );
525
545
}
@@ -528,7 +548,7 @@ class StoredIntegerElement: public LocatorPathElt {
528
548
typename = typename std::enable_if<NumNumericInputs == 3 >::type>
529
549
StoredIntegerElement (ConstraintLocator::PathElementKind kind, unsigned value0,
530
550
unsigned value1, unsigned value2)
531
- : LocatorPathElt(kind, uint64_t (value0) << 32 | uint64_t (value1) << 16 | uint64_t (value2)) {
551
+ : LocatorPathElt(kind, packValue< 0 > (value0) | packValue< 1 > (value1) | packValue< 2 > (value2)) {
532
552
assert (value0 == getValue<0 >() && " value0 truncated" );
533
553
assert (value1 == getValue<1 >() && " value1 truncated" );
534
554
assert (value2 == getValue<2 >() && " value2 truncated" );
@@ -537,13 +557,13 @@ class StoredIntegerElement: public LocatorPathElt {
537
557
// / Retrieve a value associated with the path element.
538
558
template <unsigned Index = 0 ,
539
559
typename = typename std::enable_if<(Index < NumValues)>::type>
540
- unsigned getValue () const {
541
- // We pack values into 16 bit components of the storage, with value0
560
+ uint64_t getValue () const {
561
+ // We pack values into equally-sized components of the storage, with value0
542
562
// being stored in the upper bits, valueN in the lower bits. Therefore we
543
563
// need to shift out any extra values in the lower bits.
544
564
auto extraValues = NumValues - Index - 1 ;
545
- auto value = getRawStorage () >> (extraValues * 16 );
546
- return value & 0xFFFF ;
565
+ auto value = getRawStorage () >> (extraValues * valueWidth () );
566
+ return value & valueMask ;
547
567
}
548
568
};
549
569
0 commit comments