BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlc_bitarray.h
Go to the documentation of this file.
1/// @file bdlc_bitarray.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlc_bitarray.h -*-C++-*-
8#ifndef INCLUDED_BDLC_BITARRAY
9#define INCLUDED_BDLC_BITARRAY
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlc_bitarray bdlc_bitarray
15/// @brief Provide a space-efficient, sequential container of boolean values.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlc
19/// @{
20/// @addtogroup bdlc_bitarray
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlc_bitarray-purpose"> Purpose</a>
25/// * <a href="#bdlc_bitarray-classes"> Classes </a>
26/// * <a href="#bdlc_bitarray-description"> Description </a>
27/// * <a href="#bdlc_bitarray-bit-array-specific-functionality"> Bit-Array-Specific Functionality </a>
28/// * <a href="#bdlc_bitarray-performance-and-exception-safety-guarantees"> Performance and Exception-Safety Guarantees </a>
29/// * <a href="#bdlc_bitarray-usage"> Usage </a>
30/// * <a href="#bdlc_bitarray-example-1-creating-a-nullablevector-class"> Example 1: Creating a NullableVector Class </a>
31///
32/// # Purpose {#bdlc_bitarray-purpose}
33/// Provide a space-efficient, sequential container of boolean values.
34///
35/// # Classes {#bdlc_bitarray-classes}
36///
37/// - bdlc::BitArray: vector-like, sequential container of boolean values
38///
39/// # Description {#bdlc_bitarray-description}
40/// This component implements `bdlc::BitArray`, an efficient
41/// value-semantic, sequential container of boolean values (i.e., 0 or 1) of
42/// type `bool`. A `BitArray` may be thought of as an arbitrary-precision
43/// `unsigned int`. This metaphor is used to motivate the rich set of "bitwise"
44/// operations on `BitArray` objects provided by this component, as well as the
45/// notion of "zero extension" of a (shorter) bit array during binary operations
46/// on bit arrays having lengths that are not the same.
47///
48/// ## Bit-Array-Specific Functionality {#bdlc_bitarray-bit-array-specific-functionality}
49///
50///
51/// In addition to many typical vector-like container methods, this component
52/// supports "boolean" functionality unique to `BitArray`. However, unlike
53/// other standard container types such as `bsl::bitset`, there is no
54/// `operator[](bsl::size_t index)` that returns a reference to a (modifiable)
55/// boolean element at the specified index position. This difference is due to
56/// the densely-packed internal representation of bits within bit arrays:
57/// @code
58/// bdlc::BitArray mA(128);
59/// assert(0 == mA[13]); // Ok
60/// mA[13] = 'false'; // Error -- 'mA[13]' is not an lvalue.
61/// mA.assign(13, 1); // Ok
62///
63/// const bdlc::BitArray& A = mA; // Ok
64/// assert(1 == A[13]); // Ok
65/// const bool *bp = &A[13] // Error -- 'A[13]' is not an lvalue.
66/// const bool bit = A[13]; // Ok
67/// @endcode
68/// Also note that there is no `data` method returning a contiguous sequence of
69/// `bool`.
70///
71/// Finally note that, wherever an argument of non-boolean type -- e.g., the
72/// literal `5` (of type `int`) -- is used in a `BitArray` method to specify a
73/// boolean (bit) value, every non-zero value is automatically converted (via a
74/// standard conversion) to a `bool` value `true`, before the method of the
75/// `BitArray` is invoked:
76/// @code
77/// bdlc::BitArray a(10);
78/// assert(0 == a[5]);
79/// a.assign(5, 24); // Ok -- non-boolean value converted to 'true'.
80/// assert(1 == a[5]);
81/// @endcode
82///
83/// ## Performance and Exception-Safety Guarantees {#bdlc_bitarray-performance-and-exception-safety-guarantees}
84///
85///
86/// The asymptotic worst-case performance of representative operations is
87/// characterized using big-O notation, `O[f(N,M)]`, where `N` and `M` refer to
88/// the number of respective bits (i.e., `length`) of arrays `X` and `Y`,
89/// respectively. Here, *Amortized* *Case* complexity, denoted by `A[f(N)]`, is
90/// defined as the average of `N` successive invocations, as `N` gets very
91/// large.
92/// @code
93/// Average Exception-Safety
94/// Operation Worst Case Case Guarantee
95/// --------- ---------- ------- ----------------
96/// DEFAULT CTOR O[1] No-Throw
97/// COPY CTOR(Y) O[M] Exception Safe
98///
99/// X.DTOR() O[1] No-Throw
100///
101/// X.OP=(Y) O[M] Basic <*>
102/// X.insert(index, value) O[N] Basic <*>
103///
104/// X.reserveCapacity(M) O[N] Strong <*>
105/// X.append(value) O[N] A[1] Strong <*>
106///
107/// X.assign(index, value) O[1] No-Throw
108/// X.assign1(value) O[1] No-Throw
109/// X.assign0(value) O[1] No-Throw
110///
111/// X.remove(index) O[N] No-Throw
112/// X.assignAll0() O[N] No-Throw
113/// X.assignAll1() O[N] No-Throw
114///
115/// X.length() O[1] No-Throw
116/// X.OP@ref index O[1] No-Throw
117///
118/// X.isAny1 O[N] No-Throw
119/// X.isAny0 O[N] No-Throw
120///
121/// other 'const' methods O[1] .. O[N] No-Throw
122///
123/// OP==(X, Y) O[min(N, M)] No-Throw
124/// OP!=(X, Y) O[min(N, M)] No-Throw
125///
126/// <*> No-Throw guarantee when capacity is sufficient.
127/// @endcode
128/// Note that *all* of the non-creator methods of `BitArray` provide the
129/// *No-Throw* guarantee whenever sufficient capacity is already available.
130///
131/// ## Usage {#bdlc_bitarray-usage}
132///
133///
134/// This section illustrates the intended use of this component.
135///
136/// ### Example 1: Creating a NullableVector Class {#bdlc_bitarray-example-1-creating-a-nullablevector-class}
137///
138///
139/// An efficient implementation of an arbitrary precision bit sequence container
140/// has myriad applications. For example, a `bdlc::BitArray` can be used
141/// effectively as a parallel array of flags indicating some special property,
142/// such as `isNull`, `isBusinessDay`, etc.; its use is especially indicated
143/// when (1) the number of elements of the primary array can grow large, and (2)
144/// the individual elements do not have the capacity or capability to store the
145/// information directly.
146///
147/// As a simple example, we'll implement a (heavily elided) value-semantic
148/// template class, `NullableVector<TYPE>`, that behaves like a
149/// `bsl::vector<TYPE>` but additionally allows storing a nullness flag to
150/// signify that the corresponding element was not specified. Elements added to
151/// a `NullableVector` are null by default, although there are manipulator
152/// functions that allow appending a non-null element. Each null element
153/// stores the default value for `TYPE`.
154///
155/// Note that this class has a minimal interface (suitable for illustration
156/// purpose only) that allows users to either append a (non-null) `TYPE` value
157/// or a null value. A real `NullableVector` class would support a complete set
158/// of *value* *semantic* operations, including copy construction, assignment,
159/// equality comparison, `ostream` printing, and BDEX serialization. Also note
160/// that, for simplicity, exception-neutrality is ignored (some methods are
161/// clearly not exception-neutral).
162///
163/// First, we define the interface of `NullableVector`:
164/// @code
165/// template <class TYPE>
166/// class NullableVector {
167/// // This class implements a sequential container of elements of the
168/// // template parameter 'TYPE'.
169///
170/// // DATA
171/// bsl::vector<TYPE> d_values; // data elements
172/// bdlc::BitArray d_nullFlags; // 'true' indicates i'th element is
173/// // null
174///
175/// private:
176/// // NOT IMPLEMENTED
177/// NullableVector(const NullableVector&);
178/// NullableVector& operator=(const NullableVector&);
179///
180/// public:
181/// // TRAITS
182/// BSLMF_NESTED_TRAIT_DECLARATION(NullableVector,
183/// bslma::UsesBslmaAllocator);
184///
185/// public:
186/// // CREATORS
187/// explicit
188/// NullableVector(bsl::size_t initialLength,
189/// bslma::Allocator *basicAllocator = 0);
190/// // Construct a vector having the specified 'initialLength' null
191/// // elements. Optionally specify a 'basicAllocator' used to supply
192/// // memory. If 'basicAllocator' is 0, the currently supplied
193/// // default allocator is used.
194///
195/// // ...
196///
197/// ~NullableVector();
198/// // Destroy this vector.
199///
200/// // MANIPULATORS
201/// void appendNullElement();
202/// // Append a null element to this vector. Note that the appended
203/// // element will have the same value as a default constructed 'TYPE'
204/// // object.
205///
206/// void appendElement(const TYPE& value);
207/// // Append an element having the specified 'value' to the end of
208/// // this vector.
209///
210/// void makeNonNull(bsl::size_t index);
211/// // Make the element at the specified 'index' in this vector
212/// // non-null. The behavior is undefined unless 'index < length()'.
213///
214/// void makeNull(bsl::size_t index);
215/// // Make the element at the specified 'index' in this vector null.
216/// // The behavior is undefined unless 'index < length()'. Note that
217/// // the new value of the element will be the default constructed
218/// // value for 'TYPE'.
219///
220/// TYPE& modifiableElement(bsl::size_t index);
221/// // Return a reference providing modifiable access to the (valid)
222/// // element at the specified 'index' in this vector. The behavior
223/// // is undefined unless 'index < length()'. Note that if the
224/// // element at 'index' is null then the nullness flag is reset and
225/// // the returned value is the default constructed value for 'TYPE'.
226///
227/// void removeElement(bsl::size_t index);
228/// // Remove the element at the specified 'index' in this vector. The
229/// // behavior is undefined unless 'index < length()'.
230///
231/// // ACCESSORS
232/// const TYPE& constElement(bsl::size_t index) const;
233/// // Return a reference providing non-modifiable access to the
234/// // element at the specified 'index' in this vector. The behavior
235/// // is undefined unless 'index < length()'. Note that if the
236/// // element at 'index' is null then the nullness flag is not reset
237/// // and the returned value is the default constructed value for
238/// // 'TYPE'.
239///
240/// bool isAnyElementNonNull() const;
241/// // Return 'true' if any element in this vector is non-null, and
242/// // 'false' otherwise.
243///
244/// bool isAnyElementNull() const;
245/// // Return 'true' if any element in this vector is null, and 'false'
246/// // otherwise.
247///
248/// bool isElementNull(bsl::size_t index) const;
249/// // Return 'true' if the element at the specified 'index' in this
250/// // vector is null, and 'false' otherwise. The behavior is
251/// // undefined unless 'index < length()'.
252///
253/// bsl::size_t length() const;
254/// // Return the number of elements in this vector.
255///
256/// bsl::size_t numNullElements() const;
257/// // Return the number of null elements in this vector.
258/// };
259/// @endcode
260/// Then, we implement, in turn, each of the methods declared above:
261/// @code
262/// // --------------------
263/// // class NullableVector
264/// // --------------------
265///
266/// // CREATORS
267/// template <class TYPE>
268/// NullableVector<TYPE>::NullableVector(bsl::size_t initialLength,
269/// bslma::Allocator *basicAllocator)
270/// : d_values(initialLength, TYPE(), basicAllocator)
271/// , d_nullFlags(initialLength, true, basicAllocator)
272/// {
273/// }
274///
275/// template <class TYPE>
276/// NullableVector<TYPE>::~NullableVector()
277/// {
278/// BSLS_ASSERT(d_values.size() == d_nullFlags.length());
279/// }
280///
281/// // MANIPULATORS
282/// template <class TYPE>
283/// inline
284/// void NullableVector<TYPE>::appendElement(const TYPE& value)
285/// {
286/// d_values.push_back(value);
287/// d_nullFlags.append(false);
288/// }
289///
290/// template <class TYPE>
291/// inline
292/// void NullableVector<TYPE>::appendNullElement()
293/// {
294/// d_values.push_back(TYPE());
295/// d_nullFlags.append(true);
296/// }
297///
298/// template <class TYPE>
299/// inline
300/// void NullableVector<TYPE>::makeNonNull(bsl::size_t index)
301/// {
302/// BSLS_ASSERT_SAFE(index < length());
303///
304/// d_nullFlags.assign(index, false);
305/// }
306///
307/// template <class TYPE>
308/// inline
309/// void NullableVector<TYPE>::makeNull(bsl::size_t index)
310/// {
311/// BSLS_ASSERT_SAFE(index < length());
312///
313/// d_values[index] = TYPE();
314/// d_nullFlags.assign(index, true);
315/// }
316///
317/// template <class TYPE>
318/// inline
319/// TYPE& NullableVector<TYPE>::modifiableElement(bsl::size_t index)
320/// {
321/// BSLS_ASSERT_SAFE(index < length());
322///
323/// d_nullFlags.assign(index, false);
324/// return d_values[index];
325/// }
326///
327/// template <class TYPE>
328/// inline
329/// void NullableVector<TYPE>::removeElement(bsl::size_t index)
330/// {
331/// BSLS_ASSERT_SAFE(index < length());
332///
333/// d_values.erase(d_values.begin() + index);
334/// d_nullFlags.remove(index);
335/// }
336///
337/// // ACCESSORS
338/// template <class TYPE>
339/// inline
340/// const TYPE& NullableVector<TYPE>::constElement(bsl::size_t index) const
341/// {
342/// BSLS_ASSERT_SAFE(index < length());
343///
344/// return d_values[index];
345/// }
346///
347/// template <class TYPE>
348/// inline
349/// bool NullableVector<TYPE>::isAnyElementNonNull() const
350/// {
351/// return d_nullFlags.isAny0();
352/// }
353///
354/// template <class TYPE>
355/// inline
356/// bool NullableVector<TYPE>::isAnyElementNull() const
357/// {
358/// return d_nullFlags.isAny1();
359/// }
360///
361/// template <class TYPE>
362/// inline
363/// bool NullableVector<TYPE>::isElementNull(bsl::size_t index) const
364/// {
365/// BSLS_ASSERT_SAFE(index < length());
366///
367/// return d_nullFlags[index];
368/// }
369///
370/// template <class TYPE>
371/// inline
372/// bsl::size_t NullableVector<TYPE>::length() const
373/// {
374/// return d_values.size();
375/// }
376///
377/// template <class TYPE>
378/// inline
379/// bsl::size_t NullableVector<TYPE>::numNullElements() const
380/// {
381/// return d_nullFlags.num1();
382/// }
383/// @endcode
384/// Next, we create an empty `NullableVector`:
385/// @code
386/// NullableVector<int> array(0);
387/// const NullableVector<int>& ARRAY = array;
388/// const int DEFAULT_INT = 0;
389///
390/// assert(0 == ARRAY.length());
391/// assert(0 == ARRAY.numNullElements());
392/// assert(false == ARRAY.isAnyElementNonNull());
393/// assert(false == ARRAY.isAnyElementNull());
394/// @endcode
395/// Then, we append a non-null element to it:
396/// @code
397/// array.appendElement(5);
398/// assert(1 == ARRAY.length());
399/// assert(5 == ARRAY.constElement(0));
400/// assert(false == ARRAY.isElementNull(0));
401/// assert(0 == ARRAY.numNullElements());
402/// assert(true == ARRAY.isAnyElementNonNull());
403/// assert(false == ARRAY.isAnyElementNull());
404/// @endcode
405/// Next, we append a null element:
406/// @code
407/// array.appendNullElement();
408/// assert(2 == ARRAY.length());
409/// assert(5 == ARRAY.constElement(0));
410/// assert(DEFAULT_INT == ARRAY.constElement(1));
411/// assert(false == ARRAY.isElementNull(0));
412/// assert(true == ARRAY.isElementNull(1));
413/// assert(1 == ARRAY.numNullElements());
414/// assert(true == ARRAY.isAnyElementNonNull());
415/// assert(true == ARRAY.isAnyElementNull());
416/// @endcode
417/// Then, we make the null element non-null:
418/// @code
419/// array.makeNonNull(1);
420/// assert(2 == ARRAY.length());
421/// assert(5 == ARRAY.constElement(0));
422/// assert(DEFAULT_INT == ARRAY.constElement(1));
423/// assert(false == ARRAY.isElementNull(0));
424/// assert(false == ARRAY.isElementNull(1));
425/// assert(0 == ARRAY.numNullElements());
426/// assert(true == ARRAY.isAnyElementNonNull());
427/// assert(false == ARRAY.isAnyElementNull());
428/// @endcode
429/// Next, we make the first element null:
430/// @code
431/// array.makeNull(0);
432/// assert(2 == ARRAY.length());
433/// assert(DEFAULT_INT == ARRAY.constElement(0));
434/// assert(DEFAULT_INT == ARRAY.constElement(1));
435/// assert(true == ARRAY.isElementNull(0));
436/// assert(false == ARRAY.isElementNull(1));
437/// assert(1 == ARRAY.numNullElements());
438/// assert(true == ARRAY.isAnyElementNonNull());
439/// assert(true == ARRAY.isAnyElementNull());
440/// @endcode
441/// Now, we remove the front element:
442/// @code
443/// array.removeElement(0);
444/// assert(1 == ARRAY.length());
445/// assert(DEFAULT_INT == ARRAY.constElement(0));
446/// assert(false == ARRAY.isElementNull(0));
447/// assert(0 == ARRAY.numNullElements());
448/// assert(true == ARRAY.isAnyElementNonNull());
449/// assert(false == ARRAY.isAnyElementNull());
450/// @endcode
451/// Finally, we remove the last remaining element and observe that the object is
452/// empty again:
453/// @code
454/// array.removeElement(0);
455/// assert(0 == ARRAY.length());
456/// assert(0 == ARRAY.numNullElements());
457/// assert(false == ARRAY.isAnyElementNonNull());
458/// assert(false == ARRAY.isAnyElementNull());
459/// @endcode
460/// @}
461/** @} */
462/** @} */
463
464/** @addtogroup bdl
465 * @{
466 */
467/** @addtogroup bdlc
468 * @{
469 */
470/** @addtogroup bdlc_bitarray
471 * @{
472 */
473
474#include <bdlscm_version.h>
475
476#include <bdlb_bitmaskutil.h>
477#include <bdlb_bitstringutil.h>
478
479#include <bslalg_swaputil.h>
480
481#include <bslma_allocator.h>
483
486
487#include <bsls_assert.h>
488#include <bsls_review.h>
489#include <bsls_types.h>
490
491#include <bsl_cstddef.h>
492#include <bsl_cstdint.h>
493#include <bsl_climits.h>
494#include <bsl_cstring.h>
495#include <bsl_iosfwd.h>
496#include <bsl_vector.h>
497
498#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
499#include <bsl_algorithm.h>
500#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
501
502
503namespace bdlc {
504
505 // ==============
506 // class BitArray
507 // ==============
508
509/// This class implements an efficient, value-semantic array of boolean
510/// (a.k.a. bit, i.e., binary digit) values stored in contiguous memory.
511/// The physical capacity of this array may grow, but never shrinks.
512/// Capacity may be reserved initially via a constructor, or at any time
513/// thereafter by using the `reserveCapacity` method; otherwise, capacity
514/// will be increased automatically as needed. Note that capacity is not a
515/// *salient* attribute of this object, and, as such, does not contribute to
516/// overall value. Also note that this class provides an implicit no-throw
517/// guarantee for all methods (including manipulators) that do not attempt
518/// to alter capacity.
519///
520/// See @ref bdlc_bitarray
521class BitArray {
522
523 public:
524 // PUBLIC TYPES
525 enum { k_BITS_PER_UINT64 = 64 }; // bits used to represent a 'uint64_t'
526
527 // PUBLIC CLASS DATA
528 static const bsl::size_t k_INVALID_INDEX =
530
531 private:
532 // DATA
533 bsl::vector<bsl::uint64_t> d_array; // array of 64-bit words
534 bsl::size_t d_length; // number of significant bits in this
535 // array
536
537 // CLASS DATA
538 static const bsl::uint64_t s_one = 1;
539 static const bsl::uint64_t s_minusOne = ~static_cast<bsl::uint64_t>(0);
540
541 // FRIENDS
542 friend bool operator==(const BitArray&, const BitArray&);
543
544 private:
545 // PRIVATE CLASS METHODS
546
547 /// Return the size, in 64-bit words, of the integer array required to
548 /// store the specified `numBits`.
549 static bsl::size_t arraySize(bsl::size_t numBits);
550
551 // PRIVATE MANIPULATORS
552
553 /// Return an address providing modifiable access to the array of
554 /// `uint64_t` values managed by this array.
555 bsl::uint64_t *data();
556
557 // PRIVATE ACCESSORS
558
559 /// Return an address providing non-modifiable access to the array of
560 /// `uint64_t` values managed by this array.
561 const bsl::uint64_t *data() const;
562
563 public:
564 // CLASS METHODS
565
566 // Aspects
567
568 /// Return the maximum valid BDEX format version, as indicated by the
569 /// specified `versionSelector`, to be passed to the `bdexStreamOut`
570 /// method. Note that it is highly recommended that `versionSelector`
571 /// be formatted as "YYYYMMDD", a date representation. Also note that
572 /// `versionSelector` should be a *compile*-time-chosen value that
573 /// selects a format version supported by both externalizer and
574 /// unexternalizer. See the `bslx` package-level documentation for more
575 /// information on BDEX streaming of value-semantic types and
576 /// containers.
577 static int maxSupportedBdexVersion(int versionSelector);
578
579 // CREATORS
580
581 explicit
582 BitArray(bslma::Allocator *basicAllocator = 0);
583 explicit
584 BitArray(bsl::size_t initialLength,
585 bslma::Allocator *basicAllocator = 0);
586 /// Create an array of binary digits (bits). By default, the array is
587 /// empty and has a capacity of 0 bits. Optionally specify the
588 /// `initialLength` (in bits) of the array. If `initialLength` is not
589 /// specified, the default length is 0. If `initialLength` is
590 /// specified, optionally specify the `value` for each bit in the
591 /// `initialLength`. If `value` is not specified, the default value for
592 /// each bit is `false` (0). Optionally specify a `basicAllocator` used
593 /// to supply memory. If `basicAllocator` is 0, the currently installed
594 /// default allocator is used.
595 BitArray(bsl::size_t initialLength,
596 bool value,
597 bslma::Allocator *basicAllocator = 0);
598
599 /// Create an array of binary digits (bits) having the same value as the
600 /// specified `original` array. Optionally specify a `basicAllocator`
601 /// used to supply memory. If `basicAllocator` is 0, the currently
602 /// installed default allocator is used.
603 BitArray(const BitArray& original,
604 bslma::Allocator *basicAllocator = 0);
605
606 /// Destroy this object.
608
609 // MANIPULATORS
610
611 /// Assign to this array the value of the specified `rhs` array, and
612 /// return a non-`const` reference to this array.
613 BitArray& operator=(const BitArray& rhs);
614
615 /// Bitwise AND the value of the specified `rhs` array with the value of
616 /// this array (retaining the results), and return a non-`const`
617 /// reference to this object. The length of the result will be the
618 /// maximum of the lengths of this object and `rhs`, where any
619 /// most-significant bits that are represented in one of the two but not
620 /// the other will be set to 0. Note that `a &= b;` will result in the
621 /// same value of `a` as `a = a & b;`.
622 BitArray& operator&=(const BitArray& rhs);
623
624 /// Bitwise MINUS the value of the specified `rhs` array from the value
625 /// of this array (retaining the results), and return a non-`const`
626 /// reference to this object. The length of the result will be the
627 /// maximum of the lengths of this object and `rhs`. If
628 /// `length() > rhs.length()`, the unmatched most-significant bits in
629 /// this array are left unchanged; otherwise, any high-order bits of the
630 /// result that were not present in this object prior to the operation
631 /// will be set to 0. Note that `a -= b;` will result in the same value
632 /// of `a` as `a = a - b;` and if `a` and `b` are the same length,
633 /// `a -= b;` will result in the same value of `a` as `a &= ~b;` or
634 /// `a = a & ~b;`.
635 BitArray& operator-=(const BitArray& rhs);
636
637 /// Bitwise OR the value of the specified `rhs` array with the value of
638 /// this array (retaining the results), and return a non-`const`
639 /// reference to this object. If `length() > rhs.length()`, the
640 /// unmatched most-significant bits in this array are left unchanged;
641 /// otherwise, any unmatched most-significant bits in `rhs` are
642 /// propagated to the result without modification. Note that `a |= b;`
643 /// will result in the same value of `a` as `a = a | b;`.
644 BitArray& operator|=(const BitArray& rhs);
645
646 /// Bitwise XOR the value of the specified `rhs` array with the value of
647 /// this array (retaining the results), and return a non-`const`
648 /// reference to this object. If `length() > rhs.length()`, the
649 /// unmatched most-significant bits in this array are left unchanged;
650 /// otherwise, any unmatched most-significant bits in `rhs` are
651 /// propagated to the result without modification. Note that `a ^= b;`
652 /// will result in the same value of `a` as `a = a ^ b;`.
653 BitArray& operator^=(const BitArray& rhs);
654
655 /// Shift the bits in this array LEFT by the specified `numBits`,
656 /// filling lower-order bits with zeros (retaining the results), and
657 /// return a non-`const` reference to this object. The behavior is
658 /// undefined unless `numBits <= length()`. Note that the length of
659 /// this array is unchanged and the highest-order `numBits` are
660 /// discarded.
661 BitArray& operator<<=(bsl::size_t numBits);
662
663 /// Shift the bits in this array RIGHT by the specified `numBits`,
664 /// filling higher-order bits with zeros and discarding low-order bits,
665 /// and return a non-`const` reference to this object. The behavior is
666 /// undefined unless `numBits <= length()`. Note that the length of
667 /// this array is unchanged.
668 BitArray& operator>>=(bsl::size_t numBits);
669
670 /// AND the bit at the specified `index` in this array with the
671 /// specified `value` (retaining the result). The behavior is undefined
672 /// unless `index < length()`.
673 void andEqual(bsl::size_t index, bool value);
674
675 /// Bitwise AND the specified `numBits` in this array, beginning at the
676 /// specified `dstIndex`, with values from the specified `srcArray`,
677 /// beginning at the specified `srcIndex` (retaining the results). The
678 /// behavior is undefined unless `dstIndex + numBits <= length()` and
679 /// `srcIndex + numBits <= srcArray.length()`.
680 void andEqual(bsl::size_t dstIndex,
681 const BitArray& srcArray,
682 bsl::size_t srcIndex,
683 bsl::size_t numBits);
684
685 /// Append to this array the specified `value`. Note that this method
686 /// has the same behavior as:
687 /// @code
688 /// insert(length(), value);
689 /// @endcode
690 void append(bool value);
691
692 /// Append to this array the specified `numBits` having the specified
693 /// `value`. Note that this method has the same behavior as:
694 /// @code
695 /// insert(length(), value, numBits);
696 /// @endcode
697 void append(bool value, bsl::size_t numBits);
698
699 /// Append to this array the values from the specified `srcArray`. Note
700 /// that this method has the same behavior as:
701 /// @code
702 /// insert(length(), srcArray);
703 /// @endcode
704 void append(const BitArray& srcArray);
705
706 /// Append to this array the specified `numBits` from the specified
707 /// `srcArray`, beginning at the specified `srcIndex`. The behavior is
708 /// undefined unless `srcIndex + numBits <= srcArray.length()`. Note
709 /// that this method has the same behavior as:
710 /// @code
711 /// insert(length(), srcArray, srcIndex, numBits);
712 /// @endcode
713 void append(const BitArray& srcArray,
714 bsl::size_t srcIndex,
715 bsl::size_t numBits);
716
717 /// Set the value at the specified `index` in this array to the
718 /// specified `value`. The behavior is undefined unless
719 /// `index < length()`.
720 void assign(bsl::size_t index, bool value);
721
722 /// Set the value of the specified `numBits` bits starting at the
723 /// specified `index` in this array to the specified `value`. The
724 /// behavior is undefined unless `index + numBits < length()`.
725 void assign(bsl::size_t index, bool value, bsl::size_t numBits);
726
727 /// Replace the specified `numBits` in this array, beginning at the
728 /// specified `dstIndex`, with values from the specified `srcArray`
729 /// beginning at the specified `srcIndex`. The behavior is undefined
730 /// unless `dstIndex + numBits <= length()` and
731 /// `srcIndex + numBits <= srcArray.length()`. Note that, absent
732 /// aliasing, this method has the same behavior as, but is more
733 /// efficient than:
734 /// @code
735 /// remove(dstIndex, numBits);
736 /// insert(dstIndex, srcArray, srcIndex, numBits);
737 /// @endcode
738 void assign(bsl::size_t dstIndex,
739 const BitArray& srcArray,
740 bsl::size_t srcIndex,
741 bsl::size_t numBits);
742
743 /// Set to 0 the value of the bit at the specified `index` in this
744 /// array. The behavior is undefined unless `index < length()`.
745 void assign0(bsl::size_t index);
746
747 /// Set to 0 the specified `numBits` values in this array, beginning at
748 /// the specified `index`. The behavior is undefined unless
749 /// `index + numBits <= length()`.
750 void assign0(bsl::size_t index, bsl::size_t numBits);
751
752 /// Set to 1 the value of the bit at the specified `index` in this
753 /// array. The behavior is undefined unless `index < length()`.
754 void assign1(bsl::size_t index);
755
756 /// Set to 1 the specified `numBits` values in this array, beginning at
757 /// the specified `index`. The behavior is undefined unless
758 /// `index + numBits <= length()`.
759 void assign1(bsl::size_t index, bsl::size_t numBits);
760
761 /// Set all bits in this array to the specified `value`.
762 void assignAll(bool value);
763
764 /// Set to 0 the value of every bit in this array.
765 void assignAll0();
766
767 /// Set to 1 the value of every bit in this array.
768 void assignAll1();
769
770 /// Assign the low-order specified `numBits` from the specified
771 /// `srcBits` to this object, starting at the specified `index`. The
772 /// behavior is undefined unless `numBits <= k_BITS_PER_UINT64` and
773 /// `index + numBits <= length()`.
774 void assignBits(bsl::size_t index,
775 bsl::uint64_t srcBits,
776 bsl::size_t numBits);
777
778 /// Insert into this array at the specified `dstIndex` the specified
779 /// `value`. All values with indices at or above `dstIndex` in this
780 /// array are shifted up by one bit position. The behavior is undefined
781 /// unless `dstIndex <= length()`.
782 void insert(bsl::size_t dstIndex, bool value);
783
784 /// Insert into this array at the specified `dstIndex` the specified
785 /// `numBits` having the specified `value`. All values with indices at
786 /// or above `dstIndex` in this array are shifted up by `numBits` bit
787 /// positions. The behavior is undefined unless `dstIndex <= length()`.
788 void insert(bsl::size_t dstIndex, bool value, bsl::size_t numBits);
789
790 /// Insert into this array, beginning at the specified `dstIndex`, the
791 /// values from the specified `srcArray`. All values with indices at or
792 /// above `dstIndex` in this array are shifted up by `srcArray.length()`
793 /// bit positions. The behavior is undefined unless
794 /// `dstIndex <= length()`.
795 void insert(bsl::size_t dstIndex, const BitArray& srcArray);
796
797 /// Insert into this array, beginning at the specified `dstIndex`, the
798 /// specified `numBits` from the specified `srcArray` beginning at the
799 /// specified `srcIndex`. All values with initial indices at or above
800 /// `dstIndex` are shifted up by `numBits` positions. The behavior is
801 /// undefined unless `dstIndex <= length()` and
802 /// `srcIndex + numBits <= srcArray.length()`.
803 void insert(bsl::size_t dstIndex,
804 const BitArray& srcArray,
805 bsl::size_t srcIndex,
806 bsl::size_t numBits);
807
808 /// MINUS (subtract) from the bit at the specified `index` in this array
809 /// the specified `value` (retaining the result). The behavior is
810 /// undefined unless `index < length()`. Note that the logical
811 /// difference `A - B` is defined to be `A & !B`.
812 void minusEqual(bsl::size_t index, bool value);
813
814 /// Bitwise MINUS (subtract) from the specified `numBits` in this array,
815 /// beginning at the specified `dstIndex`, values from the specified
816 /// `srcArray` beginning at the specified `srcIndex` (retaining the
817 /// results). The behavior is undefined unless
818 /// `dstIndex + numBits <= length()` and
819 /// `srcIndex + numBits <= srcArray.length()`. Note that the logical
820 /// difference `A - B` is defined to be `A & !B`.
821 void minusEqual(bsl::size_t dstIndex,
822 const BitArray& srcArray,
823 bsl::size_t srcIndex,
824 bsl::size_t numBits);
825
826 /// OR the bit at the specified `index` in this array with the specified
827 /// `value` (retaining the result). The behavior is undefined unless
828 /// `index < length()`.
829 void orEqual(bsl::size_t index, bool value);
830
831 /// Bitwise OR the specified `numBits` in this array, beginning at the
832 /// specified `dstIndex`, with values from the specified `srcArray`
833 /// beginning at the specified `srcIndex` (retaining the results). The
834 /// behavior is undefined unless `dstIndex + numBits <= length()` and
835 /// `srcIndex + numBits <= srcArray.length()`.
836 void orEqual(bsl::size_t dstIndex,
837 const BitArray& srcArray,
838 bsl::size_t srcIndex,
839 bsl::size_t numBits);
840
841 /// Remove from this array the bit at the specified `index`. All values
842 /// at indices above `index` in this array are shifted down by one bit
843 /// position. The length of this array is reduced by 1. The behavior
844 /// is undefined unless `index < length()`.
845 void remove(bsl::size_t index);
846
847 /// Remove from this array the specified `numBits`, beginning at the
848 /// specified `index`. All values at indices above `index` in this
849 /// array are shifted down by `numBits` positions. The length of this
850 /// array is reduced by `numBits`. The behavior is undefined unless
851 /// `index + numBits <= length()`.
852 void remove(bsl::size_t index, bsl::size_t numBits);
853
854 /// Remove all of the bits in this array, leaving the length 0, but
855 /// having no effect on capacity.
856 void removeAll();
857
858 /// Reserve sufficient internal capacity to accommodate a length of at
859 /// least the specified `numBits` without reallocation. If an exception
860 /// is thrown during this reallocation attempt (i.e., by the memory
861 /// allocator indicated at construction) the value of this array is
862 /// guaranteed to be unchanged.
863 void reserveCapacity(bsl::size_t numBits);
864
865 /// Shift the values in this array to the left by the specified
866 /// `numBits` positions, with the high-order values "rotating" into the
867 /// low-order bits. The behavior is undefined unless
868 /// `numBits <= length()`. Note that the length of this array remains
869 /// unchanged.
870 void rotateLeft(bsl::size_t numBits);
871
872 /// Shift the values in this array to the right by the specified
873 /// `numBits` positions, with the low-order values "rotating" into the
874 /// high-order bits. The behavior is undefined unless
875 /// `numBits <= length()`. Note that the length of this array remains
876 /// unchanged.
877 void rotateRight(bsl::size_t numBits);
878
879 /// Set the number of bits in this array to the specified `newLength`.
880 /// If `newLength < length()`, bits at index positions at or above
881 /// `newLength` are removed; otherwise, any new bits (at or above the
882 /// current length) are initialized to the optionally specified `value`,
883 /// or to 0 if `value` is not specified.
884 void setLength(bsl::size_t newLength, bool value = false);
885
886 /// Efficiently exchange the values of the bits at the specified
887 /// `index1` and `index2` indices. The behavior is undefined unless
888 /// `index1 < length()` and `index2 < length()`.
889 void swapBits(bsl::size_t index1, bsl::size_t index2);
890
891 /// Complement the value of the bit at the specified `index` in this
892 /// array. The behavior is undefined unless `index < length()`.
893 void toggle(bsl::size_t index);
894
895 /// Complement the values of each of the specified `numBits` in this
896 /// array, beginning at the specified `index`. The behavior is
897 /// undefined unless `index + numBits <= length()`.
898 void toggle(bsl::size_t index, bsl::size_t numBits);
899
900 /// Complement the value of every bit in this array. Note that the
901 /// behavior is analogous to applying the `~` operator to an object of
902 /// fundamental type `unsigned int`.
903 void toggleAll();
904
905 /// XOR the bit at the specified `index` in this array with the
906 /// specified `value` (retaining the result). The behavior is undefined
907 /// unless `index < length()`.
908 void xorEqual(bsl::size_t index, bool value);
909
910 /// Bitwise XOR the specified `numBits` in this array, beginning at the
911 /// specified `dstIndex`, with values from the specified `srcArray`
912 /// beginning at the specified `srcIndex` (retaining the results). The
913 /// behavior is undefined unless `dstIndex + numBits <= length()` and
914 /// `srcIndex + numBits <= srcArray.length()`.
915 void xorEqual(bsl::size_t dstIndex,
916 const BitArray& srcArray,
917 bsl::size_t srcIndex,
918 bsl::size_t numBits);
919
920 // Aspects
921
922 /// Assign to this object the value read from the specified input
923 /// `stream` using the specified `version` format, and return a
924 /// reference to `stream`. If `stream` is initially invalid, this
925 /// operation has no effect. If `version` is not supported, this object
926 /// is unaltered and `stream` is invalidated, but otherwise unmodified.
927 /// If `version` is supported but `stream` becomes invalid during this
928 /// operation, this object has an undefined, but valid, state. Note
929 /// that no version is read from `stream`. See the `bslx` package-level
930 /// documentation for more information on BDEX streaming of
931 /// value-semantic types and containers.
932 template <class STREAM>
933 STREAM& bdexStreamIn(STREAM& stream, int version);
934
935 /// Efficiently exchange the value of this object with the value of the
936 /// specified `other` object. This method provides the no-throw
937 /// exception-safety guarantee. The behavior is undefined unless this
938 /// object was created with the same allocator as `other`.
939 void swap(BitArray& other);
940
941 // ACCESSORS
942
943 /// Return the value of the bit at the specified `index` in this array.
944 /// The behavior is undefined unless `index < length()`.
945 bool operator[](bsl::size_t index) const;
946
947 /// Return the specified `numBits` beginning at the specified `index` in
948 /// this array as the low-order bits of the returned value. The
949 /// behavior is undefined unless
950 /// `numBits <= sizeof(uint64_t) * CHAR_BIT` and
951 /// `index + numBits <= length()`.
952 bsl::uint64_t bits(bsl::size_t index, bsl::size_t numBits) const;
953
954 /// Return the index of the most-significant 0 bit in this array in the
955 /// range optionally specified by `begin` and `end`, and
956 /// `k_INVALID_INDEX` otherwise. The range is
957 /// `[begin .. effectiveEnd)`, where `effectiveEnd == length()` if `end`
958 /// is not specified and `effectiveEnd == end` otherwise. The behavior
959 /// is undefined unless `begin <= effectiveEnd <= length()`.
960 bsl::size_t find0AtMaxIndex(bsl::size_t begin = 0,
961 bsl::size_t end = k_INVALID_INDEX) const;
962
963 /// Return the index of the least-significant 0 bit in this array in the
964 /// range optionally specified by `begin` and `end`, and
965 /// `k_INVALID_INDEX` otherwise. The range is
966 /// `[begin .. effectiveEnd)`, where `effectiveEnd == length()` if `end`
967 /// is not specified and `effectiveEnd == end` otherwise. The behavior
968 /// is undefined unless `begin <= effectiveEnd <= length()`.
969 bsl::size_t find0AtMinIndex(bsl::size_t begin = 0,
970 bsl::size_t end = k_INVALID_INDEX) const;
971
972 /// Return the index of the most-significant 1 bit in this array in the
973 /// range optionally specified by `begin` and `end`, and
974 /// `k_INVALID_INDEX` otherwise. The range is
975 /// `[begin .. effectiveEnd)`, where `effectiveEnd == length()` if `end`
976 /// is not specified and `effectiveEnd == end` otherwise. The behavior
977 /// is undefined unless `begin <= effectiveEnd <= length()`.
978 bsl::size_t find1AtMaxIndex(bsl::size_t begin = 0,
979 bsl::size_t end = k_INVALID_INDEX) const;
980
981 /// Return the index of the least-significant 1 bit in this array in the
982 /// range optionally specified by `begin` and `end`, and
983 /// `k_INVALID_INDEX` otherwise. The range is
984 /// `[begin .. effectiveEnd)`, where `effectiveEnd == length()` if `end`
985 /// is not specified and `effectiveEnd == end` otherwise. The behavior
986 /// is undefined unless `begin <= effectiveEnd <= length()`.
987 bsl::size_t find1AtMinIndex(bsl::size_t begin = 0,
988 bsl::size_t end = k_INVALID_INDEX) const;
989
990 /// Return `true` if the value of any bit in this array is 0, and
991 /// `false` otherwise.
992 bool isAny0() const;
993
994 /// Return `true` if the value of any bit in this array is 1, and
995 /// `false` otherwise.
996 bool isAny1() const;
997
998 /// Return `true` if the length of this bit array is 0, and `false`
999 /// otherwise.
1000 bool isEmpty() const;
1001
1002 /// Return the number of bits in this array.
1003 bsl::size_t length() const;
1004
1005 /// Return the number of bits in the range optionally specified by
1006 /// `begin` and `end` having a value of 0. The range is
1007 /// `[begin .. effectiveEnd)`, where `effectiveEnd == length()` if `end`
1008 /// is not specified and `effectiveEnd == end` otherwise. The behavior
1009 /// is undefined unless `begin <= effectiveEnd <= length()`.
1010 bsl::size_t num0(bsl::size_t begin = 0,
1011 bsl::size_t end = k_INVALID_INDEX) const;
1012
1013 /// Return the number of bits in the range optionally specified by
1014 /// `begin` and `end` having a value of 1. The range is
1015 /// `[begin .. effectiveEnd)`, where `effectiveEnd == length()` if `end`
1016 /// is not specified and `effectiveEnd == end` otherwise. The behavior
1017 /// is undefined unless `begin <= effectiveEnd <= length()`.
1018 bsl::size_t num1(bsl::size_t begin = 0,
1019 bsl::size_t end = k_INVALID_INDEX) const;
1020
1021 // Aspects
1022
1023 /// Return the allocator used by this object to supply memory.
1024 bslma::Allocator *allocator() const;
1025
1026 /// Write the value of this object, using the specified `version`
1027 /// format, to the specified output `stream`, and return a reference to
1028 /// `stream`. If `stream` is initially invalid, this operation has no
1029 /// effect. If `version` is not supported, `stream` is invalidated, but
1030 /// otherwise unmodified. Note that `version` is not written to
1031 /// `stream`. See the `bslx` package-level documentation for more
1032 /// information on BDEX streaming of value-semantic types and
1033 /// containers.
1034 template <class STREAM>
1035 STREAM& bdexStreamOut(STREAM& stream, int version) const;
1036
1037 /// Format this object to the specified output `stream` at the
1038 /// optionally specified indentation `level` and return a non-`const`
1039 /// reference to `stream`. If `level` is specified, optionally specify
1040 /// `spacesPerLevel`, the number of spaces per indentation level for
1041 /// this and all of its nested objects. Each line is indented by the
1042 /// absolute value of `level * spacesPerLevel`. If `level` is negative,
1043 /// suppress indentation of the first line. If `spacesPerLevel` is
1044 /// negative, suppress line breaks and format the entire output on one
1045 /// line. If `stream` is initially invalid, this operation has no
1046 /// effect. Note that a trailing newline is provided in multiline mode
1047 /// only.
1048 bsl::ostream& print(bsl::ostream& stream,
1049 int level = 0,
1050 int spacesPerLevel = 4) const;
1051
1052#ifndef BDE_OPENSOURCE_PUBLICATION // pending deprecation
1053
1054 // DEPRECATED METHODS
1055
1056 /// @deprecated Use @ref maxSupportedBdexVersion(int) instead.
1057 ///
1058 /// Return the most current BDEX streaming version number supported by
1059 /// this class.
1060 static int maxSupportedBdexVersion();
1061
1062#endif // BDE_OPENSOURCE_PUBLICATION -- pending deprecation
1063};
1064
1065// FREE OPERATORS
1066
1067/// Return `true` if the specified `lhs` and `rhs` arrays have the same
1068/// value, and `false` otherwise. Two arrays have the same value if they
1069/// have the same length, and corresponding bits at each bit position have
1070/// the same value.
1071bool operator==(const BitArray& lhs, const BitArray& rhs);
1072
1073/// Return `true` if the specified `lhs` and `rhs` arrays do not have the
1074/// same value, and `false` otherwise. Two arrays do not have the same
1075/// value if they do not have the same length, or there is at least one
1076/// valid index position at which corresponding bits do not have the same
1077/// value.
1078bool operator!=(const BitArray& lhs, const BitArray& rhs);
1079
1080/// Return the bitwise complement ("toggle") of the specified `array`.
1082
1083/// Return the value that is the bitwise AND of the specified `lhs` and
1084/// `rhs` arrays. The length of the resulting bit array will be the maximum
1085/// of that of `lhs` and `rhs`, with any unmatched high-order bits set to 0.
1086/// Note that this behavior is consistent with zero-extending a copy of the
1087/// shorter array.
1088BitArray operator&(const BitArray& lhs, const BitArray& rhs);
1089
1090/// Return the value that is the bitwise MINUS of the specified `lhs` and
1091/// `rhs` arrays. The length of the resulting bit array will be the maximum
1092/// of that of `lhs` and `rhs`, with any unmatched high-order `lhs` bits
1093/// copied unchanged, and any unmatched high-order `rhs` bits set to 0.
1094/// Note that this behavior is consistent with zero-extending a copy of the
1095/// shorter array.
1096BitArray operator-(const BitArray& lhs, const BitArray& rhs);
1097
1098/// Return the value that is the bitwise OR of the specified `lhs` and `rhs`
1099/// arrays. The length of the resulting bit array will be the maximum of
1100/// that of `lhs` and `rhs`, with any unmatched high-order bits copied
1101/// unchanged. Note that this behavior is consistent with zero-extending a
1102/// copy of the shorter array.
1103BitArray operator|(const BitArray& lhs, const BitArray& rhs);
1104
1105/// Return the value that is the bitwise XOR of the specified `lhs` and
1106/// `rhs` arrays. The length of the resulting bit array will be the maximum
1107/// of that of `lhs` and `rhs`, with any unmatched high-order bits copied
1108/// unchanged. Note that this behavior is consistent with zero-extending a
1109/// copy of the shorter array.
1110BitArray operator^(const BitArray& lhs, const BitArray& rhs);
1111
1112/// Return the value of the specified `array` left-shifted by the specified
1113/// `numBits` positions, having filled the lower-index positions with zeros.
1114/// The behavior is undefined unless `numBits <= array.length()`. Note that
1115/// the length of the result equals the length of the original array, and
1116/// that the highest-order `numBits` are discarded in the result.
1117BitArray operator<<(const BitArray& array, bsl::size_t numBits);
1118
1119/// Return the value of the specified `array` right-shifted by the specified
1120/// `numBits` positions, having filled the higher-index positions with
1121/// zeros. The behavior is undefined unless `numBits <= array.length()`.
1122/// Note that the length of the result equals the length of the original
1123/// array, and that the lowest-order `numBits` are discarded in the result.
1124BitArray operator>>(const BitArray& array, bsl::size_t numBits);
1125
1126/// Format the bits in the specified `rhs` bit array to the specified output
1127/// `stream` in a single-line format, and return a reference to `stream`.
1128bsl::ostream& operator<<(bsl::ostream& stream, const BitArray& rhs);
1129
1130// FREE FUNCTIONS
1131
1132/// Exchange the values of the specified `a` and `b` objects. This function
1133/// provides the no-throw exception-safety guarantee if the two objects were
1134/// created with the same allocator and the basic guarantee otherwise.
1135void swap(BitArray& a, BitArray& b);
1136
1137// ============================================================================
1138// INLINE DEFINITIONS
1139// ============================================================================
1140
1141 // --------------
1142 // class BitArray
1143 // --------------
1144
1145// PRIVATE CLASS METHODS
1146inline
1147bsl::size_t BitArray::arraySize(bsl::size_t numBits)
1148{
1149 // Note that we ensure that the capacity of 'd_array' is at least 1 at all
1150 // times. This way we know that 'd_array.front()' is valid.
1151
1152 const bsl::size_t ret = (numBits + k_BITS_PER_UINT64 - 1) /
1154 return ret ? ret : 1;
1155}
1156
1157// PRIVATE MANIPULATORS
1158inline
1159bsl::uint64_t *BitArray::data()
1160{
1161 BSLS_ASSERT_SAFE(!d_array.empty());
1162
1163 return d_array.data();
1164}
1165
1166// PRIVATE ACCESSORS
1167inline
1168const bsl::uint64_t *BitArray::data() const
1169{
1170 BSLS_ASSERT_SAFE(!d_array.empty());
1171
1172 return d_array.data();
1173}
1174
1175// CLASS METHODS
1176
1177 // Aspects
1178
1179inline
1181{
1182 return 1;
1183}
1184
1185// MANIPULATORS
1186inline
1188{
1189 d_array.resize(rhs.d_array.size());
1190 bsl::memcpy(d_array.data(),
1191 rhs.d_array.data(),
1192 d_array.size() * sizeof(bsl::uint64_t));
1193 d_length = rhs.d_length;
1194
1195 return *this;
1196}
1197
1198inline
1200{
1201 if (this == &rhs) {
1202 return *this; // RETURN
1203 }
1204
1205 const bsl::size_t rLen = rhs.d_length;
1206
1207 if (rLen > d_length) {
1208 setLength(rLen, false);
1209 }
1210 else if (rLen < d_length) {
1211 assign0(rLen, d_length - rLen);
1212 }
1213 bdlb::BitStringUtil::andEqual(data(), 0, rhs.data(), 0, rLen);
1214
1215 return *this;
1216}
1217
1218inline
1220{
1221 if (this == &rhs) {
1222 assignAll0();
1223
1224 return *this; // RETURN
1225 }
1226
1227 if (d_length < rhs.d_length) {
1228 setLength(rhs.d_length, false);
1229 }
1230 bdlb::BitStringUtil::minusEqual(data(), 0, rhs.data(), 0, rhs.d_length);
1231
1232 return *this;
1233}
1234
1235inline
1237{
1238 if (this == &rhs) {
1239 return *this; // RETURN
1240 }
1241
1242 if (d_length < rhs.d_length) {
1243 setLength(rhs.d_length, false);
1244 }
1245 bdlb::BitStringUtil::orEqual(data(), 0, rhs.data(), 0, rhs.d_length);
1246
1247 return *this;
1248}
1249
1250inline
1252{
1253 if (this == &rhs) {
1254 assignAll0();
1255
1256 return *this; // RETURN
1257 }
1258
1259 if (d_length < rhs.d_length) {
1260 setLength(rhs.d_length, false);
1261 }
1262 bdlb::BitStringUtil::xorEqual(data(), 0, rhs.data(), 0, rhs.d_length);
1263
1264 return *this;
1265}
1266
1267inline
1268BitArray& BitArray::operator>>=(bsl::size_t numBits)
1269{
1270 BSLS_ASSERT(numBits <= d_length);
1271
1272 if (numBits) {
1273 if (d_length > numBits) {
1274 const bsl::size_t remBits = d_length - numBits;
1275
1276 bdlb::BitStringUtil::copyRaw(data(), 0, data(), numBits, remBits);
1277 assign0(remBits, numBits);
1278 }
1279 else {
1280 assignAll0();
1281 }
1282 }
1283
1284 return *this;
1285}
1286
1287inline
1288BitArray& BitArray::operator<<=(bsl::size_t numBits)
1289{
1290 BSLS_ASSERT(numBits <= d_length);
1291
1292 if (numBits) {
1293 if (d_length > numBits) {
1294 const bsl::size_t remBits = d_length - numBits;
1295
1296 bdlb::BitStringUtil::copy(data(), numBits, data(), 0, remBits);
1297 assign0(0, numBits);
1298 }
1299 else {
1300 assignAll0();
1301 }
1302 }
1303
1304 return *this;
1305}
1306
1307inline
1308void BitArray::andEqual(bsl::size_t index, bool value)
1309{
1310 BSLS_ASSERT_SAFE(index < d_length);
1311
1312 if (!value) {
1313 assign0(index);
1314 }
1315}
1316
1317inline
1318void BitArray::andEqual(bsl::size_t dstIndex,
1319 const BitArray& srcArray,
1320 bsl::size_t srcIndex,
1321 bsl::size_t numBits)
1322{
1323 BSLS_ASSERT(dstIndex + numBits <= d_length);
1324 BSLS_ASSERT(srcIndex + numBits <= srcArray.d_length);
1325
1327 dstIndex,
1328 srcArray.data(),
1329 srcIndex,
1330 numBits);
1331}
1332
1333inline
1334void BitArray::append(bool value)
1335{
1336 if (d_length && 0 == d_length % k_BITS_PER_UINT64) {
1337 d_array.push_back(value);
1338 }
1339 else if (value) {
1340 bdlb::BitStringUtil::assign1(data(), d_length);
1341 }
1342 ++d_length;
1343}
1344
1345inline
1346void BitArray::append(bool value, bsl::size_t numBits)
1347{
1348 insert(d_length, value, numBits);
1349}
1350
1351inline
1352void BitArray::append(const BitArray& srcArray)
1353{
1354 insert(d_length, srcArray, 0, srcArray.d_length);
1355}
1356
1357inline
1358void BitArray::append(const BitArray& srcArray,
1359 bsl::size_t srcIndex,
1360 bsl::size_t numBits)
1361{
1362 BSLS_ASSERT(srcIndex + numBits <= srcArray.d_length);
1363
1364 insert(d_length, srcArray, srcIndex, numBits);
1365}
1366
1367inline
1368void BitArray::assign(bsl::size_t index, bool value)
1369{
1370 BSLS_ASSERT_SAFE(index < d_length);
1371
1372 bdlb::BitStringUtil::assign(data(), index, value);
1373}
1374
1375inline
1376void BitArray::assign(bsl::size_t index, bool value, bsl::size_t numBits)
1377{
1378 BSLS_ASSERT(index + numBits <= d_length);
1379
1380 bdlb::BitStringUtil::assign(data(), index, value, numBits);
1381}
1382
1383inline
1384void BitArray::assign(bsl::size_t dstIndex,
1385 const BitArray& srcArray,
1386 bsl::size_t srcIndex,
1387 bsl::size_t numBits)
1388{
1389 BSLS_ASSERT(dstIndex + numBits <= d_length);
1390 BSLS_ASSERT(srcIndex + numBits <= srcArray.d_length);
1391
1392 if (&srcArray == this) {
1393 // Might be overlapping copy.
1394
1396 dstIndex,
1397 srcArray.data(),
1398 srcIndex,
1399 numBits);
1400 }
1401 else {
1402 // Definitely not overlapping copy.
1403
1405 dstIndex,
1406 srcArray.data(),
1407 srcIndex,
1408 numBits);
1409 }
1410}
1411
1412inline
1413void BitArray::assign0(bsl::size_t index)
1414{
1415 BSLS_ASSERT_SAFE(index < d_length);
1416
1417 bdlb::BitStringUtil::assign0(data(), index);
1418}
1419
1420inline
1421void BitArray::assign0(bsl::size_t index, bsl::size_t numBits)
1422{
1423 BSLS_ASSERT(index + numBits <= d_length);
1424
1425 bdlb::BitStringUtil::assign0(data(), index, numBits);
1426}
1427
1428inline
1429void BitArray::assign1(bsl::size_t index)
1430{
1431 BSLS_ASSERT_SAFE(index < d_length);
1432
1433 bdlb::BitStringUtil::assign1(data(), index);
1434}
1435
1436inline
1437void BitArray::assign1(bsl::size_t index, bsl::size_t numBits)
1438{
1439 BSLS_ASSERT(index + numBits <= d_length);
1440
1441 bdlb::BitStringUtil::assign1(data(), index, numBits);
1442}
1443
1444inline
1445void BitArray::assignAll(bool value)
1446{
1447 if (value) {
1448 assignAll1();
1449 }
1450 else {
1451 assignAll0();
1452 }
1453}
1454
1455inline
1457{
1458 bdlb::BitStringUtil::assign0(data(), 0, d_length);
1459}
1460
1461inline
1463{
1464 bdlb::BitStringUtil::assign1(data(), 0, d_length);
1465}
1466
1467inline
1468void BitArray::assignBits(bsl::size_t index,
1469 bsl::uint64_t srcBits,
1470 bsl::size_t numBits)
1471{
1472 BSLS_ASSERT( numBits <= k_BITS_PER_UINT64);
1473 BSLS_ASSERT(index + numBits <= d_length);
1474
1475 bdlb::BitStringUtil::assignBits(data(), index, srcBits, numBits);
1476}
1477
1478inline
1479void BitArray::insert(bsl::size_t dstIndex, const BitArray& srcArray)
1480{
1481 BSLS_ASSERT(dstIndex <= d_length);
1482
1483 insert(dstIndex, srcArray, 0, srcArray.d_length);
1484}
1485
1486inline
1487void BitArray::insert(bsl::size_t dstIndex, bool value)
1488{
1489 BSLS_ASSERT(dstIndex <= d_length);
1490
1491 setLength(d_length + 1);
1492 bdlb::BitStringUtil::insert(data(), d_length - 1, dstIndex, value, 1);
1493}
1494
1495inline
1496void BitArray::insert(bsl::size_t dstIndex, bool value, bsl::size_t numBits)
1497{
1498 BSLS_ASSERT(dstIndex <= d_length);
1499
1500 setLength(d_length + numBits);
1502 d_length - numBits,
1503 dstIndex,
1504 value,
1505 numBits);
1506}
1507
1508inline
1509void BitArray::minusEqual(bsl::size_t index, bool value)
1510{
1511 BSLS_ASSERT_SAFE(index < d_length);
1512
1513 if (value) {
1514 assign0(index);
1515 }
1516}
1517
1518inline
1519void BitArray::minusEqual(bsl::size_t dstIndex,
1520 const BitArray& srcArray,
1521 bsl::size_t srcIndex,
1522 bsl::size_t numBits)
1523{
1524 BSLS_ASSERT(dstIndex + numBits <= d_length);
1525 BSLS_ASSERT(srcIndex + numBits <= srcArray.d_length);
1526
1528 dstIndex,
1529 srcArray.data(),
1530 srcIndex,
1531 numBits);
1532}
1533
1534inline
1535void BitArray::orEqual(bsl::size_t index, bool value)
1536{
1537 BSLS_ASSERT(index < d_length);
1538
1539 if (value) {
1540 assign1(index);
1541 }
1542}
1543
1544inline
1545void BitArray::orEqual(bsl::size_t dstIndex,
1546 const BitArray& srcArray,
1547 bsl::size_t srcIndex,
1548 bsl::size_t numBits)
1549{
1550 BSLS_ASSERT(dstIndex + numBits <= d_length);
1551 BSLS_ASSERT(srcIndex + numBits <= srcArray.d_length);
1552
1554 dstIndex,
1555 srcArray.data(),
1556 srcIndex,
1557 numBits);
1558}
1559
1560inline
1561void BitArray::remove(bsl::size_t index)
1562{
1563 BSLS_ASSERT_SAFE(index < d_length);
1564
1565 remove(index, 1);
1566}
1567
1568inline
1569void BitArray::remove(bsl::size_t index, bsl::size_t numBits)
1570{
1571 BSLS_ASSERT(index + numBits <= d_length);
1572
1573 bdlb::BitStringUtil::remove(data(), d_length, index, numBits);
1574 setLength(d_length - numBits);
1575}
1576
1577inline
1579{
1580 d_array.clear();
1581 d_array.resize(1);
1582 d_length = 0;
1583}
1584
1585inline
1586void BitArray::reserveCapacity(bsl::size_t numBits)
1587{
1588 d_array.reserve(arraySize(numBits));
1589}
1590
1591inline
1592void BitArray::swapBits(bsl::size_t index1, bsl::size_t index2)
1593{
1594 BSLS_ASSERT(index1 < d_length);
1595 BSLS_ASSERT(index2 < d_length);
1596
1597 if (index1 != index2) {
1598 const bool tmp = (*this)[index1];
1599 assign(index1, (*this)[index2]);
1600 assign(index2, tmp);
1601 }
1602}
1603
1604inline
1605void BitArray::toggle(bsl::size_t index)
1606{
1607 BSLS_ASSERT_SAFE(index < d_length);
1608
1609 const bsl::size_t idx = index / k_BITS_PER_UINT64;
1610 const int pos = static_cast<unsigned>(index) % k_BITS_PER_UINT64;
1611
1612 d_array[idx] ^= (s_one << pos);
1613}
1614
1615inline
1616void BitArray::toggle(bsl::size_t index, bsl::size_t numBits)
1617{
1618 BSLS_ASSERT(index + numBits <= d_length);
1619
1620 // 'index' and 'numBits' non-negative checked by 'BitStringUtil'.
1621
1622 bdlb::BitStringUtil::toggle(data(), index, numBits);
1623}
1624
1625inline
1627{
1628 toggle(0, d_length);
1629}
1630
1631inline
1632void BitArray::xorEqual(bsl::size_t index, bool value)
1633{
1634 BSLS_ASSERT_SAFE(index < d_length);
1635
1636 if (value) {
1637 toggle(index);
1638 }
1639}
1640
1641inline
1642void BitArray::xorEqual(bsl::size_t dstIndex,
1643 const BitArray& srcArray,
1644 bsl::size_t srcIndex,
1645 bsl::size_t numBits)
1646{
1647 BSLS_ASSERT(dstIndex + numBits <= d_length);
1648 BSLS_ASSERT(srcIndex + numBits <= srcArray.d_length);
1649
1651 dstIndex,
1652 srcArray.data(),
1653 srcIndex,
1654 numBits);
1655}
1656
1657 // Aspects
1658
1659template <class STREAM>
1660STREAM& BitArray::bdexStreamIn(STREAM& stream, int version)
1661{
1662 if (stream) {
1663 switch (version) { // Switch on the schema version (starting with 1).
1664 case 1: {
1665 int newLength;
1666 stream.getLength(newLength);
1667 if (!stream) {
1668 return stream; // RETURN
1669 }
1670
1671 if (0 == newLength) {
1672 removeAll();
1673
1674 return stream; // RETURN
1675 }
1676
1677 const bsl::size_t len = arraySize(newLength);
1678 removeAll();
1679 d_array.resize(len);
1680
1681 // 'getArrayUint64' will throw if there is bad input, so to prevent
1682 // invariants tests in the bit array destructor from failing, we
1683 // must make 'd_length' consistent with 'd_array.size()' before
1684 // that happens.
1685
1686 d_length = newLength;
1687
1688 stream.getArrayUint64(
1689 reinterpret_cast<bsls::Types::Uint64 *>(d_array.data()),
1690 static_cast<int>(len));
1691 if (!stream) {
1692 removeAll();
1693 return stream; // RETURN
1694 }
1695
1696 // Test for corrupted data.
1697
1698 const int rem = static_cast<unsigned>(d_length) %
1700 if (rem) {
1701 const bsl::uint64_t mask = (s_one << rem) - 1;
1702 if (d_array.back() & ~mask) {
1703 // Correct invalid bit array and invalidate stream. This
1704 // is fastest way to valid, arbitrary state.
1705
1706 d_array.back() &= mask;
1707 stream.invalidate();
1708 return stream; // RETURN
1709 }
1710 }
1711 } break;
1712 default: {
1713 stream.invalidate();
1714 }
1715 }
1716 }
1717 return stream;
1718}
1719
1720inline
1722{
1723 // 'swap' is undefined for objects with non-equal allocators.
1724
1725 BSLS_ASSERT(allocator() == other.allocator());
1726
1727 bslalg::SwapUtil::swap(&d_array, &other.d_array);
1728 bslalg::SwapUtil::swap(&d_length, &other.d_length);
1729}
1730
1731// ACCESSORS
1732inline
1733bool BitArray::operator[](bsl::size_t index) const
1734{
1735 BSLS_ASSERT_SAFE(index < d_length);
1736
1737 return bdlb::BitStringUtil::bit(data(), index);
1738}
1739
1740inline
1741bsl::uint64_t BitArray::bits(bsl::size_t index, bsl::size_t numBits) const
1742{
1743 BSLS_ASSERT_SAFE(index + numBits <= d_length);
1744
1745 return bdlb::BitStringUtil::bits(data(), index, numBits);
1746}
1747
1748inline
1749bsl::size_t BitArray::find0AtMaxIndex(bsl::size_t begin, bsl::size_t end) const
1750{
1751 if (k_INVALID_INDEX == end) {
1752 end = d_length;
1753 }
1754 BSLS_ASSERT(begin <= end);
1755 BSLS_ASSERT( end <= d_length);
1756
1757 return bdlb::BitStringUtil::find0AtMaxIndex(data(), begin, end);
1758}
1759
1760inline
1761bsl::size_t BitArray::find0AtMinIndex(bsl::size_t begin, bsl::size_t end) const
1762{
1763 if (k_INVALID_INDEX == end) {
1764 end = d_length;
1765 }
1766 BSLS_ASSERT(begin <= end);
1767 BSLS_ASSERT( end <= d_length);
1768
1769 return bdlb::BitStringUtil::find0AtMinIndex(data(), begin, end);
1770}
1771
1772inline
1773bsl::size_t BitArray::find1AtMaxIndex(bsl::size_t begin, bsl::size_t end) const
1774{
1775 if (k_INVALID_INDEX == end) {
1776 end = d_length;
1777 }
1778 BSLS_ASSERT(begin <= end);
1779 BSLS_ASSERT( end <= d_length);
1780
1781 return bdlb::BitStringUtil::find1AtMaxIndex(data(), begin, end);
1782}
1783
1784inline
1785bsl::size_t BitArray::find1AtMinIndex(bsl::size_t begin, bsl::size_t end) const
1786{
1787 if (k_INVALID_INDEX == end) {
1788 end = d_length;
1789 }
1790 BSLS_ASSERT(begin <= end);
1791 BSLS_ASSERT( end <= d_length);
1792
1793 return bdlb::BitStringUtil::find1AtMinIndex(data(), begin, end);
1794}
1795
1796inline
1798{
1799 return bdlb::BitStringUtil::isAny0(data(), 0, d_length);
1800}
1801
1802inline
1804{
1805 return bdlb::BitStringUtil::isAny1(data(), 0, d_length);
1806}
1807
1808inline
1810{
1811 return 0 == d_length;
1812}
1813
1814inline
1815bsl::size_t BitArray::length() const
1816{
1817 return d_length;
1818}
1819
1820inline
1821bsl::size_t BitArray::num0(bsl::size_t begin, bsl::size_t end) const
1822{
1823 if (k_INVALID_INDEX == end) {
1824 end = d_length;
1825 }
1826 BSLS_ASSERT(begin <= end);
1827 BSLS_ASSERT( end <= d_length);
1828
1829 return bdlb::BitStringUtil::num0(data(), begin, end - begin);
1830}
1831
1832inline
1833bsl::size_t BitArray::num1(bsl::size_t begin, bsl::size_t end) const
1834{
1835 if (k_INVALID_INDEX == end) {
1836 end = d_length;
1837 }
1838 BSLS_ASSERT(begin <= end);
1839 BSLS_ASSERT( end <= d_length);
1840
1841 return bdlb::BitStringUtil::num1(data(), begin, end - begin);
1842}
1843
1844 // Aspects
1845
1846inline
1848{
1849 return d_array.get_allocator().mechanism();
1850}
1851
1852template <class STREAM>
1853STREAM& BitArray::bdexStreamOut(STREAM& stream, int version) const
1854{
1855 switch (version) {
1856 case 1: {
1857 BSLS_ASSERT(d_length <= INT_MAX);
1858
1859 stream.putLength(static_cast<int>(d_length));
1860 if (0 != d_length) {
1861 stream.putArrayUint64(
1862 reinterpret_cast<const bsls::Types::Uint64 *>(d_array.data()),
1863 static_cast<int>(d_array.size()));
1864 }
1865 } break;
1866 default: {
1867 stream.invalidate();
1868 }
1869 }
1870
1871 return stream;
1872}
1873
1874#ifndef BDE_OPENSOURCE_PUBLICATION // pending deprecation
1875
1876// DEPRECATED METHODS
1877inline
1879{
1880 return 1;
1881}
1882
1883#endif // BDE_OPENSOURCE_PUBLICATION -- pending deprecation
1884
1885} // close package namespace
1886
1887// FREE OPERATORS
1888inline
1889bool bdlc::operator==(const BitArray& lhs, const BitArray& rhs)
1890{
1891 if (lhs.d_length != rhs.d_length) {
1892 return false; // RETURN
1893 }
1894
1895 return bdlb::BitStringUtil::areEqual(lhs.data(),
1896 rhs.data(),
1897 lhs.d_length);
1898}
1899
1900inline
1901bool bdlc::operator!=(const BitArray& lhs, const BitArray& rhs)
1902{
1903 return !(lhs == rhs);
1904}
1905
1906inline
1907bdlc::BitArray bdlc::operator~(const BitArray& array)
1908{
1909 BitArray tmp(array);
1910 tmp.toggleAll();
1911 return tmp;
1912}
1913
1914inline
1915bdlc::BitArray bdlc::operator&(const BitArray& lhs, const BitArray& rhs)
1916{
1917 BitArray tmp(lhs);
1918 tmp &= rhs;
1919 return tmp;
1920}
1921
1922inline
1923bdlc::BitArray bdlc::operator|(const BitArray& lhs, const BitArray& rhs)
1924{
1925 BitArray tmp(lhs);
1926 tmp |= rhs;
1927 return tmp;
1928}
1929
1930inline
1931bdlc::BitArray bdlc::operator^(const BitArray& lhs, const BitArray& rhs)
1932{
1933 BitArray tmp(lhs);
1934 tmp ^= rhs;
1935 return tmp;
1936}
1937
1938inline
1939bdlc::BitArray bdlc::operator-(const BitArray& lhs, const BitArray& rhs)
1940{
1941 BitArray tmp(lhs);
1942 tmp -= rhs;
1943 return tmp;
1944}
1945
1946inline
1947bdlc::BitArray bdlc::operator<<(const BitArray& array, bsl::size_t numBits)
1948{
1949 BSLS_ASSERT(numBits <= array.length());
1950
1951 BitArray tmp(array);
1952 tmp <<= numBits;
1953 return tmp;
1954}
1955
1956inline
1957bdlc::BitArray bdlc::operator>>(const BitArray& array, bsl::size_t numBits)
1958{
1959 BSLS_ASSERT(numBits <= array.length());
1960
1961 BitArray tmp(array);
1962 tmp >>= numBits;
1963 return tmp;
1964}
1965
1966inline
1967bsl::ostream& bdlc::operator<<(bsl::ostream& stream, const BitArray& rhs)
1968{
1969 return rhs.print(stream, 0, -1);
1970}
1971
1972namespace bslmf {
1973
1974/// This template specialization for `IsBitwiseMoveable` indicates that
1975/// `BitArray` is a bitwise movable type if `vector<uint64_t>` is a bitwise
1976/// movable type.
1977template <>
1978struct IsBitwiseMoveable<bdlc::BitArray> :
1979 public IsBitwiseMoveable<bsl::vector<bsl::uint64_t> > {
1980};
1981
1982} // close namespace bslmf
1983
1984namespace bslma {
1985
1986/// This template specialization for `UsesBslmaAllocator` indicates that
1987/// `BitArray` uses `bslma::Allocator`.
1988template <>
1990};
1991
1992} // close namespace bslma
1993
1994
1995
1996#endif
1997
1998// ----------------------------------------------------------------------------
1999// Copyright 2018 Bloomberg Finance L.P.
2000//
2001// Licensed under the Apache License, Version 2.0 (the "License");
2002// you may not use this file except in compliance with the License.
2003// You may obtain a copy of the License at
2004//
2005// http://www.apache.org/licenses/LICENSE-2.0
2006//
2007// Unless required by applicable law or agreed to in writing, software
2008// distributed under the License is distributed on an "AS IS" BASIS,
2009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2010// See the License for the specific language governing permissions and
2011// limitations under the License.
2012// ----------------------------- END-OF-FILE ----------------------------------
2013
2014/** @} */
2015/** @} */
2016/** @} */
Definition bdlc_bitarray.h:521
bsl::size_t num0(bsl::size_t begin=0, bsl::size_t end=k_INVALID_INDEX) const
Definition bdlc_bitarray.h:1821
void insert(bsl::size_t dstIndex, bool value)
Definition bdlc_bitarray.h:1487
bsl::size_t length() const
Return the number of bits in this array.
Definition bdlc_bitarray.h:1815
bool operator[](bsl::size_t index) const
Definition bdlc_bitarray.h:1733
BitArray & operator&=(const BitArray &rhs)
Definition bdlc_bitarray.h:1199
bool isAny1() const
Definition bdlc_bitarray.h:1803
void assignAll1()
Set to 1 the value of every bit in this array.
Definition bdlc_bitarray.h:1462
bsl::size_t num1(bsl::size_t begin=0, bsl::size_t end=k_INVALID_INDEX) const
Definition bdlc_bitarray.h:1833
bsl::uint64_t bits(bsl::size_t index, bsl::size_t numBits) const
Definition bdlc_bitarray.h:1741
BitArray & operator^=(const BitArray &rhs)
Definition bdlc_bitarray.h:1251
void removeAll()
Definition bdlc_bitarray.h:1578
bsl::size_t find0AtMinIndex(bsl::size_t begin=0, bsl::size_t end=k_INVALID_INDEX) const
Definition bdlc_bitarray.h:1761
void assign1(bsl::size_t index)
Definition bdlc_bitarray.h:1429
void andEqual(bsl::size_t index, bool value)
Definition bdlc_bitarray.h:1308
void toggleAll()
Definition bdlc_bitarray.h:1626
BitArray(bsl::size_t initialLength, bslma::Allocator *basicAllocator=0)
void assign(bsl::size_t index, bool value)
Definition bdlc_bitarray.h:1368
void append(bool value)
Definition bdlc_bitarray.h:1334
void rotateRight(bsl::size_t numBits)
void toggle(bsl::size_t index)
Definition bdlc_bitarray.h:1605
BitArray & operator>>=(bsl::size_t numBits)
Definition bdlc_bitarray.h:1268
void swapBits(bsl::size_t index1, bsl::size_t index2)
Definition bdlc_bitarray.h:1592
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdlc_bitarray.h:1853
void assignAll0()
Set to 0 the value of every bit in this array.
Definition bdlc_bitarray.h:1456
void swap(BitArray &other)
Definition bdlc_bitarray.h:1721
void assign0(bsl::size_t index)
Definition bdlc_bitarray.h:1413
friend bool operator==(const BitArray &, const BitArray &)
bsl::size_t find1AtMaxIndex(bsl::size_t begin=0, bsl::size_t end=k_INVALID_INDEX) const
Definition bdlc_bitarray.h:1773
void orEqual(bsl::size_t index, bool value)
Definition bdlc_bitarray.h:1535
BitArray & operator=(const BitArray &rhs)
Definition bdlc_bitarray.h:1187
BitArray & operator-=(const BitArray &rhs)
Definition bdlc_bitarray.h:1219
void xorEqual(bsl::size_t index, bool value)
Definition bdlc_bitarray.h:1632
BitArray(bsl::size_t initialLength, bool value, bslma::Allocator *basicAllocator=0)
void reserveCapacity(bsl::size_t numBits)
Definition bdlc_bitarray.h:1586
static int maxSupportedBdexVersion()
Definition bdlc_bitarray.h:1878
bsl::size_t find0AtMaxIndex(bsl::size_t begin=0, bsl::size_t end=k_INVALID_INDEX) const
Definition bdlc_bitarray.h:1749
bslma::Allocator * allocator() const
Return the allocator used by this object to supply memory.
Definition bdlc_bitarray.h:1847
bool isEmpty() const
Definition bdlc_bitarray.h:1809
BitArray & operator<<=(bsl::size_t numBits)
Definition bdlc_bitarray.h:1288
void setLength(bsl::size_t newLength, bool value=false)
static const bsl::size_t k_INVALID_INDEX
Definition bdlc_bitarray.h:528
bool isAny0() const
Definition bdlc_bitarray.h:1797
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
void minusEqual(bsl::size_t index, bool value)
Definition bdlc_bitarray.h:1509
void remove(bsl::size_t index)
Definition bdlc_bitarray.h:1561
~BitArray()
Destroy this object.
bsl::size_t find1AtMinIndex(bsl::size_t begin=0, bsl::size_t end=k_INVALID_INDEX) const
Definition bdlc_bitarray.h:1785
void assignBits(bsl::size_t index, bsl::uint64_t srcBits, bsl::size_t numBits)
Definition bdlc_bitarray.h:1468
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdlc_bitarray.h:1660
BitArray & operator|=(const BitArray &rhs)
Definition bdlc_bitarray.h:1236
void rotateLeft(bsl::size_t numBits)
BitArray(bslma::Allocator *basicAllocator=0)
void assignAll(bool value)
Set all bits in this array to the specified value.
Definition bdlc_bitarray.h:1445
void insert(bsl::size_t dstIndex, const BitArray &srcArray, bsl::size_t srcIndex, bsl::size_t numBits)
@ k_BITS_PER_UINT64
Definition bdlc_bitarray.h:525
BitArray(const BitArray &original, bslma::Allocator *basicAllocator=0)
BloombergLP::bslma::Allocator * mechanism() const
Definition bslma_bslallocator.h:1126
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this vector.
Definition bslstl_vector.h:2664
reference back()
Definition bslstl_vector.h:2577
bool empty() const BSLS_KEYWORD_NOEXCEPT
Return true if this vector has size 0, and false otherwise.
Definition bslstl_vector.h:2679
VALUE_TYPE * data() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2587
Definition bslstl_vector.h:1025
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:4019
void reserve(size_type newCapacity)
Definition bslstl_vector.h:3690
void push_back(const VALUE_TYPE &value)
Definition bslstl_vector.h:3760
void swap(vector &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits void clear() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:1712
void resize(size_type newSize)
Definition bslstl_vector.h:3616
static void swap(T *a, T *b)
Definition bslalg_swaputil.h:194
Definition bslma_allocator.h:457
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlc_bitarray.h:503
BitArray operator|(const BitArray &lhs, const BitArray &rhs)
BitArray operator&(const BitArray &lhs, const BitArray &rhs)
bool operator==(const BitArray &lhs, const BitArray &rhs)
BitArray operator>>(const BitArray &array, bsl::size_t numBits)
BitArray operator~(const BitArray &array)
Return the bitwise complement ("toggle") of the specified array.
bool operator!=(const BitArray &lhs, const BitArray &rhs)
BitArray operator^(const BitArray &lhs, const BitArray &rhs)
BitArray operator-(const BitArray &lhs, const BitArray &rhs)
BitArray operator<<(const BitArray &array, bsl::size_t numBits)
Definition balxml_encoderoptions.h:68
Definition bdlbb_blob.h:576
static bsl::size_t find0AtMinIndex(const bsl::uint64_t *bitString, bsl::size_t length)
static void assign(bsl::uint64_t *bitString, bsl::size_t index, bool value)
Definition bdlb_bitstringutil.h:839
static void toggle(bsl::uint64_t *bitString, bsl::size_t index, bsl::size_t numBits)
static void assignBits(bsl::uint64_t *bitString, bsl::size_t index, bsl::uint64_t srcValue, bsl::size_t numBits)
static void assign0(bsl::uint64_t *bitString, bsl::size_t index)
Definition bdlb_bitstringutil.h:857
static bool bit(const bsl::uint64_t *bitString, bsl::size_t index)
Definition bdlb_bitstringutil.h:945
static void orEqual(bsl::uint64_t *dstBitString, bsl::size_t dstIndex, const bsl::uint64_t *srcBitString, bsl::size_t srcIndex, bsl::size_t numBits)
static const bsl::size_t k_INVALID_INDEX
Definition bdlb_bitstringutil.h:420
static bsl::uint64_t bits(const bsl::uint64_t *bitString, bsl::size_t index, bsl::size_t numBits)
static bool areEqual(const bsl::uint64_t *bitString1, const bsl::uint64_t *bitString2, bsl::size_t numBits)
static void copyRaw(bsl::uint64_t *dstBitString, bsl::size_t dstIndex, const bsl::uint64_t *srcBitString, bsl::size_t srcIndex, bsl::size_t numBits)
static bsl::size_t find0AtMaxIndex(const bsl::uint64_t *bitString, bsl::size_t length)
static bsl::size_t find1AtMaxIndex(const bsl::uint64_t *bitString, bsl::size_t length)
static void assign1(bsl::uint64_t *bitString, bsl::size_t index)
Definition bdlb_bitstringutil.h:868
static void remove(bsl::uint64_t *bitString, bsl::size_t length, bsl::size_t index, bsl::size_t numBits)
static bool isAny0(const bsl::uint64_t *bitString, bsl::size_t index, bsl::size_t numBits)
static void andEqual(bsl::uint64_t *dstBitString, bsl::size_t dstIndex, const bsl::uint64_t *srcBitString, bsl::size_t srcIndex, bsl::size_t numBits)
static void minusEqual(bsl::uint64_t *dstBitString, bsl::size_t dstIndex, const bsl::uint64_t *srcBitString, bsl::size_t srcIndex, bsl::size_t numBits)
static bsl::size_t find1AtMinIndex(const bsl::uint64_t *bitString, bsl::size_t length)
static bsl::size_t num0(const bsl::uint64_t *bitString, bsl::size_t index, bsl::size_t numBits)
Definition bdlb_bitstringutil.h:958
static bool isAny1(const bsl::uint64_t *bitString, bsl::size_t index, bsl::size_t numBits)
static void copy(bsl::uint64_t *dstBitString, bsl::size_t dstIndex, const bsl::uint64_t *srcBitString, bsl::size_t srcIndex, bsl::size_t numBits)
static void insert(bsl::uint64_t *bitString, bsl::size_t initialLength, bsl::size_t dstIndex, bool value, bsl::size_t numBits)
Definition bdlb_bitstringutil.h:881
static void xorEqual(bsl::uint64_t *dstBitString, bsl::size_t dstIndex, const bsl::uint64_t *srcBitString, bsl::size_t srcIndex, bsl::size_t numBits)
static bsl::size_t num1(const bsl::uint64_t *bitString, bsl::size_t index, bsl::size_t numBits)
Definition bslma_usesbslmaallocator.h:343
Definition bslmf_isbitwisemoveable.h:718
unsigned long long Uint64
Definition bsls_types.h:137