ALib C++ Library
Library Version: 2511 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 ALIB_ASSERT_ERROR( int(b) >= int(TBegin)
111 && int(b) < int(TEnd),
112 "LANG", "Given bit index out of bounds: {} <= {} < {} ",
113 integer(TBegin), integer(b), integer(TEnd) )
114 return (int(b) - int(TBegin)) % bitsof(TWord);
115 }
116
117 /// Helper receive the word from the array of words.
118 /// @param b The bit to address index.
119 /// @return A reference to the word.
120 constexpr TWord& word (TInterface b) noexcept { return words[wordIdx(b)]; }
121
122 /// Helper receive a \c const reference word from the array of words.
123 /// @param b The bit to address index.
124 /// @return A reference to the word.
125 constexpr const TWord& word (TInterface b) const noexcept { return words[wordIdx(b)]; }
126
127 /// Returns a bitmask with all used bits set.
128 /// @param wIdx The index of the word in array #words.
129 /// @return A bitmask with all bits set for indices smaller than #QtyWords <c>-1</c>,
130 /// and a mask that covers the remaining bits if \p{wIdx} targets the last word.
131 constexpr static TWord mask (int wIdx) noexcept {
132 return wIdx < QtyWords- 1 || (Capacity % bitsof(TWord)) == 0
133 ? TWord(~TWord(0))
135 }
136
137 /// Returns a bitmask with only the given bit set.
138 /// @param b The index of the bit to set.
139 /// @return A bitmask with one bit set.
140 constexpr static TWord mask0010(TInterface b) noexcept { return TWord(TWord(1) << bitIdx(b)); }
141
142 /// Returns a bitmask with only the given bit unset.
143 /// @param b The index of the bit to unset.
144 /// @return A bitmask with all but one bit set.
145 constexpr static TWord mask1101(TInterface b) noexcept { return TWord(~mask0010(b)); }
146
147 public:
148 /// A publicly accessible nested class, used as a proxy object to allow users to interact with
149 /// individual bits of a bitset.
150 /// The primary use of this type is to provide a \e lvalue that can be returned from operator[].
151 /// @tparam TBitSetCM A constant or mutable \b TBitSet.
152 template<typename TBitSetCM>
154 {
155 protected:
156 #if !DOXYGEN
157 template<typename T, bool isReverse> friend class TBidiIterator;
158 #endif
159
160 TInterface bit; ///< The bit number in #bitSet this reference addresses.
161 TBitSetCM* bitSet; ///< The \b TBitSet this reference addresses.
162
163 public:
164 /// Constructor.
165 /// \note In contrast to the constructor of <c>std::bitset::reference</c>,
166 /// this constructor is public to allow easy external construction.<br>
167 /// @param set The parent \b TBitSet.
168 /// @param b The bit to represent in the TBitSet.
169 constexpr Reference(TBitSetCM& set, TInterface b) noexcept
170 : bit(b), bitSet(&set) {}
171
172 /// Defaulted copy constructor.
173 constexpr Reference(const Reference&) noexcept =default;
174
175 /// Destructor. (Is declared \c constexpr with C++23.)
176 ALIB_CPP_23(constexpr)
177 ~Reference() noexcept {}
178
179 /// Copy assignment operator. (Defaulted, as otherwise implicitly deleted due to
180 /// user-provided destructor.)
181 /// @param other The object to copy.
182 /// @return A reference to \c this.
183 Reference& operator= (const Reference& other) noexcept =default;
184
185 /// Returns the represented bit number.
186 /// @return The bit that this object refers to.
187 constexpr TInterface Bit() const noexcept { return TInterface(bit); }
188
189 /// Returns the underlying bitset.
190 /// @return The \b TBitSet that this object refers to.
191 constexpr class TBitSet& TBitSet() noexcept { return bitSet; }
192
193 /// Returns the underlying bitset.
194 /// @return The \b TBitSet that this object refers to.
195 constexpr const class TBitSet& TBitSet() const noexcept { return bitSet; }
196
197 /// Sets or resets the represented bit.
198 /// @param val The value to assign to the represented bit.
199 /// @return A reference to \c this.
200 constexpr Reference& operator=(bool val) noexcept { bitSet->Set(bit, val); return *this; }
201
202 /// Implicit conversion to bool.
203 /// @return The value of the represented bit.
204 constexpr operator bool() noexcept { return bitSet->Test(bit); }
205
206 /// Does not manipulate the bit, but returns its negated value.
207 /// @return The negated value of the represented bit.
208 constexpr bool operator~() noexcept { return !bitSet->Test(bit); }
209
210 /// Flips the represented bit.
211 /// @return A reference to \c this.
212 constexpr Reference& Flip() noexcept { bitSet->Flip(bit); return *this; }
213
214 /// Compares this object to another.
215 /// @param rhs The right-hand side of the comparison.
216 /// @return \c true if the objects reference the same bit in the same bitset, \c false
217 /// otherwise
218 constexpr bool operator== (const Reference& rhs) const noexcept =default;
219 }; // inner class Reference
220
221 //------------------------------------------ constructors ----------------------------------------
222 /// Default constructor initializing all bits to not set.
223 constexpr TBitSet() noexcept { Reset(); }
224
225 //------------------------------------------ constructors ----------------------------------------
226 /// Constructor taking a tag-type. This constructor omits any value initialization and
227 /// <b>has to be called by providing <c>nullptr</c></b> as the argument.
228 constexpr TBitSet(const std::nullptr_t&) noexcept {}
229
230 /// Constructor which takes an external #TWord which initializes the first word. If \c constexpr
231 /// field #QtyWords is greater than \c 1, the other bits are set to \c 0 and can be set using
232 /// method #Import or of course using other interface methods.
233 /// @param preset The preset value for the bits.
234 constexpr TBitSet( TWord preset ) noexcept {
235 words[0]= preset & mask(0);
236 for (int w = 1; w < QtyWords; ++w)
237 words[w]= 0;
238 }
239
240 /// Constructor which takes an external #TWord which initializes the first word. If \c constexpr
241 /// field #QtyWords is greater than \c 1, the other bits are set to \c 0 and can be set using
242 /// method #Import or of course using other interface methods.
243 /// @param preset The preset value for the bits.
244 constexpr TBitSet( bool preset ) noexcept {
245 for (int w = 0; w < QtyWords; ++w)
246 words[w]= preset ? TWord(~(TWord(0))) & mask(w)
247 : TWord(0);
248 }
249
250
251 //------------------------------------------ set / reset -----------------------------------------
252 /// Sets the \p{bit} to <c>1</c>.
253 /// @param bit The index of the bit to set.
254 /// @param val \c true or \c false to set or clear bit \p{bit}.
255 /// @return A reference to \c this object.
256 template <typename... T>
257 constexpr
258 TBitSet& Set( TInterface bit, bool val ) noexcept {
259 if( val ) Set(bit);
260 else Reset(bit);
261 return *this;
262 }
263
264 /// Sets one or more bits to <c>1</c>.
265 /// @param firstBit The index of the first bit to set.
266 /// @param furtherBits An optional continued list of bit-indices.
267 /// @return A reference to \c this object.
268 template <typename... T>
269 constexpr
270 TBitSet& Set( TInterface firstBit, T&&... furtherBits ) noexcept {
271 word(firstBit)|= mask0010(firstBit);
272 if constexpr (sizeof...(furtherBits) > 0)
273 Set(furtherBits...);
274 return *this;
275 }
276
277 /// Sets one or more bits to <c>0</c>.
278 /// @param firstBit The index of the first bit to clear.
279 /// @param furtherBits An optional continued list of bit-indices.
280 /// @return A reference to \c this object.
281 template <typename... T>
282 constexpr
283 TBitSet& Reset( TInterface firstBit, T&&... furtherBits ) noexcept {
284 word(firstBit)&= mask1101(firstBit);
285 if constexpr (sizeof...(furtherBits) > 0)
286 Reset(furtherBits...);
287 return *this;
288 }
289
290 /// Flips one or more bits from <c>0</c> to <c>1</c> and vice versa.
291 /// @param firstBit The index of the bit to flip.
292 /// @param furtherBits An optional continued list of indices of bits to flip.
293 /// @return A reference to \c this object.
294 template <typename... T>
295 constexpr
296 TBitSet& Flip( TInterface firstBit, T&&... furtherBits ) noexcept {
297 word(firstBit)^= mask0010(firstBit);
298 if constexpr (sizeof...(furtherBits) > 0)
299 Flip(furtherBits...);
300 return *this;
301 }
302
303
304 /// Sets all bits to <c>1</c>. @return A reference to this object.
305 constexpr TBitSet& Set() noexcept { for (int w = 0; w < QtyWords; ++w) words[w]= mask(w); return *this; }
306 /// Sets all bits to <c>0</c>. @return A reference to this object.
307 constexpr TBitSet& Reset() noexcept { for (int w = 0; w < QtyWords; ++w) words[w]= 0; return *this; }
308 /// Flips all bits from <c>0</c> to <c>1</c> and vice versa. @return A reference to this object.
309 constexpr TBitSet& Flip() noexcept { for (int w = 0; w < QtyWords; ++w) words[w]^= mask(w); return *this; }
310
311 //---------------------------------------------- test --------------------------------------------
312 /// Returns \c true if the \p{bit} is set, \c false otherwise.
313 /// @param bit Denotes the bit to test.
314 /// @return The state of the \p{bit}.
315 constexpr
316 bool Test( TInterface bit ) noexcept { return 0 != (word(bit) & mask0010(bit)) ; }
317
318 //--------------------------------------- count/all/any/none -------------------------------------
319 /// Returns the number of bits set to \c true in this set.
320 /// @return The number of bits counted.
321 constexpr
322 int Count() const noexcept {
323 int result= 0;
324 for (int w = 0; w < QtyWords; ++w)
325 result+= BitCount(words[w]);
326 return result;
327 }
328
329 /// Tests if any bit is set.
330 /// @return \c true if all bits are set, \c false otherwise.
331 constexpr
332 bool All() const noexcept {
333 for (int w = 0; w < QtyWords; ++w)
334 if(words[w] != mask(w) )
335 return false;
336 return true;
337 }
338
339 /// Tests if any bit is set.
340 /// @return \c true if at least one bit is set, \c false otherwise.
341 constexpr
342 bool Any() const noexcept {
343 for (int w = 0; w < QtyWords; ++w)
344 if(words[w] != 0 )
345 return true;
346 return false;
347 }
348
349 /// Tests if not any bit is set.
350 /// @return \c false if at least one bit is set, \c true otherwise.
351 constexpr
352 bool None() const noexcept { return !Any(); }
353
354 //----------------------------------------- import/export ----------------------------------------
355#if DOXYGEN
356 /// Exports the internal integral(s) holding the bits.
357 ///
358 /// \attention
359 /// Other than this documentation suggests, parameter \p{wordIdx} is only available if
360 /// the bitset size (defined by template parameters \p{TBegin} and \p{TEnd})
361 /// exceeds the number of bits in the widest possible #TWord-type, hence the size
362 /// of <c>sizeof(long long) * 8</c>. In that case, field #QtyWords provides the number of
363 /// words that are exportable.<br>
364 /// This maximum word size is 64-bit on common platforms. Here, \c 0 adresses bits 0..63,
365 /// \c 1 bits 64..127 and so forth.
366 ///
367 /// @param wordIdx The subset of bits to receive. (See note above!)
368 /// @return A reference to the inner word.
369 constexpr
370 TWord& Export(int wordIdx) noexcept
371 {}
372
373 /// Const version of #Export.
374 /// @param wordIdx The subset of bits to receive.<br>
375 /// \b ATTENTION: See non-constant variant #Export on this parameter!
376 /// @return A reference to the inner word.
377 constexpr
378 const TWord& Export(int wordIdx) const noexcept
379 {}
380#else
381 template<bool TRequires=QtyWords==1> requires TRequires constexpr TWord& Export() noexcept { return words[ 0]; }
382 template<bool TRequires=QtyWords==1> requires TRequires const constexpr TWord Export() const noexcept { return words[ 0]; }
383 template<bool TRequires=QtyWords!=1> requires TRequires constexpr TWord& Export(int wordIdx) noexcept {
385 "LANG", "Index out of bounds: 0 <= {} < {} ", wordIdx, QtyWords ) return words[wordIdx]; }
386 template<bool TRequires=QtyWords!=1> requires TRequires const constexpr TWord Export(int wordIdx) const noexcept {
387 ALIB_ASSERT_ERROR( wordIdx >= 0 && wordIdx < QtyWords, "LANG", "Index out of bounds."
388 "LANG", "Index out of bounds: 0 <= {} < {} ", wordIdx, QtyWords ) return words[wordIdx]; }
389#endif
390
391#if DOXYGEN
392 /// Imports the data from (a) given integral(s).
393 ///
394 /// \attention
395 /// Other than this documentation suggests, parameter \p{wordIdx} is only available if
396 /// the bitset size (defined by template parameters \p{TBegin} and \p{TEnd})
397 /// exceeds the number of bits in the widest possible #TWord-type, hence the size
398 /// of <c>sizeof(long long) * 8</c>. In that case, field #QtyWords provides the number of
399 /// words that are importable.<br>
400 /// This maximum word size is 64-bit on common platforms. Here, \c 0 address bits 0..63,
401 /// \c 1 bits 64..127 and so forth.
402 ///
403 /// @param val The value to import.
404 /// @param wordIdx The subset of bits to overwrite. (See note above!)
405 constexpr
406 void Import(TWord val, int wordIdx) noexcept
407 {}
408#else
409 template<bool TRequires=QtyWords==1>
410 requires TRequires
411 void Import(TWord val ) noexcept { words[0]= val & mask(0); }
412
413 template<bool TRequires=QtyWords!=1>
414 requires TRequires
415 void Import(TWord val, int wordIdx) noexcept {
416 ALIB_ASSERT_ERROR( wordIdx >= 0 && wordIdx < QtyWords, "LANG",
417 "Index out of bounds: 0 <= {} < {} ", wordIdx, QtyWords )
418 words[wordIdx]= val &= mask(wordIdx);
419 }
420#endif
421
422 //------------------------------------------- operators ------------------------------------------
423 /// Compares this bitset with another bitset of equal size.
424 /// @param rhs The other \b TBitSet to compare this with.
425 /// @return \c true if all bits are equal, \c false otherwise.
426 constexpr bool operator==( const TBitSet& rhs ) const noexcept {
427 for (int w = 0; w < QtyWords; ++w)
428 if(words[w] != rhs.words[w] )
429 return false;
430 return true;
431 }
432
433 /// Sets the bits to the result of binary AND on corresponding pairs of bits of \c this and other.
434 /// @param rhs The other \b TBitSet to compare this with.
435 /// @return A reference to \c this object.
436 constexpr TBitSet& operator&=(const TBitSet& rhs) noexcept { for(int w=0;w<QtyWords;++w) words[w]&= rhs.words[w]; return *this; }
437
438 /// Sets the bits to the result of binary OR on corresponding pairs of bits of \c this and other.
439 /// @param rhs The other \b TBitSet to compare this with.
440 /// @return A reference to \c this object.
441 constexpr TBitSet& operator|=(const TBitSet& rhs) noexcept { for(int w=0;w<QtyWords;++w) words[w]|= rhs.words[w]; return *this; }
442
443 /// Sets the bits to the result of binary XOR on corresponding pairs of bits of \c this and other.
444 /// @param rhs The other \b TBitSet to compare this with.
445 /// @return A reference to \c this object.
446 constexpr TBitSet& operator^=(const TBitSet& rhs) noexcept { for(int w=0;w<QtyWords;++w) words[w]^= rhs.words[w]; return *this; }
447
448 /// Returns a temporary copy of \c this with all bits flipped (binary NOT)..
449 /// @return A copy of this with flipped bits.
450 constexpr TBitSet operator~() const noexcept {
451 auto result= *this;
452 for(int w= 0; w<QtyWords ; ++w)
453 result.words[w]= ~words[w] & mask(w);
454 return result;
455 }
456
457 protected:
458 /// Stores a shifted result in \p{target}. This protected method is accessible via
459 /// <c>operator<<()</c> (which creates and returns a temporary target) and <c>operator<<=()</c>,
460 /// which passes \c this to parameter \p{target}.
461 /// @param cnt The number of positions to shift.
462 /// @param target The target object.
463 constexpr void shiftLeft(int cnt, TBitSet& target) const noexcept {
464 ALIB_ASSERT_ERROR( cnt >= 0, "LANG",
465 "Negative value {} for TBitSet shift operation given.", cnt )
466 // shift out of bounds?
467 if( cnt >= Capacity) {
468 target.Reset();
469 return;
470 }
471
472 int offW= cnt / bitsof(TWord);
473 int offB= cnt % bitsof(TWord);
474 // no bit hassle
475 if( offB == 0)
476 for( int w= QtyWords -1; w >= 0; --w )
477 target.words[w]= w - offW >= 0 ? words[w - offW]
478 : TWord(0);
479 // with bit shifts
480 else
481 for( int w= QtyWords -1; w >= 0; --w )
482 target.words[w]= w >= offW ? ( TWord(words[w - offW] << offB)
483 | ( w > offW ? words[w-offW-1] >> (bitsof(TWord) - offB)
484 : TWord(0) ) )
485 : TWord(0);
487 }
488
489 /// Stores a shifted result in \p{target}. This protected method is accessible via
490 /// <c>operator>>()</c> (which creates and returns a temporary target) and <c>operator>>=()</c>,
491 /// which passes \c this to parameter \p{target}.
492 /// @param cnt The number of positions to shift.
493 /// @param target The target object.
494 constexpr void shiftRight(int cnt, TBitSet& target) const noexcept {
495 ALIB_ASSERT_ERROR( cnt >= 0, "LANG",
496 "Negative value {} for TBitSet shift operation given.", cnt )
497 // shift out of bounds?
498 if( cnt >= Capacity) {
499 target.Reset();
500 return;
501 }
502
503 int offW= cnt / bitsof(TWord);
504 int offB= cnt % bitsof(TWord);
505 // no bit hassle
506 if( offB == 0)
507 for( int w= 0; w < QtyWords; ++w )
508 target.words[w]= w + offW < QtyWords ? words[w + offW]
509 : TWord(0);
510 // with bit shifts
511 else
512 for( int w= 0; w < QtyWords; ++w )
513 target.words[w]= w < QtyWords- offW ? ( TWord(words[w + offW] >> offB)
514 | ( w < QtyWords- offW - 1 ? TWord(words[w+offW+1] << (bitsof(TWord) - offB))
515 : TWord(0) ) )
516 : TWord(0);
518 }
519
520 public:
521 /// Returns a temporary copy of this with a shift to the left (towards higher index positions).
522 /// @param cnt The number of positions to shift.
523 /// @return A copy of this with shifted bits.
524 constexpr TBitSet operator<<(int cnt) const noexcept
525 { TBitSet result= TBitSet(nullptr); shiftLeft(cnt, result); return result; }
526
527 /// Shifts the bits of this object to the left (towards higher index positions).
528 /// @param cnt The number of positions to shift.
529 /// @return A reference to this object.
530 constexpr TBitSet& operator<<=(int cnt) noexcept { shiftLeft(cnt, *this); return *this; }
531
532 /// Returns a temporary copy of this with a shift to the right (towards lower index positions).
533 /// @param cnt The number of positions to shift.
534 /// @return A copy of this with shifted bits.
535 constexpr TBitSet operator>>(int cnt) const noexcept
536 { TBitSet result= TBitSet(nullptr); shiftRight(cnt, result); return result; }
537
538 /// Shifts the bits of this object to the left right (towards lower index positions).
539 /// @param cnt The number of positions to shift.
540 /// @return A reference to this object.
541 constexpr TBitSet& operator>>=(int cnt) noexcept { shiftRight(cnt, *this); return *this; }
542
543 /// Returns a reference to a specific bit.
544 /// @param bit The bit to create a reference for.
545 /// @return A reference to the bit in this object.
546 constexpr
547 Reference<TBitSet> operator[](TInterface bit) noexcept
548 { return Reference<TBitSet>(*this, bit); }
549
550 /// Returns a \c const reference to a specific bit.
551 /// @param bit The bit to create a reference for.
552 /// @return A reference to the bit in this object.
553 constexpr
554 const Reference<const TBitSet> operator[](int bit) const noexcept
555 { return Reference<const TBitSet>(*this, bit); }
556
557 protected:
558 /// Implementation of \c std::iterator_traits for class \b %TBitSet.
559 /// As the name of the class indicates, this iterator satisfies the C++ standard library
560 /// concept of <em>bidirectional iterators</em>. The template parameters allow this
561 /// type to act as a <c>const</c> or mutable as well as a forward or backward iterator.<br>
562 /// The public available type definitions which specify the template parameters and are
563 /// returned from the various \c begin() and \c end() variants of the outer class are:
564 /// - \alib{lang::TBitSet;Iterator},
565 /// - \alib{lang::TBitSet;ReverseIterator},
566 /// - \alib{lang::TBitSet;ConstIterator}, and
567 /// - \alib{lang::TBitSet;ConstReverseIterator}.
568 ///
569 /// @tparam TBitSetCM A constant or mutable TBitSet.
570 /// @tparam isReverse If set, this iterator is a swaps ++ and -- operators.
571 template<typename TBitSetCM, bool isReverse>
573 {
574 public:
575 using iterator_category = std::bidirectional_iterator_tag; ///< Implementation of <c>std::iterator_traits</c>.
576 using value_type = TInterface; ///< Implementation of <c>std::iterator_traits</c>.
577 using difference_type = int; ///< Implementation of <c>std::iterator_traits</c>.
578 using pointer = void; ///< Implementation of <c>std::iterator_traits</c>.
579 using reference = Reference<TBitSetCM>&; ///< Implementation of <c>std::iterator_traits</c>.
580
581 protected:
582 /// The bit this iterator currently addresses. This is true for forward and reverse
583 /// iterators. (Because this is not using the <c>std::reverse_iterator<</c> which would
584 /// implement an reverse iterator that points 'before' the current element.
586
587 /// Searches and moves this iterator to the next higher bit is. In case no further bit is
588 /// found, the iterator will points to illegal bit number \p{TBitSet::Capacity}
589 /// @return A reference to this object.
591 // next bit
592 ref.bit= TInterface(int(ref.bit) + 1);
593
594 // search next bit from here
595 while(int(ref.bit) < int(TEnd)) {
596 int bIdx= bitIdx(ref.bit);
597 TWord word= ref.bitSet->word(ref.bit)
598 & UpperMask<TWord>(bIdx);
599 // search
600 int trailingZeros;
601 if( word == 0
602 || ((trailingZeros= CTZ<TWord>( word )) == bitsof(TWord) ) )
603 {
604 // not found in this word
605 ref.bit= TInterface( int(ref.bit) + bitsof(TWord) - bIdx );
606 if( int(ref.bit) > int(TEnd))
607 ref.bit= TInterface(TEnd);
608 continue;
609 }
610
611 // found one
612 ref.bit= TInterface( int(ref.bit) + trailingZeros - bIdx);
613 break;
614 }
615 return *this;
616 }
617
618 /// Searches and moves this iterator to the next lower bit is. In case no lower bit is
619 /// found, the iterator will points to illegal bit number <c>-1</c>.
620 /// @return A reference to this object.
622 // next bit
623 ref.bit= TInterface(int(ref.bit) - 1);
624
625 // search next bit from here
626 while(int(ref.bit) >= int(TBegin)) {
627 int bIdx= bitIdx(ref.bit);
628 TWord word= ref.bitSet->word(ref.bit)
629 & TWord( TWord (~TWord(0)) >> (bitsof(TWord)- bIdx -1) );
630 // a lower mask, but not precisely LowerMask.
631 //...and yes, we need all these castings :-/
632 // search
633 int leadingZeros;
634 if( word == 0
635 || ((leadingZeros= CLZ<TWord>( word )) == bitsof(TWord) ) )
636 {
637 // not found in this word
638 ref.bit= TInterface(int(ref.bit) - bIdx -1);
639 if( int(ref.bit) < int(TBegin) -1)
640 ref.bit= TInterface( int(TBegin) - 1);
641 continue;
642 }
643
644 // found one
645 ref.bit= TInterface( int(ref.bit)
646 + (bitsof(TWord) - (bIdx + 1) ) // first correct to upper bit position
647 - leadingZeros ); // then subtract leading zeros
648 break;
649 }
650 return *this;
651 }
652
653 public:
654 /// Constructor.
655 /// @param bitSet The bit set to use.
656 /// @param startBit The bit number to start with.
657 explicit TBidiIterator( TBitSetCM& bitSet, TInterface startBit )
658 : ref(bitSet, startBit) {}
659
660 //############################## To satisfy concept of InputIterator ############################
661 /// Prefix increment operator.
662 /// @return A reference to this object.
663 TBidiIterator& operator++() { if constexpr (!isReverse) return up(); return down(); }
664
665 /// Postfix increment operator.
666 /// @return An iterator value that is not increased, yet.
668 auto result= *this;
669 ++*this;
670 return result;
671 }
672
673 /// Comparison operator.
674 /// @param other The iterator to compare ourselves to.
675 /// @return \c true if this and the given iterator are pointing to the same bit in the same
676 /// set, \c false otherwise.
677 bool operator==(const TBidiIterator& other) const { return ref == other.ref; }
678
679 /// Comparison operator.
680 /// @param other The iterator to compare ourselves to.
681 /// @return \c true if this and given iterator are not equal, \c false otherwise.
682 bool operator!=(const TBidiIterator& other) const { return !(*this == other); }
683
684 /// Retrieves a reference to the internal \alib{lang::TBitSet;Reference} member that this
685 /// iterator uses.
686 /// @return The reference to the bit this iterator is currently addressing.
687 reference operator*() { return ref; }
688
689 //########################## To satisfy concept of BidirectionalIterator ########################
690 /// Prefix decrement operator.
691 /// @return A reference to this object.
692 TBidiIterator& operator--() { if constexpr (isReverse) return up(); return down(); }
693
694 /// Postfix decrement operator.
695 /// @return The iterator value prior the decrement operation.
697 auto result= *this;
698 --*this;
699 return result;
700 }
701
702 //#### Comparison operators ###
703 /// Compares this iterator with the given one.
704 /// @param other The iterator to compare
705 /// @return \c true if this iterator is \e smaller than \p{other},
706 /// \c false otherwise.
707 bool operator<(TBidiIterator other) const { return ref.bit < other.ref.bit; }
708
709 /// Compares this iterator with the given one.
710 /// @param other The iterator to compare
711 /// @return \c true if this iterator is \e smaller than or equal to \p{other},
712 /// \c false otherwise.
713 bool operator<=(TBidiIterator other) const { return ref.bit <= other.ref.bit; }
714
715 /// Compares this iterator with the given one.
716 /// @param other The iterator to compare
717 /// @return \c true if this iterator is \e greater than \p{other},
718 /// \c false otherwise.
719 bool operator>(TBidiIterator other) const { return ref.bit > other.ref.bit; }
720
721 /// Compares this iterator with the given one.
722 /// @param other The iterator to compare
723 /// @return \c true if this iterator is \e greater than or equal to \p{other},
724 /// \c false otherwise.
725 bool operator>=(TBidiIterator other) const { return ref.bit >= other.ref.bit; }
726 }; // class TBidiIterator
727
728 public:
729 /// Iterator type, implementing the standard library concept of
730 /// \https{RandomAccessIterator,en.cppreference.com/w/cpp/concept/RandomAccessIterator}.
731 using Iterator = TBidiIterator<TBitSet, false>;
732
733 /// Same as #Iterator, but working from the end to the start of the \b TBitSet.
734 using ReverseIterator = TBidiIterator<TBitSet, true>;
735
736 /// The constant iterator type.
737 using ConstIterator = TBidiIterator<const TBitSet, false>;
738
739 /// Same as #ConstIterator, but working from the end to the start of the \b TBitSet.
740 using ConstReverseIterator = TBidiIterator<const TBitSet, true>;
741
742 /// Returns an iterator pointing to the first (lowest) bit set.
743 /// @param skip Defaults to \c 0. If set, denotes the amount of bits which are not examined
744 /// at the beginning of the iteration. Must not be negative.
745 /// @return The start iterator. In case no bit is set, the same as #end.
746 Iterator begin(int skip= 0)
747 { return ++Iterator(*this, TInterface(TBegin - 1) + skip); }
748
749 /// Returns an iterator pointing to the non-existing bit behind the highest one.
750 /// @return The end iterator.
751 Iterator end() { return Iterator(*this, TInterface(TEnd) ); }
752
753 /// Returns a reverse iterator pointing to the last (highest) bit set.
754 /// @param skip Defaults to \c 0. If set, denotes the amount of bits which are not examined
755 /// at the beginning of the iteration. Must not be negative.
756 /// @return The reverse iteration start.
758 { return ++ReverseIterator(*this, TInterface(TEnd) - skip ); }
759
760 /// Returns an iterator pointing to the non-existing bit before the lowest one.
761 /// @return The reverse iteratation end.
762 ReverseIterator rend() { return ReverseIterator(*this, TInterface(TBegin-1) ); }
763
764 /// Returns a const iterator pointing to the first (lowest) bit set.
765 /// @param skip Defaults to \c 0. If set, denotes the amount of bits which are not examined
766 /// at the beginning of the iteration. Must not be negative.
767 /// @return The start iterator. In case no bit is set, the same as #end.
768 ConstIterator begin(int skip= 0) const
769 { return ++ConstIterator(*this, TInterface(TBegin-1) + skip ); }
770
771 /// Returns a const iterator pointing to the first (lowest) bit set.
772 /// @param skip Defaults to \c 0. If set, denotes the amount of bits which are not examined
773 /// at the beginning of the iteration. Must not be negative.
774 /// @return The start iterator. In case no bit is set, the same as #end.
775 ConstIterator cbegin(int skip= 0) const
776 { return ++ConstIterator(*this, TInterface(TBegin-1) + skip ); }
777
778 /// Returns a const iterator pointing to the non-existing bit behind the highest one.
779 /// @return The end iterator.
780 ConstIterator end() const { return ConstIterator(*this, TInterface(TEnd) ); }
781
782 /// Returns a const iterator pointing to the non-existing bit behind the highest one.
783 /// @return The end iterator.
784 ConstIterator cend() const { return ConstIterator(*this, TInterface(TEnd) ); }
785
786 /// Returns a const reverse iterator pointing to the last (highest) bit set.
787 /// @param skip Defaults to \c 0. If set, denotes the amount of bits which are not examined
788 /// at the beginning of the iteration. Must not be negative.
789 /// @return The reverse iteration start.
790 ConstReverseIterator rbegin(int skip= 0) const
791 { return ++ConstReverseIterator(*this, TInterface(TEnd - skip) ); }
792
793 /// Returns a const iterator pointing to the non-existing bit before the lowest one.
794 /// @return The reverse iteratation end.
795 ConstReverseIterator rend() const { return ConstReverseIterator(*this, TInterface(TBegin-1) ); }
796
797 /// Returns a const reverse iterator pointing to the last (highest) bit set.
798 /// @param skip Defaults to \c 0. If set, denotes the amount of bits which are not examined
799 /// at the beginning of the iteration. Must not be negative.
800 /// @return The reverse iteration start.
802 { return ++ConstReverseIterator(*this, TInterface(TEnd - skip) ); }
803
804 /// Returns a const iterator pointing to the non-existing bit before the lowest one.
805 /// @return The reverse iteratation end.
806 ConstReverseIterator crend()const { return ConstReverseIterator(*this, TInterface(TBegin-1) ); }
807
808}; // class TBitSet
809
810} // namespace alib[::lang]
811
812DOX_MARKER([DOX_MANUAL_ALIASES_BITSET])
813/// Type alias in namespace \b alib.
814template<int TEnd, int TBegin= 0, typename TInterface= int>
816DOX_MARKER([DOX_MANUAL_ALIASES_BITSET])
817
818} // namespace [alib]
819
820//-------------------------------- global operators on class TBitSet -------------------------------
821// For documentation, these global operators are faked into namespace alib::lang
822#if DOXYGEN
823namespace alib::lang {
824#endif
825
826/// Performs binary AND operation two \b TBitSet objects (of equal size), \p{lhs} and \p{rhs}.
827/// \note This operator function is located in the global namespace. The documentation shows
828/// namespace <em>alib</em>, which is done for the purposes of organizing the manual
829/// index better.
830/// @param lhs The left-hand side operand.
831/// @param rhs The right-hand side operand.
832/// @tparam TEnd Template parameter of class \b TBitSet. Deduced by the compiler.
833/// @tparam TBegin Template parameter of class \b TBitSet. Deduced by the compiler.
834/// @tparam TInterface Template parameter of class \b TBitSet. Deduced by the compiler.
835/// @return A temporary \b TBitSet containing the result of the operation.
837template<typename TInterface, TInterface TEnd, TInterface TBegin>
840 const alib::lang::TBitSet<TInterface,TEnd,TBegin>& rhs ) noexcept {
844 result.Import( lhs.Export() & rhs.Export() );
845 else
846 for (int w = 0; w < alib::lang::TBitSet<TInterface,TEnd,TBegin>::QtyWords; ++w)
847 result.Import( lhs.Export(w) & rhs.Export(w), w );
848 return result;
849}
850
851/// Performs binary OR operation two \b TBitSet objects (of equal size), \p{lhs} and \p{rhs}.
852/// \note This operator function is located in the global namespace. The documentation shows
853/// namespace <em>alib</em>, which is done for the purposes of organizing the manual
854/// index better.
855/// @param lhs The left-hand side operand.
856/// @param rhs The right-hand side operand.
857/// @tparam TEnd Template parameter of class \b TBitSet. Deduced by the compiler.
858/// @tparam TBegin Template parameter of class \b TBitSet. Deduced by the compiler.
859/// @tparam TInterface Template parameter of class \b TBitSet. Deduced by the compiler.
860/// @return A temporary \b TBitSet containing the result of the operation.
862template<typename TInterface, TInterface TEnd, TInterface TBegin>
865 const alib::lang::TBitSet<TInterface,TEnd,TBegin>& rhs ) noexcept {
869 result.Import( lhs.Export() | rhs.Export() );
870 else
871 for (int w = 0; w < alib::lang::TBitSet<TInterface,TEnd,TBegin>::QtyWords; ++w)
872 result.Import( lhs.Export(w) | rhs.Export(w), w );
873 return result;
874}
875
876/// Performs binary XOR operation two \b TBitSet objects (of equal size), \p{lhs} and \p{rhs}.
877/// \note This operator function is located in the global namespace. The documentation shows
878/// namespace <em>alib</em>, which is done for the purposes of organizing the manual
879/// index better.
880/// @param lhs The left-hand side operand.
881/// @param rhs The right-hand side operand.
882/// @tparam TEnd Template parameter of class \b TBitSet. Deduced by the compiler.
883/// @tparam TBegin Template parameter of class \b TBitSet. Deduced by the compiler.
884/// @tparam TInterface Template parameter of class \b TBitSet. Deduced by the compiler.
885/// @return A temporary \b TBitSet containing the result of the operation.
887template<typename TInterface, TInterface TEnd, TInterface TBegin>
890 const alib::lang::TBitSet<TInterface,TEnd,TBegin>& rhs ) noexcept {
894 result.Import( lhs.Export() ^ rhs.Export() );
895 else
896 for (int w = 0; w < alib::lang::TBitSet<TInterface,TEnd,TBegin>::QtyWords; ++w)
897 result.Import( lhs.Export(w) ^ rhs.Export(w), w );
898 return result;
899}
900#include "ALib.Lang.CIMethods.H"
901#if DOXYGEN
902} // namespace [alib::lang]
903#endif
Reference & operator=(const Reference &other) noexcept=default
constexpr Reference(TBitSetCM &set, TInterface b) noexcept
Definition bitset.inl:169
constexpr class TBitSet & TBitSet() noexcept
Definition bitset.inl:191
~Reference() noexcept
Destructor. (Is declared constexpr with C++23.)
Definition bitset.inl:177
constexpr Reference & Flip() noexcept
Definition bitset.inl:212
constexpr TInterface Bit() const noexcept
Definition bitset.inl:187
constexpr const class TBitSet & TBitSet() const noexcept
Definition bitset.inl:195
constexpr Reference & operator=(bool val) noexcept
Definition bitset.inl:200
constexpr bool operator==(const Reference &rhs) const noexcept=default
constexpr bool operator~() noexcept
Definition bitset.inl:208
constexpr Reference(const Reference &) noexcept=default
Defaulted copy constructor.
TInterface value_type
Implementation of std::iterator_traits.
Definition bitset.inl:576
TBidiIterator operator--(int)
Definition bitset.inl:696
TBidiIterator operator++(int)
Definition bitset.inl:667
Reference< TBitSetCM > & reference
Implementation of std::iterator_traits.
Definition bitset.inl:579
bool operator>=(TBidiIterator other) const
Definition bitset.inl:725
bool operator!=(const TBidiIterator &other) const
Definition bitset.inl:682
bool operator>(TBidiIterator other) const
Definition bitset.inl:719
void pointer
Implementation of std::iterator_traits.
Definition bitset.inl:578
bool operator<=(TBidiIterator other) const
Definition bitset.inl:713
TBidiIterator(TBitSetCM &bitSet, TInterface startBit)
Definition bitset.inl:657
bool operator<(TBidiIterator other) const
Definition bitset.inl:707
bool operator==(const TBidiIterator &other) const
Definition bitset.inl:677
int difference_type
Implementation of std::iterator_traits.
Definition bitset.inl:577
std::bidirectional_iterator_tag iterator_category
Implementation of std::iterator_traits.
Definition bitset.inl:575
ConstReverseIterator rend() const
Definition bitset.inl:795
constexpr bool All() const noexcept
Definition bitset.inl:332
constexpr TBitSet(TWord preset) noexcept
Definition bitset.inl:234
constexpr TBitSet & Flip() noexcept
Flips all bits from 0 to 1 and vice versa.
Definition bitset.inl:309
static constexpr TWord mask(int wIdx) noexcept
Definition bitset.inl:131
constexpr TBitSet & operator&=(const TBitSet &rhs) noexcept
Definition bitset.inl:436
constexpr void shiftRight(int cnt, TBitSet &target) const noexcept
Definition bitset.inl:494
constexpr TBitSet & Reset(TInterface firstBit, T &&... furtherBits) noexcept
Definition bitset.inl:283
constexpr TBitSet & operator|=(const TBitSet &rhs) noexcept
Definition bitset.inl:441
constexpr TBitSet() noexcept
Default constructor initializing all bits to not set.
Definition bitset.inl:223
constexpr int Count() const noexcept
Definition bitset.inl:322
constexpr TBitSet & Set(TInterface bit, bool val) noexcept
Definition bitset.inl:258
ReverseIterator rbegin(int skip=0)
Definition bitset.inl:757
constexpr TBitSet & Set(TInterface firstBit, T &&... furtherBits) noexcept
Definition bitset.inl:270
constexpr TBitSet & Reset() noexcept
Sets all bits to 0.
Definition bitset.inl:307
constexpr bool operator==(const TBitSet &rhs) const noexcept
Definition bitset.inl:426
constexpr TWord & word(TInterface b) noexcept
Definition bitset.inl:120
constexpr TBitSet & operator^=(const TBitSet &rhs) noexcept
Definition bitset.inl:446
constexpr TBitSet(bool preset) noexcept
Definition bitset.inl:244
ReverseIterator rend()
Definition bitset.inl:762
constexpr TBitSet operator>>(int cnt) const noexcept
Definition bitset.inl:535
ConstIterator cbegin(int skip=0) const
Definition bitset.inl:775
static constexpr int bitIdx(TInterface b) noexcept
Definition bitset.inl:109
ConstReverseIterator rbegin(int skip=0) const
Definition bitset.inl:790
constexpr bool Test(TInterface bit) noexcept
Definition bitset.inl:316
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:378
static constexpr TWord mask1101(TInterface b) noexcept
Definition bitset.inl:145
constexpr const TWord & word(TInterface b) const noexcept
Definition bitset.inl:125
constexpr TBitSet operator~() const noexcept
Definition bitset.inl:450
constexpr void Import(TWord val, int wordIdx) noexcept
Definition bitset.inl:406
static constexpr TWord mask0010(TInterface b) noexcept
Definition bitset.inl:140
constexpr const Reference< const TBitSet > operator[](int bit) const noexcept
Definition bitset.inl:554
ConstReverseIterator crbegin(int skip=0) const
Definition bitset.inl:801
constexpr TBitSet & Flip(TInterface firstBit, T &&... furtherBits) noexcept
Definition bitset.inl:296
constexpr Reference< TBitSet > operator[](TInterface bit) noexcept
Definition bitset.inl:547
constexpr TBitSet & Set() noexcept
Sets all bits to 1.
Definition bitset.inl:305
Iterator begin(int skip=0)
Definition bitset.inl:746
constexpr bool Any() const noexcept
Definition bitset.inl:342
constexpr TBitSet(const std::nullptr_t &) noexcept
Definition bitset.inl:228
constexpr TWord & Export(int wordIdx) noexcept
Definition bitset.inl:370
ConstIterator cend() const
Definition bitset.inl:784
ConstIterator begin(int skip=0) const
Definition bitset.inl:768
constexpr TBitSet & operator<<=(int cnt) noexcept
Definition bitset.inl:530
constexpr TBitSet & operator>>=(int cnt) noexcept
Definition bitset.inl:541
ConstIterator end() const
Definition bitset.inl:780
constexpr bool None() const noexcept
Definition bitset.inl:352
ConstReverseIterator crend() const
Definition bitset.inl:806
constexpr TBitSet operator<<(int cnt) const noexcept
Definition bitset.inl:524
static constexpr int wordIdx(TInterface b) noexcept
Definition bitset.inl:103
constexpr void shiftLeft(int cnt, TBitSet &target) const noexcept
Definition bitset.inl:463
#define bitsof(type)
Definition alib.inl:1435
#define ALIB_CPP_23(...)
Definition alib.inl:476
#define ALIB_EXPORT
Definition alib.inl:497
#define ALIB_ASSERT_ERROR(cond, domain,...)
Definition alib.inl:1066
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:838
constexpr int CLZ(TIntegral value)
Definition bits.inl:232
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:888
constexpr TIntegral UpperMask()
Definition bits.inl:107
constexpr int CTZ(TIntegral value)
Definition bits.inl:271
constexpr TIntegral LowerMask()
Definition bits.inl:51
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:863
constexpr int BitCount(TIntegral value)
Definition bits.inl:215
lang::TBitSet< int, TEnd, TBegin > BitSet
Type alias in namespace alib.
Definition bitset.inl:815