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