ALib C++ Library
Library Version: 2510 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
bitset.inl
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_lang of the \aliblong.
4///
5/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8ALIB_EXPORT namespace alib { namespace lang {
10
11//==================================================================================================
12/// This class is an improved replica of <c>std::bitset</c> and hence stores and exposes a set of
13/// bits. The differences (advantages) of this class to the standard type are:
14/// - The class provides an efficient bidirectional iterator, which uses intrinsics
15/// (on supported platforms, via functions \alib{lang;CLZ} and \alib{lang;CTZ}) to search the
16/// next bit set without looping over unset bits.
17/// - The size of this type's instances is adjusted to the next fitting integral size, namely
18/// <c>char</c>, <c>short</c>, <c>int</c>, <c>long</c> and <c>long long</c>.
19/// If even larger bitsets are requested, the size becomes a multiple of the size of
20/// <c>long long</c>.
21/// - The type that denotes bit-indices, which is used in the interface methods, can optionally
22/// be altered from <c>int</c> to a custom type which is statically castable to <c>int</c>, by
23/// providing the defaulted template parameter \p{TInterface} accordingly. This avoids the need
24/// for statically casting the index type with every invocation of an interface method.<br>
25/// The main motivation for providing this was to allow to
26/// \ref alib_enums_iter_bitset "address bits with enumeration elements".
27/// - Instead of one template parameter defining the fixed size of the bitset, two parameters
28/// \p{TBegin} and \p{TEnd} are provided. This allows defining bitsets of a range
29/// of indices that do not start with <c>0</c> and in this case avoids the need for subtraction of
30/// the (fixed) start value of a range with every invocation of an interface method.
31/// - Methods #Set and #Reset allow to pass several bit indices at once using a comma-separated list.
32/// - With methods <c>std::bitset<N>::to_ulong() / to_ullong()</c>, the standard type allows
33/// the export of the internal value only to 64-bit values (on common platforms).
34/// If the higher bits are to be exported, the bitset has to be shifted, which is inefficient
35/// and destructive (a copy has to be taken).<br>
36/// This implementation provides method #Export, which - dependent on the size of the bitset -
37/// offers an additional index to address any higher word. Furthermore, for smaller bitsets
38/// the export method returns a fitting smaller integral.
39/// - Explicit uninitialized construction is possíble with
40/// \alib{lang;TBitSet::TBitSet(const std::nullptr_t&)}, which
41/// avoids code and run-time penalty, in cases where the bits are to be initialized at a later
42/// stage.
43///
44/// In respect to performance, this type equals a typical implementation <c>std::bitset</c>.
45///
46/// @see
47/// - Type definition \alib{enumops;EnumBitSet}, which defines a bitset over
48/// \ref alib_enums_iter "ALib Iterable Enums" based on this type.<br>
49/// - For a quick tutorial on the use of this type (in nice combination with C++ enumerations),
50/// see chapter \ref alib_enums_iter_bitset "3.5 Using Class TBitSet with Iterable Enums" of the
51/// Programmer's Manual of module \alib_enumops_nl.
52/// - Type definition \ref alib::BitSet "BitSet" in namespace \ref alib, which defines a set with
53/// interface-type <c>int</c>.
54/// - Class \alib{bitbuffer;BitBuffer}, which implements a sort of stream buffer to store
55/// bits in dynamic memory.
56///
57/// @tparam TInterface The interface type to denote bit position values. This type has to be
58/// statically castable to and constructible from <c>int</c>.
59/// @tparam TEnd The last index of the interface type plus <c>1</c>.
60/// @tparam TBegin The first index of the interface type. (Defaults to <c>0</c>.)
61//==================================================================================================
62template< typename TInterface, TInterface TEnd, TInterface TBegin= 0>
64{
65 protected:
66 #if !DOXYGEN
67 static_assert( !(TBegin > TEnd), "First Idx greater or equal than last index + 1" );
68 #endif
69 // forward declaration
70 template<typename TBitSetCM, bool isReverse> class TBidiIterator;
71
72 // -------------------------------------- members ------------------------------------------
73
74 public:
75 /// The number of bits in the range resulting from template parameters \p{TBegin}
76 /// and \p{TEnd}.
77 static constexpr int Capacity= int( TEnd )
78 - int( TBegin );
79
80 /// The type that is used to store the bits in.
81 /// Template programming code chooses the smallest fitting integral.
82 /// If #Capacity exceeds the type <c>long long</c>, an array of <c>long long</c>, field
83 /// #QtyWords will become greater than \c 1.
84 using TWord= std::conditional_t< (Capacity > bitsof(long) ), unsigned long long,
85 std::conditional_t< (Capacity > bitsof(int) ), unsigned long ,
86 std::conditional_t< (Capacity > bitsof(short) ), unsigned int ,
87 std::conditional_t< (Capacity > bitsof(char) ), unsigned short ,
88 unsigned char >>>>;
89
90 /// The size of the #TWord array containing the bits
91 static constexpr int QtyWords= Capacity / bitsof(TWord)
92 + ( (Capacity % bitsof(TWord)) != 0 ? 1 : 0 );
93
94 protected:
95 /// The array of integrals containing the bits needed. The unused upper bits in the last word
96 /// are always kept <c>0</c>.
98
99 // -------------------------------------- helpers ------------------------------------------
100 /// Helper to determine the bit index in the actual word.
101 /// @param b The absolute index.
102 /// @return The word index.
103 constexpr static int wordIdx(TInterface b) noexcept
104 { return (int(b) - int(TBegin)) / bitsof(TWord); }
105
106 /// Helper to determine the bit index in the actual word.
107 /// @param b The absolute index.
108 /// @return The relative index.
109 constexpr static int bitIdx (TInterface b) noexcept
110 {
111 ALIB_ASSERT_ERROR( int(b) >= int(TBegin)
112 && int(b) < int(TEnd),
113 "ALIB/BITS", "Given bit index out of bounds: {} <= {} < {} ",
114 integer(TBegin), integer(b), integer(TEnd) )
115 return (int(b) - int(TBegin)) % bitsof(TWord);
116 }
117
118 /// Helper receive the word from the array of words.
119 /// @param b The bit to address index.
120 /// @return A reference to the word.
121 constexpr TWord& word (TInterface b) noexcept { return words[wordIdx(b)]; }
122
123 /// Helper receive a \c const reference word from the array of words.
124 /// @param b The bit to address index.
125 /// @return A reference to the word.
126 constexpr const TWord& word (TInterface b) const noexcept { return words[wordIdx(b)]; }
127
128 /// Returns a bitmask with all used bits set.
129 /// @param wIdx The index of the word in array #words.
130 /// @return A bitmask with all bits set for indices smaller than #QtyWords <c>-1</c>,
131 /// and a mask that covers the remaining bits if \p{wIdx} targets the last word.
132 constexpr static TWord mask (int wIdx) noexcept
133 {
134 return wIdx < QtyWords- 1 || (Capacity % bitsof(TWord)) == 0
135 ? TWord(~TWord(0))
137 }
138
139 /// Returns a bitmask with only the given bit set.
140 /// @param b The index of the bit to set.
141 /// @return A bitmask with one bit set.
142 constexpr static TWord mask0010(TInterface b) noexcept { return TWord(TWord(1) << bitIdx(b)); }
143
144 /// Returns a bitmask with only the given bit unset.
145 /// @param b The index of the bit to unset.
146 /// @return A bitmask with all but one bit set.
147 constexpr static TWord mask1101(TInterface b) noexcept { return ~mask0010(b); }
148
149 public:
150 ////////////////////////////////////////////////////////////////////////////////////////////////
151 /// A publicly accessible nested class, used as a proxy object to allow users to interact with
152 /// individual bits of a bitset.
153 /// The primary use of this type is to provide a \e lvalue that can be returned from operator[].
154 /// @tparam TBitSetCM A constant or mutable \b TBitSet.
155 ////////////////////////////////////////////////////////////////////////////////////////////////
156 template<typename TBitSetCM>
158 {
159 protected:
160 #if !DOXYGEN
161 template<typename T, bool isReverse> friend class TBidiIterator;
162 #endif
163
164 TInterface bit; ///< The bit number in #bitSet this reference addresses.
165 TBitSetCM* bitSet; ///< The \b TBitSet this reference addresses.
166
167 public:
168 /// Constructor.
169 /// \note In contrast to the constructor of <c>std::bitset::reference</c>,
170 /// this constructor is public to allow easy external construction.<br>
171 /// @param set The parent \b TBitSet.
172 /// @param b The bit to represent in the TBitSet.
173 constexpr Reference(TBitSetCM& set, TInterface b) noexcept
174 : bit(b), bitSet(&set) {}
175
176 /// Defaulted copy constructor.
177 constexpr Reference(const Reference&) noexcept= default;
178
179 /// Destructor. (Is declared \c constexpr with C++23.)
180 ALIB_CPP_23(constexpr)
181 ~Reference() noexcept {}
182
183 /// Copy assignment operator. (Defaulted, as otherwise implicitly deleted due to
184 /// user-provided destructor.)
185 /// @param other The object to copy.
186 /// @return A reference to \c this.
187 Reference& operator= (const Reference& other) noexcept = default;
188
189 /// Returns the represented bit number.
190 /// @return The bit that this object refers to.
191 constexpr TInterface Bit() const noexcept
192 { return TInterface(bit); }
193
194 /// Returns the underlying bitset.
195 /// @return The \b TBitSet that this object refers to.
196 constexpr class TBitSet& TBitSet() noexcept
197 { return bitSet; }
198
199 /// Returns the underlying bitset.
200 /// @return The \b TBitSet that this object refers to.
201 constexpr const class TBitSet& TBitSet() const noexcept
202 { return bitSet; }
203
204 /// Sets or resets the represented bit.
205 /// @param val The value to assign to the represented bit.
206 /// @return A reference to \c this.
207 constexpr Reference& operator=(bool val) noexcept
208 { bitSet->Set(bit, val); return *this; }
209
210 /// Implicit conversion to bool.
211 /// @return The value of the represented bit.
212 constexpr operator bool() noexcept
213 { return bitSet->Test(bit); }
214
215 /// Does not manipulate the bit, but returns its negated value.
216 /// @return The negated value of the represented bit.
217 constexpr bool operator~() noexcept
218 { return !bitSet->Test(bit); }
219
220 /// Flips the represented bit.
221 /// @return A reference to \c this.
222 constexpr Reference& Flip() noexcept
223 { bitSet->Flip(bit); return *this; }
224
225 /// Compares this object to another.
226 /// @param rhs The right hand side of the comparison.
227 /// @return \c true if the objects reference the same bit in the same bitset, \c false
228 /// otherwise
229 constexpr bool operator== (const Reference& rhs) const noexcept = default;
230 }; // inner class Reference
231
232 // ------------------------------------ constructors ---------------------------------------
233 /// Default constructor initializing all bits to not set.
234 constexpr TBitSet() noexcept
235 {
236 Reset();
237 }
238
239 // ------------------------------------ constructors ---------------------------------------
240 /// Constructor taking a tag-type. This constructor omits any value initialization and
241 /// <b>has to be called by providing <c>nullptr</c></b> as the argument.
242 constexpr TBitSet(const std::nullptr_t&) noexcept {}
243
244 /// Constructor which takes an external #TWord which initializes the first word. If \c constexpr
245 /// field #QtyWords is greater than \c 1, the other bits are set to \c 0 and can be set using
246 /// method #Import or of course using other interface methods.
247 /// @param preset The preset value for the bits.
248 constexpr TBitSet( TWord preset ) noexcept
249 {
250 words[0]= preset & mask(0);
251 for (int w = 1; w < QtyWords; ++w)
252 words[w]= 0;
253 }
254
255 /// Constructor which takes an external #TWord which initializes the first word. If \c constexpr
256 /// field #QtyWords is greater than \c 1, the other bits are set to \c 0 and can be set using
257 /// method #Import or of course using other interface methods.
258 /// @param preset The preset value for the bits.
259 constexpr TBitSet( bool preset ) noexcept
260 {
261 for (int w = 0; w < QtyWords; ++w)
262 words[w]= preset ? TWord(~(TWord(0))) & mask(w)
263 : TWord(0);
264 }
265
266
267 // ----------------------------------- set / reset -----------------------------------------
268 /// Sets the \p{bit} to <c>1</c>.
269 /// @param bit The index of the bit to set.
270 /// @param val \c true or \c false to set or clear bit \p{bit}.
271 /// @return A reference to \c this object.
272 template <typename... T>
273 constexpr
274 TBitSet& Set( TInterface bit, bool val ) noexcept
275 {
276 if( val ) Set(bit);
277 else Reset(bit);
278 return *this;
279 }
280
281 /// Sets one or more bits to <c>1</c>.
282 /// @param firstBit The index of the first bit to set.
283 /// @param furtherBits An optional continued list of bit-indices.
284 /// @return A reference to \c this object.
285 template <typename... T>
286 constexpr
287 TBitSet& Set( TInterface firstBit, T&&... furtherBits ) noexcept
288 {
289 word(firstBit)|= mask0010(firstBit);
290 if constexpr (sizeof...(furtherBits) > 0)
291 Set(furtherBits...);
292 return *this;
293 }
294
295 /// Sets one or more bits to <c>0</c>.
296 /// @param firstBit The index of the first bit to clear.
297 /// @param furtherBits An optional continued list of bit-indices.
298 /// @return A reference to \c this object.
299 template <typename... T>
300 constexpr
301 TBitSet& Reset( TInterface firstBit, T&&... furtherBits ) noexcept
302 {
303 word(firstBit)&= mask1101(firstBit);
304 if constexpr (sizeof...(furtherBits) > 0)
305 Reset(furtherBits...);
306 return *this;
307 }
308
309 /// Flips one or more bits from <c>0</c> to <c>1</c> and vice versa.
310 /// @param firstBit The index of the bit to flip.
311 /// @param furtherBits An optional continued list of indices of bits to flip.
312 /// @return A reference to \c this object.
313 template <typename... T>
314 constexpr
315 TBitSet& Flip( TInterface firstBit, T&&... furtherBits ) noexcept
316 {
317 word(firstBit)^= mask0010(firstBit);
318 if constexpr (sizeof...(furtherBits) > 0)
319 Flip(furtherBits...);
320 return *this;
321 }
322
323
324 /// Sets all bits to <c>1</c>. @return A reference to this object.
325 constexpr TBitSet& Set() noexcept { for (int w = 0; w < QtyWords; ++w) words[w]= mask(w); return *this; }
326 /// Sets all bits to <c>0</c>. @return A reference to this object.
327 constexpr TBitSet& Reset() noexcept { for (int w = 0; w < QtyWords; ++w) words[w]= 0; return *this; }
328 /// Flips all bits from <c>0</c> to <c>1</c> and vice versa. @return A reference to this object.
329 constexpr TBitSet& Flip() noexcept { for (int w = 0; w < QtyWords; ++w) words[w]^= mask(w); return *this; }
330
331 // -------------------------------------- test ---------------------------------------------
332 /// Returns \c true if the \p{bit} is set, \c false otherwise.
333 /// @param bit Denotes the bit to test.
334 /// @return The state of the \p{bit}.
335 constexpr
336 bool Test( TInterface bit ) noexcept
337 {
338 return 0 != (word(bit) & mask0010(bit)) ;
339 }
340
341 // ---------------------------------- count/all/any/none -----------------------------------
342 /// Returns the number of bits set to \c true in this set.
343 /// @return The number of bits counted.
344 constexpr
345 int Count() const noexcept
346 {
347 int result= 0;
348 for (int w = 0; w < QtyWords; ++w)
349 result+= BitCount(words[w]);
350 return result;
351 }
352
353 /// Tests if any bit is set.
354 /// @return \c true if all bits are set, \c false otherwise.
355 constexpr
356 bool All() const noexcept
357 {
358 for (int w = 0; w < QtyWords; ++w)
359 if(words[w] != mask(w) )
360 return false;
361 return true;
362 }
363
364 /// Tests if any bit is set.
365 /// @return \c true if at least one bit is set, \c false otherwise.
366 constexpr
367 bool Any() const noexcept
368 {
369 for (int w = 0; w < QtyWords; ++w)
370 if(words[w] != 0 )
371 return true;
372 return false;
373 }
374
375 /// Tests if not any bit is set.
376 /// @return \c false if at least one bit is set, \c true otherwise.
377 constexpr
378 bool None() const noexcept
379 {
380 return !Any();
381 }
382
383 // --------------------------------- import/export -----------------------------------------
384#if DOXYGEN
385 /// Exports the internal integral(s) holding the bits.
386 ///
387 /// \attention
388 /// Other than this documentation suggests, parameter \p{wordIdx} is only available if
389 /// the bitset size (defined by template parameters \p{TBegin} and \p{TEnd})
390 /// exceeds the number of bits in the widest possible #TWord-type, hence the size
391 /// of <c>sizeof(long long) * 8</c>. In that case, field #QtyWords provides the number of
392 /// words that are exportable.<br>
393 /// This maximum word size is 64-bit on common platforms. Here, \c 0 adresses bits 0..63,
394 /// \c 1 bits 64..127 and so forth.
395 ///
396 /// @param wordIdx The subset of bits to receive. (See note above!)
397 /// @return A reference to the inner word.
398 constexpr
399 TWord& Export(int wordIdx) noexcept
400 {}
401
402 /// Const version of #Export.
403 /// @param wordIdx The subset of bits to receive.<br>
404 /// \b ATTENTION: See non-constant variant #Export on this parameter!
405 /// @return A reference to the inner word.
406 constexpr
407 const TWord& Export(int wordIdx) const noexcept
408 {}
409#else
410 template<bool TRequires=QtyWords==1> requires TRequires constexpr TWord& Export() noexcept { return words[ 0]; }
411 template<bool TRequires=QtyWords==1> requires TRequires const constexpr TWord Export() const noexcept { return words[ 0]; }
412 template<bool TRequires=QtyWords!=1> requires TRequires constexpr TWord& Export(int wordIdx) noexcept {
414 "ALIB/BITS", "Index out of bounds: 0 <= {} < {} ", wordIdx, QtyWords ) return words[wordIdx]; }
415 template<bool TRequires=QtyWords!=1> requires TRequires const constexpr TWord Export(int wordIdx) const noexcept {
416 ALIB_ASSERT_ERROR( wordIdx >= 0 && wordIdx < QtyWords, "ALIB/BITS", "Index out of bounds."
417 "ALIB/BITS", "Index out of bounds: 0 <= {} < {} ", wordIdx, QtyWords ) return words[wordIdx]; }
418#endif
419
420#if DOXYGEN
421 /// Imports the data from (a) given integral(s).
422 ///
423 /// \attention
424 /// Other than this documentation suggests, parameter \p{wordIdx} is only available if
425 /// the bitset size (defined by template parameters \p{TBegin} and \p{TEnd})
426 /// exceeds the number of bits in the widest possible #TWord-type, hence the size
427 /// of <c>sizeof(long long) * 8</c>. In that case, field #QtyWords provides the number of
428 /// words that are importable.<br>
429 /// This maximum word size is 64-bit on common platforms. Here, \c 0 address bits 0..63,
430 /// \c 1 bits 64..127 and so forth.
431 ///
432 /// @param val The value to import.
433 /// @param wordIdx The subset of bits to overwrite. (See note above!)
434 constexpr
435 void Import(TWord val, int wordIdx) noexcept
436 {}
437#else
438 template<bool TRequires=QtyWords==1>
439 requires TRequires
440 void Import(TWord val ) noexcept { words[0]= val & mask(0); }
441
442 template<bool TRequires=QtyWords!=1>
443 requires TRequires
444 void Import(TWord val, int wordIdx) noexcept
445 {
446 ALIB_ASSERT_ERROR( wordIdx >= 0 && wordIdx < QtyWords, "ALIB/BITS",
447 "Index out of bounds: 0 <= {} < {} ", wordIdx, QtyWords )
448 words[wordIdx]= val &= mask(wordIdx);
449 }
450#endif
451
452 // ---------------------------------- operators ------------------------------------------
453 /// Compares this bitset with another bitset of equal size.
454 /// @param rhs The other \b TBitSet to compare this with.
455 /// @return \c true if all bits are equal, \c false otherwise.
456 constexpr bool operator==( const TBitSet& rhs ) const noexcept
457 {
458 for (int w = 0; w < QtyWords; ++w)
459 if(words[w] != rhs.words[w] )
460 return false;
461 return true;
462 }
463
464 /// Sets the bits to the result of binary AND on corresponding pairs of bits of \c this and other.
465 /// @param rhs The other \b TBitSet to compare this with.
466 /// @return A reference to \c this object.
467 constexpr TBitSet& operator&=(const TBitSet& rhs) noexcept { for(int w=0;w<QtyWords;++w) words[w]&= rhs.words[w]; return *this; }
468
469 /// Sets the bits to the result of binary OR on corresponding pairs of bits of \c this and other.
470 /// @param rhs The other \b TBitSet to compare this with.
471 /// @return A reference to \c this object.
472 constexpr TBitSet& operator|=(const TBitSet& rhs) noexcept { for(int w=0;w<QtyWords;++w) words[w]|= rhs.words[w]; return *this; }
473
474 /// Sets the bits to the result of binary XOR on corresponding pairs of bits of \c this and other.
475 /// @param rhs The other \b TBitSet to compare this with.
476 /// @return A reference to \c this object.
477 constexpr TBitSet& operator^=(const TBitSet& rhs) noexcept { for(int w=0;w<QtyWords;++w) words[w]^= rhs.words[w]; return *this; }
478
479 /// Returns a temporary copy of \c this with all bits flipped (binary NOT)..
480 /// @return A copy of this with flipped bits.
481 constexpr TBitSet operator~() const noexcept
482 {
483 auto result= *this;
484 for(int w= 0; w<QtyWords ; ++w)
485 result.words[w]= ~words[w] & mask(w);
486 return result;
487 }
488
489 protected:
490 /// Stores a shifted result in \p{target}. This protected method is accessible via
491 /// <c>operator<<()</c> (which creates and returns a temporary target) and <c>operator<<=()</c>,
492 /// which passes \c this to parameter \p{target}.
493 /// @param cnt The number of positions to shift.
494 /// @param target The target object.
495 constexpr void shiftLeft(int cnt, TBitSet& target) const noexcept
496 {
497 ALIB_ASSERT_ERROR( cnt >= 0, "ALIB/BITS",
498 "Negative value {} for TBitSet shift operation given.", cnt )
499 // shift out of bounds?
500 if( cnt >= Capacity)
501 {
502 target.Reset();
503 return;
504 }
505
506 int offW= cnt / bitsof(TWord);
507 int offB= cnt % bitsof(TWord);
508 // no bit hassle
509 if( offB == 0)
510 for( int w= QtyWords -1; w >= 0; --w )
511 target.words[w]= w - offW >= 0 ? words[w - offW]
512 : TWord(0);
513 // with bit shifts
514 else
515 for( int w= QtyWords -1; w >= 0; --w )
516 target.words[w]= w >= offW ? ( TWord(words[w - offW] << offB)
517 | ( w > offW ? words[w-offW-1] >> (bitsof(TWord) - offB)
518 : TWord(0) ) )
519 : TWord(0);
521 }
522
523 /// Stores a shifted result in \p{target}. This protected method is accessible via
524 /// <c>operator>>()</c> (which creates and returns a temporary target) and <c>operator>>=()</c>,
525 /// which passes \c this to parameter \p{target}.
526 /// @param cnt The number of positions to shift.
527 /// @param target The target object.
528 constexpr void shiftRight(int cnt, TBitSet& target) const noexcept
529 {
530 ALIB_ASSERT_ERROR( cnt >= 0, "ALIB/BITS",
531 "Negative value {} for TBitSet shift operation given.", cnt )
532 // shift out of bounds?
533 if( cnt >= Capacity)
534 {
535 target.Reset();
536 return;
537 }
538
539 int offW= cnt / bitsof(TWord);
540 int offB= cnt % bitsof(TWord);
541 // no bit hassle
542 if( offB == 0)
543 for( int w= 0; w < QtyWords; ++w )
544 target.words[w]= w + offW < QtyWords ? words[w + offW]
545 : TWord(0);
546 // with bit shifts
547 else
548 for( int w= 0; w < QtyWords; ++w )
549 target.words[w]= w < QtyWords- offW ? ( TWord(words[w + offW] >> offB)
550 | ( w < QtyWords- offW - 1 ? TWord(words[w+offW+1] << (bitsof(TWord) - offB))
551 : TWord(0) ) )
552 : TWord(0);
554 }
555
556 public:
557 /// Returns a temporary copy of this with a shift to the left (towards higher index positions).
558 /// @param cnt The number of positions to shift.
559 /// @return A copy of this with shifted bits.
560 constexpr TBitSet operator<<(int cnt) const noexcept
561 { TBitSet result= TBitSet(nullptr); shiftLeft(cnt, result); return result; }
562
563 /// Shifts the bits of this object to the left left (towards higher index positions).
564 /// @param cnt The number of positions to shift.
565 /// @return A reference to this object.
566 constexpr TBitSet& operator<<=(int cnt) noexcept
567 { shiftLeft(cnt, *this); return *this; }
568
569 /// Returns a temporary copy of this with a shift to the right (towards lower index positions).
570 /// @param cnt The number of positions to shift.
571 /// @return A copy of this with shifted bits.
572 constexpr TBitSet operator>>(int cnt) const noexcept
573 { TBitSet result= TBitSet(nullptr); shiftRight(cnt, result); return result; }
574
575 /// Shifts the bits of this object to the left right (towards lower index positions).
576 /// @param cnt The number of positions to shift.
577 /// @return A reference to this object.
578 constexpr TBitSet& operator>>=(int cnt) noexcept
579 { shiftRight(cnt, *this); return *this; }
580
581 /// Returns a reference to a specific bit.
582 /// @param bit The bit to create a reference for.
583 /// @return A reference to the bit in this object.
584 constexpr
585 Reference<TBitSet> operator[](TInterface bit) noexcept
586 { return Reference<TBitSet>(*this, bit); }
587
588 /// Returns a \c const reference to a specific bit.
589 /// @param bit The bit to create a reference for.
590 /// @return A reference to the bit in this object.
591 constexpr
592 const Reference<const TBitSet> operator[](int bit) const noexcept
593 { return Reference<const TBitSet>(*this, bit); }
594
595 protected:
596 ////////////////////////////////////////////////////////////////////////////////////////////////
597 /// Implementation of \c std::iterator_traits for class \b %TBitSet.
598 /// As the name of the class indicates, this iterator satisfies the C++ standard library
599 /// concept of <em>bidirectional iterators</em>. The template parameters allow this
600 /// type to act as a <c>const</c> or mutable as well as a forward or backward iterator.<br>
601 /// The public available type definitions which specify the template parameters and are
602 /// returned from the various \c begin() and \c end() variants of the outer class are:
603 /// - \alib{lang::TBitSet;Iterator},
604 /// - \alib{lang::TBitSet;ReverseIterator},
605 /// - \alib{lang::TBitSet;ConstIterator}, and
606 /// - \alib{lang::TBitSet;ConstReverseIterator}.
607 ///
608 /// @tparam TBitSetCM A constant or mutable TBitSet.
609 /// @tparam isReverse If set, this iterator is a swaps ++ and -- operators.
610 ////////////////////////////////////////////////////////////////////////////////////////////////
611 template<typename TBitSetCM, bool isReverse>
613 {
614 public:
615 using iterator_category = std::bidirectional_iterator_tag; ///< Implementation of <c>std::iterator_traits</c>.
616 using value_type = TInterface; ///< Implementation of <c>std::iterator_traits</c>.
617 using difference_type = int; ///< Implementation of <c>std::iterator_traits</c>.
618 using pointer = void; ///< Implementation of <c>std::iterator_traits</c>.
619 using reference = Reference<TBitSetCM>&; ///< Implementation of <c>std::iterator_traits</c>.
620
621 protected:
622 /// The bit this iterator currently addresses. This is true for forward and reverse
623 /// iterators. (Because this is not using the <c>std::reverse_iterator<</c> which would
624 /// implement an reverse iterator that points 'before' the current element.
626
627 /// Searches and moves this iterator to the next higher bit is. In case no further bit is
628 /// found, the iterator will points to illegal bit number \p{TBitSet::Capacity}
629 /// @return A reference to this object.
631 {
632 // next bit
633 ref.bit= TInterface(int(ref.bit) + 1);
634
635 // search next bit from here
636 while(int(ref.bit) < int(TEnd))
637 {
638 int bIdx= bitIdx(ref.bit);
639 TWord word= ref.bitSet->word(ref.bit)
640 & UpperMask<TWord>(bIdx);
641 // search
642 int trailingZeros;
643 if( word == 0
644 || ((trailingZeros= CTZ<TWord>( word )) == bitsof(TWord) ) )
645 {
646 // not found in this word
647 ref.bit= TInterface( int(ref.bit) + bitsof(TWord) - bIdx );
648 if( int(ref.bit) > int(TEnd))
649 ref.bit= TInterface(TEnd);
650 continue;
651 }
652
653 // found one
654 ref.bit= TInterface( int(ref.bit) + trailingZeros - bIdx);
655 break;
656 }
657 return *this;
658 }
659
660 /// Searches and moves this iterator to the next lower bit is. In case no lower bit is
661 /// found, the iterator will points to illegal bit number <c>-1</c>.
662 /// @return A reference to this object.
664 {
665 // next bit
666 ref.bit= TInterface(int(ref.bit) - 1);
667
668 // search next bit from here
669 while(int(ref.bit) >= int(TBegin))
670 {
671 int bIdx= bitIdx(ref.bit);
672 TWord word= ref.bitSet->word(ref.bit)
673 & TWord( TWord (~TWord(0)) >> (bitsof(TWord)- bIdx -1) );
674 // a lower mask, but not precisely LowerMask.
675 //...and yes, we need all these castings :-/
676 // search
677 int leadingZeros;
678 if( word == 0
679 || ((leadingZeros= CLZ<TWord>( word )) == bitsof(TWord) ) )
680 {
681 // not found in this word
682 ref.bit= TInterface(int(ref.bit) - bIdx -1);
683 if( int(ref.bit) < int(TBegin) -1)
684 ref.bit= TInterface( int(TBegin) - 1);
685 continue;
686 }
687
688 // found one
689 ref.bit= TInterface( int(ref.bit)
690 + (bitsof(TWord) - (bIdx + 1) ) // first correct to upper bit position
691 - leadingZeros ); // then subtract leading zeros
692 break;
693 }
694 return *this;
695 }
696
697 public:
698 /// Constructor.
699 /// @param bitSet The bit set to use.
700 /// @param startBit The bit number to start with.
701 explicit TBidiIterator( TBitSetCM& bitSet, TInterface startBit )
702 : ref(bitSet, startBit)
703 {}
704
705 //###################### To satisfy concept of InputIterator ######################
706 /// Prefix increment operator.
707 /// @return A reference to this object.
709 {
710 if constexpr (!isReverse) return up();
711 return down();
712 }
713
714 /// Postfix increment operator.
715 /// @return An iterator value that is not increased, yet.
717 {
718 auto result= *this;
719 ++*this;
720 return result;
721 }
722
723 /// Comparison operator.
724 /// @param other The iterator to compare ourselves to.
725 /// @return \c true if this and the given iterator are pointing to the same bit in the same
726 /// set, \c false otherwise.
727 bool operator==(const TBidiIterator& other) const
728 {
729 return ref == other.ref;
730 }
731
732 /// Comparison operator.
733 /// @param other The iterator to compare ourselves to.
734 /// @return \c true if this and given iterator are not equal, \c false otherwise.
735 bool operator!=(const TBidiIterator& other) const
736 {
737 return !(*this == other);
738 }
739
740 /// Retrieves a reference to the internal \alib{lang::TBitSet;Reference} member that this
741 /// iterator uses.
742 /// @return The reference to the bit this iterator is currently addressing.
744 {
745 return ref;
746 }
747
748 //################## To satisfy concept of BidirectionalIterator ##################
749 /// Prefix decrement operator.
750 /// @return A reference to this object.
752 {
753 if constexpr (isReverse) return up();
754 return down();
755 }
756
757 /// Postfix decrement operator.
758 /// @return The iterator value prior the decrement operation.
760 {
761 auto result= *this;
762 --*this;
763 return result;
764 }
765
766 //#### Comparison operators ###
767 /// Compares this iterator with the given one.
768 /// @param other The iterator to compare
769 /// @return \c true if this iterator is \e smaller than \p{other},
770 /// \c false otherwise.
771 bool operator<(TBidiIterator other) const
772 { return ref.bit < other.ref.bit; }
773
774 /// Compares this iterator with the given one.
775 /// @param other The iterator to compare
776 /// @return \c true if this iterator is \e smaller than or equal to \p{other},
777 /// \c false otherwise.
778 bool operator<=(TBidiIterator other) const
779 { return ref.bit <= other.ref.bit; }
780
781 /// Compares this iterator with the given one.
782 /// @param other The iterator to compare
783 /// @return \c true if this iterator is \e greater than \p{other},
784 /// \c false otherwise.
785 bool operator>(TBidiIterator other) const
786 { return ref.bit > other.ref.bit; }
787
788 /// Compares this iterator with the given one.
789 /// @param other The iterator to compare
790 /// @return \c true if this iterator is \e greater than or equal to \p{other},
791 /// \c false otherwise.
792 bool operator>=(TBidiIterator other) const
793 { return ref.bit >= other.ref.bit; }
794 }; // class TBidiIterator
795
796 public:
797 /// Iterator type, implementing the standard library concept of
798 /// \https{RandomAccessIterator,en.cppreference.com/w/cpp/concept/RandomAccessIterator}.
799 using Iterator = TBidiIterator<TBitSet, false>;
800
801 /// Same as #Iterator, but working from the end to the start of the \b TBitSet.
802 using ReverseIterator = TBidiIterator<TBitSet, true>;
803
804 /// The constant iterator type.
805 using ConstIterator = TBidiIterator<const TBitSet, false>;
806
807 /// Same as #ConstIterator, but working from the end to the start of the \b TBitSet.
808 using ConstReverseIterator = TBidiIterator<const TBitSet, true>;
809
810 /// Returns an iterator pointing to the first (lowest) bit set.
811 /// @param skip Defaults to \c 0. If set, denotes the amount of bits which are not examined
812 /// at the beginning of the iteration. Must not be negative.
813 /// @return The start iterator. In case no bit is set, the same as #end.
814 Iterator begin(int skip= 0) { return ++Iterator(*this, TInterface(TBegin - 1) + skip); }
815
816 /// Returns an iterator pointing to the non-existing bit behind the highest one.
817 /// @return The end iterator.
818 Iterator end() { return Iterator(*this, TInterface(TEnd) ); }
819
820 /// Returns a reverse iterator pointing to the last (highest) bit set.
821 /// @param skip Defaults to \c 0. If set, denotes the amount of bits which are not examined
822 /// at the beginning of the iteration. Must not be negative.
823 /// @return The reverse iteration start.
824 ReverseIterator rbegin(int skip= 0) { return ++ReverseIterator(*this, TInterface(TEnd) - skip ); }
825
826 /// Returns an iterator pointing to the non-existing bit before the lowest one.
827 /// @return The reverse iteratation end.
828 ReverseIterator rend() { return ReverseIterator(*this, TInterface(TBegin-1) ); }
829
830 /// Returns a const iterator pointing to the first (lowest) bit set.
831 /// @param skip Defaults to \c 0. If set, denotes the amount of bits which are not examined
832 /// at the beginning of the iteration. Must not be negative.
833 /// @return The start iterator. In case no bit is set, the same as #end.
834 ConstIterator begin(int skip= 0) const { return ++ConstIterator(*this, TInterface(TBegin-1) + skip ); }
835
836 /// Returns a const iterator pointing to the first (lowest) bit set.
837 /// @param skip Defaults to \c 0. If set, denotes the amount of bits which are not examined
838 /// at the beginning of the iteration. Must not be negative.
839 /// @return The start iterator. In case no bit is set, the same as #end.
840 ConstIterator cbegin(int skip= 0) const { return ++ConstIterator(*this, TInterface(TBegin-1) + skip ); }
841
842 /// Returns a const iterator pointing to the non-existing bit behind the highest one.
843 /// @return The end iterator.
844 ConstIterator end() const { return ConstIterator(*this, TInterface(TEnd) ); }
845
846 /// Returns a const iterator pointing to the non-existing bit behind the highest one.
847 /// @return The end iterator.
848 ConstIterator cend() const { return ConstIterator(*this, TInterface(TEnd) ); }
849
850 /// Returns a const reverse iterator pointing to the last (highest) bit set.
851 /// @param skip Defaults to \c 0. If set, denotes the amount of bits which are not examined
852 /// at the beginning of the iteration. Must not be negative.
853 /// @return The reverse iteration start.
854 ConstReverseIterator rbegin(int skip= 0)const { return ++ConstReverseIterator(*this, TInterface(TEnd - skip) ); }
855
856 /// Returns a const iterator pointing to the non-existing bit before the lowest one.
857 /// @return The reverse iteratation end.
858 ConstReverseIterator rend() const { return ConstReverseIterator(*this, TInterface(TBegin-1) ); }
859
860 /// Returns a const reverse iterator pointing to the last (highest) bit set.
861 /// @param skip Defaults to \c 0. If set, denotes the amount of bits which are not examined
862 /// at the beginning of the iteration. Must not be negative.
863 /// @return The reverse iteration start.
864 ConstReverseIterator crbegin(int skip=0)const { return ++ConstReverseIterator(*this, TInterface(TEnd - skip) ); }
865
866 /// Returns a const iterator pointing to the non-existing bit before the lowest one.
867 /// @return The reverse iteratation end.
868 ConstReverseIterator crend() const { return ConstReverseIterator(*this, TInterface(TBegin-1) ); }
869
870}; // class TBitSet
871
872} // namespace alib[::lang]
873
874DOX_MARKER([DOX_MANUAL_ALIASES_BITSET])
875/// Type alias in namespace \b alib.
876template<int TEnd, int TBegin= 0, typename TInterface= int>
878DOX_MARKER([DOX_MANUAL_ALIASES_BITSET])
879
880} // namespace [alib]
881
882// ------------------------ global operators on class TBitSet ---------------------------------
883// For documentation, these global operators are faked into namespace alib::lang
884#if DOXYGEN
885namespace alib::lang {
886#endif
887
888/// Performs binary AND operation two \b TBitSet objects (of equal size), \p{lhs} and \p{rhs}.
889/// \note This operator function is located in the global namespace. The documentation shows
890/// namespace <em>alib</em>, which is done for the purposes of organizing the manual
891/// index better.
892/// @param lhs The left hand side operand.
893/// @param rhs The right hand side operand.
894/// @tparam TEnd Template parameter of class \b TBitSet. Deduced by the compiler.
895/// @tparam TBegin Template parameter of class \b TBitSet. Deduced by the compiler.
896/// @tparam TInterface Template parameter of class \b TBitSet. Deduced by the compiler.
897/// @return A temporary \b TBitSet containing the result of the operation.
899template<typename TInterface, TInterface TEnd, TInterface TBegin>
903{
907 result.Import( lhs.Export() & rhs.Export() );
908 else
909 for (int w = 0; w < alib::lang::TBitSet<TInterface,TEnd,TBegin>::QtyWords; ++w)
910 result.Import( lhs.Export(w) & rhs.Export(w), w );
911 return result;
912}
913
914/// Performs binary OR operation two \b TBitSet objects (of equal size), \p{lhs} and \p{rhs}.
915/// \note This operator function is located in the global namespace. The documentation shows
916/// namespace <em>alib</em>, which is done for the purposes of organizing the manual
917/// index better.
918/// @param lhs The left hand side operand.
919/// @param rhs The right hand side operand.
920/// @tparam TEnd Template parameter of class \b TBitSet. Deduced by the compiler.
921/// @tparam TBegin Template parameter of class \b TBitSet. Deduced by the compiler.
922/// @tparam TInterface Template parameter of class \b TBitSet. Deduced by the compiler.
923/// @return A temporary \b TBitSet containing the result of the operation.
925template<typename TInterface, TInterface TEnd, TInterface TBegin>
929{
933 result.Import( lhs.Export() | rhs.Export() );
934 else
935 for (int w = 0; w < alib::lang::TBitSet<TInterface,TEnd,TBegin>::QtyWords; ++w)
936 result.Import( lhs.Export(w) | rhs.Export(w), w );
937 return result;
938}
939
940/// Performs binary XOR operation two \b TBitSet objects (of equal size), \p{lhs} and \p{rhs}.
941/// \note This operator function is located in the global namespace. The documentation shows
942/// namespace <em>alib</em>, which is done for the purposes of organizing the manual
943/// index better.
944/// @param lhs The left hand side operand.
945/// @param rhs The right hand side operand.
946/// @tparam TEnd Template parameter of class \b TBitSet. Deduced by the compiler.
947/// @tparam TBegin Template parameter of class \b TBitSet. Deduced by the compiler.
948/// @tparam TInterface Template parameter of class \b TBitSet. Deduced by the compiler.
949/// @return A temporary \b TBitSet containing the result of the operation.
951template<typename TInterface, TInterface TEnd, TInterface TBegin>
955{
959 result.Import( lhs.Export() ^ rhs.Export() );
960 else
961 for (int w = 0; w < alib::lang::TBitSet<TInterface,TEnd,TBegin>::QtyWords; ++w)
962 result.Import( lhs.Export(w) ^ rhs.Export(w), w );
963 return result;
964}
965#include "ALib.Lang.CIMethods.H"
966#if DOXYGEN
967} // namespace [alib::lang]
968#endif
969
970
Reference & operator=(const Reference &other) noexcept=default
constexpr Reference(TBitSetCM &set, TInterface b) noexcept
Definition bitset.inl:173
constexpr class TBitSet & TBitSet() noexcept
Definition bitset.inl:196
~Reference() noexcept
Destructor. (Is declared constexpr with C++23.)
Definition bitset.inl:181
constexpr Reference & Flip() noexcept
Definition bitset.inl:222
constexpr TInterface Bit() const noexcept
Definition bitset.inl:191
constexpr const class TBitSet & TBitSet() const noexcept
Definition bitset.inl:201
constexpr Reference & operator=(bool val) noexcept
Definition bitset.inl:207
constexpr bool operator==(const Reference &rhs) const noexcept=default
constexpr bool operator~() noexcept
Definition bitset.inl:217
constexpr Reference(const Reference &) noexcept=default
Defaulted copy constructor.
TInterface value_type
Implementation of std::iterator_traits.
Definition bitset.inl:616
TBidiIterator operator--(int)
Definition bitset.inl:759
TBidiIterator operator++(int)
Definition bitset.inl:716
Reference< TBitSetCM > & reference
Implementation of std::iterator_traits.
Definition bitset.inl:619
bool operator>=(TBidiIterator other) const
Definition bitset.inl:792
bool operator!=(const TBidiIterator &other) const
Definition bitset.inl:735
bool operator>(TBidiIterator other) const
Definition bitset.inl:785
void pointer
Implementation of std::iterator_traits.
Definition bitset.inl:618
bool operator<=(TBidiIterator other) const
Definition bitset.inl:778
TBidiIterator(TBitSetCM &bitSet, TInterface startBit)
Definition bitset.inl:701
bool operator<(TBidiIterator other) const
Definition bitset.inl:771
bool operator==(const TBidiIterator &other) const
Definition bitset.inl:727
int difference_type
Implementation of std::iterator_traits.
Definition bitset.inl:617
std::bidirectional_iterator_tag iterator_category
Implementation of std::iterator_traits.
Definition bitset.inl:615
ConstReverseIterator rend() const
Definition bitset.inl:858
constexpr bool All() const noexcept
Definition bitset.inl:356
constexpr TBitSet(TWord preset) noexcept
Definition bitset.inl:248
constexpr TBitSet & Flip() noexcept
Flips all bits from 0 to 1 and vice versa.
Definition bitset.inl:329
static constexpr TWord mask(int wIdx) noexcept
Definition bitset.inl:132
constexpr TBitSet & operator&=(const TBitSet &rhs) noexcept
Definition bitset.inl:467
constexpr void shiftRight(int cnt, TBitSet &target) const noexcept
Definition bitset.inl:528
constexpr TBitSet & Reset(TInterface firstBit, T &&... furtherBits) noexcept
Definition bitset.inl:301
constexpr TBitSet & operator|=(const TBitSet &rhs) noexcept
Definition bitset.inl:472
constexpr TBitSet() noexcept
Default constructor initializing all bits to not set.
Definition bitset.inl:234
constexpr int Count() const noexcept
Definition bitset.inl:345
constexpr TBitSet & Set(TInterface bit, bool val) noexcept
Definition bitset.inl:274
ReverseIterator rbegin(int skip=0)
Definition bitset.inl:824
constexpr TBitSet & Set(TInterface firstBit, T &&... furtherBits) noexcept
Definition bitset.inl:287
constexpr TBitSet & Reset() noexcept
Sets all bits to 0.
Definition bitset.inl:327
constexpr bool operator==(const TBitSet &rhs) const noexcept
Definition bitset.inl:456
constexpr TWord & word(TInterface b) noexcept
Definition bitset.inl:121
constexpr TBitSet & operator^=(const TBitSet &rhs) noexcept
Definition bitset.inl:477
constexpr TBitSet(bool preset) noexcept
Definition bitset.inl:259
ReverseIterator rend()
Definition bitset.inl:828
constexpr TBitSet operator>>(int cnt) const noexcept
Definition bitset.inl:572
ConstIterator cbegin(int skip=0) const
Definition bitset.inl:840
static constexpr int bitIdx(TInterface b) noexcept
Definition bitset.inl:109
ConstReverseIterator rbegin(int skip=0) const
Definition bitset.inl:854
constexpr bool Test(TInterface bit) noexcept
Definition bitset.inl:336
std::conditional_t<(Capacity > bitsof(long)), unsigned long long, std::conditional_t<(Capacity > bitsof(int)), unsigned long, std::conditional_t<(Capacity > bitsof(short)), unsigned int, std::conditional_t<(Capacity > bitsof(char)), unsigned short, unsigned char > > > > TWord
Definition bitset.inl:84
constexpr const TWord & Export(int wordIdx) const noexcept
Definition bitset.inl:407
static constexpr TWord mask1101(TInterface b) noexcept
Definition bitset.inl:147
constexpr const TWord & word(TInterface b) const noexcept
Definition bitset.inl:126
constexpr TBitSet operator~() const noexcept
Definition bitset.inl:481
constexpr void Import(TWord val, int wordIdx) noexcept
Definition bitset.inl:435
static constexpr TWord mask0010(TInterface b) noexcept
Definition bitset.inl:142
constexpr const Reference< const TBitSet > operator[](int bit) const noexcept
Definition bitset.inl:592
ConstReverseIterator crbegin(int skip=0) const
Definition bitset.inl:864
constexpr TBitSet & Flip(TInterface firstBit, T &&... furtherBits) noexcept
Definition bitset.inl:315
constexpr Reference< TBitSet > operator[](TInterface bit) noexcept
Definition bitset.inl:585
constexpr TBitSet & Set() noexcept
Sets all bits to 1.
Definition bitset.inl:325
Iterator begin(int skip=0)
Definition bitset.inl:814
constexpr bool Any() const noexcept
Definition bitset.inl:367
constexpr TBitSet(const std::nullptr_t &) noexcept
Definition bitset.inl:242
constexpr TWord & Export(int wordIdx) noexcept
Definition bitset.inl:399
ConstIterator cend() const
Definition bitset.inl:848
ConstIterator begin(int skip=0) const
Definition bitset.inl:834
constexpr TBitSet & operator<<=(int cnt) noexcept
Definition bitset.inl:566
constexpr TBitSet & operator>>=(int cnt) noexcept
Definition bitset.inl:578
ConstIterator end() const
Definition bitset.inl:844
constexpr bool None() const noexcept
Definition bitset.inl:378
ConstReverseIterator crend() const
Definition bitset.inl:868
constexpr TBitSet operator<<(int cnt) const noexcept
Definition bitset.inl:560
static constexpr int wordIdx(TInterface b) noexcept
Definition bitset.inl:103
constexpr void shiftLeft(int cnt, TBitSet &target) const noexcept
Definition bitset.inl:495
#define bitsof(type)
Definition alib.inl:1418
#define ALIB_CPP_23(...)
Definition alib.inl:476
#define ALIB_EXPORT
Definition alib.inl:488
#define ALIB_ASSERT_ERROR(cond, domain,...)
Definition alib.inl:1049
platform_specific integer
Definition integers.inl:32
ALIB_EXPORT constexpr alib::lang::TBitSet< TInterface, TEnd, TBegin > operator&(const alib::lang::TBitSet< TInterface, TEnd, TBegin > &lhs, const alib::lang::TBitSet< TInterface, TEnd, TBegin > &rhs) noexcept
Definition bitset.inl:900
constexpr int CLZ(TIntegral value)
Definition bits.inl:239
ALIB_EXPORT constexpr alib::lang::TBitSet< TInterface, TEnd, TBegin > operator^(const alib::lang::TBitSet< TInterface, TEnd, TBegin > &lhs, const alib::lang::TBitSet< TInterface, TEnd, TBegin > &rhs) noexcept
Definition bitset.inl:952
constexpr TIntegral UpperMask()
Definition bits.inl:111
constexpr int CTZ(TIntegral value)
Definition bits.inl:280
constexpr TIntegral LowerMask()
Definition bits.inl:53
ALIB_EXPORT constexpr alib::lang::TBitSet< TInterface, TEnd, TBegin > operator|(const alib::lang::TBitSet< TInterface, TEnd, TBegin > &lhs, const alib::lang::TBitSet< TInterface, TEnd, TBegin > &rhs) noexcept
Definition bitset.inl:926
constexpr int BitCount(TIntegral value)
Definition bits.inl:222
lang::TBitSet< int, TEnd, TBegin > BitSet
Type alias in namespace alib.
Definition bitset.inl:877