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