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 #ifndef bitSetAsUint64InClass_DEFINED
6 #define bitSetAsUint64InClass_DEFINED 1
9 #include "bitsetasuint64.h"
10 #include "stdmacros.h"
12 template <typename Env, typename BitSetTraits>
13 class BitSetUint64ValueRetType;
15 template <typename Env, typename BitSetTraits>
16 class BitSetUint64Iter;
18 template <typename Env, typename BitSetTraits>
22 typedef BitSetUint64<Env, BitSetTraits> Rep;
25 friend class BitSetOps</*BitSetType*/ BitSetUint64<Env, BitSetTraits>,
26 /*Brand*/ BSUInt64Class,
28 /*BitSetTraits*/ BitSetTraits>;
30 friend class BitSetUint64ValueRetType<Env, BitSetTraits>;
38 typedef BitSetOps<UINT64, BSUInt64, Env, BitSetTraits> Uint64BitSetOps;
40 void CheckEpoch(Env env) const
43 assert(m_epoch == BitSetTraits::GetEpoch(env));
47 bool operator==(const BitSetUint64& bs) const
49 return m_bits == bs.m_bits
51 && m_epoch == bs.m_epoch
57 BitSetUint64& operator=(const BitSetUint64& bs)
66 BitSetUint64(const BitSetUint64& bs)
75 // Return the number of bits set in the BitSet.
76 inline unsigned Count(Env env) const
79 return Uint64BitSetOps::Count(env, m_bits);
82 inline void DiffD(Env env, const BitSetUint64& bs2)
86 Uint64BitSetOps::DiffD(env, m_bits, bs2.m_bits);
89 inline BitSetUint64 Diff(Env env, const BitSetUint64& bs2) const
93 BitSetUint64 res(*this);
94 Uint64BitSetOps::DiffD(env, res.m_bits, bs2.m_bits);
98 inline void RemoveElemD(Env env, unsigned i)
101 Uint64BitSetOps::RemoveElemD(env, m_bits, i);
104 inline BitSetUint64 RemoveElem(Env env, unsigned i) const
107 BitSetUint64 res(*this);
108 Uint64BitSetOps::RemoveElemD(env, res.m_bits, i);
112 inline void AddElemD(Env env, unsigned i)
115 Uint64BitSetOps::AddElemD(env, m_bits, i);
118 inline BitSetUint64 AddElem(Env env, unsigned i) const
121 BitSetUint64 res(*this);
122 Uint64BitSetOps::AddElemD(env, res.m_bits, i);
126 inline bool IsMember(Env env, unsigned i) const
129 return Uint64BitSetOps::IsMember(env, m_bits, i);
132 inline void IntersectionD(Env env, const BitSetUint64& bs2)
136 m_bits = m_bits & bs2.m_bits;
139 inline BitSetUint64 Intersection(Env env, const BitSetUint64& bs2) const
143 BitSetUint64 res(*this);
144 Uint64BitSetOps::IntersectionD(env, res.m_bits, bs2.m_bits);
148 inline bool IsEmptyUnion(Env env, const BitSetUint64& bs2) const
152 return Uint64BitSetOps::IsEmptyUnion(env, m_bits, bs2.m_bits);
155 inline void UnionD(Env env, const BitSetUint64& bs2)
159 Uint64BitSetOps::UnionD(env, m_bits, bs2.m_bits);
162 inline BitSetUint64 Union(Env env, const BitSetUint64& bs2) const
166 BitSetUint64 res(*this);
167 Uint64BitSetOps::UnionD(env, res.m_bits, bs2.m_bits);
171 inline void ClearD(Env env)
173 assert(m_epoch == BitSetTraits::GetEpoch(env));
174 Uint64BitSetOps::ClearD(env, m_bits);
177 inline bool IsEmpty(Env env) const
180 return Uint64BitSetOps::IsEmpty(env, m_bits);
183 inline void LivenessD(Env env, const BitSetUint64& def, const BitSetUint64& use, const BitSetUint64& out)
189 return Uint64BitSetOps::LivenessD(env, m_bits, def.m_bits, use.m_bits, out.m_bits);
192 inline bool IsSubset(Env env, const BitSetUint64& bs2) const
196 return Uint64BitSetOps::IsSubset(env, m_bits, bs2.m_bits);
199 inline bool IsEmptyIntersection(Env env, const BitSetUint64& bs2) const
203 return Uint64BitSetOps::IsEmptyIntersection(env, m_bits, bs2.m_bits);
206 inline bool Equal(Env env, const BitSetUint64& bs2) const
210 return Uint64BitSetOps::Equal(env, m_bits, bs2.m_bits);
213 const char* ToString(Env env) const
215 return Uint64BitSetOps::ToString(env, m_bits);
223 , m_epoch(UINT32_MAX) // Undefined.
228 BitSetUint64(Env env, bool full = false)
231 , m_epoch(BitSetTraits::GetEpoch(env))
236 m_bits = Uint64BitSetOps::MakeFull(env);
240 inline BitSetUint64(const BitSetUint64ValueRetType<Env, BitSetTraits>& rt);
242 BitSetUint64(Env env, unsigned bitNum)
243 : m_bits(Uint64BitSetOps::MakeSingleton(env, bitNum))
245 , m_epoch(BitSetTraits::GetEpoch(env))
248 assert(bitNum < BitSetTraits::GetSize(env));
252 template <typename Env, typename BitSetTraits>
253 class BitSetUint64ValueRetType
255 friend class BitSetUint64<Env, BitSetTraits>;
257 BitSetUint64<Env, BitSetTraits> m_bs;
260 BitSetUint64ValueRetType(const BitSetUint64<Env, BitSetTraits>& bs) : m_bs(bs)
265 template <typename Env, typename BitSetTraits>
266 BitSetUint64<Env, BitSetTraits>::BitSetUint64(const BitSetUint64ValueRetType<Env, BitSetTraits>& rt)
267 : m_bits(rt.m_bs.m_bits)
269 , m_epoch(rt.m_bs.m_epoch)
274 template <typename Env, typename BitSetTraits>
275 class BitSetOps</*BitSetType*/ BitSetUint64<Env, BitSetTraits>,
276 /*Brand*/ BSUInt64Class,
278 /*BitSetTraits*/ BitSetTraits>
280 typedef BitSetUint64<Env, BitSetTraits> BST;
281 typedef const BitSetUint64<Env, BitSetTraits>& BSTValArg;
282 typedef BitSetUint64ValueRetType<Env, BitSetTraits> BSTRetVal;
285 static BSTRetVal UninitVal()
287 return BitSetUint64<Env, BitSetTraits>();
290 static bool MayBeUninit(BSTValArg bs)
292 return bs == UninitVal();
295 static void Assign(Env env, BST& lhs, BSTValArg rhs)
300 static void AssignNouninit(Env env, BST& lhs, BSTValArg rhs)
305 static void AssignAllowUninitRhs(Env env, BST& lhs, BSTValArg rhs)
310 static void AssignNoCopy(Env env, BST& lhs, BSTValArg rhs)
315 static void ClearD(Env env, BST& bs)
320 static BSTRetVal MakeSingleton(Env env, unsigned bitNum)
322 assert(bitNum < BitSetTraits::GetSize(env));
323 return BST(env, bitNum);
326 static BSTRetVal MakeCopy(Env env, BSTValArg bs)
331 static bool IsEmpty(Env env, BSTValArg bs)
333 return bs.IsEmpty(env);
336 static unsigned Count(Env env, BSTValArg bs)
338 return bs.Count(env);
341 static bool IsEmptyUnion(Env env, BSTValArg bs1, BSTValArg bs2)
343 return bs1.IsEmptyUnion(env, bs2);
346 static void UnionD(Env env, BST& bs1, BSTValArg bs2)
348 bs1.UnionD(env, bs2);
351 static BSTRetVal Union(Env env, BSTValArg bs1, BSTValArg bs2)
353 return bs1.Union(env, bs2);
356 static void DiffD(Env env, BST& bs1, BSTValArg bs2)
361 static BSTRetVal Diff(Env env, BSTValArg bs1, BSTValArg bs2)
363 return bs1.Diff(env, bs2);
366 static void RemoveElemD(Env env, BST& bs1, unsigned i)
368 assert(i < BitSetTraits::GetSize(env));
369 bs1.RemoveElemD(env, i);
372 static BSTRetVal RemoveElem(Env env, BSTValArg bs1, unsigned i)
374 assert(i < BitSetTraits::GetSize(env));
375 return bs1.RemoveElem(env, i);
378 static void AddElemD(Env env, BST& bs1, unsigned i)
380 assert(i < BitSetTraits::GetSize(env));
381 bs1.AddElemD(env, i);
384 static BSTRetVal AddElem(Env env, BSTValArg bs1, unsigned i)
386 assert(i < BitSetTraits::GetSize(env));
387 return bs1.AddElem(env, i);
390 static bool IsMember(Env env, BSTValArg bs1, unsigned i)
392 assert(i < BitSetTraits::GetSize(env));
393 return bs1.IsMember(env, i);
396 static void IntersectionD(Env env, BST& bs1, BSTValArg bs2)
398 bs1.IntersectionD(env, bs2);
401 static BSTRetVal Intersection(Env env, BSTValArg bs1, BSTValArg bs2)
403 return bs1.Intersection(env, bs2);
406 static bool IsEmptyIntersection(Env env, BSTValArg bs1, BSTValArg bs2)
408 return bs1.IsEmptyIntersection(env, bs2);
411 static void LivenessD(Env env, BST& in, BSTValArg def, BSTValArg use, BSTValArg out)
413 in.LivenessD(env, def, use, out);
415 static bool IsSubset(Env env, BSTValArg bs1, BSTValArg bs2)
417 return bs1.IsSubset(env, bs2);
420 static bool Equal(Env env, BSTValArg bs1, BSTValArg bs2)
422 return bs1.Equal(env, bs2);
425 static bool NotEqual(Env env, BSTValArg bs1, BSTValArg bs2)
427 return !bs1.Equal(env, bs2);
430 static BSTRetVal MakeEmpty(Env env)
435 static BSTRetVal MakeFull(Env env)
437 return BST(env, /*full*/ true);
441 static const char* ToString(Env env, BSTValArg bs)
443 return bs.ToString(env);
447 // You *can* clear a bit after it's been iterated. But you shouldn't otherwise mutate the
448 // bitset during bit iteration.
455 Iter(Env env, const BitSetUint64<Env, BitSetTraits>& bs) : m_bits(bs.m_bits), m_bitNum(0)
459 bool NextElem(unsigned* pElem)
461 static const unsigned UINT64_SIZE = 64;
463 if ((m_bits & 0x1) != 0)
472 // Skip groups of 4 zeros -- an optimization for sparse bitsets.
473 while (m_bitNum < UINT64_SIZE && (m_bits & 0xf) == 0)
478 while (m_bitNum < UINT64_SIZE && (m_bits & 0x1) == 0)
483 if (m_bitNum < UINT64_SIZE)
498 typedef const BitSetUint64<Env, BitSetTraits>& ValArgType;
499 typedef BitSetUint64ValueRetType<Env, BitSetTraits> RetValType;
501 #endif // bitSetAsUint64InClass_DEFINED