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