BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlc_packedintarray.h
Go to the documentation of this file.
1/// @file bdlc_packedintarray.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlc_packedintarray.h -*-C++-*-
8#ifndef INCLUDED_BDLC_PACKEDINTARRAY
9#define INCLUDED_BDLC_PACKEDINTARRAY
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlc_packedintarray bdlc_packedintarray
15/// @brief Provide an extensible, packed array of integral values.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlc
19/// @{
20/// @addtogroup bdlc_packedintarray
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlc_packedintarray-purpose"> Purpose</a>
25/// * <a href="#bdlc_packedintarray-classes"> Classes </a>
26/// * <a href="#bdlc_packedintarray-description"> Description </a>
27/// * <a href="#bdlc_packedintarray-usage"> Usage </a>
28/// * <a href="#bdlc_packedintarray-example-1-temperature-map"> Example 1: Temperature Map </a>
29///
30/// # Purpose {#bdlc_packedintarray-purpose}
31/// Provide an extensible, packed array of integral values.
32///
33/// # Classes {#bdlc_packedintarray-classes}
34///
35/// - bdlc::PackedIntArray: packed array of integral values
36/// - bdlc::PackedIntArrayConstIterator: bidirectional `const_iterator`
37///
38/// # Description {#bdlc_packedintarray-description}
39/// This component provides a space-efficient value-semantic array
40/// class template, `bdlc::PackedIntArray`, and an associated iterator,
41/// `bdlc::PackedIntArrayConstIterator`, that provides non-modifiable access to
42/// its elements. The interface of this class provides the user with
43/// functionality similar to a `bsl::vector<int>`. The implementation is
44/// designed to reduce dynamic memory usage by storing its contents differently
45/// according to the magnitude of values placed within it. The user need not be
46/// concerned with the internal representation of the data. The array supports
47/// primitive operations (e.g., insertion, look-up, removal) as well as a
48/// complete set of value-semantic operations; however, direct reference to
49/// individual elements is not available. Users can access the value of
50/// individual elements by calling the indexing operator or via iterators. Note
51/// that iterators are *not* invalidated if an array object reallocates memory.
52///
53/// ## Usage {#bdlc_packedintarray-usage}
54///
55///
56/// This section illustrates intended use of this component.
57///
58/// ### Example 1: Temperature Map {#bdlc_packedintarray-example-1-temperature-map}
59///
60///
61/// There exist many applications in which the range of `int` data that a
62/// container will hold is not known at design time. This means in order to
63/// build a robust component one must default to `bsl::vector<int>`, which for
64/// many applications is excessive in its usage of space.
65///
66/// Suppose we are creating a map of temperatures for every city in the United
67/// States for every day. This represents a large body of data, most of which
68/// is easily representable in a `signed char`, and in only rare situations is a
69/// `short` required.
70///
71/// To be able to represent all possible values for all areas and times,
72/// including extremes like Death Valley, a traditional implementation would
73/// require use of a `vector<short>` for each day for each area. This is
74/// excessive for all but the most extreme values, and therefore wasteful for
75/// this map as a whole.
76///
77/// We can use `bdlc::PackedIntArray` to efficiently store this data.
78///
79/// First, we declare and define a `my_Date` class. This class is very similar
80/// to `bdlt::Date`, and therefore is elided for the sake of compactness.
81/// @code
82/// // =======
83/// // my_Date
84/// // =======
85/// class my_Date {
86/// // A (value-semantic) attribute class that provides a very simple date.
87/// signed char d_day; // the day
88/// signed char d_month; // the month
89/// int d_year; // the year
90///
91/// // FRIENDS
92/// friend bool operator<(const my_Date&, const my_Date&);
93///
94/// public:
95/// // CREATORS
96/// explicit my_Date(int year = 1,
97/// signed char month = 1,
98/// signed char day = 1);
99/// // Create a 'my_Date' object having the optionally specified 'day',
100/// // 'month', and 'year'. Each, if unspecified, will default to 1.
101/// };
102///
103/// bool operator<(const my_Date& lhs, const my_Date& rhs);
104/// // Return 'true' if the specified 'lhs' represents an earlier date than
105/// // the specified 'rhs' object, and 'false' otherwise.
106///
107/// // -------
108/// // my_Date
109/// // -------
110/// // CREATORS
111/// inline
112/// my_Date::my_Date(int year, signed char month , signed char day)
113/// : d_day(day)
114/// , d_month(month)
115/// , d_year(year)
116/// {
117/// }
118///
119/// bool operator<(const my_Date& lhs, const my_Date& rhs)
120/// {
121/// return 10000 * lhs.d_year + 100 * lhs.d_month + lhs.d_day <
122/// 10000 * rhs.d_year + 100 * rhs.d_month + rhs.d_day;
123/// }
124/// @endcode
125/// Then, we create our `temperatureMap`, which is a map of dates to a map of
126/// zip codes to a `PackedIntArray` of temperatures. Each `PackedIntArray` has
127/// entries for each temperature from 12 A.M, to 11 P.M for each city in each
128/// zip code. Notice that we use a `PackedIntArray` to hold the data compactly.
129/// @code
130/// bsl::map<my_Date, bsl::map<bsl::string, bdlc::PackedIntArray<int> > >
131/// temperatureMap;
132/// @endcode
133/// Next, we add data to the map (provided by the National Weather Service) for
134/// a normal case, and the extreme.
135/// @code
136/// bdlc::PackedIntArray<int>& nyc
137/// = temperatureMap[my_Date(2013, 9, 6)]["10023"];
138/// bdlc::PackedIntArray<int>& dValley
139/// = temperatureMap[my_Date(1913, 7, 10)]["92328"];
140/// bdlc::PackedIntArray<int>& boston
141/// = temperatureMap[my_Date(2013, 9, 6)]["02202"];
142///
143/// int nycTemperatures[24] = { 60, 58, 57, 56, 55, 54, 54, 55,
144/// 56, 59, 61, 64, 66, 67, 69, 69,
145/// 70, 70, 68, 67, 65, 63, 61, 60};
146///
147/// int deathValleyTemps[24] = { 65, 55, 50, 47, 62, 75, 77, 89,
148/// 91, 92, 95, 110, 113, 121, 134, 126,
149/// 113, 99, 96, 84, 79, 81, 73, 69};
150///
151/// int bostonTemps[24] = { 55, 53, 52, 51, 50, 49, 49, 50,
152/// 51, 54, 56, 59, 61, 62, 64, 64,
153/// 65, 65, 63, 62, 60, 58, 56, 55};
154/// @endcode
155/// Then, since the size of the data set is known at design time, as well as
156/// extreme values for the areas, we can use the `reserveCapacity()` method to
157/// give the container hints about the data to come.
158/// @code
159/// nyc.reserveCapacity (24, 54, 70);
160/// dValley.reserveCapacity(24, 47, 134);
161/// boston.reserveCapacity (24, 49, 65);
162/// @endcode
163/// Now we add the data to the respective containers.
164/// @code
165/// for (bsl::size_t i= 0; i < 24; ++i) {
166/// nyc.append(nycTemperatures[i]);
167/// dValley.append(deathValleyTemps[i]);
168/// boston.append(bostonTemps[i]);
169/// }
170/// @endcode
171/// Finally, notice that in order to represent these values in a
172/// `PackedIntArray`, it required `24 * sizeof(signed char)` bytes (24 on most
173/// systems) of dynamic memory for `nyc`, which represents the normal case for
174/// this data. A `vector<short>` would require `24 * sizeof(short)` bytes (48
175/// on most systems) of dynamic memory to represent the same data.
176/// @code
177/// assert(static_cast<int>(sizeof(signed char)) == nyc.bytesPerElement());
178/// assert( 24 == nyc.length());
179/// @endcode
180/// @}
181/** @} */
182/** @} */
183
184/** @addtogroup bdl
185 * @{
186 */
187/** @addtogroup bdlc
188 * @{
189 */
190/** @addtogroup bdlc_packedintarray
191 * @{
192 */
193
194#include <bdlscm_version.h>
195
196#include <bslalg_swaputil.h>
197
198#include <bslh_hash.h>
199
200#include <bslma_allocator.h>
202
203#include <bslmf_conditional.h>
204#include <bslmf_issame.h>
205
206#include <bsls_assert.h>
207#include <bsls_performancehint.h>
208#include <bsls_review.h>
209#include <bsls_types.h>
210
211#include <bsl_cstddef.h>
212#include <bsl_cstdint.h>
213#include <bsl_cstring.h>
214#include <bsl_limits.h>
215#include <bsl_iosfwd.h>
216
217#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
218#include <bslmf_if.h>
219#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
220
221
222namespace bdlc {
223
224// FORWARD DECLARATIONS
225template <class TYPE> class PackedIntArray;
226
227template <class TYPE> class PackedIntArrayConstIterator;
228
229template <class TYPE> PackedIntArrayConstIterator<TYPE>
231
232template <class TYPE> PackedIntArrayConstIterator<TYPE>
234
235template <class TYPE>
238
239template <class TYPE>
242
243template <class TYPE>
246
247template <class TYPE>
250
251template <class TYPE>
254
255template <class TYPE>
258
259template <class TYPE>
262
263 // ===============================
264 // struct PackedIntArrayImp_Signed
265 // ===============================
266
267/// This `struct` provides a namespace for types and methods used to
268/// implement a space-efficient value-semantic array class representing a
269/// sequence of `TYPE` elements; `TYPE` must be convertible to either a
270/// `bsl::int64_t`. Specifically, it defines the types used to store the
271/// array's data, methods needed to externalize and unexternalize the array,
272/// and a method to determine the storage size to use for a given value.
274
275 // PUBLIC TYPES
276 typedef bsl::int8_t OneByteStorageType;
277 typedef bsl::int16_t TwoByteStorageType;
278 typedef bsl::int32_t FourByteStorageType;
279 typedef bsl::int64_t EightByteStorageType;
280
281 // CLASS METHODS
282
283 /// Read from the specified `stream` the specified `variable` as per the
284 /// requirements of the BDEX protocol.
285 template <class STREAM>
286 static void bdexGet8(STREAM& stream, bsl::int8_t& variable);
287
288 /// Read from the specified `stream` the specified `variable` as per the
289 /// requirements of the BDEX protocol.
290 template <class STREAM>
291 static void bdexGet16(STREAM& stream, bsl::int16_t& variable);
292
293 /// Read from the specified `stream` the specified `variable` as per the
294 /// requirements of the BDEX protocol.
295 template <class STREAM>
296 static void bdexGet32(STREAM& stream, bsl::int32_t& variable);
297
298 /// Read from the specified `stream` the specified `variable` as per the
299 /// requirements of the BDEX protocol.
300 template <class STREAM>
301 static void bdexGet64(STREAM& stream, bsl::int64_t& variable);
302
303 /// Write to the specified `stream` the specified `value` as per the
304 /// requirements of the BDEX protocol.
305 template <class STREAM>
306 static void bdexPut8(STREAM& stream, bsl::int8_t value);
307
308 /// Write to the specified `stream` the specified `value` as per the
309 /// requirements of the BDEX protocol.
310 template <class STREAM>
311 static void bdexPut16(STREAM& stream, bsl::int16_t value);
312
313 /// Write to the specified `stream` the specified `value` as per the
314 /// requirements of the BDEX protocol.
315 template <class STREAM>
316 static void bdexPut32(STREAM& stream, bsl::int32_t value);
317
318 /// Write to the specified `stream` the specified `value` as per the
319 /// requirements of the BDEX protocol.
320 template <class STREAM>
321 static void bdexPut64(STREAM& stream, bsl::int64_t value);
322
323 /// Return the required number of bytes to store the specified `value`.
325};
326
327 // =================================
328 // struct PackedIntArrayImp_Unsigned
329 // =================================
330
331/// This `struct` provides a namespace for types and methods used to
332/// implement a space-efficient value-semantic array class representing a
333/// sequence of `TYPE` elements; `TYPE` must be convertible to either a
334/// `bsl::uint64_t`. Specifically, it defines the types used to store the
335/// array's data, methods needed to externalize and unexternalize the array,
336/// and a method to determine the storage size to use for a given value.
338
339 // PUBLIC TYPES
340 typedef bsl::uint8_t OneByteStorageType;
341 typedef bsl::uint16_t TwoByteStorageType;
342 typedef bsl::uint32_t FourByteStorageType;
343 typedef bsl::uint64_t EightByteStorageType;
344
345 // CLASS METHODS
346
347 /// Read from the specified `stream` the specified `variable` as per the
348 /// requirements of the BDEX protocol.
349 template <class STREAM>
350 static void bdexGet8(STREAM& stream, bsl::uint8_t& variable);
351
352 /// Read from the specified `stream` the specified `variable` as per the
353 /// requirements of the BDEX protocol.
354 template <class STREAM>
355 static void bdexGet16(STREAM& stream, bsl::uint16_t& variable);
356
357 /// Read from the specified `stream` the specified `variable` as per the
358 /// requirements of the BDEX protocol.
359 template <class STREAM>
360 static void bdexGet32(STREAM& stream, bsl::uint32_t& variable);
361
362 /// Read from the specified `stream` the specified `variable` as per the
363 /// requirements of the BDEX protocol.
364 template <class STREAM>
365 static void bdexGet64(STREAM& stream, bsl::uint64_t& variable);
366
367 /// Write to the specified `stream` the specified `value` as per the
368 /// requirements of the BDEX protocol.
369 template <class STREAM>
370 static void bdexPut8(STREAM& stream, bsl::uint8_t value);
371
372 /// Write to the specified `stream` the specified `value` as per the
373 /// requirements of the BDEX protocol.
374 template <class STREAM>
375 static void bdexPut16(STREAM& stream, bsl::uint16_t value);
376
377 /// Write to the specified `stream` the specified `value` as per the
378 /// requirements of the BDEX protocol.
379 template <class STREAM>
380 static void bdexPut32(STREAM& stream, bsl::uint32_t value);
381
382 /// Write to the specified `stream` the specified `value` as per the
383 /// requirements of the BDEX protocol.
384 template <class STREAM>
385 static void bdexPut64(STREAM& stream, bsl::uint64_t value);
386
387 /// Return the required number of bytes to store the specified `value`.
389};
390
391 // =======================
392 // class PackedIntArrayImp
393 // =======================
394
395/// This space-efficient value-semantic array class represents a sequence of
396/// `STORAGE::EightByteStorageType` elements;
397/// `STORAGE::EightByteStorageType` must be convertible to either a signed
398/// or unsigned 64-bit integer using @ref static_cast . The interface provides
399/// functionality similar to a `vector<int>` however references to
400/// individual elements are not provided.
401///
402/// See @ref bdlc_packedintarray
403template <class STORAGE>
405
406 public:
407 // PUBLIC TYPES
408 typedef typename STORAGE::EightByteStorageType ElementType;
409
410 // CLASS DATA
411 static const bsl::size_t k_MAX_CAPACITY = 0x7fffffff; // maximum capacity
412 // in bytes
413
414 private:
415 // DATA
416 void *d_storage_p; // allocated memory
417
418 bsl::size_t d_length; // length of the array
419
420 int d_bytesPerElement; // number of bytes used to store each
421 // element
422
423 bsl::size_t d_capacityInBytes; // capacity of the array
424
425 bslma::Allocator *d_allocator_p; // allocator used for all memory
426
427 private:
428 // PRIVATE CLASS METHODS
429
430 /// Return the next valid number of bytes of capacity that is at least
431 /// the specified `minValue`, starting from the specified `value`.
432 static bsl::size_t nextCapacityGE(bsl::size_t minValue, bsl::size_t value);
433
434 // PRIVATE MANIPULATORS
435
436 /// Make the capacity of this array at least the specified
437 /// `requiredCapacityInBytes` and increase the bytes used to store an
438 /// element to the specified `requiredBytesPerElement`. The behavior is
439 /// undefined unless `requiredBytesPerElement > bytesPerElement()`.
440 void expandImp(int requiredBytesPerElement,
441 bsl::size_t requiredCapacityInBytes);
442
443 /// Change the value of the element at the specified `dstIndex` in this
444 /// array to the specified `value`. The behavior is undefined unless
445 /// `dstIndex < length()` and the required bytes to store the `value` is
446 /// less than or equal to `bytesPerElement()`.
447 void replaceImp(bsl::size_t dstIndex, ElementType value);
448
449 /// Change the values of the specified `numElements` elements in the
450 /// specified `dst` array beginning at the specified `dstIndex` with the
451 /// specified `dstBytesPerElement` to those of the `numElements` values
452 /// in the specified `src` array beginning at the specified `srcIndex`
453 /// with the specified `srcBytesPerElement`. The behavior is undefined
454 /// unless the source array has sufficient values,
455 /// `dstIndex + numElements <= length()`,
456 /// `srcBytesPerElement != dstBytesPerElement`, and either the memory
457 /// ranges do not overlap or: `dst == src` and `dstIndex >= srcIndex`
458 /// and `dstBytesPerElement > srcBytesPerElement`.
459 void replaceImp(void *dst,
460 bsl::size_t dstIndex,
461 int dstBytesPerElement,
462 void *src,
463 bsl::size_t srcIndex,
464 int srcBytesPerElement,
465 bsl::size_t numElements);
466
467 // PRIVATE ACCESSORS
468
469 /// Return the address of the storage as a `char *`.
470 char *address() const;
471
472 /// Return `true` if this and the specified `other` array have the same
473 /// value, and `false` otherwise. Two `PackedIntArrayImp` arrays have
474 /// the same value if they have the same length, and all corresponding
475 /// elements (those at the same indices) have the same value. The
476 /// behavior is undefined unless `length() == other.length()` and
477 /// `bytesPerElement() != other.bytesPerElement()`.
478 bool isEqualImp(const PackedIntArrayImp& other) const;
479
480 /// Return the required number of bytes to store the specified
481 /// `numValues` values of this array starting at the specified `index`.
482 /// The behavior is undefined unless `index + numElements <= length()`.
483 int requiredBytesPerElement(bsl::size_t index,
484 bsl::size_t numElements) const;
485
486 public:
487 // CLASS METHODS
488
489 /// Return the `version` to be used with the `bdexStreamOut` method
490 /// corresponding to the specified `serializationVersion`. See the
491 /// `bslx` package-level documentation for more information on BDEX
492 /// streaming of value-semantic types and containers.
493 static int maxSupportedBdexVersion(int serializationVersion);
494
495 // CREATORS
496
497 /// Create an empty `PackedIntArrayImp`. Optionally specify a
498 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0,
499 /// the currently installed default allocator is used.
500 explicit PackedIntArrayImp(bslma::Allocator *basicAllocator = 0);
501
502 /// Create a `PackedIntArrayImp` having the specified `numElements`.
503 /// Optionally specify a `value` to which each element will be set. If
504 /// value is not specified, 0 is used. Optionally specify a
505 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0,
506 /// the currently installed default allocator is used.
507 explicit PackedIntArrayImp(bsl::size_t numElements,
508 ElementType value = 0,
509 bslma::Allocator *basicAllocator = 0);
510
511 /// Create a `PackedIntArrayImp` having the same value as the specified
512 /// `original` one. Optionally specify a `basicAllocator` used to
513 /// supply memory. If `basicAllocator` is 0, the currently installed
514 /// default allocator is used.
516 bslma::Allocator *basicAllocator = 0);
517
518 /// Destroy this object
520
521 // MANIPULATORS
522
523 /// Assign to this array the value of the specified `rhs` array, and
524 /// return a reference providing modifiable access to this array.
526
527 /// Append an element having the specified `value` to the end of this
528 /// array.
529 void append(ElementType value);
530
531 /// Append the sequence of values represented by the specified
532 /// `srcArray` to the end of this array. Note that if this array and
533 /// `srcArray` are the same, the behavior is as if a copy of `srcArray`
534 /// were passed.
535 void append(const PackedIntArrayImp& srcArray);
536
537 /// Append the sequence of values of the specified `numElements`
538 /// starting at the specified `srcIndex` in the specified `srcArray` to
539 /// the end of this array. The behavior is undefined unless
540 /// `srcIndex + numElements <= srcArray.length()`. Note that if this
541 /// array and `srcArray` are the same, the behavior is as if a copy of
542 /// `srcArray` were passed.
543 void append(const PackedIntArrayImp& srcArray,
544 bsl::size_t srcIndex,
545 bsl::size_t numElements);
546
547 /// Assign to this object the value read from the specified input
548 /// `stream` using the specified `version` format, and return a
549 /// reference to `stream`. If `stream` is initially invalid, this
550 /// operation has no effect. If `version` is not supported, this object
551 /// is unaltered and `stream` is invalidated but otherwise unmodified.
552 /// If `version` is supported but `stream` becomes invalid during this
553 /// operation, this object has an undefined, but valid, state. Note
554 /// that no version is read from `stream`. See the `bslx` package-level
555 /// documentation for more information on BDEX streaming of
556 /// value-semantic types and containers.
557 template <class STREAM>
558 STREAM& bdexStreamIn(STREAM& stream, int version);
559
560 /// Insert into this array, at the specified `dstIndex`, an element of
561 /// specified `value`, shifting any elements originally at or above
562 /// `dstIndex` up by one. The behavior is undefined unless
563 /// `dstIndex <= length()`.
564 void insert(bsl::size_t dstIndex, ElementType value);
565
566 /// Insert into this array, at the specified `dstIndex`, the sequence of
567 /// values represented by the specified `srcArray`, shifting any
568 /// elements originally at or above `dstIndex` up by `srcArray.length()`
569 /// indices higher. The behavior is undefined unless
570 /// `dstIndex <= length()`. Note that if this array and `srcArray` are
571 /// the same, the behavior is as if a copy of `srcArray` were passed.
572 void insert(bsl::size_t dstIndex, const PackedIntArrayImp& srcArray);
573
574 /// Insert into this array, at the specified `dstIndex`, the specified
575 /// `numElements` values in the specified `srcArray` starting at the
576 /// specified `srcIndex`. Elements greater than or equal to `dstIndex`
577 /// are shifted up `numElements` positions. The behavior is undefined
578 /// unless `dstIndex <= length()` and
579 /// `srcIndex + numElements <= srcArray.length()`. Note that if this
580 /// array and `srcArray` are the same, the behavior is as if a copy of
581 /// `srcArray` were passed.
582 void insert(bsl::size_t dstIndex,
583 const PackedIntArrayImp& srcArray,
584 bsl::size_t srcIndex,
585 bsl::size_t numElements);
586
587 /// Remove the last element from this array. The behavior is undefined
588 /// unless `0 < length()` .
589 void pop_back();
590
591 /// Append an element having the specified `value` to the end of this
592 /// array.
593 void push_back(ElementType value);
594
595 /// Remove from this array the element at the specified `dstIndex`.
596 /// Each element having an index greater than `dstIndex` before the
597 /// removal is shifted down by one index position. The behavior is
598 /// undefined unless `dstIndex < length()` .
599 void remove(bsl::size_t dstIndex);
600
601 /// Remove from this array, starting at the specified `dstIndex`, the
602 /// specified `numElements`. Shift the elements of this array that are
603 /// at `dstIndex + numElements` or above to `numElements` indices lower.
604 /// The behavior is undefined unless
605 /// `dstIndex + numElements <= length()`.
606 void remove(bsl::size_t dstIndex, bsl::size_t numElements);
607
608 /// Remove all the elements from this array and set the storage required
609 /// per element to one byte.
610 void removeAll();
611
612 /// Change the value of the element at the specified `dstIndex` in this
613 /// array to the specified `value`. The behavior is undefined unless
614 /// `dstIndex < length()`.
615 void replace(bsl::size_t dstIndex, ElementType value);
616
617 /// Change the values of the specified `numElements` elements in this
618 /// array beginning at the specified `dstIndex` to those of the
619 /// `numElements` values in the specified `srcArray` beginning at the
620 /// specified `srcIndex`. The behavior is undefined unless
621 /// `srcIndex + numElements <= srcArray.length()` and
622 /// `dstIndex + numElements <= length()`. Note that if this array and
623 /// `srcArray` are the same, the behavior is as if a copy of `srcArray`
624 /// were passed.
625 void replace(bsl::size_t dstIndex,
626 const PackedIntArrayImp& srcArray,
627 bsl::size_t srcIndex,
628 bsl::size_t numElements);
629
630 /// Make the capacity of this array at least the specified
631 /// `requiredCapacityInBytes`. This method has no effect if the
632 /// current capacity meets or exceeds the required capacity.
633 void reserveCapacityImp(bsl::size_t requiredCapacityInBytes);
634
635 /// Make the capacity of this array at least the specified
636 /// `numElements` assuming the current `bytesPerElement()`. This
637 /// method has no effect if the current capacity meets or exceeds the
638 /// required capacity.
639 void reserveCapacity(bsl::size_t numElements);
640
641 /// Make the capacity of this array at least the specified
642 /// `numElements`. The specified `maxValue` denotes the maximum element
643 /// value that will be subsequently added to this array. After this
644 /// call `numElements` having values in the range `[0, maxValue]` are
645 /// guaranteed to not cause a reallocation. This method has no effect
646 /// if the current capacity meets or exceeds the required capacity.
647 /// The behavior is undefined unless `0 <= maxValue`.
648 void reserveCapacity(bsl::size_t numElements, ElementType maxValue);
649
650 /// Make the capacity of this array at least the specified
651 /// `numElements`. The specified `minValue` and `maxValue` denote,
652 /// respectively, the minimum and maximum elements values that will be
653 /// subsequently added to this array. After this call `numElements`
654 /// having values in the range `[minValue, maxValue]` are guaranteed to
655 /// not cause a reallocation. This method has no effect if the current
656 /// capacity meets or exceeds the required capacity. The behavior is
657 /// undefined unless `minValue <= maxValue`.
658 void reserveCapacity(bsl::size_t numElements,
659 ElementType minValue,
660 ElementType maxValue);
661
662 /// Set the length of this array to the specified `numElements`. If
663 /// `numElements > length()`, the added elements are initialized to 0.
664 void resize(bsl::size_t numElements);
665
666 /// Efficiently exchange the value of this array with the value of the
667 /// specified `other` array. This method provides the no-throw
668 /// exception-safety guarantee. The behavior is undefined unless this
669 /// array was created with the same allocator as `other`.
670 void swap(PackedIntArrayImp& other);
671
672 // ACCESSORS
673
674 /// Return the value of the element at the specified `index`. The
675 /// behavior is undefined unless `index < length()`.
676 ElementType operator[](bsl::size_t index) const;
677
678 /// Return the allocator used by this array to supply memory.
680
681 /// Write this value to the specified output `stream` using the
682 /// specified `version` format, and return a reference to `stream`. If
683 /// `stream` is initially invalid, this operation has no effect. If
684 /// `version` is not supported, `stream` is invalidated but otherwise
685 /// unmodified. Note that `version` is not written to `stream`. See
686 /// the `bslx` package-level documentation for more information on BDEX
687 /// streaming of value-semantic types and containers.
688 template <class STREAM>
689 STREAM& bdexStreamOut(STREAM& stream, int version) const;
690
691 /// Return the number of bytes currently used to store each element in
692 /// this array.
693 int bytesPerElement() const;
694
695 /// Return the number of elements this array can hold in terms of the
696 /// current data type used to store its elements.
697 bsl::size_t capacity() const;
698
699 /// Return `true` if there are no elements in this array, and `false`
700 /// otherwise.
701 bool isEmpty() const;
702
703 /// Return `true` if this and the specified `other` array have the same
704 /// value, and `false` otherwise. Two `PackedIntArrayImp` arrays have
705 /// the same value if they have the same length, and all corresponding
706 /// elements (those at the same indices) have the same value.
707 bool isEqual(const PackedIntArrayImp& other) const;
708
709 /// Return number of elements in this array.
710 bsl::size_t length() const;
711
712 /// Write the value of this array to the specified output `stream` in a
713 /// human-readable format, and return a reference to `stream`.
714 /// Optionally specify an initial indentation `level`, whose absolute
715 /// value is incremented recursively for nested arrays. If `level` is
716 /// specified, optionally specify `spacesPerLevel`, whose absolute value
717 /// indicates the number of spaces per indentation level for this and
718 /// all of its nested arrays. If `level` is negative, format the entire
719 /// output on one line, suppressing all but the initial indentation (as
720 /// governed by `level`). If `stream` is not valid on entry, this
721 /// operation has no effect. Note that the format is not fully
722 /// specified, and can change without notice.
723 bsl::ostream& print(bsl::ostream& stream,
724 int level = 0,
725 int spacesPerLevel = 4) const;
726};
727
728 // ============================
729 // struct PackedIntArrayImpType
730 // ============================
731
732/// This meta-function selects
733/// `PackedIntArrayImp<PackedIntArrayImp_Unsigned>` if `TYPE` should be
734/// stored as an unsigned integer, and
735/// `PackedIntArrayImp<PackedIntArrayImp_Signed>` otherwise.
736template <class TYPE>
753
754 // =================================
755 // class PackedIntArrayConstIterator
756 // =================================
757
758/// This unconstrained (value-semantic) class represents a random access
759/// iterator providing non-modifiable access to the elements of a
760/// `PackedIntArray`. This class provides all functionality of a random
761/// access iterator, as defined by the standard, but is *not* compatible
762/// with most standard methods requiring a bidirectional const_iterator.
763///
764/// This class does not perform any bounds checking. The returned iterator,
765/// `it`, referencing an element within a `PackedIntArray`, `array`, remains
766/// valid while `0 <= it - array.begin() < array.length()`.
767///
768/// See @ref bdlc_packedintarray
769template <class TYPE>
771
772 // PRIVATE TYPES
774
775 // DATA
776 const ImpType *d_array_p; // A pointer to the 'PackedIntArrayImp' into
777 // which this iterator references.
778
779 bsl::size_t d_index; // The index of the referenced value within the
780 // array.
781
782 // FRIENDS
783 friend class PackedIntArray<TYPE>;
784
786 operator++<>(PackedIntArrayConstIterator&, int);
787
789 operator--<>(PackedIntArrayConstIterator&, int);
790
791 friend bool operator==<>(const PackedIntArrayConstIterator&,
793
794 friend bool operator!=<>(const PackedIntArrayConstIterator&,
796
797 friend bsl::ptrdiff_t operator-<>(const PackedIntArrayConstIterator&,
799
800 friend bool operator< <>(const PackedIntArrayConstIterator&,
802
803 friend bool operator<=<>(const PackedIntArrayConstIterator&,
805
806 friend bool operator><>(const PackedIntArrayConstIterator&,
808
809 friend bool operator>=<>(const PackedIntArrayConstIterator&,
811
812 public:
813 // PUBLIC TYPES
814
815 // The following typedefs define the traits for this iterator to make it
816 // compatible with standard functions.
817
818 typedef bsl::ptrdiff_t difference_type; // The type
819 // used for the
820 // distance
821 // between two
822 // iterators.
823
824 typedef bsl::size_t size_type; // The type
825 // used for any
826 // function
827 // requiring a
828 // length (i.e,
829 // index).
830
831 typedef TYPE value_type; // The type for
832 // all returns
833 // of element
834 // values.
835
836 typedef void * pointer; // The type of
837 // an arbitrary
838 // pointer into
839 // the array.
840
841 typedef TYPE& reference; // The type for
842 // all returns
843 // of element
844 // references.
845
846 private:
847 // PRIVATE CREATORS
848
849 /// Create a `PackedIntArrayConstIterator` object with a pointer to the
850 /// specified `array` and the specified `index`. The behavior is
851 /// undefined unless `index <= array->length()`.
852 PackedIntArrayConstIterator(const ImpType *array, bsl::size_t index);
853
854 public:
855 // CREATORS
856
857 /// Create a default `PackedIntArrayConstIterator`. Note that the use
858 /// of most methods - as indicated in their documentation - upon this
859 /// iterator will result in undefined behavior.
861
862 /// Create a `PackedIntArrayConstIterator` having the same value as the
863 /// specified `original` one.
865
867 // Destroy this object.
868
869 // MANIPULATORS
870
871 /// Assign to this iterator the value of the specified `rhs` iterator,
872 /// and return a reference providing modifiable access to this iterator.
875
876 /// Advance this iterator to refer to the next element in the referenced
877 /// array and return a reference to this iterator *after* the
878 /// advancement. The returned iterator, `it`, referencing an element
879 /// within a `PackedIntArray`, `array`, remains valid as long as
880 /// `0 <= it - array.begin() <= array.length()`. The behavior is
881 /// undefined unless, on entry,
882 /// `PackedIntArrayConstInterator() != *this` and
883 /// `*this - array.begin() < array.length()`.
885
886 /// Decrement this iterator to refer to the previous element in the
887 /// referenced array and return a reference to this iterator *after* the
888 /// decrementation. The returned iterator, `it`, referencing an element
889 /// within a `PackedIntArray`, `array`, remains valid as long as
890 /// `0 <= it - array.begin() <= array.length()`. The behavior is
891 /// undefined unless, on entry, `0 < *this - array.begin()`.
893
894 /// Advance this iterator by the specified `offset` from the element
895 /// referenced to this iterator. The returned iterator, `it`,
896 /// referencing an element within a `PackedIntArray`, `array`, remains
897 /// valid as long as `0 <= it - array.begin() <= array.length()`. The
898 /// behavior is undefined unless
899 /// `PackedIntArrayConstInterator() != *this` and
900 /// `0 <= *this - array.begin() + offset <= array.length()`.
901 PackedIntArrayConstIterator& operator+=(bsl::ptrdiff_t offset);
902
903 /// Decrement this iterator by the specified `offset` from the element
904 /// referenced to this iterator. The returned iterator, `it`,
905 /// referencing an element within a `PackedIntArray`, `array`, remains
906 /// valid as long as `0 <= it - array.begin() <= array.length()`. The
907 /// behavior is undefined unless
908 /// `PackedIntArrayConstInterator() != *this` and
909 /// `0 <= *this - array.begin() - offset <= array.length()`.
910 PackedIntArrayConstIterator& operator-=(bsl::ptrdiff_t offset);
911
912 // ACCESSORS
913
914 /// Return the element value referenced by this iterator. The behavior
915 /// is undefined unless for this iterator, referencing an element within
916 /// a `PackedIntArray` `array`,
917 /// `PackedIntArrayConstInterator() != *this` and
918 /// `*this - array.begin() < array.length()`.
919 TYPE operator*() const;
920
921 /// Return the element value referenced by this iterator. The behavior
922 /// is undefined unless for this iterator, referencing an element within
923 /// a `PackedIntArray` `array`,
924 /// `PackedIntArrayConstInterator() != *this` and
925 /// `*this - array.begin() < array.length()`.
926 TYPE operator->() const;
927
928 /// Return the element that is the specified `offset` from the element
929 /// reference by this array. The behavior is undefined unless for this
930 /// iterator, referencing an element within a `PackedIntArray` `array`,
931 /// `PackedIntArrayConstInterator() != *this` and
932 /// `0 <= *this - array.begin() + offset < array.length()`.
933 TYPE operator[](bsl::ptrdiff_t offset) const;
934
935 /// Return an iterator referencing the location at the specified
936 /// `offset` from the element referenced by this iterator. The returned
937 /// iterator, `it`, referencing an element within a `PackedIntArray`,
938 /// `array`, remains valid as long as
939 /// `0 <= it - array.begin() <= array.length()`. The behavior is
940 /// undefined unless
941 /// `0 <= *this - array.begin() + offset <= array.length()`.
942 PackedIntArrayConstIterator operator+(bsl::ptrdiff_t offset) const;
943
944 /// Return an iterator referencing the location at the specified
945 /// `offset` from the element referenced by this iterator. The returned
946 /// iterator, `it`, referencing an element within a `PackedIntArray`,
947 /// `array`, remains valid as long as
948 /// `0 <= it - array.begin() <= array.length()`. The behavior is
949 /// undefined unless `PackedIntArrayConstInterator() != *this` and
950 /// `0 <= *this - array.begin() - offset <= array.length()`.
951 PackedIntArrayConstIterator operator-(bsl::ptrdiff_t offset) const;
952};
953
954// FREE FUNCTIONS
955
956/// Advance the specified iterator `iter` to refer to the next element in
957/// the referenced array, and return an iterator referring to the original
958/// element (*before* the advancement). The returned iterator, `it`,
959/// referencing an element within a `PackedIntArray`, `array`, remains valid
960/// as long as `0 <= it - array.begin() <= array.length()`. The behavior is
961/// undefined unless, on entry, `PackedIntArrayConstInterator() != iter` and
962/// `iter - array.begin() < array.length()`.
963template <class TYPE>
966
967/// Decrement the specified iterator `iter` to refer to the previous element
968/// in the referenced array, and return an iterator referring to the
969/// original element (*before* the decrementation). The returned iterator,
970/// `it`, referencing an element within a `PackedIntArray`, `array`, remains
971/// valid as long as `0 <= it - array.begin() <= array.length()`. The
972/// behavior is undefined unless, on entry,
973/// `PackedIntArrayConstInterator() != iter` and `0 < iter - array.begin()`.
974template <class TYPE>
977
978/// Return `true` if the specified `lhs` and `rhs` iterators have the same
979/// value, and `false` otherwise. Two `PackedIntArrayConstIterator`
980/// iterators have the same value if they refer to the same array, and have
981/// the same index.
982template <class TYPE>
983bool operator==(const PackedIntArrayConstIterator<TYPE>& lhs,
985
986/// Return `true` if the specified `lhs` and `rhs` iterators do not have the
987/// same value and `false` otherwise. Two `PackedIntArrayConstIterator`
988/// iterators do not have the same value if they do not refer to the same
989/// array, or do not have the same index.
990template <class TYPE>
991bool operator!=(const PackedIntArrayConstIterator<TYPE>& lhs,
993
994/// Return the number of elements between specified `lhs` and `rhs`. The
995/// behavior is undefined unless `lhs` and `rhs` reference the same array.
996template <class TYPE>
997bsl::ptrdiff_t operator-(const PackedIntArrayConstIterator<TYPE>& lhs,
999
1000/// Return `true` if the specified `lhs` has a value less than the specified
1001/// `rhs`, `false` otherwise. An iterator has a value less than another if
1002/// its index is less the other's index. The behavior is undefined unless
1003/// `lhs` and `rhs` refer to the same array.
1004template <class TYPE>
1005bool operator<(const PackedIntArrayConstIterator<TYPE>& lhs,
1007
1008/// Return `true` if the specified `lhs` has a value less than or equal to
1009/// the specified `rhs, `false' otherwise. An iterator has a value less
1010/// than or equal to another if its index is less or equal the other's
1011/// index. The behavior is undefined unless `lhs` and `rhs` refer to the
1012/// same array.
1013template <class TYPE>
1014bool operator<=(const PackedIntArrayConstIterator<TYPE>& lhs,
1016
1017/// Return `true` if the specified `lhs` has a value greater than the
1018/// specified `rhs`, `false` otherwise. An iterator has a value greater
1019/// than another if its index is greater the other's index. The behavior is
1020/// undefined unless `lhs` and `rhs` refer to the same array.
1021template <class TYPE>
1022bool operator>(const PackedIntArrayConstIterator<TYPE>& lhs,
1024
1025/// Return `true` if the specified `lhs` has a value greater or equal than
1026/// the specified `rhs`, `false` otherwise. An iterator has a value greater
1027/// than or equal to another if its index is greater the other's index. The
1028/// behavior is undefined unless `lhs` and `rhs` refer to the same array.
1029template <class TYPE>
1030bool operator>=(const PackedIntArrayConstIterator<TYPE>& lhs,
1032
1033 // ====================
1034 // class PackedIntArray
1035 // ====================
1036
1037/// This space-efficient value-semantic array class represents a sequence of
1038/// `TYPE` elements; `TYPE` must be convertible to either a signed or
1039/// unsigned 64-bit integer using @ref static_cast . The interface provides
1040/// functionality similar to a `vector<int>` however references to
1041/// individual elements are not provided. This class provides accessors
1042/// that return iterators that provide non-modifiable access to its
1043/// elements. The returned iterators, unlike those returned by a
1044/// `vector<int>` are *not* invalidated upon reallocation.
1045///
1046/// See @ref bdlc_packedintarray
1047template <class TYPE>
1049
1050 // PRIVATE TYPES
1052
1053 // PRIVATE CLASS DATA
1054 static const bsl::size_t k_MAX_BYTES_PER_ELEMENT = 8;
1055
1056 // DATA
1057 ImpType d_imp; // Implementation of either a signed or unsigned 64-bit
1058 // integer packed array.
1059
1060 public:
1061 // PUBLIC TYPES
1062 typedef TYPE value_type; // The type for all returns of element values.
1063
1065
1066 // CLASS METHODS
1067
1068 /// Return the `version` to be used with the `bdexStreamOut` method
1069 /// corresponding to the specified `serializationVersion`. See the
1070 /// `bslx` package-level documentation for more information on BDEX
1071 /// streaming of value-semantic types and containers.
1072 static int maxSupportedBdexVersion(int serializationVersion);
1073
1074 // CREATORS
1075
1076 /// Create an empty `PackedIntArray`. Optionally specify a
1077 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0,
1078 /// the currently installed default allocator is used.
1079 explicit PackedIntArray(bslma::Allocator *basicAllocator = 0);
1080
1081 /// Create a `PackedIntArray` having the specified `numElements`.
1082 /// Optionally specify a `value` to which each element will be set. If
1083 /// value is not specified, 0 is used. Optionally specify a
1084 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0,
1085 /// the currently installed default allocator is used.
1086 explicit PackedIntArray(bsl::size_t numElements,
1087 TYPE value = 0,
1088 bslma::Allocator *basicAllocator = 0);
1089
1090 /// Create a `PackedIntArray` having the same value as the specified
1091 /// `original` one. Optionally specify a `basicAllocator` used to
1092 /// supply memory. If `basicAllocator` is 0, the currently installed
1093 /// default allocator is used.
1095 bslma::Allocator *basicAllocator = 0);
1096
1097 /// Destroy this object
1099
1100 // MANIPULATORS
1101
1102 /// Assign to this array the value of the specified `rhs` array, and
1103 /// return a reference providing modifiable access to this array.
1105
1106 /// Append an element having the specified `value` to the end of this
1107 /// array.
1108 void append(TYPE value);
1109
1110 /// Append the sequence of values represented by the specified
1111 /// `srcArray` to the end of this array. Note that if this array and
1112 /// `srcArray` are the same, the behavior is as if a copy of `srcArray`
1113 /// were passed.
1114 void append(const PackedIntArray& srcArray);
1115
1116 /// Append the sequence of values of the specified `numElements`
1117 /// starting at the specified `srcIndex` in the specified `srcArray` to
1118 /// the end of this array. The behavior is undefined unless
1119 /// `srcIndex + numElements <= srcArray.length()`. Note that if this
1120 /// array and `srcArray` are the same, the behavior is as if a copy of
1121 /// `srcArray` were passed.
1122 void append(const PackedIntArray& srcArray,
1123 bsl::size_t srcIndex,
1124 bsl::size_t numElements);
1125
1126 /// Assign to this object the value read from the specified input
1127 /// `stream` using the specified `version` format, and return a
1128 /// reference to `stream`. If `stream` is initially invalid, this
1129 /// operation has no effect. If `version` is not supported, this object
1130 /// is unaltered and `stream` is invalidated but otherwise unmodified.
1131 /// If `version` is supported but `stream` becomes invalid during this
1132 /// operation, this object has an undefined, but valid, state. Note
1133 /// that no version is read from `stream`. See the `bslx` package-level
1134 /// documentation for more information on BDEX streaming of
1135 /// value-semantic types and containers.
1136 template <class STREAM>
1137 STREAM& bdexStreamIn(STREAM& stream, int version);
1138
1139 /// Insert into this array, at the specified `dstIndex`, an element
1140 /// having the specified `value`, shifting any elements originally at
1141 /// or above `dstIndex` up by one. The behavior is undefined unless
1142 /// `dstIndex <= length()`.
1143 void insert(bsl::size_t dstIndex, TYPE value);
1144
1145 /// Insert into this array, at the specified `dst`, an element having
1146 /// the specified `value`, shifting any elements originally at or above
1147 /// `dst` up by one. Return an iterator to the newly inserted element.
1149
1150 /// Insert into this array, at the specified `dstIndex`, the sequence of
1151 /// values represented by the specified `srcArray`, shifting any
1152 /// elements originally at or above `dstIndex` up by `srcArray.length()`
1153 /// indices higher. The behavior is undefined unless
1154 /// `dstIndex <= length()`. Note that if this array and `srcArray` are
1155 /// the same, the behavior is as if a copy of `srcArray` were passed.
1156 void insert(bsl::size_t dstIndex, const PackedIntArray& srcArray);
1157
1158 /// Insert into this array, at the specified `dstIndex`, the specified
1159 /// `numElements` values in the specified `srcArray` starting at the
1160 /// specified `srcIndex`. Elements greater than or equal to `dstIndex`
1161 /// are shifted up `numElements` positions. The behavior is undefined
1162 /// unless `dstIndex <= length()` and
1163 /// `srcIndex + numElements <= srcArray.length()`. Note that if this
1164 /// array and `srcArray` are the same, the behavior is as if a copy of
1165 /// `srcArray` were passed.
1166 void insert(bsl::size_t dstIndex,
1167 const PackedIntArray& srcArray,
1168 bsl::size_t srcIndex,
1169 bsl::size_t numElements);
1170
1171 /// Remove the last element from this array. The behavior is undefined
1172 /// unless `0 < length()` .
1173 void pop_back();
1174
1175 /// Append an element having the specified `value` to the end of this
1176 /// array.
1177 void push_back(TYPE value);
1178
1179 /// Remove from this array the element at the specified `dstIndex`.
1180 /// Each element having an index greater than `dstIndex` before the
1181 /// removal is shifted down by one index position. The behavior is
1182 /// undefined unless `dstIndex < length()` .
1183 void remove(bsl::size_t dstIndex);
1184
1185 /// Remove from this array, starting at the specified `dstIndex`, the
1186 /// specified `numElements`, shifting the elements of this array that
1187 /// are at `dstIndex + numElements` or above to `numElements` indices
1188 /// lower. The behavior is undefined unless
1189 /// `dstIndex + numElements <= length()`.
1190 void remove(bsl::size_t dstIndex, bsl::size_t numElements);
1191
1192 /// Remove from this array the elements starting from the specified
1193 /// `dstFirst` up to, but not including, the specified `dstLast`,
1194 /// shifting the elements of this array that are at or above `dstLast`
1195 /// to `dstLast - dstFirst` indices lower. Return an iterator to the
1196 /// new position of the element that was referred to by `dstLast` or
1197 /// `end()` if `dstLast == end()`. The behavior is undefined unless
1198 /// `dstFirst <= dstLast`.
1200
1201 /// Remove all the elements from this array and set the storage required
1202 /// per element to one byte.
1204
1205 /// Change the value of the element at the specified `dstIndex` in this
1206 /// array to the specified `value`. The behavior is undefined unless
1207 /// `dstIndex < length()`.
1208 void replace(bsl::size_t dstIndex, TYPE value);
1209
1210 /// Change the values of the specified `numElements` elements in this
1211 /// array beginning at the specified `dstIndex` to those of the
1212 /// `numElements` values in the specified `srcArray` beginning at the
1213 /// specified `srcIndex`. The behavior is undefined unless
1214 /// `srcIndex + numElements <= srcArray.length()` and
1215 /// `dstIndex + numElements <= length()`. Note that if this array and
1216 /// `srcArray` are the same, the behavior is as if a copy of `srcArray`
1217 /// were passed.
1218 void replace(bsl::size_t dstIndex,
1219 const PackedIntArray& srcArray,
1220 bsl::size_t srcIndex,
1221 bsl::size_t numElements);
1222
1223 /// Make the capacity of this array at least the specified
1224 /// `numElements`. This method has no effect if the current capacity
1225 /// meets or exceeds the required capacity.
1226 void reserveCapacity(bsl::size_t numElements);
1227
1228 /// Make the capacity of this array at least the specified
1229 /// `numElements`. The specified `maxValue` denotes the maximum element
1230 /// value that will be subsequently added to this array. After this
1231 /// call `numElements` having values in the range `[0, maxValue]` are
1232 /// guaranteed to not cause a reallocation. This method has no effect
1233 /// if the current capacity meets or exceeds the required capacity.
1234 /// The behavior is undefined unless `0 <= maxValue`.
1235 void reserveCapacity(bsl::size_t numElements, TYPE maxValue);
1236
1237 /// Make the capacity of this array at least the specified
1238 /// `numElements`. The specified `minValue` and `maxValue` denote,
1239 /// respectively, the minimum and maximum elements values that will be
1240 /// subsequently added to this array. After this call `numElements`
1241 /// having values in the range `[minValue, maxValue]` are guaranteed to
1242 /// not cause a reallocation. This method has no effect if the current
1243 /// capacity meets or exceeds the required capacity. The behavior is
1244 /// undefined unless `minValue <= maxValue`.
1245 void reserveCapacity(bsl::size_t numElements,
1246 TYPE minValue,
1247 TYPE maxValue);
1248
1249 /// Set the length of this array to the specified `numElements`. If
1250 /// `numElements > length()`, the added elements are initialized to 0.
1251 void resize(bsl::size_t numElements);
1252
1253 /// Efficiently exchange the value of this array with the value of the
1254 /// specified `other` array. This method provides the no-throw
1255 /// exception-safety guarantee. The behavior is undefined unless this
1256 /// array was created with the same allocator as `other`.
1257 void swap(PackedIntArray& other);
1258
1259 // ACCESSORS
1260
1261 /// Return the value of the element at the specified `index`. The
1262 /// behavior is undefined unless `index < length()`.
1263 TYPE operator[](bsl::size_t index) const;
1264
1265 /// Return the allocator used by this array to supply memory.
1267
1268 /// Return the value of the element at the back of this array. The
1269 /// behavior is undefined unless `0 < length()`. Note that this
1270 /// function is logically equivalent to:
1271 /// @code
1272 /// operator[](length() - 1)
1273 /// @endcode
1274 TYPE back() const;
1275
1276 /// Write this value to the specified output `stream` using the
1277 /// specified `version` format, and return a reference to `stream`. If
1278 /// `stream` is initially invalid, this operation has no effect. If
1279 /// `version` is not supported, `stream` is invalidated but otherwise
1280 /// unmodified. Note that `version` is not written to `stream`. See
1281 /// the `bslx` package-level documentation for more information on BDEX
1282 /// streaming of value-semantic types and containers.
1283 template <class STREAM>
1284 STREAM& bdexStreamOut(STREAM& stream, int version) const;
1285
1286 /// Return an iterator referring to the first element in this array (or
1287 /// the past-the-end iterator if this array is empty). This reference
1288 /// remains valid as long as this array exists.
1290
1291 /// Return the number of bytes currently used to store each element in
1292 /// this array.
1293 int bytesPerElement() const;
1294
1295 /// Return the number of elements this array can hold in terms of the
1296 /// current data type used to store its elements.
1297 bsl::size_t capacity() const;
1298
1299 /// Return an iterator referring to one element beyond the last element
1300 /// in this array. This reference remains valid as long as this array
1301 /// exists, and length does not decrease.
1303
1304 /// Return the value of the element at the front of this array. The
1305 /// behavior is undefined unless `0 < length()`. Note that this
1306 /// function is logically equivalent to:
1307 /// @code
1308 /// operator[](0)
1309 /// @endcode
1310 TYPE front() const;
1311
1312 /// Return `true` if there are no elements in this array, and `false`
1313 /// otherwise.
1314 bool isEmpty() const;
1315
1316 /// Return `true` if this and the specified `other` array have the same
1317 /// value, and `false` otherwise. Two `PackedIntArray` arrays have the
1318 /// same value if they have the same length, and all corresponding
1319 /// elements (those at the same indices) have the same value.
1320 bool isEqual(const PackedIntArray& other) const;
1321
1322 /// Return number of elements in this array.
1323 bsl::size_t length() const;
1324
1325 /// Write the value of this array to the specified output `stream` in a
1326 /// human-readable format, and return a reference to `stream`.
1327 /// Optionally specify an initial indentation `level`, whose absolute
1328 /// value is incremented recursively for nested arrays. If `level` is
1329 /// specified, optionally specify `spacesPerLevel`, whose absolute value
1330 /// indicates the number of spaces per indentation level for this and
1331 /// all of its nested arrays. If `level` is negative, format the entire
1332 /// output on one line, suppressing all but the initial indentation (as
1333 /// governed by `level`). If `stream` is not valid on entry, this
1334 /// operation has no effect. Note that the format is not fully
1335 /// specified, and can change without notice.
1336 bsl::ostream& print(bsl::ostream& stream,
1337 int level = 0,
1338 int spacesPerLevel = 4) const;
1339};
1340
1341// FREE OPERATORS
1342
1343/// Write the value of the specified `array` to the specified output
1344/// `stream` in a single-line format, and return a reference providing
1345/// modifiable access to `stream`. If `stream` is not valid on entry, this
1346/// operation has no effect. Note that this human-readable format is not
1347/// fully specified and can change without notice.
1348template <class TYPE>
1349bsl::ostream& operator<<(bsl::ostream& stream,
1350 const PackedIntArray<TYPE>& array);
1351
1352/// Return `true` if the specified `lhs` and `rhs` arrays have the same
1353/// value, and `false` otherwise. Two `PackedIntArray` arrays have the same
1354/// value if they have the same length, and all corresponding elements
1355/// (those at the same indices) have the same value.
1356template <class TYPE>
1357bool operator==(const PackedIntArray<TYPE>& lhs,
1358 const PackedIntArray<TYPE>& rhs);
1359
1360/// Return `true` if the specified `lhs` and `rhs` arrays do not have the
1361/// same value, and `false` otherwise. Two `PackedIntArray` arrays do not
1362/// have the same value if they do not have the same length, or if any
1363/// corresponding elements (those at the same indices) do not have the same
1364/// value.
1365template <class TYPE>
1366bool operator!=(const PackedIntArray<TYPE>& lhs,
1367 const PackedIntArray<TYPE>& rhs);
1368
1369// FREE FUNCTIONS
1370
1371/// Exchange the values of the specified `a` and `b` objects. This function
1372/// provides the no-throw exception-safety guarantee if the two objects were
1373/// created with the same allocator and the basic guarantee otherwise.
1374template <class TYPE>
1376
1377// HASH SPECIALIZATIONS
1378
1379/// Pass the specified `input` to the specified `hashAlg`
1380template <class HASHALG, class TYPE>
1381void hashAppend(HASHALG& hashAlg, const PackedIntArray<TYPE>& input);
1382
1383// ============================================================================
1384// INLINE DEFINITIONS
1385// ============================================================================
1386
1387 // -------------------------------
1388 // struct PackedIntArrayImp_Signed
1389 // -------------------------------
1390
1391template <class STREAM>
1392void PackedIntArrayImp_Signed::bdexGet8(STREAM& stream, bsl::int8_t& variable)
1393{
1394 char v = 0;
1395 stream.getInt8(v);
1396 variable = static_cast<bsl::int8_t>(v);
1397}
1398
1399template <class STREAM>
1401 bsl::int16_t& variable)
1402{
1403 short v = 0;
1404 stream.getInt16(v);
1405 variable = static_cast<bsl::int16_t>(v);
1406}
1407
1408template <class STREAM>
1410 bsl::int32_t& variable)
1411{
1412 int v = 0;
1413 stream.getInt32(v);
1414 variable = static_cast<bsl::int32_t>(v);
1415}
1416
1417template <class STREAM>
1419 bsl::int64_t& variable)
1420{
1421 bsls::Types::Int64 v = 0;
1422 stream.getInt64(v);
1423 variable = static_cast<bsl::int64_t>(v);
1424}
1425
1426template <class STREAM>
1427void PackedIntArrayImp_Signed::bdexPut8(STREAM& stream, bsl::int8_t value)
1428{
1429 stream.putInt8(static_cast<int>(value));
1430}
1431
1432template <class STREAM>
1433void PackedIntArrayImp_Signed::bdexPut16(STREAM& stream, bsl::int16_t value)
1434{
1435 stream.putInt16(static_cast<int>(value));
1436}
1437
1438template <class STREAM>
1439void PackedIntArrayImp_Signed::bdexPut32(STREAM& stream, bsl::int32_t value)
1440{
1441 stream.putInt32(static_cast<int>(value));
1442}
1443
1444template <class STREAM>
1445void PackedIntArrayImp_Signed::bdexPut64(STREAM& stream, bsl::int64_t value)
1446{
1447 stream.putInt64(static_cast<bsls::Types::Int64>(value));
1448}
1449
1450 // ---------------------------------
1451 // struct PackedIntArrayImp_Unsigned
1452 // ---------------------------------
1453
1454template <class STREAM>
1456 bsl::uint8_t& variable)
1457{
1458 unsigned char v;
1459 stream.getUint8(v);
1460 variable = static_cast<bsl::uint8_t>(v);
1461}
1462
1463template <class STREAM>
1465 bsl::uint16_t& variable)
1466{
1467 unsigned short v;
1468 stream.getUint16(v);
1469 variable = static_cast<bsl::uint16_t>(v);
1470}
1471
1472template <class STREAM>
1474 bsl::uint32_t& variable)
1475{
1476 unsigned int v;
1477 stream.getUint32(v);
1478 variable = static_cast<bsl::uint32_t>(v);
1479}
1480
1481template <class STREAM>
1483 bsl::uint64_t& variable)
1484{
1486 stream.getUint64(v);
1487 variable = static_cast<bsl::uint64_t>(v);
1488}
1489
1490template <class STREAM>
1491void PackedIntArrayImp_Unsigned::bdexPut8(STREAM& stream, bsl::uint8_t value)
1492{
1493 stream.putUint8(static_cast<unsigned int>(value));
1494}
1495
1496template <class STREAM>
1497void PackedIntArrayImp_Unsigned::bdexPut16(STREAM& stream, bsl::uint16_t value)
1498{
1499 stream.putUint16(static_cast<unsigned int>(value));
1500}
1501
1502template <class STREAM>
1503void PackedIntArrayImp_Unsigned::bdexPut32(STREAM& stream, bsl::uint32_t value)
1504{
1505 stream.putUint32(static_cast<unsigned int>(value));
1506}
1507
1508template <class STREAM>
1509void PackedIntArrayImp_Unsigned::bdexPut64(STREAM& stream, bsl::uint64_t value)
1510{
1511 stream.putUint64(static_cast<bsls::Types::Uint64>(value));
1512}
1513
1514 // ------------------------
1515 // struct PackedIntArrayImp
1516 // ------------------------
1517
1518// PRIVATE CLASS METHODS
1519template <class STORAGE>
1520inline
1521bsl::size_t PackedIntArrayImp<STORAGE>::nextCapacityGE(bsl::size_t minValue,
1522 bsl::size_t value)
1523{
1524 BSLS_ASSERT(minValue <= k_MAX_CAPACITY);
1525
1526 static const bsl::size_t k_TOP_CAPACITY = k_MAX_CAPACITY / 3 * 2 - 3;
1527
1528 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(minValue >= k_TOP_CAPACITY)) {
1530 return minValue; // RETURN
1531 }
1532
1533 while (value < minValue) {
1534 value += (value + 3) / 2;
1535 }
1536
1537 return value;
1538}
1539
1540// PRIVATE ACCESSORS
1541template <class STORAGE>
1542inline
1543char *PackedIntArrayImp<STORAGE>::address() const
1544{
1545 return static_cast<char *>(d_storage_p);
1546}
1547
1548// CLASS METHODS
1549template <class STORAGE>
1550inline
1555
1556// MANIPULATORS
1557template <class STORAGE>
1558inline
1560 append(const PackedIntArrayImp<STORAGE>& srcArray)
1561{
1562 append(srcArray, 0, srcArray.d_length);
1563}
1564
1565template <class STORAGE>
1566template <class STREAM>
1567inline
1568STREAM& PackedIntArrayImp<STORAGE>::bdexStreamIn(STREAM& stream, int version)
1569{
1570 if (stream) {
1571 switch (version) { // switch on the schema version
1572 case 1: {
1573 int tmpBytesPerElement;
1574 {
1575 char v = 0;
1576 stream.getInt8(v);
1577 tmpBytesPerElement = static_cast<int>(v);
1578 }
1579 if ( 1 != tmpBytesPerElement
1580 && 2 != tmpBytesPerElement
1581 && 4 != tmpBytesPerElement
1582 && 8 != tmpBytesPerElement) {
1583 stream.invalidate();
1584 }
1585 else {
1586 bsl::size_t tmpLength;
1587 {
1588 int v;
1589 stream.getLength(v);
1590 tmpLength = static_cast<bsl::size_t>(v);
1591 }
1592 if (stream) {
1593 bsl::size_t numBytes = tmpBytesPerElement * tmpLength;
1594 if (numBytes > d_capacityInBytes) {
1595 // Compute next capacity level.
1596
1597 bsl::size_t requiredCapacityInBytes =
1598 nextCapacityGE(numBytes, d_capacityInBytes);
1599
1600 // Allocate new memory.
1601 void *dst =
1602 d_allocator_p->allocate(requiredCapacityInBytes);
1603
1604 // Deallocate original memory.
1605
1606 d_allocator_p->deallocate(d_storage_p);
1607
1608 // Update storage and capacity.
1609
1610 d_storage_p = dst;
1611 d_capacityInBytes = requiredCapacityInBytes;
1612 }
1613
1614 // Update bytes per element and length.
1615
1616 d_bytesPerElement = tmpBytesPerElement;
1617 d_length = tmpLength;
1618
1619 // Populate the data from the stream.
1620
1621 switch (d_bytesPerElement) {
1622 case 1: {
1623 typename STORAGE::OneByteStorageType *s =
1624 static_cast<typename STORAGE::OneByteStorageType *>
1625 (d_storage_p);
1626 for (bsl::size_t i = 0; i < d_length; ++i) {
1627 STORAGE::bdexGet8(stream, s[i]);
1628 }
1629 } break;
1630 case 2: {
1631 typename STORAGE::TwoByteStorageType *s =
1632 static_cast<typename STORAGE::TwoByteStorageType *>
1633 (d_storage_p);
1634 for (bsl::size_t i = 0; i < d_length; ++i) {
1635 STORAGE::bdexGet16(stream, s[i]);
1636 }
1637 } break;
1638 case 4: {
1639 typename STORAGE::FourByteStorageType *s =
1640 static_cast<typename STORAGE::FourByteStorageType *>
1641 (d_storage_p);
1642 for (bsl::size_t i = 0; i < d_length; ++i) {
1643 STORAGE::bdexGet32(stream, s[i]);
1644 }
1645 } break;
1646 case 8: {
1647 typename STORAGE::EightByteStorageType *s =
1648 static_cast<typename STORAGE::EightByteStorageType *>
1649 (d_storage_p);
1650 for (bsl::size_t i = 0; i < d_length; ++i) {
1651 STORAGE::bdexGet64(stream, s[i]);
1652 }
1653 } break;
1654 }
1655 }
1656 }
1657 } break;
1658 default: {
1659 stream.invalidate(); // unrecognized version number
1660 }
1661 }
1662 }
1663 return stream;
1664}
1665
1666template <class STORAGE>
1667inline
1669 bsl::size_t dstIndex,
1670 const PackedIntArrayImp<STORAGE>& srcArray)
1671{
1672 BSLS_ASSERT(dstIndex <= d_length);
1673
1674 insert(dstIndex, srcArray, 0, srcArray.length());
1675}
1676
1677template <class STORAGE>
1678inline
1680{
1681 BSLS_ASSERT_SAFE(0 < d_length);
1682
1683 --d_length;
1684}
1685
1686template <class STORAGE>
1687inline
1689{
1690 append(value);
1691}
1692
1693template <class STORAGE>
1694inline
1695void PackedIntArrayImp<STORAGE>::remove(bsl::size_t dstIndex)
1696{
1697 BSLS_ASSERT(dstIndex < d_length);
1698
1699 remove(dstIndex, 1);
1700}
1701
1702template <class STORAGE>
1703inline
1704void PackedIntArrayImp<STORAGE>::remove(bsl::size_t dstIndex,
1705 bsl::size_t numElements)
1706{
1707 // Assert 'dstIndex + numElements <= d_length' without risk of overflow.
1708 BSLS_ASSERT(numElements <= d_length);
1709 BSLS_ASSERT(dstIndex <= d_length - numElements);
1710
1711 d_length -= numElements;
1712
1713 if (address()) {
1714 bsl::memmove(address() + dstIndex * d_bytesPerElement,
1715 address() + (dstIndex + numElements) * d_bytesPerElement,
1716 (d_length - dstIndex) * d_bytesPerElement);
1717 }
1718}
1719
1720template <class STORAGE>
1721inline
1723{
1724 d_length = 0;
1725 d_bytesPerElement = 1;
1726}
1727
1728template <class STORAGE>
1729inline
1731{
1732 // Test for potential overflow.
1733 BSLS_ASSERT(k_MAX_CAPACITY / d_bytesPerElement >= numElements);
1734
1735 size_t requiredCapacityInBytes = d_bytesPerElement * numElements;
1736 if (requiredCapacityInBytes > d_capacityInBytes) {
1737 reserveCapacityImp(requiredCapacityInBytes);
1738 }
1739}
1740
1741template <class STORAGE>
1742inline
1744 ElementType maxValue)
1745{
1746 BSLS_ASSERT(0 <= maxValue);
1747
1748 int requiredBytesPerElement = d_bytesPerElement;
1749
1750 int rbpe = STORAGE::requiredBytesPerElement(maxValue);
1751 if (rbpe > requiredBytesPerElement) {
1752 requiredBytesPerElement = rbpe;
1753 }
1754
1755 // Test for potential overflow.
1756 BSLS_ASSERT(k_MAX_CAPACITY / requiredBytesPerElement >= numElements);
1757
1758 size_t requiredCapacityInBytes = requiredBytesPerElement * numElements;
1759
1760 if (requiredCapacityInBytes > d_capacityInBytes) {
1761 reserveCapacityImp(requiredCapacityInBytes);
1762 }
1763}
1764
1765template <>
1766inline
1768 reserveCapacity(bsl::size_t numElements,
1769 ElementType maxValue)
1770{
1771 int requiredBytesPerElement = d_bytesPerElement;
1772
1774 if (rbpe > requiredBytesPerElement) {
1775 requiredBytesPerElement = rbpe;
1776 }
1777
1778 // Test for potential overflow.
1779 BSLS_ASSERT(k_MAX_CAPACITY / requiredBytesPerElement >= numElements);
1780
1781 size_t requiredCapacityInBytes = requiredBytesPerElement * numElements;
1782
1783 if (requiredCapacityInBytes > d_capacityInBytes) {
1784 reserveCapacityImp(requiredCapacityInBytes);
1785 }
1786}
1787
1788template <class STORAGE>
1789inline
1791 ElementType minValue,
1792 ElementType maxValue)
1793{
1794 BSLS_ASSERT(minValue <= maxValue);
1795
1796 int requiredBytesPerElement = d_bytesPerElement;
1797
1798 int rbpe = STORAGE::requiredBytesPerElement(maxValue);
1799 if (rbpe > requiredBytesPerElement) {
1800 requiredBytesPerElement = rbpe;
1801 }
1802
1803 rbpe = STORAGE::requiredBytesPerElement(minValue);
1804 if (rbpe > requiredBytesPerElement) {
1805 requiredBytesPerElement = rbpe;
1806 }
1807
1808 // Test for potential overflow.
1809 BSLS_ASSERT(k_MAX_CAPACITY / requiredBytesPerElement >= numElements);
1810
1811 size_t requiredCapacityInBytes = requiredBytesPerElement * numElements;
1812
1813 if (requiredCapacityInBytes > d_capacityInBytes) {
1814 reserveCapacityImp(requiredCapacityInBytes);
1815 }
1816}
1817
1818template <class STORAGE>
1819inline
1820void PackedIntArrayImp<STORAGE>::resize(bsl::size_t numElements)
1821{
1822 if (numElements > d_length) {
1823 reserveCapacity(numElements);
1824 bsl::memset(address() + d_length * d_bytesPerElement,
1825 0,
1826 (numElements - d_length) * d_bytesPerElement);
1827 }
1828 d_length = numElements;
1829}
1830
1831template <class STORAGE>
1832inline
1834{
1835 BSLS_ASSERT(d_allocator_p == other.d_allocator_p);
1836
1837 bslalg::SwapUtil::swap(&d_storage_p, &other.d_storage_p);
1838 bslalg::SwapUtil::swap(&d_length, &other.d_length);
1839 bslalg::SwapUtil::swap(&d_bytesPerElement, &other.d_bytesPerElement);
1840 bslalg::SwapUtil::swap(&d_capacityInBytes, &other.d_capacityInBytes);
1841}
1842
1843// ACCESSORS
1844template <class STORAGE>
1845inline
1847{
1848 return d_allocator_p;
1849}
1850
1851template <class STORAGE>
1852template <class STREAM>
1853inline
1855 int version) const
1856{
1857 if (stream) {
1858 switch (version) {
1859 case 1: {
1860 stream.putInt8(d_bytesPerElement);
1861 stream.putLength(static_cast<int>(d_length));
1862 switch (d_bytesPerElement) {
1863 case 1: {
1864 typename STORAGE::OneByteStorageType *s =
1865 static_cast<typename STORAGE::OneByteStorageType *>
1866 (d_storage_p);
1867 for (bsl::size_t i = 0; i < d_length; ++i) {
1868 STORAGE::bdexPut8(stream, s[i]);
1869 }
1870 } break;
1871 case 2: {
1872 typename STORAGE::TwoByteStorageType *s =
1873 static_cast<typename STORAGE::TwoByteStorageType *>
1874 (d_storage_p);
1875 for (bsl::size_t i = 0; i < d_length; ++i) {
1876 STORAGE::bdexPut16(stream, s[i]);
1877 }
1878 } break;
1879 case 4: {
1880 typename STORAGE::FourByteStorageType *s =
1881 static_cast<typename STORAGE::FourByteStorageType *>
1882 (d_storage_p);
1883 for (bsl::size_t i = 0; i < d_length; ++i) {
1884 STORAGE::bdexPut32(stream, s[i]);
1885 }
1886 } break;
1887 case 8: {
1888 typename STORAGE::EightByteStorageType *s =
1889 static_cast<typename STORAGE::EightByteStorageType *>
1890 (d_storage_p);
1891 for (bsl::size_t i = 0; i < d_length; ++i) {
1892 STORAGE::bdexPut64(stream, s[i]);
1893 }
1894 } break;
1895 }
1896 } break;
1897 default: {
1898 stream.invalidate(); // unrecognized version number
1899 }
1900 }
1901 }
1902 return stream;
1903}
1904
1905template <class STORAGE>
1906inline
1908 return d_bytesPerElement;
1909}
1910
1911template <class STORAGE>
1912inline
1914 return d_capacityInBytes / d_bytesPerElement;
1915}
1916
1917template <class STORAGE>
1918inline
1920 return 0 == d_length;
1921}
1922
1923template <class STORAGE>
1924inline
1926 const PackedIntArrayImp<STORAGE>& other) const
1927{
1928 if (d_length == other.d_length) {
1929 if (0 == d_length) {
1930 return true; // RETURN
1931 }
1932 else if (d_bytesPerElement == other.d_bytesPerElement) {
1933 return 0 == bsl::memcmp(d_storage_p,
1934 other.d_storage_p,
1935 d_length * d_bytesPerElement); // RETURN
1936 }
1937 else {
1938 return isEqualImp(other); // RETURN
1939 }
1940 }
1941 return false;
1942}
1943
1944template <class STORAGE>
1945inline
1947{
1948 return d_length;
1949}
1950
1951 // ---------------------------------
1952 // class PackedIntArrayConstIterator
1953 // ---------------------------------
1954
1955// PRIVATE CREATORS
1956template <class TYPE>
1957inline
1959 const ImpType *array,
1960 bsl::size_t index)
1961: d_array_p(array)
1962, d_index(index)
1963{
1964 BSLS_ASSERT(d_index <= d_array_p->length());
1965}
1966
1967// CREATORS
1968template <class TYPE>
1969inline
1971: d_array_p(0)
1972, d_index(0)
1973{
1974}
1975
1976template <class TYPE>
1977inline
1979 const PackedIntArrayConstIterator& original)
1980: d_array_p(original.d_array_p)
1981, d_index(original.d_index)
1982{
1983}
1984
1985// MANIPULATORS
1986template <class TYPE>
1987inline
1990{
1991 d_array_p = rhs.d_array_p;
1992 d_index = rhs.d_index;
1993 return *this;
1994}
1995
1996template <class TYPE>
1997inline
2000{
2001 BSLS_ASSERT_SAFE(d_array_p);
2002 BSLS_ASSERT_SAFE(d_index < d_array_p->length());
2003
2004 ++d_index;
2005 return *this;
2006}
2007
2008template <class TYPE>
2009inline
2012{
2013 BSLS_ASSERT_SAFE(d_array_p);
2014 BSLS_ASSERT_SAFE(0 < d_index);
2015
2016 --d_index;
2017 return *this;
2018}
2019
2020template <class TYPE>
2021inline
2024{
2025 BSLS_ASSERT_SAFE(d_array_p);
2026
2027 // Assert '0 <= d_index + offset <= d_array_p->length()' without risk of
2028 // overflow.
2029 BSLS_ASSERT_SAFE(0 <= offset || d_index >= bsl::size_t(-offset));
2030 BSLS_ASSERT_SAFE( 0 >= offset
2031 || d_array_p->length() - d_index >= bsl::size_t(offset));
2032
2033 d_index += offset;
2034 return *this;
2035}
2036
2037template <class TYPE>
2038inline
2041{
2042 BSLS_ASSERT_SAFE(d_array_p);
2043
2044 // Assert '0 <= d_index - offset <= d_array_p->length()' without risk of
2045 // overflow.
2046 BSLS_ASSERT_SAFE( 0 >= offset || d_index >= bsl::size_t(offset));
2047 BSLS_ASSERT_SAFE( 0 <= offset
2048 || d_array_p->length() - d_index >= bsl::size_t(-offset));
2049
2050 d_index -= offset;
2051 return *this;
2052}
2053
2054// ACCESSORS
2055template <class TYPE>
2056inline
2058{
2059 BSLS_ASSERT_SAFE(d_array_p);
2060 BSLS_ASSERT_SAFE(d_index < d_array_p->length());
2061
2062 return static_cast<TYPE>((*d_array_p)[d_index]);
2063}
2064
2065template <class TYPE>
2066inline
2068{
2069 BSLS_ASSERT_SAFE(d_array_p);
2070 BSLS_ASSERT_SAFE(d_index < d_array_p->length());
2071
2072 return *(*this);
2073}
2074
2075template <class TYPE>
2076inline
2077TYPE PackedIntArrayConstIterator<TYPE>::operator[](bsl::ptrdiff_t offset) const
2078{
2079 BSLS_ASSERT_SAFE(d_array_p);
2080
2081 // Assert '0 <= d_index + offset < d_array_p->length()' without risk of
2082 // overflow.
2083 BSLS_ASSERT_SAFE(0 <= offset || d_index >= bsl::size_t(-offset));
2084 BSLS_ASSERT_SAFE( 0 >= offset
2085 || d_array_p->length() - d_index > bsl::size_t(offset));
2086
2087 return static_cast<TYPE>((*d_array_p)[d_index + offset]);
2088}
2089
2090template <class TYPE>
2091inline
2094{
2095 BSLS_ASSERT_SAFE(d_array_p);
2096
2097 // Assert '0 <= d_index + offset <= d_array_p->length()' without risk of
2098 // overflow.
2099 BSLS_ASSERT_SAFE(0 <= offset || d_index >= bsl::size_t(-offset));
2100 BSLS_ASSERT_SAFE( 0 >= offset
2101 || d_array_p->length() - d_index >= bsl::size_t(offset));
2102
2103 return PackedIntArrayConstIterator<TYPE>(d_array_p, d_index + offset);
2104}
2105
2106
2107template <class TYPE>
2108inline
2111{
2112 BSLS_ASSERT_SAFE(d_array_p);
2113
2114 // Assert '0 <= d_index - offset <= d_array_p->length()' without risk of
2115 // overflow.
2116 BSLS_ASSERT_SAFE( 0 >= offset || d_index >= bsl::size_t(offset));
2117 BSLS_ASSERT_SAFE( 0 <= offset
2118 || d_array_p->length() - d_index >= bsl::size_t(-offset));
2119
2120 return PackedIntArrayConstIterator<TYPE>(d_array_p, d_index - offset);
2121}
2122
2123} // close package namespace
2124
2125// FREE FUNCTIONS
2126template <class TYPE>
2127inline
2129 PackedIntArrayConstIterator<TYPE>& iter,
2130 int)
2131{
2132 BSLS_ASSERT_SAFE(iter.d_array_p);
2133 BSLS_ASSERT_SAFE(iter.d_index < iter.d_array_p->length());
2134
2135 const PackedIntArrayConstIterator<TYPE> curr = iter;
2136 ++iter;
2137 return curr;
2138}
2139
2140template <class TYPE>
2141inline
2143 PackedIntArrayConstIterator<TYPE>& iter,
2144 int)
2145{
2146 BSLS_ASSERT_SAFE(iter.d_array_p);
2147 BSLS_ASSERT_SAFE(iter.d_index > 0);
2148
2149 const PackedIntArrayConstIterator<TYPE> curr = iter;
2150 --iter;
2151 return curr;
2152}
2153
2154template <class TYPE>
2155inline
2156bool bdlc::operator==(const PackedIntArrayConstIterator<TYPE>& lhs,
2157 const PackedIntArrayConstIterator<TYPE>& rhs)
2158{
2159 return lhs.d_array_p == rhs.d_array_p && lhs.d_index == rhs.d_index;
2160}
2161
2162template <class TYPE>
2163inline
2164bool bdlc::operator!=(const PackedIntArrayConstIterator<TYPE>& lhs,
2165 const PackedIntArrayConstIterator<TYPE>& rhs)
2166{
2167 return lhs.d_array_p != rhs.d_array_p || lhs.d_index != rhs.d_index;
2168}
2169
2170template <class TYPE>
2171inline
2172bsl::ptrdiff_t bdlc::operator-(const PackedIntArrayConstIterator<TYPE>& lhs,
2173 const PackedIntArrayConstIterator<TYPE>& rhs)
2174{
2175 BSLS_ASSERT(lhs.d_array_p == rhs.d_array_p);
2176
2178 lhs.d_index >= rhs.d_index
2179 ? lhs.d_index - rhs.d_index <=
2180 bsl::size_t(bsl::numeric_limits<bsl::ptrdiff_t>::max())
2181 : rhs.d_index - lhs.d_index <=
2182 bsl::size_t(bsl::numeric_limits<bsl::ptrdiff_t>::min()));
2183
2184 return static_cast<bsl::ptrdiff_t>(lhs.d_index - rhs.d_index);
2185}
2186
2187template <class TYPE>
2188inline
2189bool bdlc::operator<(const PackedIntArrayConstIterator<TYPE>& lhs,
2190 const PackedIntArrayConstIterator<TYPE>& rhs)
2191{
2192 BSLS_ASSERT(lhs.d_array_p == rhs.d_array_p);
2193
2194 return lhs.d_index < rhs.d_index;
2195}
2196
2197template <class TYPE>
2198inline
2199bool bdlc::operator<=(const PackedIntArrayConstIterator<TYPE>& lhs,
2200 const PackedIntArrayConstIterator<TYPE>& rhs)
2201{
2202 BSLS_ASSERT(lhs.d_array_p == rhs.d_array_p);
2203
2204 return lhs.d_index <= rhs.d_index;
2205}
2206
2207template <class TYPE>
2208inline
2209bool bdlc::operator>(const PackedIntArrayConstIterator<TYPE>& lhs,
2210 const PackedIntArrayConstIterator<TYPE>& rhs)
2211{
2212 BSLS_ASSERT(lhs.d_array_p == rhs.d_array_p);
2213
2214 return lhs.d_index > rhs.d_index;
2215}
2216
2217template <class TYPE>
2218inline
2219bool bdlc::operator>=(const PackedIntArrayConstIterator<TYPE>& lhs,
2220 const PackedIntArrayConstIterator<TYPE>& rhs)
2221{
2222 BSLS_ASSERT(lhs.d_array_p == rhs.d_array_p);
2223
2224 return lhs.d_index >= rhs.d_index;
2225}
2226
2227namespace bdlc {
2228
2229 // --------------------
2230 // class PackedIntArray
2231 // --------------------
2232
2233// CLASS METHODS
2234template <class TYPE>
2235inline
2237{
2238 return ImpType::maxSupportedBdexVersion(serializationVersion);
2239}
2240
2241// CREATORS
2242template <class TYPE>
2243inline
2245: d_imp(basicAllocator)
2246{
2247}
2248
2249template <class TYPE>
2250inline
2252 TYPE value,
2253 bslma::Allocator *basicAllocator)
2254: d_imp(numElements,
2255 static_cast<typename ImpType::ElementType>(value),
2256 basicAllocator)
2257{
2258}
2259
2260template <class TYPE>
2261inline
2263 const PackedIntArray<TYPE>& original,
2264 bslma::Allocator *basicAllocator)
2265: d_imp(original.d_imp, basicAllocator)
2266{
2267}
2268
2269template <class TYPE>
2270inline
2274
2275// MANIPULATORS
2276template <class TYPE>
2277inline
2279 const PackedIntArray<TYPE>& rhs)
2280{
2281 d_imp = rhs.d_imp;
2282 return *this;
2283}
2284
2285template <class TYPE>
2286inline
2288{
2289 d_imp.append(static_cast<typename ImpType::ElementType>(value));
2290}
2291
2292template <class TYPE>
2293inline
2295{
2296 d_imp.append(srcArray.d_imp);
2297}
2298
2299template <class TYPE>
2300inline
2302 bsl::size_t srcIndex,
2303 bsl::size_t numElements)
2304{
2305 // Assert 'srcIndex + numElements <= srcArray.length()' without risk of
2306 // overflow.
2307 BSLS_ASSERT(numElements <= srcArray.length());
2308 BSLS_ASSERT(srcIndex <= srcArray.length() - numElements);
2309
2310 d_imp.append(srcArray.d_imp, srcIndex, numElements);
2311}
2312
2313template <class TYPE>
2314template <class STREAM>
2315inline
2316STREAM& PackedIntArray<TYPE>::bdexStreamIn(STREAM& stream, int version)
2317{
2318 return d_imp.bdexStreamIn(stream, version);
2319}
2320
2321template <class TYPE>
2322inline
2323void PackedIntArray<TYPE>::insert(bsl::size_t dstIndex, TYPE value)
2324{
2325 BSLS_ASSERT_SAFE(dstIndex <= length());
2326
2327 d_imp.insert(dstIndex, static_cast<typename ImpType::ElementType>(value));
2328}
2329
2330template <class TYPE>
2331inline
2334{
2335 insert(dst.d_index, value);
2336 return dst;
2337}
2338
2339template <class TYPE>
2340inline
2341void PackedIntArray<TYPE>::insert(bsl::size_t dstIndex,
2342 const PackedIntArray<TYPE>& srcArray)
2343{
2344 BSLS_ASSERT(dstIndex <= length());
2345
2346 d_imp.insert(dstIndex, srcArray.d_imp);
2347}
2348
2349template <class TYPE>
2350inline
2351void PackedIntArray<TYPE>::insert(bsl::size_t dstIndex,
2352 const PackedIntArray<TYPE>& srcArray,
2353 bsl::size_t srcIndex,
2354 bsl::size_t numElements)
2355{
2356 BSLS_ASSERT(dstIndex <= length());
2357
2358 // Assert 'srcIndex + numElements <= srcArray.length()' without risk of
2359 // overflow.
2360 BSLS_ASSERT(numElements <= srcArray.length());
2361 BSLS_ASSERT(srcIndex <= srcArray.length() - numElements);
2362
2363 d_imp.insert(dstIndex, srcArray.d_imp, srcIndex, numElements);
2364}
2365
2366template <class TYPE>
2367inline
2369{
2370 BSLS_ASSERT_SAFE(0 < length());
2371
2372 d_imp.pop_back();
2373}
2374
2375template <class TYPE>
2376inline
2378{
2379 d_imp.push_back(static_cast<typename ImpType::ElementType>(value));
2380}
2381
2382template <class TYPE>
2383inline
2384void PackedIntArray<TYPE>::remove(bsl::size_t dstIndex)
2385{
2386 BSLS_ASSERT(dstIndex < length());
2387
2388 d_imp.remove(dstIndex);
2389}
2390
2391template <class TYPE>
2392inline
2393void PackedIntArray<TYPE>::remove(bsl::size_t dstIndex,
2394 bsl::size_t numElements)
2395{
2396 // Assert 'dstIndex + numElements <= length()' without risk of overflow.
2397 BSLS_ASSERT(numElements <= length());
2398 BSLS_ASSERT(dstIndex <= length() - numElements);
2399
2400 d_imp.remove(dstIndex, numElements);
2401}
2402
2403template <class TYPE>
2404inline
2407{
2408 BSLS_ASSERT(dstFirst <= dstLast);
2409
2410 remove(dstFirst.d_index, dstLast.d_index - dstFirst.d_index);
2411 return dstFirst;
2412}
2413
2414template <class TYPE>
2415inline
2417{
2418 d_imp.removeAll();
2419}
2420
2421template <class TYPE>
2422inline
2423void PackedIntArray<TYPE>::replace(bsl::size_t dstIndex, TYPE value)
2424{
2425 BSLS_ASSERT_SAFE(dstIndex < length());
2426
2427 d_imp.replace(dstIndex, static_cast<typename ImpType::ElementType>(value));
2428}
2429
2430template <class TYPE>
2431inline
2432void PackedIntArray<TYPE>::replace(bsl::size_t dstIndex,
2433 const PackedIntArray<TYPE>& srcArray,
2434 bsl::size_t srcIndex,
2435 bsl::size_t numElements)
2436{
2437 // Assert 'dstIndex + numElements <= length()' without risk of overflow.
2438 BSLS_ASSERT(numElements <= length());
2439 BSLS_ASSERT(dstIndex <= length() - numElements);
2440
2441 // Assert 'srcIndex + numElements <= srcArray.length()' without risk of
2442 // overflow.
2443 BSLS_ASSERT(numElements <= srcArray.length());
2444 BSLS_ASSERT(srcIndex <= srcArray.length() - numElements);
2445
2446 d_imp.replace(dstIndex, srcArray.d_imp, srcIndex, numElements);
2447}
2448
2449template <class TYPE>
2450inline
2451void PackedIntArray<TYPE>::reserveCapacity(bsl::size_t numElements)
2452{
2453 // Test for potential overflow.
2455 ImpType::k_MAX_CAPACITY / k_MAX_BYTES_PER_ELEMENT >= numElements);
2456
2457 d_imp.reserveCapacityImp(numElements * k_MAX_BYTES_PER_ELEMENT);
2458}
2459
2460template <class TYPE>
2461inline
2462void PackedIntArray<TYPE>::reserveCapacity(bsl::size_t numElements,
2463 TYPE maxValue)
2464{
2465 // To avoid a compiler warning, asserting '0 <= maxValue' is omitted; the
2466 // test is performed in 'd_imp.reserveCapacity'.
2467
2468 d_imp.reserveCapacity(numElements, maxValue);
2469}
2470
2471template <class TYPE>
2472inline
2473void PackedIntArray<TYPE>::reserveCapacity(bsl::size_t numElements,
2474 TYPE minValue,
2475 TYPE maxValue)
2476{
2477 BSLS_ASSERT(minValue <= maxValue);
2478
2479 d_imp.reserveCapacity(numElements, minValue, maxValue);
2480}
2481
2482template <class TYPE>
2483inline
2484void PackedIntArray<TYPE>::resize(bsl::size_t numElements)
2485{
2486 d_imp.resize(numElements);
2487}
2488
2489template <class TYPE>
2490inline
2492{
2493 BSLS_ASSERT(allocator() == other.allocator());
2494
2495 d_imp.swap(other.d_imp);
2496}
2497
2498// ACCESSORS
2499template <class TYPE>
2500inline
2501TYPE PackedIntArray<TYPE>::operator[](bsl::size_t index) const
2502{
2503 BSLS_ASSERT_SAFE(index < length());
2504
2505 return static_cast<TYPE>(d_imp[index]);
2506}
2507
2508template <class TYPE>
2509inline
2511{
2512 return d_imp.allocator();
2513}
2514
2515template <class TYPE>
2516inline
2518{
2519 BSLS_ASSERT_SAFE(0 < length());
2520
2521 return static_cast<TYPE>(d_imp[length() - 1]);
2522}
2523
2524template <class TYPE>
2525template <class STREAM>
2526inline
2527STREAM& PackedIntArray<TYPE>::bdexStreamOut(STREAM& stream, int version) const
2528{
2529 return d_imp.bdexStreamOut(stream, version);
2530}
2531
2532template <class TYPE>
2533inline
2536{
2537 return const_iterator(&d_imp, 0);
2538}
2539
2540template <class TYPE>
2541inline
2543{
2544 return d_imp.bytesPerElement();
2545}
2546
2547template <class TYPE>
2548inline
2550{
2551 return d_imp.capacity();
2552}
2553
2554template <class TYPE>
2555inline
2557{
2558 return const_iterator(&d_imp, d_imp.length());
2559}
2560
2561template <class TYPE>
2562inline
2564{
2565 BSLS_ASSERT_SAFE(0 < length());
2566
2567 return static_cast<TYPE>(d_imp[0]);
2568}
2569
2570template <class TYPE>
2571inline
2573{
2574 return d_imp.isEmpty();
2575}
2576
2577template <class TYPE>
2578inline
2580{
2581 return d_imp.isEqual(other.d_imp);
2582}
2583
2584template <class TYPE>
2585inline
2587{
2588 return d_imp.length();
2589}
2590
2591template <class TYPE>
2592bsl::ostream& PackedIntArray<TYPE>::print(bsl::ostream& stream,
2593 int level,
2594 int spacesPerLevel) const
2595{
2596 return d_imp.print(stream, level, spacesPerLevel);
2597}
2598
2599} // close package namespace
2600
2601// FREE OPERATORS
2602template <class TYPE>
2603inline
2604bsl::ostream& bdlc::operator<<(bsl::ostream& stream,
2605 const PackedIntArray<TYPE>& array)
2606{
2607 return array.print(stream);
2608}
2609
2610template <class TYPE>
2611inline
2612bool bdlc::operator==(const PackedIntArray<TYPE>& lhs,
2613 const PackedIntArray<TYPE>& rhs)
2614{
2615 return lhs.isEqual(rhs);
2616}
2617
2618template <class TYPE>
2619inline
2620bool bdlc::operator!=(const PackedIntArray<TYPE>& lhs,
2621 const PackedIntArray<TYPE>& rhs)
2622{
2623 return !(lhs == rhs);
2624}
2625
2626// FREE FUNCTIONS
2627template <class TYPE>
2628void bdlc::swap(PackedIntArray<TYPE>& a, PackedIntArray<TYPE>& b)
2629{
2630 if (a.allocator() == b.allocator()) {
2631 a.swap(b);
2632
2633 return; // RETURN
2634 }
2635
2636 PackedIntArray<TYPE> futureA(b, a.allocator());
2637 PackedIntArray<TYPE> futureB(a, b.allocator());
2638
2639 futureA.swap(a);
2640 futureB.swap(b);
2641}
2642
2643// HASH SPECIALIZATIONS
2644template <class HASHALG, class TYPE>
2645inline
2646void bdlc::hashAppend(HASHALG& hashAlg, const PackedIntArray<TYPE>& input)
2647{
2648 using ::BloombergLP::bslh::hashAppend;
2649 typedef typename PackedIntArray<TYPE>::const_iterator ci_t;
2650 hashAppend(hashAlg, input.length());
2651 for (ci_t b = input.begin(), e = input.end(); b != e; ++b) {
2652 hashAppend(hashAlg, *b);
2653 }
2654}
2655
2656
2657
2658// TRAITS
2659
2660namespace bslma {
2661
2662template <class STORAGE>
2663struct UsesBslmaAllocator<bdlc::PackedIntArrayImp<STORAGE> >
2664 : bsl::true_type {};
2665
2666template <class TYPE>
2667struct UsesBslmaAllocator<bdlc::PackedIntArray<TYPE> > : bsl::true_type {};
2668
2669} // close namespace bslma
2670
2671
2672#endif
2673// ----------------------------------------------------------------------------
2674// Copyright 2018 Bloomberg Finance L.P.
2675//
2676// Licensed under the Apache License, Version 2.0 (the "License");
2677// you may not use this file except in compliance with the License.
2678// You may obtain a copy of the License at
2679//
2680// http://www.apache.org/licenses/LICENSE-2.0
2681//
2682// Unless required by applicable law or agreed to in writing, software
2683// distributed under the License is distributed on an "AS IS" BASIS,
2684// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2685// See the License for the specific language governing permissions and
2686// limitations under the License.
2687// ----------------------------- END-OF-FILE ----------------------------------
2688
2689/** @} */
2690/** @} */
2691/** @} */
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
Definition bdlc_packedintarray.h:770
friend bsl::ptrdiff_t operator-(const PackedIntArrayConstIterator &, const PackedIntArrayConstIterator &)
PackedIntArrayConstIterator & operator=(const PackedIntArrayConstIterator &rhs)
Definition bdlc_packedintarray.h:1989
PackedIntArrayConstIterator & operator-=(bsl::ptrdiff_t offset)
Definition bdlc_packedintarray.h:2040
TYPE value_type
Definition bdlc_packedintarray.h:831
bsl::ptrdiff_t difference_type
Definition bdlc_packedintarray.h:818
TYPE operator*() const
Definition bdlc_packedintarray.h:2057
TYPE operator[](bsl::ptrdiff_t offset) const
Definition bdlc_packedintarray.h:2077
friend PackedIntArrayConstIterator operator--(PackedIntArrayConstIterator &, int)
PackedIntArrayConstIterator & operator+=(bsl::ptrdiff_t offset)
Definition bdlc_packedintarray.h:2023
PackedIntArrayConstIterator operator+(bsl::ptrdiff_t offset) const
Definition bdlc_packedintarray.h:2093
bsl::size_t size_type
Definition bdlc_packedintarray.h:824
void * pointer
Definition bdlc_packedintarray.h:836
friend PackedIntArrayConstIterator operator++(PackedIntArrayConstIterator &, int)
TYPE operator->() const
Definition bdlc_packedintarray.h:2067
TYPE & reference
Definition bdlc_packedintarray.h:841
PackedIntArrayConstIterator()
Definition bdlc_packedintarray.h:1970
Definition bdlc_packedintarray.h:404
bool isEqual(const PackedIntArrayImp &other) const
Definition bdlc_packedintarray.h:1925
~PackedIntArrayImp()
Destroy this object.
PackedIntArrayImp(bslma::Allocator *basicAllocator=0)
void swap(PackedIntArrayImp &other)
Definition bdlc_packedintarray.h:1833
bsl::size_t length() const
Return number of elements in this array.
Definition bdlc_packedintarray.h:1946
void append(const PackedIntArrayImp &srcArray, bsl::size_t srcIndex, bsl::size_t numElements)
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdlc_packedintarray.h:1568
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdlc_packedintarray.h:1854
void insert(bsl::size_t dstIndex, ElementType value)
bslma::Allocator * allocator() const
Return the allocator used by this array to supply memory.
Definition bdlc_packedintarray.h:1846
PackedIntArrayImp & operator=(const PackedIntArrayImp &rhs)
PackedIntArrayImp(const PackedIntArrayImp &original, bslma::Allocator *basicAllocator=0)
static int maxSupportedBdexVersion(int serializationVersion)
Definition bdlc_packedintarray.h:1551
bsl::size_t capacity() const
Definition bdlc_packedintarray.h:1913
void reserveCapacity(bsl::size_t numElements)
Definition bdlc_packedintarray.h:1730
void reserveCapacityImp(bsl::size_t requiredCapacityInBytes)
void insert(bsl::size_t dstIndex, const PackedIntArrayImp &srcArray, bsl::size_t srcIndex, bsl::size_t numElements)
void replace(bsl::size_t dstIndex, const PackedIntArrayImp &srcArray, bsl::size_t srcIndex, bsl::size_t numElements)
void pop_back()
Definition bdlc_packedintarray.h:1679
static const bsl::size_t k_MAX_CAPACITY
Definition bdlc_packedintarray.h:411
void append(ElementType value)
int bytesPerElement() const
Definition bdlc_packedintarray.h:1907
void remove(bsl::size_t dstIndex)
Definition bdlc_packedintarray.h:1695
void push_back(ElementType value)
Definition bdlc_packedintarray.h:1688
void replace(bsl::size_t dstIndex, ElementType value)
bool isEmpty() const
Definition bdlc_packedintarray.h:1919
void resize(bsl::size_t numElements)
Definition bdlc_packedintarray.h:1820
ElementType operator[](bsl::size_t index) const
void removeAll()
Definition bdlc_packedintarray.h:1722
STORAGE::EightByteStorageType ElementType
Definition bdlc_packedintarray.h:408
PackedIntArrayImp(bsl::size_t numElements, ElementType value=0, bslma::Allocator *basicAllocator=0)
Definition bdlc_packedintarray.h:1048
const_iterator end() const
Definition bdlc_packedintarray.h:2556
void pop_back()
Definition bdlc_packedintarray.h:2368
void append(const PackedIntArray &srcArray)
Definition bdlc_packedintarray.h:2294
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdlc_packedintarray.h:2527
const_iterator begin() const
Definition bdlc_packedintarray.h:2535
void reserveCapacity(bsl::size_t numElements, TYPE maxValue)
Definition bdlc_packedintarray.h:2462
bool isEmpty() const
Definition bdlc_packedintarray.h:2572
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdlc_packedintarray.h:2316
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
Definition bdlc_packedintarray.h:2592
bsl::size_t capacity() const
Definition bdlc_packedintarray.h:2549
void replace(bsl::size_t dstIndex, const PackedIntArray &srcArray, bsl::size_t srcIndex, bsl::size_t numElements)
Definition bdlc_packedintarray.h:2432
void swap(PackedIntArray &other)
Definition bdlc_packedintarray.h:2491
void append(const PackedIntArray &srcArray, bsl::size_t srcIndex, bsl::size_t numElements)
Definition bdlc_packedintarray.h:2301
void insert(bsl::size_t dstIndex, const PackedIntArray &srcArray, bsl::size_t srcIndex, bsl::size_t numElements)
Definition bdlc_packedintarray.h:2351
PackedIntArray(bslma::Allocator *basicAllocator=0)
Definition bdlc_packedintarray.h:2244
void removeAll()
Definition bdlc_packedintarray.h:2416
PackedIntArrayConstIterator< TYPE > const_iterator
Definition bdlc_packedintarray.h:1064
void resize(bsl::size_t numElements)
Definition bdlc_packedintarray.h:2484
static int maxSupportedBdexVersion(int serializationVersion)
Definition bdlc_packedintarray.h:2236
bsl::size_t length() const
Return number of elements in this array.
Definition bdlc_packedintarray.h:2586
TYPE back() const
Definition bdlc_packedintarray.h:2517
void reserveCapacity(bsl::size_t numElements)
Definition bdlc_packedintarray.h:2451
void push_back(TYPE value)
Definition bdlc_packedintarray.h:2377
TYPE front() const
Definition bdlc_packedintarray.h:2563
PackedIntArray(const PackedIntArray &original, bslma::Allocator *basicAllocator=0)
Definition bdlc_packedintarray.h:2262
void insert(bsl::size_t dstIndex, const PackedIntArray &srcArray)
Definition bdlc_packedintarray.h:2341
PackedIntArray(bsl::size_t numElements, TYPE value=0, bslma::Allocator *basicAllocator=0)
Definition bdlc_packedintarray.h:2251
~PackedIntArray()
Destroy this object.
Definition bdlc_packedintarray.h:2271
void append(TYPE value)
Definition bdlc_packedintarray.h:2287
TYPE value_type
Definition bdlc_packedintarray.h:1062
void insert(bsl::size_t dstIndex, TYPE value)
Definition bdlc_packedintarray.h:2323
const_iterator remove(const_iterator dstFirst, const_iterator dstLast)
Definition bdlc_packedintarray.h:2406
PackedIntArray & operator=(const PackedIntArray &rhs)
Definition bdlc_packedintarray.h:2278
bslma::Allocator * allocator() const
Return the allocator used by this array to supply memory.
Definition bdlc_packedintarray.h:2510
void remove(bsl::size_t dstIndex)
Definition bdlc_packedintarray.h:2384
TYPE operator[](bsl::size_t index) const
Definition bdlc_packedintarray.h:2501
int bytesPerElement() const
Definition bdlc_packedintarray.h:2542
const_iterator insert(const_iterator dst, TYPE value)
Definition bdlc_packedintarray.h:2333
void remove(bsl::size_t dstIndex, bsl::size_t numElements)
Definition bdlc_packedintarray.h:2393
void replace(bsl::size_t dstIndex, TYPE value)
Definition bdlc_packedintarray.h:2423
bool isEqual(const PackedIntArray &other) const
Definition bdlc_packedintarray.h:2579
void reserveCapacity(bsl::size_t numElements, TYPE minValue, TYPE maxValue)
Definition bdlc_packedintarray.h:2473
static void swap(T *a, T *b)
Definition bslalg_swaputil.h:194
Definition bslma_allocator.h:457
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_PERFORMANCEHINT_UNLIKELY_HINT
Definition bsls_performancehint.h:484
#define BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(expr)
Definition bsls_performancehint.h:452
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)
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
Definition bdlc_packedintarray.h:737
bsl::conditional< bsl::is_same< TYPE, unsignedchar >::value||bsl::is_same< TYPE, unsignedshort >::value||bsl::is_same< TYPE, unsignedint >::value||bsl::is_same< TYPE, unsignedlongint >::value||bsl::is_same< TYPE, bsls::Types::Uint64 >::value||bsl::is_same< TYPE, bsl::uint8_t >::value||bsl::is_same< TYPE, bsl::uint16_t >::value||bsl::is_same< TYPE, bsl::uint32_t >::value||bsl::is_same< TYPE, bsl::uint64_t >::value, PackedIntArrayImp< PackedIntArrayImp_Unsigned >, PackedIntArrayImp< PackedIntArrayImp_Signed > >::type Type
Definition bdlc_packedintarray.h:751
Definition bdlc_packedintarray.h:273
bsl::int8_t OneByteStorageType
Definition bdlc_packedintarray.h:276
static void bdexPut16(STREAM &stream, bsl::int16_t value)
Definition bdlc_packedintarray.h:1433
bsl::int64_t EightByteStorageType
Definition bdlc_packedintarray.h:279
static void bdexGet64(STREAM &stream, bsl::int64_t &variable)
Definition bdlc_packedintarray.h:1418
static void bdexGet16(STREAM &stream, bsl::int16_t &variable)
Definition bdlc_packedintarray.h:1400
static void bdexGet32(STREAM &stream, bsl::int32_t &variable)
Definition bdlc_packedintarray.h:1409
bsl::int16_t TwoByteStorageType
Definition bdlc_packedintarray.h:277
static void bdexGet8(STREAM &stream, bsl::int8_t &variable)
Definition bdlc_packedintarray.h:1392
static int requiredBytesPerElement(EightByteStorageType value)
Return the required number of bytes to store the specified value.
static void bdexPut32(STREAM &stream, bsl::int32_t value)
Definition bdlc_packedintarray.h:1439
static void bdexPut64(STREAM &stream, bsl::int64_t value)
Definition bdlc_packedintarray.h:1445
bsl::int32_t FourByteStorageType
Definition bdlc_packedintarray.h:278
static void bdexPut8(STREAM &stream, bsl::int8_t value)
Definition bdlc_packedintarray.h:1427
Definition bdlc_packedintarray.h:337
static void bdexGet16(STREAM &stream, bsl::uint16_t &variable)
Definition bdlc_packedintarray.h:1464
bsl::uint8_t OneByteStorageType
Definition bdlc_packedintarray.h:340
static void bdexGet64(STREAM &stream, bsl::uint64_t &variable)
Definition bdlc_packedintarray.h:1482
bsl::uint16_t TwoByteStorageType
Definition bdlc_packedintarray.h:341
static void bdexPut16(STREAM &stream, bsl::uint16_t value)
Definition bdlc_packedintarray.h:1497
static void bdexGet8(STREAM &stream, bsl::uint8_t &variable)
Definition bdlc_packedintarray.h:1455
static void bdexPut32(STREAM &stream, bsl::uint32_t value)
Definition bdlc_packedintarray.h:1503
static void bdexGet32(STREAM &stream, bsl::uint32_t &variable)
Definition bdlc_packedintarray.h:1473
bsl::uint32_t FourByteStorageType
Definition bdlc_packedintarray.h:342
bsl::uint64_t EightByteStorageType
Definition bdlc_packedintarray.h:343
static int requiredBytesPerElement(EightByteStorageType value)
Return the required number of bytes to store the specified value.
static void bdexPut8(STREAM &stream, bsl::uint8_t value)
Definition bdlc_packedintarray.h:1491
static void bdexPut64(STREAM &stream, bsl::uint64_t value)
Definition bdlc_packedintarray.h:1509
Definition bslmf_conditional.h:120
Definition bslmf_integralconstant.h:244
Definition bslmf_issame.h:146
Definition bslma_usesbslmaallocator.h:343
unsigned long long Uint64
Definition bsls_types.h:137
long long Int64
Definition bsls_types.h:132