BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlc_compactedarray.h
Go to the documentation of this file.
1/// @file bdlc_compactedarray.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlc_compactedarray.h -*-C++-*-
8#ifndef INCLUDED_BDLC_COMPACTEDARRAY
9#define INCLUDED_BDLC_COMPACTEDARRAY
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlc_compactedarray bdlc_compactedarray
15/// @brief Provide a compacted array of `const` user-defined objects.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlc
19/// @{
20/// @addtogroup bdlc_compactedarray
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlc_compactedarray-purpose"> Purpose</a>
25/// * <a href="#bdlc_compactedarray-classes"> Classes </a>
26/// * <a href="#bdlc_compactedarray-description"> Description </a>
27/// * <a href="#bdlc_compactedarray-usage"> Usage </a>
28/// * <a href="#bdlc_compactedarray-example-1-storing-daily-schedules"> Example 1: Storing Daily Schedules </a>
29///
30/// # Purpose {#bdlc_compactedarray-purpose}
31/// Provide a compacted array of `const` user-defined objects.
32///
33/// # Classes {#bdlc_compactedarray-classes}
34///
35/// - bdlc::CompactedArray: compacted array of user-defined objects
36///
37/// # Description {#bdlc_compactedarray-description}
38/// This component provides a space-efficient value-semantic array,
39/// `bdlc::CompactedArray`, and an associated iterator,
40/// `bdlc::CompactedArray::const_iterator`, that provides non-modifiable access
41/// to its elements. The interface of this class provides the user with
42/// functionality similar to a `bsl::vector<T>`. The implementation is designed
43/// to reduce dynamic memory usage by (1) removing data duplication at the
44/// expense of an additional indirection to obtain the stored objects (using the
45/// flyweight design pattern) and (2) requiring `operator<` to be defined for
46/// the type of the stored objects. The array supports primitive operations
47/// (e.g., insertion, look-up, removal), as well as a complete set of
48/// value-semantic operations; however, modifiable reference to individual
49/// elements is not available. Users can access the (non-modifiable) value of
50/// individual elements by calling the indexing operator or via iterators.
51///
52/// ## Usage {#bdlc_compactedarray-usage}
53///
54///
55/// This section illustrates intended use of this component.
56///
57/// ### Example 1: Storing Daily Schedules {#bdlc_compactedarray-example-1-storing-daily-schedules}
58///
59///
60/// Suppose we are creating a sequence of daily schedules for an employee. Most
61/// Mondays (and Tuesdays, Wednesdays, etc.) will have the same schedule,
62/// although some may differ. Instead of storing this data in a
63/// `bsl::vector<my_DailySchedule>`, we can use
64/// `bdlc::CompactedArray<my_DailySchedule>` to efficiently store this data.
65///
66/// First, we declare and define a `my_DailySchedule` class. This class is not
67/// overly relevant to the example and is elided for the sake of brevity:
68/// @code
69/// // ================
70/// // my_DailySchedule
71/// // ================
72///
73/// class my_DailySchedule {
74/// // A value-semantic class that provides a daily schedule and consumes a
75/// // significant amount of memory.
76///
77/// int d_initialLocationId;
78///
79/// // ...
80///
81/// // FRIENDS
82/// friend bool operator<(const my_DailySchedule&,
83/// const my_DailySchedule&);
84///
85/// public:
86/// // CREATORS
87/// my_DailySchedule(int initialLocationId,
88/// bslma::Allocator *basicAllocator = 0);
89/// // Create a 'my_DailySchedule' object having the specified
90/// // 'initialLocationId'. Optionally specify a 'basicAllocator' used
91/// // to supply memory. If 'basicAllocator' is 0, the currently
92/// // installed default allocator is used.
93///
94/// // ...
95///
96/// };
97///
98/// bool operator<(const my_DailySchedule& lhs, const my_DailySchedule& rhs);
99/// // Return 'true' if the specified 'lhs' is lexicographically less than
100/// // the specified 'rhs' object, and 'false' otherwise.
101///
102/// // ----------------
103/// // my_DailySchedule
104/// // ----------------
105///
106/// // CREATORS
107/// inline
108/// my_DailySchedule::my_DailySchedule(int initialLocationId,
109/// bslma::Allocator *basicAllocator)
110/// : d_initialLocationId(initialLocationId)
111/// {
112/// (void)basicAllocator; // suppress unused variable compiler warning
113///
114/// // ...
115/// }
116///
117/// bool operator<(const my_DailySchedule& lhs, const my_DailySchedule& rhs)
118/// {
119/// if (lhs.d_initialLocationId < rhs.d_initialLocationId) {
120/// return true; // RETURN
121/// }
122///
123/// // ...
124///
125/// return false;
126/// }
127/// @endcode
128/// Then, we create our schedule, which is an array of `my_DailySchedule` where
129/// the index of each element is the date offset (from an arbitrary epoch
130/// measured in days).
131/// @code
132/// bdlc::CompactedArray<my_DailySchedule> schedule;
133/// @endcode
134/// Now, we create some daily schedules and append them to the `schedule`:
135/// @code
136/// my_DailySchedule evenDays(0);
137/// my_DailySchedule oddDays(1);
138///
139/// // Population of the 'my_DailySchedule' objects is elided.
140///
141/// schedule.push_back(evenDays);
142/// schedule.push_back(oddDays);
143/// schedule.push_back(evenDays);
144/// schedule.push_back(oddDays);
145/// schedule.push_back(evenDays);
146/// @endcode
147/// Finally, we verify that the storage is compacted:
148/// @code
149/// assert(5 == schedule.length());
150/// assert(2 == schedule.uniqueLength());
151/// @endcode
152/// @}
153/** @} */
154/** @} */
155
156/** @addtogroup bdl
157 * @{
158 */
159/** @addtogroup bdlc
160 * @{
161 */
162/** @addtogroup bdlc_compactedarray
163 * @{
164 */
165
166#include <bdlscm_version.h>
167
168#include <bdlc_packedintarray.h>
169
171#include <bslalg_swaputil.h>
172
173#include <bslh_hash.h>
174
175#include <bslim_printer.h>
176
177#include <bslma_allocator.h>
180
181#include <bsls_assert.h>
182#include <bsls_objectbuffer.h>
183#include <bsls_review.h>
184
185#include <bsl_algorithm.h>
186#include <bsl_cstddef.h>
187#include <bsl_iosfwd.h>
188#include <bsl_iterator.h>
189#include <bsl_limits.h>
190#include <bsl_vector.h>
191
192
193namespace bdlc {
194
195// FORWARD DECLARATIONS
196template <class TYPE> class CompactedArray;
197
198template <class TYPE> class CompactedArray_ConstIterator;
199
200template <class TYPE> CompactedArray_ConstIterator<TYPE>
202
203template <class TYPE> CompactedArray_ConstIterator<TYPE>
205
206template <class TYPE>
209 bsl::ptrdiff_t);
210
211template <class TYPE>
214 bsl::ptrdiff_t);
215
216template <class TYPE>
219
220template <class TYPE>
223
224template <class TYPE>
227
228template <class TYPE>
231
232template <class TYPE>
235
236template <class TYPE>
239
240template <class TYPE>
243
244 // =====================================
245 // class CompactedArray_RemoveAllProctor
246 // =====================================
247
248/// This class implements a proctor that, unless its `release` method has
249/// previously been invoked, automatically invokes `removeAll` on a
250/// `CompactedArray` upon destruction.
251///
252/// See @ref bdlc_compactedarray
253template <class TYPE>
255
256 // DATA
257 CompactedArray<TYPE> *d_array_p; // managed array
258
259 // NOT IMPLEMENTED
264
265 public:
266 // CREATORS
267
268 /// Create a `removeAll` proctor that conditionally manages the
269 /// specified `array` (if non-zero).
271
272 /// Destroy this object and, if `release` has not been invoked, invoke
273 /// the managed array's `removeAll` method.
275
276 // MANIPULATORS
277
278 /// Release from management the array currently managed by this proctor.
279 /// If no array, this method has no effect.
280 void release();
281};
282
283 // ==================================
284 // struct CompactedArray_CountedValue
285 // ==================================
286
287/// This `struct` represents a reference-counted value. Note that
288/// comparison of `d_count` is intentionally omitted from the free
289/// equality-comparison operators of this class.
290template <class TYPE>
292
293 // PUBLIC DATA
294 bsls::ObjectBuffer<TYPE> d_value; // footprint of stored object
295 bsl::size_t d_count; // reference count of the stored object
296
297 // CREATORS
298
299 /// Create a `CompactedArray_CountedValue` having the specified `value`
300 /// and reference `count`. The specified `basicAllocator` is used to
301 /// supply memory. The behavior is undefined unless
302 /// `0 != basicAllocator`.
303 CompactedArray_CountedValue(const TYPE& value,
304 bsl::size_t count,
305 bslma::Allocator *basicAllocator);
306
307 /// Create a `CompactedArray_CountedValue` having the same underlying
308 /// object value and reference count as the specified `original` object.
309 /// The specified `basicAllocator` is used to supply memory. The
310 /// behavior is undefined unless `0 != basicAllocator`.
312 const CompactedArray_CountedValue<TYPE>& original,
313 bslma::Allocator *basicAllocator);
314
315 /// Destroy this object.
317
318 // MANIPULATORS
319
320 /// Assign to this object the underlying object value and reference
321 /// count of the specified `rhs` object, and return a reference
322 /// providing modifiable access to this object.
325};
326
327// FREE OPERATORS
328
329/// Return `true` if the underlying object value of the specified `lhs` is
330/// the same as the underlying object value of the specified `rhs`, and
331/// `false` otherwise. Note that the reference counts are intentionally
332/// ignored.
333template <class TYPE>
334bool operator==(const CompactedArray_CountedValue<TYPE>& lhs,
336
337/// Return `true` if the underlying object value of the specified `lhs` is
338/// not the same as the underlying object value of the specified `rhs`, and
339/// `false` otherwise. Note that the reference counts are intentionally
340/// ignored.
341template <class TYPE>
342bool operator!=(const CompactedArray_CountedValue<TYPE>& lhs,
344
345/// Return `true` if the underlying object value of the specified `lhs` is
346/// less than the value of the specified `rhs`, and `false` otherwise. Note
347/// that the reference count is intentionally ignored.
348template <class TYPE>
349bool operator<(const CompactedArray_CountedValue<TYPE>& lhs, const TYPE& rhs);
350
351/// Return `true` if the value of the specified `lhs` is less than the
352/// underlying object value of the specified `rhs`, and `false` otherwise.
353/// Note that the reference count is intentionally ignored.
354template <class TYPE>
355bool operator<(const TYPE& lhs, const CompactedArray_CountedValue<TYPE>& rhs);
356
357 // ==================================
358 // class CompactedArray_ConstIterator
359 // ==================================
360
361/// This value-semantic class represents a random access iterator providing
362/// non-modifiable access to the elements of a `CompactedArray`. This class
363/// provides all functionality of a random access iterator, as defined by
364/// the standard, but is *not* compatible with most standard methods
365/// requiring a bidirectional `const_iterator`.
366///
367/// This class does not perform any bounds checking. Any iterator, `it`,
368/// referencing a `CompactedArray` `array`, remains valid while
369/// `0 <= it - array.begin() < array.length()`.
370///
371/// See @ref bdlc_compactedarray
372template <class TYPE>
374
375 // DATA
376 const CompactedArray<TYPE> *d_array_p; // 'CompactedArray' referenced by
377 // this iterator, or 0 if default
378 // value
379
380 bsl::size_t d_index; // index of the referenced element,
381 // or one past the end of
382 // 'd_array_p'
383
384 // FRIENDS
385 friend class CompactedArray<TYPE>;
386
388 operator++<>(CompactedArray_ConstIterator&, int);
389
391 operator--<>(CompactedArray_ConstIterator&, int);
392
393 friend bool operator==<>(const CompactedArray_ConstIterator&,
395
396 friend bool operator!=<>(const CompactedArray_ConstIterator&,
398
401 bsl::ptrdiff_t);
402
405 bsl::ptrdiff_t);
406
407 friend bsl::ptrdiff_t operator-<>(const CompactedArray_ConstIterator&,
409
410 friend bool operator< <>(const CompactedArray_ConstIterator&,
412
413 friend bool operator<=<>(const CompactedArray_ConstIterator&,
415
416 friend bool operator><>(const CompactedArray_ConstIterator&,
418
419 friend bool operator>=<>(const CompactedArray_ConstIterator&,
421
422 public:
423 // PUBLIC TYPES
424
425 // The following 'typedef's define the traits for this iterator to make it
426 // compatible with standard functions.
427
428 typedef bsl::ptrdiff_t difference_type; // The type used for the distance
429 // between two iterators.
430
431 typedef bsl::size_t size_type; // The type used for any function
432 // requiring a length (i.e,
433 // index).
434
435 typedef TYPE value_type; // The type for elements.
436
437 typedef TYPE *pointer; // The type of an arbitrary
438 // pointer into the array.
439
440 typedef TYPE& reference; // The type for element
441 // references.
442
443 typedef std::random_access_iterator_tag iterator_category;
444 // This is a random access
445 // iterator.
446
447 private:
448 // PRIVATE CREATORS
449
450 /// Create a `CompactedArray_ConstIterator` object that refers to the
451 /// element at the specified `index` in the specified `array`, or the
452 /// past-the-end iterator for `array` if `index == array->length()`.
453 /// The behavior is undefined unless `index <= array->length()`.
455 bsl::size_t index);
456
457 public:
458 // CREATORS
459
460 /// Create a default `CompactedArray_ConstIterator`. Note that the
461 /// behavior of most methods is undefined when used on a
462 /// default-constructed iterator.
464
465 /// Create a `CompactedArray_ConstIterator` having the same value as the
466 /// specified `original` object.
468
470 // Destroy this object.
471
472 // MANIPULATORS
473
474 /// Assign to this iterator the value of the specified `rhs` iterator,
475 /// and return a reference providing modifiable access to this iterator.
477 operator=(
479
480 /// Advance this iterator by the specified `offset` from the location
481 /// referenced by this iterator, and return a reference providing
482 /// modifiable access to this iterator. The returned iterator, `it`,
483 /// referencing a `CompactedArray` `array`, remains valid as long as
484 /// `0 <= it - array.begin() <= array.length()`. The behavior is
485 /// undefined unless `CompactedArray_ConstIterator() != *this` and
486 /// `0 <= *this - array.begin() + offset <= array.length()`.
487 CompactedArray_ConstIterator& operator+=(bsl::ptrdiff_t offset);
488
489 /// Decrement this iterator by the specified `offset` from the location
490 /// referenced by this iterator, and return a reference providing
491 /// modifiable access to this iterator. The returned iterator, `it`,
492 /// referencing a `CompactedArray` `array`, remains valid as long as
493 /// `0 <= it - array.begin() <= array.length()`. The behavior is
494 /// undefined unless `CompactedArray_ConstIterator() != *this` and
495 /// `0 <= *this - array.begin() - offset <= array.length()`.
496 CompactedArray_ConstIterator& operator-=(bsl::ptrdiff_t offset);
497
498 /// Advance this iterator to refer to the next location in the
499 /// referenced array, and return a reference to this iterator *after*
500 /// the advancement. The returned iterator, `it`, referencing a
501 /// `CompactedArray` `array`, remains valid as long as
502 /// `0 <= it - array.begin() <= array.length()`. The behavior is
503 /// undefined unless, on entry,
504 /// `CompactedArray_ConstIterator() != *this` and
505 /// `*this - array.begin() < array.length()`.
507
508 /// Decrement this iterator to refer to the previous location in the
509 /// referenced array, and return a reference to this iterator *after*
510 /// the decrementation. The returned iterator, `it`, referencing a
511 /// `CompactedArray` `array`, remains valid as long as
512 /// `0 <= it - array.begin() <= array.length()`. The behavior is
513 /// undefined unless, on entry,
514 /// `CompactedArray_ConstIterator() != *this` and
515 /// `0 < *this - array.begin()`.
517
518 // ACCESSORS
519
520 /// Return a `const` reference to the element referenced by this
521 /// iterator. The behavior is undefined unless for this iterator,
522 /// referencing a `CompactedArray` `array`,
523 /// `CompactedArray_ConstIterator() != *this` and
524 /// `*this - array.begin() < array.length()`.
525 const TYPE& operator*() const;
526
527 /// Return a `const` reference to the element referenced by this
528 /// iterator. The behavior is undefined unless for this iterator,
529 /// referencing a `CompactedArray` `array`,
530 /// `CompactedArray_ConstIterator() != *this` and
531 /// `*this - array.begin() < array.length()`.
532 const TYPE& operator->() const;
533
534 /// Return a `const` reference to the element at the specified `offset`
535 /// from the location referenced by this iterator. The behavior is
536 /// undefined unless for this iterator, referencing a `CompactedArray`
537 /// `array`, `CompactedArray_ConstIterator() != *this` and
538 /// `0 <= *this - array.begin() + offset < array.length()`.
539 const TYPE& operator[](bsl::ptrdiff_t offset) const;
540};
541
542// FREE OPERATORS
543
544/// Advance the specified `iterator` to refer to the next location in the
545/// referenced array, and return an iterator referring to the original
546/// location (*before* the advancement). The returned iterator, `it`,
547/// referencing a `CompactedArray` `array`, remains valid as long as
548/// `0 <= it - array.begin() <= array.length()`. The behavior is undefined
549/// unless, on entry, `CompactedArray_ConstIterator() != iterator` and
550/// `iterator - array.begin() < array.length()`.
551template <class TYPE>
554 int);
555
556/// Decrement the specified `iterator` to refer to the previous location in
557/// the referenced array, and return an iterator referring to the original
558/// location (*before* the decrementation). The returned iterator, `it`,
559/// referencing a `CompactedArray` `array`, remains valid as long as
560/// `0 <= it - array.begin() <= array.length()`. The behavior is undefined
561/// unless, on entry, `CompactedArray_ConstIterator() != iterator` and
562/// `0 < iterator - array.begin()`.
563template <class TYPE>
566 int);
567
568/// Return an iterator referencing the location at the specified `offset`
569/// from the location referenced by the specified `iterator`. The returned
570/// iterator, `it`, referencing a `CompactedArray` `array`, remains valid as
571/// long as `0 <= it - array.begin() <= array.length()`. The behavior is
572/// undefined unless `CompactedArray_ConstIterator() != iterator` and
573/// `0 <= iterator - array.begin() + offset <= array.length()`.
574template <class TYPE>
577 bsl::ptrdiff_t offset);
578template <class TYPE>
580 bsl::ptrdiff_t offset,
581 const CompactedArray_ConstIterator<TYPE>& iterator);
582
583/// Return an iterator referencing the location at the specified `offset`
584/// from the location referenced by the specified `iterator`. The returned
585/// iterator, `it`, referencing a `CompactedArray` `array`, remains valid as
586/// long as `0 <= it - array.begin() <= array.length()`. The behavior is
587/// undefined unless `CompactedArray_ConstIterator() != iterator` and
588/// `0 <= iterator - array.begin() - offset <= array.length()`.
589template <class TYPE>
592 bsl::ptrdiff_t offset);
593
594/// Return the number of elements between the specified `lhs` and `rhs` as a
595/// signed value. The behavior is undefined unless `lhs` and `rhs`
596/// reference the same array. Note that the return value is positive when a
597/// positive number of `rhs++` invocations would result in `lhs == rhs`, and
598/// negative when a positive number of `rhs--` invocations would result in
599/// `lhs == rhs`.
600template <class TYPE>
601bsl::ptrdiff_t operator-(const CompactedArray_ConstIterator<TYPE>& lhs,
603
604/// Return `true` if the specified `lhs` and `rhs` iterators have the same
605/// value, and `false` otherwise. Two `CompactedArray_ConstIterator`
606/// iterators have the same value if they both have the default value, or
607/// neither has the default value and they reference the same location in
608/// the same array.
609template <class TYPE>
610bool operator==(const CompactedArray_ConstIterator<TYPE>& lhs,
612
613/// Return `true` if the specified `lhs` and `rhs` iterators do not have the
614/// same value, and `false` otherwise. Two `CompactedArray_ConstIterator`
615/// iterators do not have the same value if one has the default value and
616/// the other does not, or neither has the default value and they do not
617/// reference the same location in the same array.
618template <class TYPE>
619bool operator!=(const CompactedArray_ConstIterator<TYPE>& lhs,
621
622/// Return `true` if the specified `lhs` has a value less than the specified
623/// `rhs`, and `false` otherwise. Iterator `lhs` has a value less than
624/// iterator `rhs` if `0 < rhs - lhs` (see `operator-`). The behavior is
625/// undefined unless `lhs` and `rhs` refer to the same array.
626template <class TYPE>
627bool operator<(const CompactedArray_ConstIterator<TYPE>& lhs,
629
630/// Return `true` if the specified `lhs` has a value less than or equal to
631/// the specified `rhs, and `false' otherwise. Iterator `lhs` has a value
632/// less than or equal to iterator `rhs` if `0 <= rhs - lhs` (see
633/// `operator-`). The behavior is undefined unless `lhs` and `rhs` refer to
634/// the same array.
635template <class TYPE>
636bool operator<=(const CompactedArray_ConstIterator<TYPE>& lhs,
638
639/// Return `true` if the specified `lhs` has a value greater than the
640/// specified `rhs`, and `false` otherwise. Iterator `lhs` has a value
641/// greater than iterator `rhs` if `0 > rhs - lhs` (see `operator-`). The
642/// behavior is undefined unless `lhs` and `rhs` refer to the same array.
643template <class TYPE>
644bool operator>(const CompactedArray_ConstIterator<TYPE>& lhs,
646
647/// Return `true` if the specified `lhs` has a value greater or equal than
648/// the specified `rhs`, and `false` otherwise. Iterator `lhs` has a value
649/// greater than or equal to iterator `rhs` if `0 >= rhs - lhs` (see
650/// `operator-`). The behavior is undefined unless `lhs` and `rhs` refer to
651/// the same array.
652template <class TYPE>
653bool operator>=(const CompactedArray_ConstIterator<TYPE>& lhs,
655
656 // ====================
657 // class CompactedArray
658 // ====================
659
660/// This space-efficient, value-semantic array class represents a sequence
661/// of `TYPE` elements. The interface provides functionality similar to a
662/// `vector<TYPE>`, however, modifiable references to individual elements
663/// are not provided. This class provides accessors that return iterators
664/// that provide non-modifiable access to its elements. The returned
665/// iterators, unlike those returned by a `vector<TYPE>`, are *not*
666/// invalidated upon reallocation.
667///
668/// See @ref bdlc_compactedarray
669template <class TYPE>
671
672 // PRIVATE TYPES
674
675 // DATA
676 Data d_data; // sorted vector of reference-counted
677 // unique objects
678
679 PackedIntArray<bsl::size_t> d_index; // array of indices into 'd_data'
680
681 private:
682 // PRIVATE MANIPULATORS
683
684 /// Remove the element in `d_data` at the specified `index`. Update the
685 /// `d_index` values to account for this removal. The behavior is
686 /// undefined unless `index < uniqueLength()`.
687 void erase(bsl::size_t index);
688
689 /// Find the element in `d_data` equal to the specified `value`,
690 /// increment the element's reference count by the specified `count`,
691 /// and return the element's index. If the `value` is not in `d_data`,
692 /// insert the element so as to retain sorted order in `d_data`, assign
693 /// `count` as the new element's reference count, and return the
694 /// inserted element's index. The behavior is undefined unless
695 /// `0 < count`.
696 bsl::size_t increment(const TYPE& value, bsl::size_t count = 1);
697
698 public:
699 // PUBLIC TYPES
700 typedef TYPE value_type; // The type for elements.
701
703
704 // CREATORS
705
706 /// Create an empty `CompactedArray`. Optionally specify a
707 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0,
708 /// the currently installed default allocator is used.
709 explicit CompactedArray(bslma::Allocator *basicAllocator = 0);
710
711 /// Create a `CompactedArray` having the specified `numElements`.
712 /// Optionally specify a `value` to which each element will be set. If
713 /// `value` is not specified, `TYPE()` is used. Optionally specify a
714 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0,
715 /// the currently installed default allocator is used.
716 explicit CompactedArray(bsl::size_t numElements,
717 const TYPE& value = TYPE(),
718 bslma::Allocator *basicAllocator = 0);
719
720 /// Create a `CompactedArray` having the same value as the specified
721 /// `original` object. Optionally specify a `basicAllocator` used to
722 /// supply memory. If `basicAllocator` is 0, the currently installed
723 /// default allocator is used.
725 bslma::Allocator *basicAllocator = 0);
726
727 /// Destroy this object
729
730 // MANIPULATORS
731
732 /// Assign to this array the value of the specified `rhs` array, and
733 /// return a reference providing modifiable access to this array.
735
736 /// Append to this array an element having the specified `value`. Note
737 /// that this method is logically equivalent to:
738 /// @code
739 /// push_back(value);
740 /// @endcode
741 void append(const TYPE& value);
742
743 /// Append to this array the elements from the specified `srcArray`.
744 /// Note that if this array and `srcArray` are the same, the behavior is
745 /// as if a copy of `srcArray` were passed.
746 void append(const CompactedArray& srcArray);
747
748 /// Append to this array the specified `numElements` starting at the
749 /// specified `srcIndex` in the specified `srcArray`. The behavior is
750 /// undefined unless `srcIndex + numElements <= srcArray.length()`.
751 /// Note that if this array and `srcArray` are the same, the behavior is
752 /// as if a copy of `srcArray` were passed.
753 void append(const CompactedArray& srcArray,
754 bsl::size_t srcIndex,
755 bsl::size_t numElements);
756
757 /// Insert into this array, at the specified `dstIndex`, an element
758 /// having the specified `value`, shifting any elements originally at or
759 /// above `dstIndex` up by one index position. The behavior is
760 /// undefined unless `dstIndex <= length()`.
761 void insert(bsl::size_t dstIndex, const TYPE& value);
762
763 /// Insert into this array, at the specified `dst`, an element having
764 /// the specified `value`, shifting any elements originally at or above
765 /// `dst` up by one index position. Return an iterator to the newly
766 /// inserted element. The behavior is undefined unless `dst` is an
767 /// iterator over this array.
768 const_iterator insert(const_iterator dst, const TYPE& value);
769
770 /// Insert into this array, at the specified `dstIndex`, the elements
771 /// from the specified `srcArray`, shifting any elements originally at
772 /// or above `dstIndex` up by `srcArray.length()` index positions. The
773 /// behavior is undefined unless `dstIndex <= length()`. Note that if
774 /// this array and `srcArray` are the same, the behavior is as if a copy
775 /// of `srcArray` were passed.
776 void insert(bsl::size_t dstIndex, const CompactedArray& srcArray);
777
778 /// Insert into this array, at the specified `dstIndex`, the specified
779 /// `numElements` starting at the specified `srcIndex` in the specified
780 /// `srcArray`. Elements having an index greater than or equal to
781 /// `dstIndex` before the insertion are shifted up by `numElements`
782 /// index positions. The behavior is undefined unless
783 /// `dstIndex <= length()` and
784 /// `srcIndex + numElements <= srcArray.length()`. Note that if this
785 /// array and `srcArray` are the same, the behavior is as if a copy of
786 /// `srcArray` were passed.
787 void insert(bsl::size_t dstIndex,
788 const CompactedArray& srcArray,
789 bsl::size_t srcIndex,
790 bsl::size_t numElements);
791
792 /// Remove the last element from this array. The behavior is undefined
793 /// unless `0 < length()`.
794 void pop_back();
795
796 /// Append to this array an element having the specified `value`.
797 void push_back(const TYPE& value);
798
799 /// Remove from this array the element at the specified `dstIndex`.
800 /// Each element having an index greater than `dstIndex` before the
801 /// removal is shifted down by one index position. The behavior is
802 /// undefined unless `dstIndex < length()`.
803 void remove(bsl::size_t dstIndex);
804
805 /// Remove from this array the specified `numElements` starting at the
806 /// specified `dstIndex`. Each element having an index greater than or
807 /// equal to `dstIndex + numElements` before the removal is shifted down
808 /// by `numElements` index positions. The behavior is undefined unless
809 /// `dstIndex + numElements <= length()`.
810 void remove(bsl::size_t dstIndex, bsl::size_t numElements);
811
812 /// Remove from this array the elements starting at the specified
813 /// `dstFirst` iterator up to, but not including, the specified
814 /// `dstLast` iterator. Each element at or above `dstLast` before the
815 /// removal is shifted down by `dstLast - dstFirst` index positions.
816 /// Return an iterator to the new position of the element that was
817 /// referred to by `dstLast`, or `end()` if `dstLast == end()`. The
818 /// behavior is undefined unless `dstFirst` and `dstLast` are iterators
819 /// over this array, and `dstFirst <= dstLast`.
821
822 /// Remove all the elements from this array.
823 void removeAll();
824
825 /// Change the value of the element at the specified `dstIndex` in this
826 /// array to the specified `value`. The behavior is undefined unless
827 /// `dstIndex < length()`.
828 void replace(bsl::size_t dstIndex, const TYPE& value);
829
830 /// Change the values of the specified `numElements` starting at the
831 /// specified `dstIndex` in this array to those of the `numElements`
832 /// starting at the specified `srcIndex` in the specified `srcArray`.
833 /// The behavior is undefined unless
834 /// `srcIndex + numElements <= srcArray.length()` and
835 /// `dstIndex + numElements <= length()`. Note that if this array and
836 /// `srcArray` are the same, the behavior is as if a copy of `srcArray`
837 /// were passed.
838 void replace(bsl::size_t dstIndex,
839 const CompactedArray& srcArray,
840 bsl::size_t srcIndex,
841 bsl::size_t numElements);
842
843 /// Make the capacity of this array at least the specified
844 /// `numElements`, assuming the number of unique elements within this
845 /// array does not increase. This method has no effect if the current
846 /// capacity meets or exceeds the required capacity. The behavior is
847 /// undefined unless `false == isEmpty() || 0 == numElements`. Note
848 /// that the assumption of not increasing the number of unique elements
849 /// implies the need for the narrow contract.
850 void reserveCapacity(bsl::size_t numElements);
851
852 /// Make the capacity of this array at least the specified
853 /// `numElements`, assuming the number of unique elements in this array
854 /// does not exceed the greater of the specified `numUniqueElements` and
855 /// `uniqueLength()`. This method has no effect if the current capacity
856 /// meets or exceeds the required capacity. The behavior is undefined
857 /// unless `numUniqueElements <= numElements` and
858 /// `0 < numUniqueElements || 0 == numElements`.
859 void reserveCapacity(bsl::size_t numElements,
860 bsl::size_t numUniqueElements);
861
862 /// Set the length of this array to the specified `numElements`. If
863 /// `numElements > length()`, the added elements are initialized to
864 /// `TYPE()`.
865 void resize(bsl::size_t numElements);
866
867 /// Efficiently exchange the value of this array with the value of the
868 /// specified `other` array. This method provides the no-throw
869 /// exception-safety guarantee. The behavior is undefined unless this
870 /// array was created with the same allocator as `other`.
871 void swap(CompactedArray& other);
872
873 // ACCESSORS
874
875 /// Return a `const` reference to the element at the specified `index`
876 /// in this array. The behavior is undefined unless `index < length()`.
877 const TYPE& operator[](bsl::size_t index) const;
878
879 /// Return the allocator used by this array to supply memory.
881
882 /// Return a `const` reference to the element at the back of this array.
883 /// The behavior is undefined unless `0 < length()`. Note that this
884 /// method is logically equivalent to:
885 /// @code
886 /// operator[](length() - 1)
887 /// @endcode
888 const TYPE& back() const;
889
890 /// Return an iterator referring to the first element in this array, or
891 /// the past-the-end iterator if this array is empty. The iterator
892 /// remains valid as long as this array exists.
894
895 /// Return the number of elements this array can hold, without
896 /// reallocation, assuming the number of unique elements within this
897 /// array does not increase.
898 bsl::size_t capacity() const;
899
900 /// Return the past-the-end iterator for this array. The iterator
901 /// remains valid as long as this array exists, and its length does not
902 /// decrease.
904
905 /// Return a `const` reference to the element at the front of this
906 /// array. The behavior is undefined unless `0 < length()`. Note that
907 /// this method is logically equivalent to:
908 /// @code
909 /// operator[](0)
910 /// @endcode
911 const TYPE& front() const;
912
913 /// Return `true` if there are no elements in this array, and `false`
914 /// otherwise.
915 bool isEmpty() const;
916
917 /// Return `true` if this and the specified `other` array have the same
918 /// value, and `false` otherwise. Two `CompactedArray` arrays have the
919 /// same value if they have the same length, and all corresponding
920 /// elements (those at the same indices) have the same value.
921 bool isEqual(const CompactedArray& other) const;
922
923 /// Return the number of elements in this array.
924 bsl::size_t length() const;
925
926 /// Write the value of this array to the specified output `stream` in a
927 /// human-readable format, and return a reference to `stream`.
928 /// Optionally specify an initial indentation `level`, whose absolute
929 /// value is incremented recursively for nested arrays. If `level` is
930 /// specified, optionally specify `spacesPerLevel`, whose absolute value
931 /// indicates the number of spaces per indentation level for this and
932 /// all of its nested arrays. If `level` is negative, format the entire
933 /// output on one line, suppressing all but the initial indentation (as
934 /// governed by `level`). If `stream` is not valid on entry, this
935 /// operation has no effect. Note that the format is not fully
936 /// specified, and can change without notice.
937 bsl::ostream& print(bsl::ostream& stream,
938 int level = 0,
939 int spacesPerLevel = 4) const;
940
941 /// Return a `const` reference to the element at the specified `index`
942 /// within the sorted sequence of unique element values in this object.
943 /// The behavior is undefined unless `index < uniqueLength()`. Note
944 /// that `uniqueElement(index)` and `operator@ref index ` can return
945 /// different objects.
946 const TYPE& uniqueElement(bsl::size_t index) const;
947
948 /// Return the number of unique elements in this array.
949 bsl::size_t uniqueLength() const;
950};
951
952// FREE OPERATORS
953
954/// Write the value of the specified `array` to the specified output
955/// `stream` in a single-line format, and return a reference providing
956/// modifiable access to `stream`. If `stream` is not valid on entry, this
957/// operation has no effect. Note that this human-readable format is not
958/// fully specified and can change without notice.
959template <class TYPE>
960bsl::ostream& operator<<(bsl::ostream& stream,
961 const CompactedArray<TYPE>& array);
962
963/// Return `true` if the specified `lhs` and `rhs` arrays have the same
964/// value, and `false` otherwise. Two `CompactedArray` arrays have the same
965/// value if they have the same length, and all corresponding elements
966/// (those at the same indices) have the same value.
967template <class TYPE>
968bool operator==(const CompactedArray<TYPE>& lhs,
969 const CompactedArray<TYPE>& rhs);
970
971/// Return `true` if the specified `lhs` and `rhs` arrays do not have the
972/// same value, and `false` otherwise. Two `CompactedArray` arrays do not
973/// have the same value if they do not have the same length, or if any
974/// corresponding elements (those at the same indices) do not have the same
975/// value.
976template <class TYPE>
977bool operator!=(const CompactedArray<TYPE>& lhs,
978 const CompactedArray<TYPE>& rhs);
979
980// FREE FUNCTIONS
981
982/// Exchange the values of the specified `a` and `b` objects. This function
983/// provides the no-throw exception-safety guarantee if the two objects were
984/// created with the same allocator and the basic guarantee otherwise.
985template <class TYPE>
987
988// HASH SPECIALIZATIONS
989
990/// Pass the specified `input` to the specified `hashAlg`.
991template <class HASHALG, class TYPE>
992void hashAppend(HASHALG& hashAlg, const CompactedArray<TYPE>& input);
993
994// ============================================================================
995// INLINE DEFINITIONS
996// ============================================================================
997
998 // -------------------------------------
999 // class CompactedArray_RemoveAllProctor
1000 // -------------------------------------
1001
1002// CREATORS
1003template <class TYPE>
1004inline
1010
1011template <class TYPE>
1012inline
1014{
1015 if (d_array_p) {
1016 d_array_p->removeAll();
1017 }
1018}
1019
1020// MANIPULATORS
1021template <class TYPE>
1022inline
1024{
1025 d_array_p = 0;
1026}
1027
1028 // ----------------------------------
1029 // struct CompactedArray_CountedValue
1030 // ----------------------------------
1031
1032// CREATORS
1033template <class TYPE>
1034inline
1036 const TYPE& value,
1037 bsl::size_t count,
1038 bslma::Allocator *basicAllocator)
1039: d_count(count)
1040{
1041 BSLS_ASSERT(basicAllocator);
1042
1044 basicAllocator,
1045 value);
1046}
1047
1048template <class TYPE>
1049inline
1051 const CompactedArray_CountedValue<TYPE>& original,
1052 bslma::Allocator *basicAllocator)
1053: d_count(original.d_count)
1054{
1055 BSLS_ASSERT(basicAllocator);
1056
1058 basicAllocator,
1059 original.d_value.object());
1060}
1061
1062template <class TYPE>
1063inline
1065{
1066 d_value.object().~TYPE();
1067}
1068
1069// MANIPULATORS
1070template <class TYPE>
1071inline
1075{
1076 d_value.object() = rhs.d_value.object();
1077 d_count = rhs.d_count;
1078
1079 return *this;
1080}
1081
1082} // close package namespace
1083
1084// FREE OPERATORS
1085template <class TYPE>
1086inline
1087bool bdlc::operator==(const CompactedArray_CountedValue<TYPE>& lhs,
1088 const CompactedArray_CountedValue<TYPE>& rhs)
1089{
1090 return lhs.d_value.object() == rhs.d_value.object();
1091}
1092
1093template <class TYPE>
1094inline
1095bool bdlc::operator!=(const CompactedArray_CountedValue<TYPE>& lhs,
1096 const CompactedArray_CountedValue<TYPE>& rhs)
1097{
1098 return lhs.d_value.object() != rhs.d_value.object();
1099}
1100
1101template <class TYPE>
1102inline
1103bool bdlc::operator<(const CompactedArray_CountedValue<TYPE>& lhs,
1104 const TYPE& rhs)
1105{
1106 return lhs.d_value.object() < rhs;
1107}
1108
1109template <class TYPE>
1110inline
1111bool bdlc::operator<(const TYPE& lhs,
1112 const CompactedArray_CountedValue<TYPE>& rhs)
1113{
1114 return lhs < rhs.d_value.object();
1115}
1116
1117namespace bdlc {
1118
1119 // ----------------------------------
1120 // class CompactedArray_ConstIterator
1121 // ----------------------------------
1122
1123// PRIVATE CREATORS
1124template <class TYPE>
1125inline
1127 const CompactedArray<TYPE> *array,
1128 bsl::size_t index)
1129: d_array_p(array)
1130, d_index(index)
1131{
1132 BSLS_ASSERT(d_array_p);
1133 BSLS_ASSERT(d_index <= d_array_p->length());
1134}
1135
1136// CREATORS
1137template <class TYPE>
1138inline
1140: d_array_p(0)
1141, d_index(0)
1142{
1143}
1144
1145template <class TYPE>
1146inline
1148 const CompactedArray_ConstIterator& original)
1149: d_array_p(original.d_array_p)
1150, d_index(original.d_index)
1151{
1152}
1153
1154// MANIPULATORS
1155template <class TYPE>
1156inline
1159{
1160 d_array_p = rhs.d_array_p;
1161 d_index = rhs.d_index;
1162 return *this;
1163}
1164
1165template <class TYPE>
1166inline
1169{
1170 BSLS_ASSERT(d_array_p);
1171
1172 // Assert '0 <= d_index + offset <= d_array_p->length()' without risk of
1173 // overflow.
1174 BSLS_ASSERT( 0 <= offset || d_index >= bsl::size_t(-offset));
1175 BSLS_ASSERT( 0 >= offset
1176 || d_array_p->length() - d_index >= bsl::size_t(offset));
1177
1178 d_index += offset;
1179 return *this;
1180}
1181
1182template <class TYPE>
1183inline
1186{
1187 BSLS_ASSERT(d_array_p);
1188
1189 // Assert '0 <= d_index - offset <= d_array_p->length()' without risk of
1190 // overflow.
1191 BSLS_ASSERT( 0 >= offset || d_index >= bsl::size_t(offset));
1192 BSLS_ASSERT( 0 <= offset
1193 || d_array_p->length() - d_index >= bsl::size_t(-offset));
1194
1195 d_index -= offset;
1196 return *this;
1197}
1198
1199template <class TYPE>
1200inline
1203{
1204 BSLS_ASSERT(d_array_p);
1205 BSLS_ASSERT(d_index < d_array_p->length());
1206
1207 ++d_index;
1208 return *this;
1209}
1210
1211template <class TYPE>
1212inline
1215{
1216 BSLS_ASSERT(d_array_p);
1217 BSLS_ASSERT(0 < d_index);
1218
1219 --d_index;
1220 return *this;
1221}
1222
1223// ACCESSORS
1224template <class TYPE>
1225inline
1227{
1228 BSLS_ASSERT(d_array_p);
1229 BSLS_ASSERT(d_index < d_array_p->length());
1230
1231 return (*d_array_p)[d_index];
1232}
1233
1234template <class TYPE>
1235inline
1237{
1238 BSLS_ASSERT(d_array_p);
1239 BSLS_ASSERT(d_index < d_array_p->length());
1240
1241 return (*d_array_p)[d_index];
1242}
1243
1244template <class TYPE>
1245inline
1247 operator[](bsl::ptrdiff_t offset) const
1248{
1249 BSLS_ASSERT(d_array_p);
1250
1251 // Assert '0 <= d_index + offset < d_array_p->length()' without risk of
1252 // overflow.
1253 BSLS_ASSERT( 0 <= offset || d_index >= bsl::size_t(-offset));
1254 BSLS_ASSERT( 0 >= offset
1255 || d_array_p->length() - d_index > bsl::size_t(offset));
1256
1257 return (*d_array_p)[d_index + offset];
1258}
1259
1260} // close package namespace
1261
1262// FREE OPERATORS
1263template <class TYPE>
1264inline
1266 CompactedArray_ConstIterator<TYPE>& iterator,
1267 int)
1268{
1269 BSLS_ASSERT(iterator.d_array_p);
1270 BSLS_ASSERT(iterator.d_index < iterator.d_array_p->length());
1271
1272 const CompactedArray_ConstIterator<TYPE> curr = iterator;
1273 ++iterator;
1274 return curr;
1275}
1276
1277template <class TYPE>
1278inline
1280 CompactedArray_ConstIterator<TYPE>& iterator,
1281 int)
1282{
1283 BSLS_ASSERT(iterator.d_array_p);
1284 BSLS_ASSERT(iterator.d_index > 0);
1285
1286 const CompactedArray_ConstIterator<TYPE> curr = iterator;
1287 --iterator;
1288 return curr;
1289}
1290
1291template <class TYPE>
1292inline
1294 const CompactedArray_ConstIterator<TYPE>& iterator,
1295 bsl::ptrdiff_t offset)
1296{
1297 BSLS_ASSERT(iterator.d_array_p);
1298
1299 // Assert '0 <= iterator.d_index + offset <= iterator.d_array_p->length()'
1300 // without risk of overflow.
1301 BSLS_ASSERT( 0 <= offset
1302 || iterator.d_index >= bsl::size_t(-offset));
1303 BSLS_ASSERT( 0 >= offset
1304 || iterator.d_array_p->length() - iterator.d_index
1305 >= bsl::size_t( offset));
1306
1307 return CompactedArray_ConstIterator<TYPE>(iterator.d_array_p,
1308 iterator.d_index + offset);
1309}
1310
1311template <class TYPE>
1312inline
1314 bsl::ptrdiff_t offset,
1315 const CompactedArray_ConstIterator<TYPE>& iterator)
1316{
1317 return iterator + offset;
1318}
1319
1320template <class TYPE>
1321inline
1323 const CompactedArray_ConstIterator<TYPE>& iterator,
1324 bsl::ptrdiff_t offset)
1325{
1326 BSLS_ASSERT(iterator.d_array_p);
1327
1328 // Assert '0 <= iterator.d_index - offset <= iterator.d_array_p->length()'
1329 // without risk of overflow.
1330 BSLS_ASSERT( 0 >= offset
1331 || iterator.d_index >= bsl::size_t( offset));
1332 BSLS_ASSERT( 0 <= offset
1333 || iterator.d_array_p->length() - iterator.d_index
1334 >= bsl::size_t(-offset));
1335
1336 return CompactedArray_ConstIterator<TYPE>(iterator.d_array_p,
1337 iterator.d_index - offset);
1338}
1339
1340template <class TYPE>
1341inline
1342bsl::ptrdiff_t bdlc::operator-(const CompactedArray_ConstIterator<TYPE>& lhs,
1343 const CompactedArray_ConstIterator<TYPE>& rhs)
1344{
1345 BSLS_ASSERT(lhs.d_array_p);
1346 BSLS_ASSERT(rhs.d_array_p);
1347 BSLS_ASSERT(lhs.d_array_p == rhs.d_array_p);
1348
1350 lhs.d_index >= rhs.d_index
1351 ? lhs.d_index - rhs.d_index <=
1352 bsl::size_t(bsl::numeric_limits<bsl::ptrdiff_t>::max())
1353 : rhs.d_index - lhs.d_index <=
1354 bsl::size_t(bsl::numeric_limits<bsl::ptrdiff_t>::min()));
1355
1356 return static_cast<bsl::ptrdiff_t>(lhs.d_index - rhs.d_index);
1357}
1358
1359template <class TYPE>
1360inline
1361bool bdlc::operator==(const CompactedArray_ConstIterator<TYPE>& lhs,
1362 const CompactedArray_ConstIterator<TYPE>& rhs)
1363{
1364 return lhs.d_array_p == rhs.d_array_p && lhs.d_index == rhs.d_index;
1365}
1366
1367template <class TYPE>
1368inline
1369bool bdlc::operator!=(const CompactedArray_ConstIterator<TYPE>& lhs,
1370 const CompactedArray_ConstIterator<TYPE>& rhs)
1371{
1372 return lhs.d_array_p != rhs.d_array_p || lhs.d_index != rhs.d_index;
1373}
1374
1375template <class TYPE>
1376inline
1377bool bdlc::operator<(const CompactedArray_ConstIterator<TYPE>& lhs,
1378 const CompactedArray_ConstIterator<TYPE>& rhs)
1379{
1380 BSLS_ASSERT(lhs.d_array_p);
1381 BSLS_ASSERT(rhs.d_array_p);
1382 BSLS_ASSERT(lhs.d_array_p == rhs.d_array_p);
1383
1384 return lhs.d_index < rhs.d_index;
1385}
1386
1387template <class TYPE>
1388inline
1389bool bdlc::operator<=(const CompactedArray_ConstIterator<TYPE>& lhs,
1390 const CompactedArray_ConstIterator<TYPE>& rhs)
1391{
1392 BSLS_ASSERT(lhs.d_array_p);
1393 BSLS_ASSERT(rhs.d_array_p);
1394 BSLS_ASSERT(lhs.d_array_p == rhs.d_array_p);
1395
1396 return lhs.d_index <= rhs.d_index;
1397}
1398
1399template <class TYPE>
1400inline
1401bool bdlc::operator>(const CompactedArray_ConstIterator<TYPE>& lhs,
1402 const CompactedArray_ConstIterator<TYPE>& rhs)
1403{
1404 BSLS_ASSERT(lhs.d_array_p);
1405 BSLS_ASSERT(rhs.d_array_p);
1406 BSLS_ASSERT(lhs.d_array_p == rhs.d_array_p);
1407
1408 return lhs.d_index > rhs.d_index;
1409}
1410
1411template <class TYPE>
1412inline
1413bool bdlc::operator>=(const CompactedArray_ConstIterator<TYPE>& lhs,
1414 const CompactedArray_ConstIterator<TYPE>& rhs)
1415{
1416 BSLS_ASSERT(lhs.d_array_p);
1417 BSLS_ASSERT(rhs.d_array_p);
1418 BSLS_ASSERT(lhs.d_array_p == rhs.d_array_p);
1419
1420 return lhs.d_index >= rhs.d_index;
1421}
1422
1423namespace bdlc {
1424
1425 // --------------------
1426 // class CompactedArray
1427 // --------------------
1428
1429// PRIVATE MANIPULATORS
1430template <class TYPE>
1431void CompactedArray<TYPE>::erase(bsl::size_t index)
1432{
1433 BSLS_ASSERT(index < uniqueLength());
1434
1435 for (bsl::size_t i = 0; i < d_index.length(); ++i) {
1436 if (d_index[i] > index) {
1437 d_index.replace(i, d_index[i] - 1);
1438 }
1439 }
1440
1441 d_data.erase(d_data.begin() + index);
1442}
1443
1444template <class TYPE>
1445bsl::size_t CompactedArray<TYPE>::increment(const TYPE& value,
1446 bsl::size_t count)
1447{
1448 BSLS_ASSERT(0 < count);
1449
1450 bsl::size_t index;
1451
1452 typename Data::iterator iter =
1454 d_data.end(),
1455 value);
1456
1457 if (iter == d_data.end()) {
1458 index = d_data.size();
1459 d_data.emplace_back(value, count);
1460 }
1461 else if (value < iter->d_value.object()) {
1462 index = iter - d_data.begin();
1463
1464 d_data.insert(iter,
1465 CompactedArray_CountedValue<TYPE>(
1466 value,
1467 count,
1468 d_data.get_allocator().mechanism()));
1469
1470 for (bsl::size_t i = 0; i < d_index.length(); ++i) {
1471 if (d_index[i] >= index) {
1472 d_index.replace(i, d_index[i] + 1);
1473 }
1474 }
1475 }
1476 else {
1477 index = iter - d_data.begin();
1478
1479 iter->d_count += count;
1480 }
1481
1482 return index;
1483}
1484
1485// CREATORS
1486template <class TYPE>
1488: d_data(basicAllocator)
1489, d_index(basicAllocator)
1490{
1491}
1492
1493template <class TYPE>
1495 const TYPE& value,
1496 bslma::Allocator *basicAllocator)
1497: d_data(basicAllocator)
1498, d_index(basicAllocator)
1499{
1500 if (numElements) {
1501 d_index.reserveCapacity(numElements, 1);
1502
1503 d_data.emplace_back(value, numElements);
1504 d_index.resize(numElements);
1505 }
1506}
1507
1508template <class TYPE>
1510 const CompactedArray<TYPE>& original,
1511 bslma::Allocator *basicAllocator)
1512: d_data(original.d_data, basicAllocator)
1513, d_index(original.d_index, basicAllocator)
1514{
1515}
1516
1517template <class TYPE>
1521
1522// MANIPULATORS
1523template <class TYPE>
1525 const CompactedArray<TYPE>& rhs)
1526{
1527 if (this != &rhs) {
1529
1530 d_index.reserveCapacity(rhs.length(), rhs.uniqueLength());
1531 d_data = rhs.d_data;
1532 d_index = rhs.d_index;
1533
1534 proctor.release();
1535 }
1536
1537 return *this;
1538}
1539
1540template <class TYPE>
1541void CompactedArray<TYPE>::append(const TYPE& value)
1542{
1544
1545 d_index.reserveCapacity(d_index.length() + 1, d_data.size() + 1);
1546
1547 d_index.push_back(increment(value));
1548
1549 proctor.release();
1550}
1551
1552template <class TYPE>
1554{
1555 if (&srcArray != this) {
1557
1558 d_index.reserveCapacity(d_index.length() + srcArray.d_index.length(),
1559 d_data.size() + srcArray.d_data.size());
1560
1561 for (bsl::size_t i = 0; i < srcArray.length(); ++i) {
1562 d_index.push_back(increment(srcArray[i]));
1563 }
1564
1565 proctor.release();
1566 }
1567 else {
1568 d_index.reserveCapacity(d_index.length() * 2);
1569
1570 for (bsl::size_t i = 0; i < d_data.size(); ++i) {
1571 d_data[i].d_count *= 2;
1572 }
1573
1574 d_index.append(d_index);
1575 }
1576}
1577
1578template <class TYPE>
1580 bsl::size_t srcIndex,
1581 bsl::size_t numElements)
1582{
1583 // Assert 'srcIndex + numElements <= srcArray.length()' without risk of
1584 // overflow.
1585 BSLS_ASSERT(numElements <= srcArray.length());
1586 BSLS_ASSERT(srcIndex <= srcArray.length() - numElements);
1587
1588 if (&srcArray != this) {
1590
1591 d_index.reserveCapacity(d_index.length() + numElements,
1592 d_data.size() + numElements);
1593
1594 for (bsl::size_t i = 0; i < numElements; ++i) {
1595 d_index.push_back(increment(srcArray[srcIndex + i]));
1596 }
1597
1598 proctor.release();
1599 }
1600 else {
1601 d_index.reserveCapacity(d_index.length() + numElements);
1602
1603 for (bsl::size_t i = 0; i < numElements; ++i) {
1604 d_data[d_index[srcIndex + i]].d_count += 1;
1605 }
1606
1607 d_index.append(d_index, srcIndex, numElements);
1608 }
1609}
1610
1611template <class TYPE>
1612void CompactedArray<TYPE>::insert(bsl::size_t dstIndex, const TYPE& value)
1613{
1614 BSLS_ASSERT(dstIndex <= d_index.length());
1615
1617
1618 d_index.reserveCapacity(d_index.length() + 1, d_data.size() + 1);
1619
1620 d_index.insert(dstIndex, increment(value));
1621
1622 proctor.release();
1623}
1624
1625template <class TYPE>
1626inline
1629{
1630 BSLS_ASSERT(this == dst.d_array_p);
1631
1632 insert(dst.d_index, value);
1633 return dst;
1634}
1635
1636template <class TYPE>
1637void CompactedArray<TYPE>::insert(bsl::size_t dstIndex,
1638 const CompactedArray& srcArray)
1639{
1640 BSLS_ASSERT(dstIndex <= d_index.length());
1641
1642 if (&srcArray != this) {
1644
1645 d_index.reserveCapacity(d_index.length() + srcArray.d_index.length(),
1646 d_data.size() + srcArray.d_data.size());
1647
1648 for (bsl::size_t i = 0; i < srcArray.length(); ++i) {
1649 d_index.insert(dstIndex + i, increment(srcArray[i]));
1650 }
1651
1652 proctor.release();
1653 }
1654 else {
1655 d_index.reserveCapacity(d_index.length() * 2);
1656
1657 for (bsl::size_t i = 0; i < d_data.size(); ++i) {
1658 d_data[i].d_count *= 2;
1659 }
1660
1661 d_index.insert(dstIndex, d_index);
1662 }
1663}
1664
1665template <class TYPE>
1666void CompactedArray<TYPE>::insert(bsl::size_t dstIndex,
1667 const CompactedArray& srcArray,
1668 bsl::size_t srcIndex,
1669 bsl::size_t numElements)
1670{
1671 BSLS_ASSERT(dstIndex <= d_index.length());
1672
1673 // Assert 'srcIndex + numElements <= srcArray.length()' without risk of
1674 // overflow.
1675 BSLS_ASSERT(numElements <= srcArray.length());
1676 BSLS_ASSERT(srcIndex <= srcArray.length() - numElements);
1677
1678 if (&srcArray != this) {
1680
1681 d_index.reserveCapacity(d_index.length() + numElements,
1682 d_data.size() + numElements);
1683
1684 for (bsl::size_t i = 0; i < numElements; ++i) {
1685 d_index.insert(dstIndex + i, increment(srcArray[srcIndex + i]));
1686 }
1687
1688 proctor.release();
1689 }
1690 else {
1691 d_index.reserveCapacity(d_index.length() + numElements);
1692
1693 for (bsl::size_t i = 0; i < numElements; ++i) {
1694 d_data[d_index[srcIndex + i]].d_count += 1;
1695 }
1696
1697 d_index.insert(dstIndex, d_index, srcIndex, numElements);
1698 }
1699}
1700
1701template <class TYPE>
1703{
1704 BSLS_ASSERT(!isEmpty());
1705
1706 bsl::size_t dataIndex = d_index.back();
1707 CompactedArray_CountedValue<TYPE>& dataValue = d_data[dataIndex];
1708
1709 d_index.pop_back();
1710
1711 if (0 == --dataValue.d_count) {
1713
1714 erase(dataIndex);
1715
1716 proctor.release();
1717 }
1718}
1719
1720template <class TYPE>
1721inline
1722void CompactedArray<TYPE>::push_back(const TYPE& value)
1723{
1724 append(value);
1725}
1726
1727template <class TYPE>
1728inline
1729void CompactedArray<TYPE>::remove(bsl::size_t dstIndex)
1730{
1731 BSLS_ASSERT(dstIndex < d_index.length());
1732
1733 remove(dstIndex, 1);
1734}
1735
1736template <class TYPE>
1737void CompactedArray<TYPE>::remove(bsl::size_t dstIndex,
1738 bsl::size_t numElements)
1739{
1740 // Assert 'dstIndex + numElements <= d_index.length()' without risk of
1741 // overflow.
1742 BSLS_ASSERT(numElements <= d_index.length());
1743 BSLS_ASSERT(dstIndex <= d_index.length() - numElements);
1744
1746
1747 bsl::size_t endIndex = dstIndex + numElements;
1748 for (bsl::size_t i = dstIndex; i < endIndex; ++i) {
1749 bsl::size_t dataIndex = d_index[i];
1750 CompactedArray_CountedValue<TYPE>& dataValue = d_data[dataIndex];
1751
1752 if (0 == --dataValue.d_count) {
1753 erase(dataIndex);
1754 }
1755 }
1756
1757 d_index.remove(dstIndex, numElements);
1758
1759 proctor.release();
1760}
1761
1762template <class TYPE>
1763inline
1766 const_iterator dstLast)
1767{
1768 BSLS_ASSERT(this == dstFirst.d_array_p);
1769 BSLS_ASSERT(this == dstLast.d_array_p);
1770 BSLS_ASSERT(dstFirst <= dstLast);
1771
1772 remove(dstFirst.d_index, dstLast.d_index - dstFirst.d_index);
1773 return dstFirst;
1774}
1775
1776template <class TYPE>
1778{
1779 d_data.clear();
1780 d_index.removeAll();
1781}
1782
1783template <class TYPE>
1784void CompactedArray<TYPE>::replace(bsl::size_t dstIndex, const TYPE& value)
1785{
1786 BSLS_ASSERT(dstIndex < length());
1787
1789
1790 d_index.reserveCapacity(d_index.length(), d_data.size() + 1);
1791
1792 bsl::size_t newDataIndex = increment(value);
1793 bsl::size_t dataIndex = d_index[dstIndex];
1794 CompactedArray_CountedValue<TYPE>& dataValue = d_data[dataIndex];
1795
1796 if (0 == --dataValue.d_count) {
1797 erase(dataIndex);
1798 if (dataIndex <= newDataIndex) {
1799 --newDataIndex;
1800 }
1801 }
1802
1803 d_index.replace(dstIndex, newDataIndex);
1804
1805 proctor.release();
1806}
1807
1808template <class TYPE>
1809void CompactedArray<TYPE>::replace(bsl::size_t dstIndex,
1810 const CompactedArray& srcArray,
1811 bsl::size_t srcIndex,
1812 bsl::size_t numElements)
1813{
1814 // Assert 'dstIndex + numElements <= length()' without risk of overflow.
1815 BSLS_ASSERT(numElements <= length());
1816 BSLS_ASSERT(dstIndex <= length() - numElements);
1817
1818 // Assert 'srcIndex + numElements <= srcArray.length()' without risk of
1819 // overflow.
1820 BSLS_ASSERT(numElements <= srcArray.length());
1821 BSLS_ASSERT(srcIndex <= srcArray.length() - numElements);
1822
1824
1825 if (&srcArray != this) {
1826 d_index.reserveCapacity(d_index.length(), d_data.size() + numElements);
1827
1828 for (bsl::size_t i = 0; i < numElements; ++i) {
1829 bsl::size_t newDataIndex = increment(srcArray[srcIndex + i]);
1830 bsl::size_t dataIndex = d_index[dstIndex + i];
1831
1832 CompactedArray_CountedValue<TYPE>& dataValue = d_data[dataIndex];
1833
1834 if (0 == --dataValue.d_count) {
1835 erase(dataIndex);
1836 if (dataIndex <= newDataIndex) {
1837 --newDataIndex;
1838 }
1839 }
1840
1841 d_index.replace(dstIndex + i, newDataIndex);
1842 }
1843 }
1844 else {
1845 bsl::size_t endIndex;
1846
1847 endIndex = srcIndex + numElements;
1848 for (bsl::size_t i = srcIndex; i < endIndex; ++i) {
1849 ++d_data[d_index[i]].d_count;
1850 }
1851
1852 endIndex = dstIndex + numElements;
1853 for (bsl::size_t i = dstIndex; i < endIndex; ++i) {
1854 bsl::size_t dataIndex = d_index[i];
1855 CompactedArray_CountedValue<TYPE>& dataValue = d_data[dataIndex];
1856
1857 if (0 == --dataValue.d_count) {
1858 erase(dataIndex);
1859 }
1860 }
1861
1862 d_index.replace(dstIndex, d_index, srcIndex, numElements);
1863 }
1864
1865 proctor.release();
1866}
1867
1868template <class TYPE>
1869void CompactedArray<TYPE>::reserveCapacity(bsl::size_t numElements)
1870{
1871 BSLS_ASSERT(false == isEmpty() || 0 == numElements);
1872
1873 if (0 < numElements) {
1874 d_index.reserveCapacity(numElements, d_data.size() - 1);
1875 }
1876}
1877
1878template <class TYPE>
1879void CompactedArray<TYPE>::reserveCapacity(bsl::size_t numElements,
1880 bsl::size_t numUniqueElements)
1881{
1882 BSLS_ASSERT(numUniqueElements <= numElements);
1883 BSLS_ASSERT(0 < numUniqueElements || 0 == numElements);
1884
1885 if (0 < numElements) {
1886 d_data.reserve(numUniqueElements);
1887 if (d_data.size() > numUniqueElements) {
1888 numUniqueElements = d_data.size();
1889 }
1890 d_index.reserveCapacity(numElements, numUniqueElements - 1);
1891 }
1892}
1893
1894template <class TYPE>
1895void CompactedArray<TYPE>::resize(bsl::size_t numElements)
1896{
1897 if (d_index.length() < numElements) {
1899
1900 d_index.reserveCapacity(numElements, d_data.size() + 1);
1901
1902 bsl::size_t count = numElements - d_index.length();
1903 bsl::size_t index = increment(TYPE(), count);
1904
1905 for (bsl::size_t i = 0; i < count; ++i) {
1906 d_index.push_back(index);
1907 }
1908
1909 proctor.release();
1910 }
1911 else {
1912 bsl::size_t count = d_index.length() - numElements;
1913
1914 for (bsl::size_t i = 0; i < count; ++i) {
1915 pop_back();
1916 }
1917 }
1918}
1919
1920template <class TYPE>
1922{
1923 BSLS_ASSERT(allocator() == other.allocator());
1924
1925 bslalg::SwapUtil::swap(&d_data, &other.d_data);
1926 bslalg::SwapUtil::swap(&d_index, &other.d_index);
1927}
1928
1929// ACCESSORS
1930template <class TYPE>
1931inline
1932const TYPE& CompactedArray<TYPE>::operator[](bsl::size_t index) const
1933{
1934 BSLS_ASSERT(index < length());
1935
1936 return d_data[d_index[index]].d_value.object();
1937}
1938
1939template <class TYPE>
1940inline
1942{
1943 return d_index.allocator();
1944}
1945
1946template <class TYPE>
1947inline
1949{
1950 BSLS_ASSERT(0 < length());
1951
1952 return operator[](length() - 1);
1953}
1954
1955template <class TYPE>
1956inline
1959{
1960 return const_iterator(this, 0);
1961}
1962
1963template <class TYPE>
1964inline
1966{
1967 return d_index.isEmpty() ? 0 : d_index.capacity();
1968}
1969
1970template <class TYPE>
1971inline
1973{
1974 return const_iterator(this, d_index.length());
1975}
1976
1977template <class TYPE>
1978inline
1980{
1981 BSLS_ASSERT(0 < length());
1982
1983 return operator[](0);
1984}
1985
1986template <class TYPE>
1987inline
1989{
1990 return 0 == length();
1991}
1992
1993template <class TYPE>
1994inline
1996{
1997 return d_index == other.d_index && d_data == other.d_data;
1998}
1999
2000template <class TYPE>
2001inline
2003{
2004 return d_index.length();
2005}
2006
2007template <class TYPE>
2008bsl::ostream& CompactedArray<TYPE>::print(bsl::ostream& stream,
2009 int level,
2010 int spacesPerLevel) const
2011{
2012 if (stream.bad()) {
2013 return stream; // RETURN
2014 }
2015
2016 bslim::Printer printer(&stream, level, spacesPerLevel);
2017 printer.start();
2018 for (bsl::size_t i = 0; i < d_index.length(); ++i) {
2019 printer.printValue(d_data[d_index[i]].d_value.object());
2020 }
2021 printer.end();
2022
2023 return stream;
2024}
2025
2026template <class TYPE>
2027inline
2028const TYPE& CompactedArray<TYPE>::uniqueElement(bsl::size_t index) const
2029{
2030 BSLS_ASSERT(index < uniqueLength());
2031
2032 return d_data[index].d_value.object();
2033}
2034
2035template <class TYPE>
2036inline
2038{
2039 return d_data.size();
2040}
2041
2042} // close package namespace
2043
2044// FREE OPERATORS
2045template <class TYPE>
2046inline
2047bsl::ostream& bdlc::operator<<(bsl::ostream& stream,
2048 const CompactedArray<TYPE>& array)
2049{
2050 return array.print(stream, 0, -1);
2051}
2052
2053template <class TYPE>
2054inline
2055bool bdlc::operator==(const CompactedArray<TYPE>& lhs,
2056 const CompactedArray<TYPE>& rhs)
2057{
2058 return lhs.isEqual(rhs);
2059}
2060
2061template <class TYPE>
2062inline
2063bool bdlc::operator!=(const CompactedArray<TYPE>& lhs,
2064 const CompactedArray<TYPE>& rhs)
2065{
2066 return !lhs.isEqual(rhs);
2067}
2068
2069// FREE FUNCTIONS
2070template <class TYPE>
2071void bdlc::swap(CompactedArray<TYPE>& a, CompactedArray<TYPE>& b)
2072{
2073 if (a.allocator() == b.allocator()) {
2074 a.swap(b);
2075
2076 return; // RETURN
2077 }
2078
2079 CompactedArray<TYPE> futureA(b, a.allocator());
2080 CompactedArray<TYPE> futureB(a, b.allocator());
2081
2082 futureA.swap(a);
2083 futureB.swap(b);
2084}
2085
2086// HASH SPECIALIZATIONS
2087template <class HASHALG, class TYPE>
2088void bdlc::hashAppend(HASHALG& hashAlg, const CompactedArray<TYPE>& input)
2089{
2090 using ::BloombergLP::bslh::hashAppend;
2091 typedef typename CompactedArray<TYPE>::const_iterator citer;
2092 hashAppend(hashAlg, input.length());
2093 for (citer b = input.begin(), e = input.end(); b != e; ++b) {
2094 hashAppend(hashAlg, *b);
2095 }
2096}
2097
2098
2099
2100// TRAITS
2101
2102
2103namespace bslma {
2104
2105template <class TYPE>
2106struct UsesBslmaAllocator<bdlc::CompactedArray_CountedValue<TYPE> >
2107 : bsl::true_type {};
2108
2109template <class TYPE>
2110struct UsesBslmaAllocator<bdlc::CompactedArray<TYPE> > : bsl::true_type {};
2111
2112} // close namespace bslma
2113
2114
2115#endif
2116
2117// ----------------------------------------------------------------------------
2118// Copyright 2018 Bloomberg Finance L.P.
2119//
2120// Licensed under the Apache License, Version 2.0 (the "License");
2121// you may not use this file except in compliance with the License.
2122// You may obtain a copy of the License at
2123//
2124// http://www.apache.org/licenses/LICENSE-2.0
2125//
2126// Unless required by applicable law or agreed to in writing, software
2127// distributed under the License is distributed on an "AS IS" BASIS,
2128// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2129// See the License for the specific language governing permissions and
2130// limitations under the License.
2131// ----------------------------- END-OF-FILE ----------------------------------
2132
2133/** @} */
2134/** @} */
2135/** @} */
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
Definition bdlc_compactedarray.h:373
TYPE value_type
Definition bdlc_compactedarray.h:435
std::random_access_iterator_tag iterator_category
Definition bdlc_compactedarray.h:443
bsl::size_t size_type
Definition bdlc_compactedarray.h:431
CompactedArray_ConstIterator()
Definition bdlc_compactedarray.h:1139
CompactedArray_ConstIterator & operator=(const CompactedArray_ConstIterator &rhs)
Definition bdlc_compactedarray.h:1158
const TYPE & operator->() const
Definition bdlc_compactedarray.h:1236
const TYPE & operator[](bsl::ptrdiff_t offset) const
Definition bdlc_compactedarray.h:1247
TYPE & reference
Definition bdlc_compactedarray.h:440
const TYPE & operator*() const
Definition bdlc_compactedarray.h:1226
bsl::ptrdiff_t difference_type
Definition bdlc_compactedarray.h:428
TYPE * pointer
Definition bdlc_compactedarray.h:437
CompactedArray_ConstIterator & operator-=(bsl::ptrdiff_t offset)
Definition bdlc_compactedarray.h:1185
CompactedArray_ConstIterator & operator+=(bsl::ptrdiff_t offset)
Definition bdlc_compactedarray.h:1168
friend CompactedArray_ConstIterator operator++(CompactedArray_ConstIterator &, int)
friend CompactedArray_ConstIterator operator--(CompactedArray_ConstIterator &, int)
Definition bdlc_compactedarray.h:254
~CompactedArray_RemoveAllProctor()
Definition bdlc_compactedarray.h:1013
void release()
Definition bdlc_compactedarray.h:1023
Definition bdlc_compactedarray.h:670
const_iterator end() const
Definition bdlc_compactedarray.h:1972
void append(const CompactedArray &srcArray)
Definition bdlc_compactedarray.h:1553
const TYPE & uniqueElement(bsl::size_t index) const
Definition bdlc_compactedarray.h:2028
void remove(bsl::size_t dstIndex, bsl::size_t numElements)
Definition bdlc_compactedarray.h:1737
void push_back(const TYPE &value)
Append to this array an element having the specified value.
Definition bdlc_compactedarray.h:1722
CompactedArray & operator=(const CompactedArray &rhs)
Definition bdlc_compactedarray.h:1524
bsl::size_t capacity() const
Definition bdlc_compactedarray.h:1965
void insert(bsl::size_t dstIndex, const CompactedArray &srcArray)
Definition bdlc_compactedarray.h:1637
const_iterator insert(const_iterator dst, const TYPE &value)
Definition bdlc_compactedarray.h:1628
void swap(CompactedArray &other)
Definition bdlc_compactedarray.h:1921
const_iterator remove(const_iterator dstFirst, const_iterator dstLast)
Definition bdlc_compactedarray.h:1765
void reserveCapacity(bsl::size_t numElements, bsl::size_t numUniqueElements)
Definition bdlc_compactedarray.h:1879
void replace(bsl::size_t dstIndex, const TYPE &value)
Definition bdlc_compactedarray.h:1784
const TYPE & front() const
Definition bdlc_compactedarray.h:1979
bool isEmpty() const
Definition bdlc_compactedarray.h:1988
TYPE value_type
Definition bdlc_compactedarray.h:700
~CompactedArray()
Destroy this object.
Definition bdlc_compactedarray.h:1518
void insert(bsl::size_t dstIndex, const TYPE &value)
Definition bdlc_compactedarray.h:1612
bool isEqual(const CompactedArray &other) const
Definition bdlc_compactedarray.h:1995
void reserveCapacity(bsl::size_t numElements)
Definition bdlc_compactedarray.h:1869
bsl::size_t uniqueLength() const
Return the number of unique elements in this array.
Definition bdlc_compactedarray.h:2037
CompactedArray(bsl::size_t numElements, const TYPE &value=TYPE(), bslma::Allocator *basicAllocator=0)
Definition bdlc_compactedarray.h:1494
void insert(bsl::size_t dstIndex, const CompactedArray &srcArray, bsl::size_t srcIndex, bsl::size_t numElements)
Definition bdlc_compactedarray.h:1666
const_iterator begin() const
Definition bdlc_compactedarray.h:1958
void append(const TYPE &value)
Definition bdlc_compactedarray.h:1541
bslma::Allocator * allocator() const
Return the allocator used by this array to supply memory.
Definition bdlc_compactedarray.h:1941
CompactedArray(const CompactedArray &original, bslma::Allocator *basicAllocator=0)
Definition bdlc_compactedarray.h:1509
const TYPE & back() const
Definition bdlc_compactedarray.h:1948
void append(const CompactedArray &srcArray, bsl::size_t srcIndex, bsl::size_t numElements)
Definition bdlc_compactedarray.h:1579
bsl::size_t length() const
Return the number of elements in this array.
Definition bdlc_compactedarray.h:2002
CompactedArray_ConstIterator< TYPE > const_iterator
Definition bdlc_compactedarray.h:702
void resize(bsl::size_t numElements)
Definition bdlc_compactedarray.h:1895
const TYPE & operator[](bsl::size_t index) const
Definition bdlc_compactedarray.h:1932
void removeAll()
Remove all the elements from this array.
Definition bdlc_compactedarray.h:1777
CompactedArray(bslma::Allocator *basicAllocator=0)
Definition bdlc_compactedarray.h:1487
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
Definition bdlc_compactedarray.h:2008
void replace(bsl::size_t dstIndex, const CompactedArray &srcArray, bsl::size_t srcIndex, bsl::size_t numElements)
Definition bdlc_compactedarray.h:1809
void remove(bsl::size_t dstIndex)
Definition bdlc_compactedarray.h:1729
void pop_back()
Definition bdlc_compactedarray.h:1702
Definition bdlc_packedintarray.h:1048
void resize(bsl::size_t numElements)
Definition bdlc_packedintarray.h:2484
bsl::size_t length() const
Return number of elements in this array.
Definition bdlc_packedintarray.h:2586
void reserveCapacity(bsl::size_t numElements)
Definition bdlc_packedintarray.h:2451
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this vector.
Definition bslstl_vector.h:2664
Definition bslstl_vector.h:1025
VALUE_TYPE & emplace_back(Args &&... arguments)
Definition bslstl_vector.h:3741
static void swap(T *a, T *b)
Definition bslalg_swaputil.h:194
Definition bslim_printer.h:601
void printValue(const TYPE &data) const
Definition bslim_printer.h:1207
void end(bool suppressBracket=false) const
void start(bool suppressBracket=false) const
Definition bslma_allocator.h:457
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
void hashAppend(HASH_ALGORITHM &hashAlg, const baljsn::EncoderTestAddress &object)
Definition baljsn_encoder_testtypes.h:9236
Definition bdlc_bitarray.h:503
CompactedArray_ConstIterator< TYPE > operator--(CompactedArray_ConstIterator< TYPE > &, int)
CompactedArray_ConstIterator< TYPE > operator+(const CompactedArray_ConstIterator< TYPE > &, bsl::ptrdiff_t)
void hashAppend(HASHALG &hashAlg, const CompactedArray< TYPE > &input)
Pass the specified input to the specified hashAlg.
void swap(BitArray &a, BitArray &b)
bool operator>(const CompactedArray_ConstIterator< TYPE > &, const CompactedArray_ConstIterator< TYPE > &)
bool operator<=(const CompactedArray_ConstIterator< TYPE > &, const CompactedArray_ConstIterator< TYPE > &)
bool operator==(const BitArray &lhs, const BitArray &rhs)
bool operator>=(const CompactedArray_ConstIterator< TYPE > &, const CompactedArray_ConstIterator< TYPE > &)
bool operator!=(const BitArray &lhs, const BitArray &rhs)
bool operator<(const CompactedArray_ConstIterator< TYPE > &, const CompactedArray_ConstIterator< TYPE > &)
BitArray operator-(const BitArray &lhs, const BitArray &rhs)
CompactedArray_ConstIterator< TYPE > operator++(CompactedArray_ConstIterator< TYPE > &, int)
BitArray operator<<(const BitArray &array, bsl::size_t numBits)
Definition bdlb_printmethods.h:283
Definition balxml_encoderoptions.h:68
static FORWARD_IT lowerBound(FORWARD_IT first, FORWARD_IT last, const TYPE &value)
Definition bdlb_algorithmworkaroundutil.h:157
Definition bdlc_compactedarray.h:291
bsl::size_t d_count
Definition bdlc_compactedarray.h:295
CompactedArray_CountedValue(const TYPE &value, bsl::size_t count, bslma::Allocator *basicAllocator)
Definition bdlc_compactedarray.h:1035
CompactedArray_CountedValue & operator=(const CompactedArray_CountedValue< TYPE > &rhs)
Definition bdlc_compactedarray.h:1073
~CompactedArray_CountedValue()
Destroy this object.
Definition bdlc_compactedarray.h:1064
bsls::ObjectBuffer< TYPE > d_value
Definition bdlc_compactedarray.h:294
static void construct(TARGET_TYPE *address, const ALLOCATOR &allocator)
Definition bslma_constructionutil.h:1243
Definition bslma_usesbslmaallocator.h:343
Definition bsls_objectbuffer.h:276