1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 // A set of integers in the range [0..N], for some N defined by the "Env" (via "BitSetTraits").
7 // Represented as a pointer-sized item. If N bits can fit in this item, the representation is "direct"; otherwise,
8 // the item is a pointer to an array of K size_t's, where K is the number of size_t's necessary to hold N bits.
10 #ifndef bitSetAsShortLong_DEFINED
11 #define bitSetAsShortLong_DEFINED 1
14 #include "compilerbitsettraits.h"
16 typedef size_t* BitSetShortLongRep;
18 template <typename Env, typename BitSetTraits>
19 class BitSetOps</*BitSetType*/ BitSetShortLongRep,
20 /*Brand*/ BSShortLong,
22 /*BitSetTraits*/ BitSetTraits>
25 typedef BitSetShortLongRep Rep;
28 static const unsigned BitsInSizeT = sizeof(size_t) * BitSetSupport::BitsInByte;
30 inline static bool IsShort(Env env)
32 return BitSetTraits::GetArrSize(env, sizeof(size_t)) <= 1;
35 // The operations on the "long" (pointer-to-array-of-size_t) versions of the representation.
36 static void AssignLong(Env env, BitSetShortLongRep& lhs, BitSetShortLongRep rhs);
37 static BitSetShortLongRep MakeSingletonLong(Env env, unsigned bitNum);
38 static BitSetShortLongRep MakeCopyLong(Env env, BitSetShortLongRep bs);
39 static bool IsEmptyLong(Env env, BitSetShortLongRep bs);
40 static unsigned CountLong(Env env, BitSetShortLongRep bs);
41 static bool IsEmptyUnionLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2);
42 static void UnionDLong(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2);
43 static void DiffDLong(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2);
44 static void AddElemDLong(Env env, BitSetShortLongRep& bs, unsigned i);
45 static bool TryAddElemDLong(Env env, BitSetShortLongRep& bs, unsigned i);
46 static void RemoveElemDLong(Env env, BitSetShortLongRep& bs, unsigned i);
47 static void ClearDLong(Env env, BitSetShortLongRep& bs);
48 static BitSetShortLongRep MakeUninitArrayBits(Env env);
49 static BitSetShortLongRep MakeEmptyArrayBits(Env env);
50 static BitSetShortLongRep MakeFullArrayBits(Env env);
51 static bool IsMemberLong(Env env, BitSetShortLongRep bs, unsigned i);
52 static bool EqualLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2);
53 static bool IsSubsetLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2);
54 static bool IsEmptyIntersectionLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2);
55 static void IntersectionDLong(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2);
56 static void DataFlowDLong(Env env,
57 BitSetShortLongRep& out,
58 const BitSetShortLongRep gen,
59 const BitSetShortLongRep in);
60 static void LivenessDLong(Env env,
61 BitSetShortLongRep& in,
62 const BitSetShortLongRep def,
63 const BitSetShortLongRep use,
64 const BitSetShortLongRep out);
66 static const char* ToStringLong(Env env, BitSetShortLongRep bs);
70 inline static BitSetShortLongRep UninitVal()
75 static bool MayBeUninit(BitSetShortLongRep bs)
77 return bs == UninitVal();
80 static void Assign(Env env, BitSetShortLongRep& lhs, BitSetShortLongRep rhs)
82 // We can't assert that rhs != UninitVal in the Short case, because in that
83 // case it's a legal value.
89 else if (lhs == UninitVal())
91 assert(rhs != UninitVal());
92 lhs = MakeCopy(env, rhs);
96 AssignLong(env, lhs, rhs);
100 static void AssignAllowUninitRhs(Env env, BitSetShortLongRep& lhs, BitSetShortLongRep rhs)
107 else if (rhs == UninitVal())
111 else if (lhs == UninitVal())
113 lhs = MakeCopy(env, rhs);
117 AssignLong(env, lhs, rhs);
121 static void AssignNoCopy(Env env, BitSetShortLongRep& lhs, BitSetShortLongRep rhs)
126 static void ClearD(Env env, BitSetShortLongRep& bs)
130 bs = (BitSetShortLongRep) nullptr;
134 assert(bs != UninitVal());
139 static BitSetShortLongRep MakeSingleton(Env env, unsigned bitNum)
141 assert(bitNum < BitSetTraits::GetSize(env));
144 return BitSetShortLongRep(((size_t)1) << bitNum);
148 return MakeSingletonLong(env, bitNum);
152 static BitSetShortLongRep MakeCopy(Env env, BitSetShortLongRep bs)
160 return MakeCopyLong(env, bs);
164 static bool IsEmpty(Env env, BitSetShortLongRep bs)
168 return bs == nullptr;
172 assert(bs != UninitVal());
173 return IsEmptyLong(env, bs);
177 static unsigned Count(Env env, BitSetShortLongRep bs)
181 return BitSetSupport::CountBitsInIntegral(size_t(bs));
185 assert(bs != UninitVal());
186 return CountLong(env, bs);
190 static bool IsEmptyUnion(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
194 return (((size_t)bs1) | ((size_t)bs2)) == 0;
198 return IsEmptyUnionLong(env, bs1, bs2);
202 static void UnionD(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2)
206 bs1 = (BitSetShortLongRep)(((size_t)bs1) | ((size_t)bs2));
210 UnionDLong(env, bs1, bs2);
213 static BitSetShortLongRep Union(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
215 BitSetShortLongRep res = MakeCopy(env, bs1);
216 UnionD(env, res, bs2);
220 static void DiffD(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2)
224 bs1 = (BitSetShortLongRep)(((size_t)bs1) & (~(size_t)bs2));
228 DiffDLong(env, bs1, bs2);
231 static BitSetShortLongRep Diff(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
233 BitSetShortLongRep res = MakeCopy(env, bs1);
234 DiffD(env, res, bs2);
238 static void RemoveElemD(Env env, BitSetShortLongRep& bs, unsigned i)
240 assert(i < BitSetTraits::GetSize(env));
243 size_t mask = ((size_t)1) << i;
245 bs = (BitSetShortLongRep)(((size_t)bs) & mask);
249 assert(bs != UninitVal());
250 RemoveElemDLong(env, bs, i);
253 static BitSetShortLongRep RemoveElem(Env env, BitSetShortLongRep bs, unsigned i)
255 BitSetShortLongRep res = MakeCopy(env, bs);
256 RemoveElemD(env, res, i);
260 static void AddElemD(Env env, BitSetShortLongRep& bs, unsigned i)
262 assert(i < BitSetTraits::GetSize(env));
265 size_t mask = ((size_t)1) << i;
266 bs = (BitSetShortLongRep)(((size_t)bs) | mask);
270 AddElemDLong(env, bs, i);
273 static BitSetShortLongRep AddElem(Env env, BitSetShortLongRep bs, unsigned i)
275 BitSetShortLongRep res = MakeCopy(env, bs);
276 AddElemD(env, res, i);
280 static bool TryAddElemD(Env env, BitSetShortLongRep& bs, unsigned i)
282 assert(i < BitSetTraits::GetSize(env));
285 size_t mask = ((size_t)1) << i;
286 size_t bits = (size_t)bs;
287 bool added = (bits & mask) == 0;
288 bs = (BitSetShortLongRep)(bits | mask);
293 return TryAddElemDLong(env, bs, i);
297 static bool IsMember(Env env, const BitSetShortLongRep bs, unsigned i)
299 assert(i < BitSetTraits::GetSize(env));
302 size_t mask = ((size_t)1) << i;
303 return (((size_t)bs) & mask) != 0;
307 assert(bs != UninitVal());
308 return IsMemberLong(env, bs, i);
312 static void IntersectionD(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2)
316 (size_t&)bs1 &= (size_t)bs2;
320 IntersectionDLong(env, bs1, bs2);
324 static BitSetShortLongRep Intersection(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
326 BitSetShortLongRep res = MakeCopy(env, bs1);
327 IntersectionD(env, res, bs2);
330 static bool IsEmptyIntersection(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
334 return (((size_t)bs1) & ((size_t)bs2)) == 0;
338 return IsEmptyIntersectionLong(env, bs1, bs2);
342 static void DataFlowD(Env env, BitSetShortLongRep& out, const BitSetShortLongRep gen, const BitSetShortLongRep in)
346 (size_t&)out = (size_t)out & ((size_t)gen | (size_t)in);
350 DataFlowDLong(env, out, gen, in);
354 static void LivenessD(Env env,
355 BitSetShortLongRep& in,
356 const BitSetShortLongRep def,
357 const BitSetShortLongRep use,
358 const BitSetShortLongRep out)
362 (size_t&)in = (size_t)use | ((size_t)out & ~(size_t)def);
366 LivenessDLong(env, in, def, use, out);
370 static bool IsSubset(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
374 size_t u1 = (size_t)bs1;
375 size_t u2 = (size_t)bs2;
376 return (u1 & u2) == u1;
380 return IsSubsetLong(env, bs1, bs2);
384 static bool Equal(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
388 return (size_t)bs1 == (size_t)bs2;
392 return EqualLong(env, bs1, bs2);
397 // Returns a string valid until the allocator releases the memory.
398 static const char* ToString(Env env, BitSetShortLongRep bs)
402 assert(sizeof(BitSetShortLongRep) == sizeof(size_t));
403 const int CharsForSizeT = sizeof(size_t) * 2;
405 const int ShortAllocSize = CharsForSizeT + 4;
406 res = (char*)BitSetTraits::DebugAlloc(env, ShortAllocSize);
407 size_t bits = (size_t)bs;
408 unsigned remaining = ShortAllocSize;
410 if (sizeof(size_t) == sizeof(int64_t))
412 sprintf_s(ptr, remaining, "%016llX", bits);
416 assert(sizeof(size_t) == sizeof(int));
417 sprintf_s(ptr, remaining, "%08X", bits);
423 return ToStringLong(env, bs);
428 static BitSetShortLongRep MakeEmpty(Env env)
436 return MakeEmptyArrayBits(env);
440 static BitSetShortLongRep MakeFull(Env env)
444 // Can't just shift by numBits+1, since that might be 32 (and (1 << 32( == 1, for an unsigned).
445 unsigned numBits = BitSetTraits::GetSize(env);
446 if (numBits == BitsInSizeT)
448 // Can't use the implementation below to get all 1's...
449 return BitSetShortLongRep(size_t(-1));
453 return BitSetShortLongRep((size_t(1) << numBits) - 1);
458 return MakeFullArrayBits(env);
464 // The BitSet that we're iterating over. This is updated to point at the current
465 // size_t set of bits.
466 BitSetShortLongRep m_bs;
468 // The end of the iteration.
469 BitSetShortLongRep m_bsEnd;
471 // The remaining bits to be iterated over in the current size_t set of bits.
472 // In the "short" case, these are all the remaining bits.
473 // In the "long" case, these are remaining bits in the current element;
474 // these and the bits in the remaining elements comprise the remaining bits.
477 // The number of bits that have already been iterated over (set or clear). If you
478 // add this to the bit number of the next bit in "m_bits", you get the proper bit number of that
479 // bit in "m_bs". This is only updated when we increment m_bs.
483 Iter(Env env, const BitSetShortLongRep& bs) : m_bs(bs), m_bitNum(0)
485 if (BitSetOps::IsShort(env))
489 // Set the iteration end condition, valid even though this is not a pointer in the short case.
494 assert(bs != BitSetOps::UninitVal());
497 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
502 bool NextElem(unsigned* pElem)
504 #if BITSET_TRACK_OPCOUNTS
505 BitSetStaticsImpl::RecordOp(BitSetStaticsImpl::BSOP_NextBit);
512 static_assert_no_msg(sizeof(size_t) == 8);
513 hasBit = BitScanForward64(&nextBit, m_bits);
515 static_assert_no_msg(sizeof(size_t) == 4);
516 hasBit = BitScanForward(&nextBit, m_bits);
519 // If there's a bit, doesn't matter if we're short or long.
522 *pElem = m_bitNum + nextBit;
523 m_bits &= ~(((size_t)1) << nextBit); // clear bit we just found so we don't find it again
528 // Go to the next size_t bit element. For short bitsets, this will hit the end condition
536 // If we get here, it's not a short type, so get the next size_t element.
537 m_bitNum += sizeof(size_t) * BitSetSupport::BitsInByte;
544 typedef const BitSetShortLongRep& ValArgType;
545 typedef BitSetShortLongRep RetValType;
548 template <typename Env, typename BitSetTraits>
549 void BitSetOps</*BitSetType*/ BitSetShortLongRep,
550 /*Brand*/ BSShortLong,
552 /*BitSetTraits*/ BitSetTraits>::AssignLong(Env env, BitSetShortLongRep& lhs, BitSetShortLongRep rhs)
554 assert(!IsShort(env));
555 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
556 for (unsigned i = 0; i < len; i++)
562 template <typename Env, typename BitSetTraits>
563 BitSetShortLongRep BitSetOps</*BitSetType*/ BitSetShortLongRep,
564 /*Brand*/ BSShortLong,
566 /*BitSetTraits*/ BitSetTraits>::MakeSingletonLong(Env env, unsigned bitNum)
568 assert(!IsShort(env));
569 BitSetShortLongRep res = MakeEmptyArrayBits(env);
570 unsigned index = bitNum / BitsInSizeT;
571 res[index] = ((size_t)1) << (bitNum % BitsInSizeT);
575 template <typename Env, typename BitSetTraits>
576 BitSetShortLongRep BitSetOps</*BitSetType*/ BitSetShortLongRep,
577 /*Brand*/ BSShortLong,
579 /*BitSetTraits*/ BitSetTraits>::MakeCopyLong(Env env, BitSetShortLongRep bs)
581 assert(!IsShort(env));
582 BitSetShortLongRep res = MakeUninitArrayBits(env);
583 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
584 for (unsigned i = 0; i < len; i++)
591 template <typename Env, typename BitSetTraits>
592 bool BitSetOps</*BitSetType*/ BitSetShortLongRep,
593 /*Brand*/ BSShortLong,
595 /*BitSetTraits*/ BitSetTraits>::IsEmptyLong(Env env, BitSetShortLongRep bs)
597 assert(!IsShort(env));
598 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
599 for (unsigned i = 0; i < len; i++)
609 template <typename Env, typename BitSetTraits>
610 unsigned BitSetOps</*BitSetType*/ BitSetShortLongRep,
611 /*Brand*/ BSShortLong,
613 /*BitSetTraits*/ BitSetTraits>::CountLong(Env env, BitSetShortLongRep bs)
615 assert(!IsShort(env));
616 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
618 for (unsigned i = 0; i < len; i++)
620 res += BitSetSupport::CountBitsInIntegral(bs[i]);
625 template <typename Env, typename BitSetTraits>
626 void BitSetOps</*BitSetType*/ BitSetShortLongRep,
627 /*Brand*/ BSShortLong,
629 /*BitSetTraits*/ BitSetTraits>::UnionDLong(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2)
631 assert(!IsShort(env));
632 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
633 for (unsigned i = 0; i < len; i++)
639 template <typename Env, typename BitSetTraits>
640 void BitSetOps</*BitSetType*/ BitSetShortLongRep,
641 /*Brand*/ BSShortLong,
643 /*BitSetTraits*/ BitSetTraits>::DiffDLong(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2)
645 assert(!IsShort(env));
646 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
647 for (unsigned i = 0; i < len; i++)
653 template <typename Env, typename BitSetTraits>
654 void BitSetOps</*BitSetType*/ BitSetShortLongRep,
655 /*Brand*/ BSShortLong,
657 /*BitSetTraits*/ BitSetTraits>::AddElemDLong(Env env, BitSetShortLongRep& bs, unsigned i)
659 assert(!IsShort(env));
660 unsigned index = i / BitsInSizeT;
661 size_t mask = ((size_t)1) << (i % BitsInSizeT);
665 template <typename Env, typename BitSetTraits>
666 bool BitSetOps</*BitSetType*/ BitSetShortLongRep,
667 /*Brand*/ BSShortLong,
669 /*BitSetTraits*/ BitSetTraits>::TryAddElemDLong(Env env, BitSetShortLongRep& bs, unsigned i)
671 assert(!IsShort(env));
672 unsigned index = i / BitsInSizeT;
673 size_t mask = ((size_t)1) << (i % BitsInSizeT);
674 size_t bits = bs[index];
675 bool added = (bits & mask) == 0;
676 bs[index] = bits | mask;
680 template <typename Env, typename BitSetTraits>
681 void BitSetOps</*BitSetType*/ BitSetShortLongRep,
682 /*Brand*/ BSShortLong,
684 /*BitSetTraits*/ BitSetTraits>::RemoveElemDLong(Env env, BitSetShortLongRep& bs, unsigned i)
686 assert(!IsShort(env));
687 unsigned index = i / BitsInSizeT;
688 size_t mask = ((size_t)1) << (i % BitsInSizeT);
693 template <typename Env, typename BitSetTraits>
694 void BitSetOps</*BitSetType*/ BitSetShortLongRep,
695 /*Brand*/ BSShortLong,
697 /*BitSetTraits*/ BitSetTraits>::ClearDLong(Env env, BitSetShortLongRep& bs)
699 assert(!IsShort(env));
700 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
701 for (unsigned i = 0; i < len; i++)
707 template <typename Env, typename BitSetTraits>
708 BitSetShortLongRep BitSetOps</*BitSetType*/ BitSetShortLongRep,
709 /*Brand*/ BSShortLong,
711 /*BitSetTraits*/ BitSetTraits>::MakeUninitArrayBits(Env env)
713 assert(!IsShort(env));
714 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
715 assert(len > 1); // Or else would not require an array.
716 return (BitSetShortLongRep)(BitSetTraits::Alloc(env, len * sizeof(size_t)));
719 template <typename Env, typename BitSetTraits>
720 BitSetShortLongRep BitSetOps</*BitSetType*/ BitSetShortLongRep,
721 /*Brand*/ BSShortLong,
723 /*BitSetTraits*/ BitSetTraits>::MakeEmptyArrayBits(Env env)
725 assert(!IsShort(env));
726 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
727 assert(len > 1); // Or else would not require an array.
728 BitSetShortLongRep res = (BitSetShortLongRep)(BitSetTraits::Alloc(env, len * sizeof(size_t)));
729 for (unsigned i = 0; i < len; i++)
736 template <typename Env, typename BitSetTraits>
737 BitSetShortLongRep BitSetOps</*BitSetType*/ BitSetShortLongRep,
738 /*Brand*/ BSShortLong,
740 /*BitSetTraits*/ BitSetTraits>::MakeFullArrayBits(Env env)
742 assert(!IsShort(env));
743 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
744 assert(len > 1); // Or else would not require an array.
745 BitSetShortLongRep res = (BitSetShortLongRep)(BitSetTraits::Alloc(env, len * sizeof(size_t)));
746 for (unsigned i = 0; i < len - 1; i++)
750 // Start with all ones, shift in zeros in the last elem.
751 unsigned lastElemBits = (BitSetTraits::GetSize(env) - 1) % BitsInSizeT + 1;
752 res[len - 1] = (size_t(-1) >> (BitsInSizeT - lastElemBits));
756 template <typename Env, typename BitSetTraits>
757 bool BitSetOps</*BitSetType*/ BitSetShortLongRep,
758 /*Brand*/ BSShortLong,
760 /*BitSetTraits*/ BitSetTraits>::IsMemberLong(Env env, BitSetShortLongRep bs, unsigned i)
762 assert(!IsShort(env));
763 unsigned index = i / BitsInSizeT;
764 unsigned bitInElem = (i % BitsInSizeT);
765 size_t mask = ((size_t)1) << bitInElem;
766 return (bs[index] & mask) != 0;
769 template <typename Env, typename BitSetTraits>
770 void BitSetOps</*BitSetType*/ BitSetShortLongRep,
771 /*Brand*/ BSShortLong,
773 /*BitSetTraits*/ BitSetTraits>::IntersectionDLong(Env env,
774 BitSetShortLongRep& bs1,
775 BitSetShortLongRep bs2)
777 assert(!IsShort(env));
778 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
779 for (unsigned i = 0; i < len; i++)
785 template <typename Env, typename BitSetTraits>
786 bool BitSetOps</*BitSetType*/ BitSetShortLongRep,
787 /*Brand*/ BSShortLong,
789 /*BitSetTraits*/ BitSetTraits>::IsEmptyIntersectionLong(Env env,
790 BitSetShortLongRep bs1,
791 BitSetShortLongRep bs2)
793 assert(!IsShort(env));
794 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
795 for (unsigned i = 0; i < len; i++)
797 if ((bs1[i] & bs2[i]) != 0)
805 template <typename Env, typename BitSetTraits>
806 bool BitSetOps</*BitSetType*/ BitSetShortLongRep,
807 /*Brand*/ BSShortLong,
809 /*BitSetTraits*/ BitSetTraits>::IsEmptyUnionLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
811 assert(!IsShort(env));
812 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
813 for (unsigned i = 0; i < len; i++)
815 if ((bs1[i] | bs2[i]) != 0)
823 template <typename Env, typename BitSetTraits>
824 void BitSetOps</*BitSetType*/ BitSetShortLongRep,
825 /*Brand*/ BSShortLong,
827 /*BitSetTraits*/ BitSetTraits>::DataFlowDLong(Env env,
828 BitSetShortLongRep& out,
829 const BitSetShortLongRep gen,
830 const BitSetShortLongRep in)
832 assert(!IsShort(env));
833 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
834 for (unsigned i = 0; i < len; i++)
836 out[i] = out[i] & (gen[i] | in[i]);
840 template <typename Env, typename BitSetTraits>
841 void BitSetOps</*BitSetType*/ BitSetShortLongRep,
842 /*Brand*/ BSShortLong,
844 /*BitSetTraits*/ BitSetTraits>::LivenessDLong(Env env,
845 BitSetShortLongRep& in,
846 const BitSetShortLongRep def,
847 const BitSetShortLongRep use,
848 const BitSetShortLongRep out)
850 assert(!IsShort(env));
851 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
852 for (unsigned i = 0; i < len; i++)
854 in[i] = use[i] | (out[i] & ~def[i]);
858 template <typename Env, typename BitSetTraits>
859 bool BitSetOps</*BitSetType*/ BitSetShortLongRep,
860 /*Brand*/ BSShortLong,
862 /*BitSetTraits*/ BitSetTraits>::EqualLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
864 assert(!IsShort(env));
865 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
866 for (unsigned i = 0; i < len; i++)
868 if (bs1[i] != bs2[i])
876 template <typename Env, typename BitSetTraits>
877 bool BitSetOps</*BitSetType*/ BitSetShortLongRep,
878 /*Brand*/ BSShortLong,
880 /*BitSetTraits*/ BitSetTraits>::IsSubsetLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
882 assert(!IsShort(env));
883 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
884 for (unsigned i = 0; i < len; i++)
886 if ((bs1[i] & bs2[i]) != bs1[i])
895 template <typename Env, typename BitSetTraits>
896 const char* BitSetOps</*BitSetType*/ BitSetShortLongRep,
897 /*Brand*/ BSShortLong,
899 /*BitSetTraits*/ BitSetTraits>::ToStringLong(Env env, BitSetShortLongRep bs)
901 assert(!IsShort(env));
902 unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
903 const int CharsForSizeT = sizeof(size_t) * 2;
904 unsigned allocSz = len * CharsForSizeT + 4;
905 unsigned remaining = allocSz;
906 char* res = (char*)BitSetTraits::DebugAlloc(env, allocSz);
908 for (unsigned i = len; 0 < i; i--)
910 size_t bits = bs[i - 1];
911 for (unsigned bytesDone = 0; bytesDone < sizeof(size_t); bytesDone += sizeof(unsigned))
913 unsigned bits0 = (unsigned)bits;
914 sprintf_s(temp, remaining, "%08X", bits0);
918 assert(sizeof(unsigned) == 4);
919 // Doing this twice by 16, rather than once by 32, avoids warnings when size_t == unsigned.
928 #endif // bitSetAsShortLong_DEFINED