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