BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslstl_array.h
Go to the documentation of this file.
1/// @file bslstl_array.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_array.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_ARRAY
9#define INCLUDED_BSLSTL_ARRAY
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_array bslstl_array
15/// @brief Provide an STL compliant array.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_array
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_array-purpose"> Purpose</a>
25/// * <a href="#bslstl_array-classes"> Classes </a>
26/// * <a href="#bslstl_array-canonical-header"> Canonical Header </a>
27/// * <a href="#bslstl_array-description"> Description </a>
28/// * <a href="#bslstl_array-operations"> Operations </a>
29/// * <a href="#bslstl_array-comparing-an-array-of-floating-point-values"> Comparing an array of floating point values </a>
30/// * <a href="#bslstl_array-usage"> Usage </a>
31/// * <a href="#bslstl_array-example-1-returning-an-array-from-a-function"> Example 1: Returning an array from a function </a>
32///
33/// # Purpose {#bslstl_array-purpose}
34/// Provide an STL compliant array.
35///
36/// # Classes {#bslstl_array-classes}
37///
38/// - bsl::array: an STL compliant array
39///
40/// # Canonical Header {#bslstl_array-canonical-header}
41/// bsl_array.h
42///
43/// @see bslstl_vector
44///
45/// # Description {#bslstl_array-description}
46/// This component defines a single class template, `bsl::array`,
47/// implementing the standard container `std::array`, holding a non-resizable
48/// array of values of a template parameter type where the size is specified as
49/// the second template parameter.
50///
51/// An instantiation of `array` is a value-semantic type whose salient
52/// attributes are its size and the sequence of values the array contains. If
53/// `array` is instantiated with a value type that is not value-semantic, then
54/// the array will not retain all of its value-semantic qualities. In
55/// particular, if a value type cannot be tested for equality, then an `array`
56/// containing objects of that type will fail to compile the equality comparison
57/// operator. Similarly, if an `array` is instantiated with a type that does
58/// not have a copy-constructor, then the `array` will not be copyable.
59///
60/// An array meets most the requirements of a container with random access
61/// iterators in the C++ standard [array]. The `array` implemented here follows
62/// the C++11 standard when compiled with a C++11 compiler and follows the C++03
63/// standard otherwise.
64///
65/// An array lacks certain requirements of a sequential container. Array lacks
66/// `insert`, `erase`, `emplace`, and `clear`, as these functions would require
67/// modifying the size of the array.
68///
69/// An array also meets the requirements of an aggregate. This means that an
70/// array has: no user-declared constructors, no private or protected non-static
71/// data members, no base classes, and no virtual functions. An array can be
72/// constructed using aggregate initialization. Refer to the section
73/// [del.init.aggr] in the C++ standard for more detailed information.
74///
75/// ## Operations {#bslstl_array-operations}
76///
77///
78/// This section describes the run-time complexity of operations on instances of
79/// `array`:
80/// @code
81/// Legend
82/// ------
83/// 'V' - (template parameter) 'VALUE_TYPE' of the array
84/// 'S' - (template parameter) 'SIZE' of the array
85/// 'a', 'b' - two distinct objects of type 'array<V, S>'
86/// 'k' - non-negative integer
87/// 'vt1', 'vt2', 'vt3' - objects of type 'VALUE_TYPE'
88///
89/// |-----------------------------------------+-------------------------------|
90/// | Operation | Complexity |
91/// |=========================================+===============================|
92/// | array<V> a (default construction) | O[1] |
93/// |-----------------------------------------+-------------------------------|
94/// | array<V> a(b) (copy construction) | O[S] |
95/// |-----------------------------------------+-------------------------------|
96/// | array<V> a = {{vt1, vt2, vt3}} | O[S] |
97/// | array<V> a = {vt1, vt2, vt3} | |
98/// | (aggregate initialization)| |
99/// |-----------------------------------------+-------------------------------|
100/// | a.~array<V>() (destruction) | O[S] |
101/// |-----------------------------------------+-------------------------------|
102/// | a.begin(), a.end(), | O[1] |
103/// | a.cbegin(), a.cend(), | |
104/// | a.rbegin(), a.rend(), | |
105/// | a.crbegin(), a.crend() | |
106/// |-----------------------------------------+-------------------------------|
107/// | a.size() | O[1] |
108/// |-----------------------------------------+-------------------------------|
109/// | a.max_size() | O[1] |
110/// |-----------------------------------------+-------------------------------|
111/// | a.empty() | O[1] |
112/// |-----------------------------------------+-------------------------------|
113/// | a[k] | O[1] |
114/// |-----------------------------------------+-------------------------------|
115/// | a.at(k) | O[1] |
116/// |-----------------------------------------+-------------------------------|
117/// | a.front() | O[1] |
118/// |-----------------------------------------+-------------------------------|
119/// | a.back() | O[1] |
120/// |-----------------------------------------+-------------------------------|
121/// | a.swap(b), swap(a,b) | O[S] |
122/// |-----------------------------------------+-------------------------------|
123/// | a = b; (copy assignment) | O[S] |
124/// |-----------------------------------------+-------------------------------|
125/// | a == b, a != b | O[S] |
126/// |-----------------------------------------+-------------------------------|
127/// | a < b, a <= b, a > b, a >= b | O[S] |
128/// |-----------------------------------------+-------------------------------|
129/// @endcode
130///
131/// ## Comparing an array of floating point values {#bslstl_array-comparing-an-array-of-floating-point-values}
132///
133///
134/// The comparison operator performs a bit-wise comparison for floating point
135/// types (`float` and `double`), which produces results for NaN, +0, and -0
136/// values that do not meet the guarantees provided by the standard.
137/// The `bslmf::IsBitwiseEqualityComparable` trait for `double` and `float`
138/// types returns `true` which is incorrect because a comparison with a NaN
139/// value is always `false`, and -0 and +0 are equal.
140/// @code
141/// bsl::array<double, 1> a{bsl::numeric_limits<double>::quiet_NaN()};
142/// ASSERT(a == a); // This assertion will *NOT* fail!
143/// @endcode
144/// Addressing this issue, i.e., updating `bslmf::IsBitwiseEqualityComparable`
145/// to return `false` for floating point types, could potentially destabilize
146/// production software so the change (for the moment) has not been made.
147///
148/// ## Usage {#bslstl_array-usage}
149///
150///
151/// In this section we show intended use of this component.
152///
153/// ### Example 1: Returning an array from a function {#bslstl_array-example-1-returning-an-array-from-a-function}
154///
155///
156/// Suppose we want to define a function that will return an array of `float`s.
157/// If a raw array were used, the size would need to be tracked separately
158/// because raw arrays decay to pointers when passed as function arguments, or
159/// returned by-value. `bsl::array` does not decay, and so provides a simple
160/// solution to this problem.
161/// @code
162/// typedef bsl::array<float, 3> Point;
163///
164/// Point createPoint(float f1, float f2, float f3)
165/// {
166/// bsl::array<float, 3> ret = {f1, f2, f3};
167/// return ret;
168/// }
169/// @endcode
170/// Create a bsl::array object containing three values set to the specified
171/// `f1`, `f2`, `f3`.
172/// @code
173/// void usageExample()
174/// {
175/// Point p1 = createPoint(1.0, 1.0, 1.0);
176/// Point p2 = createPoint(2.0, 2.0, 2.0);
177/// Point p3 = createPoint(3.0, 3.0, 3.0);
178///
179/// bsl::array<Point, 3> points = {p1, p2, p3};
180///
181/// for(size_t i = 0; i < points.size(); ++i) {
182/// for(size_t j = 0; j < points[i].size(); ++j) {
183/// points[i][j] *= 2.0f;
184/// }
185/// }
186/// }
187/// @endcode
188/// Use the createPoint function to generate three arrays of floats. The arrays
189/// are returned by copy and the `size()` member function is used to access the
190/// size of the arrays that could not be done with a raw array.
191/// @}
192/** @} */
193/** @} */
194
195/** @addtogroup bsl
196 * @{
197 */
198/** @addtogroup bslstl
199 * @{
200 */
201/** @addtogroup bslstl_array
202 * @{
203 */
204
205#include <bslscm_version.h>
206
207#include <bslstl_algorithm.h>
208#include <bslstl_iterator.h>
209#include <bslstl_stdexceptutil.h>
210
212#include <bslalg_rangecompare.h>
215
216#include <bslh_hash.h>
217
218#include <bslma_default.h>
219
220#include <bslmf_assert.h>
221#include <bslmf_enableif.h>
223#include <bslmf_issame.h>
224#include <bslmf_movableref.h>
225#include <bslmf_removecv.h>
226
227#include <bsls_assert.h>
229#include <bsls_keyword.h>
230#include <bsls_libraryfeatures.h>
231#include <bsls_platform.h>
232
233#include <stddef.h>
234
235#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE)
236# include <tuple> // 'std::tuple_size' etc.
237#endif
238
239#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY)
240#include <utility> // std::swap (C++11)
241#else
242#include <algorithm> // std::swap (C++03)
243#endif
244
245#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
246#include <bsls_nativestd.h>
247#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
248
249#if defined (BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY) && \
250 !(defined(BSLS_LIBRARYFEATURES_FORCE_ABI_ENABLED) && \
251 (BSLS_LIBRARYFEATURES_FORCE_ABI_ENABLED < 17))
252
253#include <array> // 'std::array'
254#include <tuple> // 'std::get'
255
256namespace bsl {
257using std::array;
258using std::get;
259} // close namespace bsl
260
261#define BSLSTL_ARRAY_IS_ALIASED
262#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY && not disabled
263
264#ifndef BSLSTL_ARRAY_IS_ALIASED
265
266// DEFECT DETECTION MACROS
267
268#if defined(BSLS_COMPILERFEATURES_SUPPORT_CONSTEXPR_CPP14) \
269 && defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION < 60000
270// gcc 5.4 (and earlier) does not allow non-`constexpr` code in a relaxed
271// `constexpr` function, such as a `BSLS_ASSERT` macro. As use of such code in
272// this component is limited to function templates, the effect is to silently
273// disable the `constexpr`-ness of those functions, which parse correctly and
274// evaluate as expected at run-time, but fail to compile in a constant
275// evaluation context. In order to support C++14 standard conformance, we
276// choose to disable our BDE contract checks on platforms affected by this
277// compiler bug.
278# define BSLSTL_ARRAY_DISABLE_CONSTEXPR_CONTRACTS 1
279#endif
280
281namespace bsl {
282 // ===========
283 // class array
284 // ===========
285
286/// This class template provides a standard conforming implementation of
287/// `std::array`. `array` is an aggregate wrapper around a raw array,
288/// supporting aggregate initialization and an iterator interface as
289/// required for a standard container.
290///
291/// See @ref bslstl_array
292template <class VALUE_TYPE, size_t SIZE>
293struct array {
294
295// BDE_VERIFY pragma: push
296// BDE_VERIFY pragma: -KS02 // Tag implicitly requires private declaration
297
298 // DATA
299 VALUE_TYPE d_data[(0 == SIZE) ? 1 : SIZE];
300
301// BDE_VERIFY pragma: pop
302
303 // PUBLIC TYPES
304 typedef VALUE_TYPE value_type;
305 typedef VALUE_TYPE *pointer;
306 typedef const VALUE_TYPE *const_pointer;
307 typedef VALUE_TYPE& reference;
308 typedef const VALUE_TYPE& const_reference;
309 typedef size_t size_type;
310 typedef ptrdiff_t difference_type;
313 typedef bsl::reverse_iterator<iterator> reverse_iterator;
314 typedef bsl::reverse_iterator<const_iterator> const_reverse_iterator;
315
316 // CREATORS
317
318 /// Create an `array` object. Every element is default constructed if
319 /// `VALUE_TYPE` is default constructible; otherwise, `array` is not
320 /// default constructible.
321 array() = default;
322
323 /// Create an `array` object having the same value as the specified
324 /// `original` object. Every element is copy constructed from the
325 /// corresponding element in the specified `original` if `VALUE_TYPE` is
326 /// copy constructible; otherwise, `array` is not copy constructible.
327 /// Only in C++11 and later.
328 array(const array& original) = default;
329
330 /// Create an `array` object having the same value as the specified
331 /// `original` object. Every element is move constructed from the
332 /// corresponding element in the specified `original` if `VALUE_TYPE` is
333 /// move constructible; otherwise, `array` is not move constructible.
334 array(array&& original) = default;
335
336 /// Destroy this object. Evert element is destroyed if `VALUE_TYPE` is
337 /// destructible; otherwise, array is not destructible.
338 ~array() = default;
339
340 // MANIPULATORS
341
342 /// Set every element in this array to the specified `value` using the
343 /// `operator=` of `value_type`.
344 void fill(const VALUE_TYPE& value);
345
346 /// Exchange each corresponding element between this array and the
347 /// specified `rhs` array by calling `swap(a,b)` where `swap` is found
348 /// by overload resolution including at least the namespaces `std` and
349 /// the associated namespaces of `VALUE_TYPE`.
351 bsl::is_nothrow_swappable<VALUE_TYPE>::value);
352
353 /// Return an iterator providing modifiable access to the first element
354 /// in this array; return a past-the-end iterator if this array has size
355 /// 0.
358
359 /// Return a past-the-end iterator providing modifiable access to this
360 /// array.
363
364 /// Return a reverse iterator providing modifiable access to the last
365 /// element in this array; return a past-the-end iterator if this array
366 /// has size 0.
369
370 /// Return the past-the-end reverse iterator providing modifiable access
371 /// to this array.
374
375 /// Return a reference providing modifiable access to the element at the
376 /// specified `position` in this array.
377 ///
378 /// \pre The behavior is undefined unless `position < size()`.
380 reference operator[](size_type position);
381
382 /// Return a reference to the element at the specified `position` in
383 /// this array. Throw an @ref out_of_range exception if
384 /// `position >= size()`.
387
388 /// Return a reference to the first element in this array.
389 ///
390 /// \pre The behavior is undefined unless `SIZE > 0`.
393
394 /// Return a reference to the last element in this array.
395 ///
396 /// \pre The behavior is undefined unless `SIZE > 0`.
399
400 /// Return the address of the first element of the underlying raw array.
401 /// Return a valid `T*` which cannot be dereferenced if the `SIZE` is 0.
404
405 /// Sets every element in this array to the corresponding element in the
406 /// specified `other` if `VALUE_TYPE` is copy assignable; otherwise,
407 /// `array` is not copy assignable.
408 array& operator=(const array& other);
409
410 /// Moves every element in the specified `other` into the corresponding
411 /// element in this array in the if `VALUE_TYPE` is moves assignable;
412 /// otherwise, `array` is not move assignable.
413 array& operator=(array&& other);
414
415 // BDE_VERIFY pragma: -FABC01 // Function not in alphanumeric order
416
417 // ACCESSORS
418
419 /// Return an iterator providing non-modifiable access to the first
420 /// element in this array; return a past-the-end iterator if this array
421 /// has size 0.
426
427 /// Return a past-the-end iterator providing non-modifiable access to
428 /// this array.
433
434 /// Return a reverse iterator providing non-modifiable access to the
435 /// last element in this array, and the past-the-end reverse iterator if
436 /// this array has size 0.
441
442 /// Return the past-the-end reverse iterator providing non-modifiable
443 /// access to this `array`.
448
449 /// Return `true` if the array has size 0, and `false` otherwise.
451
452 /// Return the number of elements in this array.
455
456 /// Return a reference providing non-modifiable access to the element at
457 /// the specified `position` in this array.
458 ///
459 /// \pre The behavior is undefined unless `position < size()`.
461 const_reference operator[](size_type position) const;
462
463 /// Return a reference providing non-modifiable access to the element at
464 /// the specified `position` in this array. Throw an @ref out_of_range
465 /// exception if `position >= size()`.
467 const_reference at(size_type position) const;
468
469 /// Return a reference providing non-modifiable access to the first element in this array.
470 ///
471 /// \pre The behavior is undefined unless `SIZE > 0`.
473
474 /// Return a reference providing non-modifiable access to the last
475 /// element in this array. Behavior is undefined unless `SIZE > 0`.
477
478 /// Return the address of the first element of the underlying raw array.
479 /// Return a valid `T*` which cannot be dereferenced if the `SIZE` is 0.
482};
483
484#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
485// CLASS TEMPLATE DEDUCTION GUIDES
486
487/// Deduce the specified types `VALUE_TYPE` and `SIZE` from the
488/// corresponding elements in the sequence supplied to the constructor of
489/// `array`. The type of the first element in the sequence is the type of
490/// the elements of the array, and the length of the sequence is the size of
491/// the array.
492template<class VALUE_TYPE,
493 class... OTHERS,
494 class = bsl::enable_if_t<(bsl::is_same_v<VALUE_TYPE, OTHERS> && ...)>
495 >
496array(VALUE_TYPE, OTHERS...) -> array<VALUE_TYPE, 1 + sizeof...(OTHERS)>;
497#endif
498
499// FREE OPERATORS
500
501/// Return `true` if the specified `lhs` has the same value as the specified
502/// `rhs`; return false otherwise. Two arrays have the same value if each
503/// element has the same value as the corresponding element in the other
504/// array.
505template <class VALUE_TYPE, size_t SIZE>
506bool operator==(const array<VALUE_TYPE, SIZE>& lhs,
508
509#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
510
511/// Return `true` if the specified `lhs` does not have the same value as the
512/// specified `rhs`; return false otherwise. Two arrays do not have the
513/// same value if some element in the ordered sequence of elements of `lhs`
514/// does not have the same value as the corresponding element in the ordered
515/// sequence of elements of `rhs`.
516template <class VALUE_TYPE, size_t SIZE>
517bool operator!=(const array<VALUE_TYPE, SIZE>& lhs,
519
520#endif // BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
521
522#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
523
524/// Perform a lexicographic three-way comparison of the specified `lhs` and
525/// the specified `rhs` arrays by using the comparison operators of
526/// `VALUE_TYPE` on each element; return the result of that comparison.
527template <class VALUE_TYPE, size_t SIZE>
528BloombergLP::bslalg::SynthThreeWayUtil::Result<VALUE_TYPE> operator<=>(
531
532#else
533
534/// Return `true` if the specified `lhs` is lexicographically less than the
535/// specified `rhs` by using the comparison operators of `VALUE_TYPE` on
536/// each element; return `false` otherwise.
537template <class VALUE_TYPE, size_t SIZE>
538bool operator<(const array<VALUE_TYPE, SIZE>& lhs,
540
541/// Return `true` if the specified `lhs` is lexicographically greater than
542/// the specified `rhs` by using the comparison operators of `VALUE_TYPE` on
543/// each element; return `false` otherwise.
544template <class VALUE_TYPE, size_t SIZE>
545bool operator>(const array<VALUE_TYPE, SIZE>& lhs,
547
548/// Return `true` if the specified `lhs` is lexicographically less than the
549/// specified `rhs` by using the comparison operators of `VALUE_TYPE` on
550/// each element or if `lhs` and `rhs` are equal; return `false` otherwise.
551template <class VALUE_TYPE, size_t SIZE>
552bool operator<=(const array<VALUE_TYPE, SIZE>& lhs,
554
555/// Return `true` if the specified `lhs` is lexicographically greater than
556/// the specified `rhs` by using the comparison operators of `VALUE_TYPE` on
557/// each element or if `lhs` and `rhs` are equal; return `false` otherwise.
558template <class VALUE_TYPE, size_t SIZE>
559bool operator>=(const array<VALUE_TYPE, SIZE>& lhs,
561
562#endif // BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
563
564// FREE FUNCTIONS
565
566/// Call `swap` using ADL on each element of the specified `lhs` with the
567/// corresponding element in the specified `rhs`.
568template <class VALUE_TYPE, size_t SIZE>
570
571/// Return a reference providing modifiable access to the element of the
572/// specified `a`, having the ordinal number specified by the (template
573/// parameter) `INDEX`. This function will not compile unless `INDEX < N`.
574template<size_t INDEX, class TYPE, size_t SIZE>
577
578/// Return a reference providing non-modifiable access to the element of the
579/// specified `a`, having the ordinal number specified by the (template
580/// parameter) `INDEX`. This function will not compile unless `INDEX < N`.
581template<size_t INDEX, class TYPE, size_t SIZE>
584
585#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
586/// Return an rvalue reference providing modifiable access to the element of
587/// the specified `a`, having the ordinal number specified by the (template
588/// parameter) `INDEX`. This function will not compile unless `INDEX < N`.
589template<size_t INDEX, class TYPE, size_t SIZE>
592
593/// Return an rvalue reference providing non-modifiable access to the
594/// element of the specified `a`, having the ordinal number specified by the
595/// (template parameter) `INDEX`. This function will not compile unless
596/// `INDEX < N`.
597template<size_t INDEX, class TYPE, size_t SIZE>
599const TYPE&& get(const array<TYPE, SIZE>&& a) BSLS_KEYWORD_NOEXCEPT;
600#endif // BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES
601
602// HASH SPECIALIZATIONS
603
604/// Pass the specified `input` to the specified `hashAlgorithm`
605template <class HASH_ALGORITHM, class TYPE, size_t SIZE>
606void hashAppend(HASH_ALGORITHM& hashAlgorithm, const array<TYPE, SIZE>& input);
607
608} // close namespace bsl
609
610#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE)
611
612namespace std {
613
614#if defined(BSLS_PLATFORM_CMP_CLANG)
615#pragma clang diagnostic push
616#pragma clang diagnostic ignored "-Wmismatched-tags"
617 // The native STL library headers for libstdc++ are internally inconsistent
618 // so it is not possible for this header to resolve this warning by picking
619 // either `struct` or `class` for the class introducer. We do not see this
620 // warning directly from the native libraries only because they are tagged
621 // as system headers, which implicitly silences all warnings.
622#endif
623
624 // ====================
625 // struct tuple_element
626 // ====================
627
628/// This partial specialization of @ref tuple_element provides compile-time
629/// access to the type of the array's elements.
630template<size_t INDEX, class TYPE, size_t SIZE>
631struct tuple_element<INDEX, bsl::array<TYPE, SIZE> >
632{
633
634 // STATIC CHECKS
635 BSLMF_ASSERT(INDEX < SIZE);
636
637 // TYPES
638 typedef TYPE type;
639};
640
641 // =================
642 // struct tuple_size
643 // =================
644
645/// This meta-function provides a compile-time way to obtain the number of
646/// elements in an array.
647template<class TYPE, size_t SIZE>
648struct tuple_size<bsl::array<TYPE, SIZE> > : integral_constant<size_t, SIZE>
649{
650};
651
652#if defined(BSLS_PLATFORM_CMP_CLANG)
653#pragma clang diagnostic pop
654#endif
655
656} // close namespace std
657
658#endif // BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE
659#endif // !BSLSTL_ARRAY_IS_ALIASED
660
661#ifdef BSLSTL_ARRAY_IS_ALIASED
662
663namespace bslh {
664
665// HASH SPECIALIZATIONS
666
667/// Pass the specified `input` to the specified `hashAlgorithm` hashing
668/// algorithm of the (template parameter) type `HASH_ALGORITHM`.
669///
670/// \note Note that this function violates the BDE coding standard, adding a function for a
671/// namespace for a different package, and none of the function parameters
672/// are from this package either. This is necessary in order to provide an
673/// implementation of `bslh::hashAppend` for the (native) standard library
674/// `array` type as we are not allowed to add overloads directly into
675/// namespace `std`, and this component essentially provides the interface
676/// between `bsl` and `std` array types.
677template <class HASH_ALGORITHM, class TYPE, size_t SIZE>
678void hashAppend(HASH_ALGORITHM& hashAlgorithm,
679 const std::array<TYPE, SIZE>& input);
680
681} // close namespace bslh
682
683
684#endif // BSLSTL_ARRAY_IS_ALIASED
685
686// ============================================================================
687// TEMPLATE AND INLINE FUNCTION DEFINITIONS
688// ============================================================================
689
690#ifndef BSLSTL_ARRAY_IS_ALIASED
691
692namespace bsl {
693 // -----------
694 // class array
695 // -----------
696
697// MANIPULATORS
698
699// suppress comparison of 'unsigned' expression is always false warnings
700#ifdef BSLS_PLATFORM_HAS_PRAGMA_GCC_DIAGNOSTIC
701#pragma GCC diagnostic push
702#pragma GCC diagnostic ignored "-Wtype-limits"
703#endif
704
705template <class VALUE_TYPE, size_t SIZE>
706void array<VALUE_TYPE, SIZE>::fill(const VALUE_TYPE& value)
707{
708 for (size_t i = 0; i < SIZE; ++i) {
709 d_data[i] = value;
710 }
711}
712
713template <class VALUE_TYPE, size_t SIZE>
716 bsl::is_nothrow_swappable<VALUE_TYPE>::value)
717{
718 for (size_t i = 0; i < SIZE; ++i) {
719 using std::swap;
720 swap(d_data[i], rhs.d_data[i]);
721 }
722}
723
724// suppress comparison of 'unsigned' expression is always false warnings
725#ifdef BSLS_PLATFORM_HAS_PRAGMA_GCC_DIAGNOSTIC
726#pragma GCC diagnostic pop
727#endif
728
729// ACCESSORS
730template <class VALUE_TYPE, size_t SIZE>
734{
735 return d_data;
736}
737
738template <class VALUE_TYPE, size_t SIZE>
742{
743 return d_data;
744}
745
746template <class VALUE_TYPE, size_t SIZE>
750{
751 return d_data + SIZE;
752}
753
754template <class VALUE_TYPE, size_t SIZE>
758{
759 return d_data + SIZE;
760}
761
762template <class VALUE_TYPE, size_t SIZE>
769
770template <class VALUE_TYPE, size_t SIZE>
777
778template <class VALUE_TYPE, size_t SIZE>
785
786template <class VALUE_TYPE, size_t SIZE>
793
794template <class VALUE_TYPE, size_t SIZE>
798{
799 return d_data;
800}
801
802template <class VALUE_TYPE, size_t SIZE>
806{
807 return d_data + SIZE;
808}
809
810template <class VALUE_TYPE, size_t SIZE>
817
818template <class VALUE_TYPE, size_t SIZE>
825
826template <class VALUE_TYPE, size_t SIZE>
829{
830 return SIZE == 0;
831}
832
833template <class VALUE_TYPE, size_t SIZE>
836{
837 return SIZE;
838}
839
840template <class VALUE_TYPE, size_t SIZE>
843{
844 return SIZE;
845}
846
847template <class VALUE_TYPE, size_t SIZE>
851{
852 BSLS_ASSERT(position < SIZE);
853 return d_data[position];
854}
855
856template <class VALUE_TYPE, size_t SIZE>
860{
861#if !defined(BSLSTL_ARRAY_DISABLE_CONSTEXPR_CONTRACTS)
862 BSLS_ASSERT(position < SIZE);
863#endif
864
865 return d_data[position];
866}
867
868template <class VALUE_TYPE, size_t SIZE>
871 size_type position)
872{
873 if (position >= SIZE) {
874 BloombergLP::bslstl::StdExceptUtil::throwOutOfRange(
875 "array<...>::at(position): invalid position");
876 }
877 return d_data[position];
878}
879
880template <class VALUE_TYPE, size_t SIZE>
884{
885 if (position >= SIZE) {
886 BloombergLP::bslstl::StdExceptUtil::throwOutOfRange(
887 "array<...>::at(position): invalid position");
888 }
889 return d_data[position];
890}
891
892template <class VALUE_TYPE, size_t SIZE>
896{
897 BSLS_ASSERT(SIZE > 0);
898 return d_data[0];
899}
900
901template <class VALUE_TYPE, size_t SIZE>
905{
906#if !defined(BSLSTL_ARRAY_DISABLE_CONSTEXPR_CONTRACTS)
907 BSLS_ASSERT(SIZE > 0);
908#endif
909
910 return d_data[0];
911}
912
913template <class VALUE_TYPE, size_t SIZE>
917{
918 BSLS_ASSERT(SIZE > 0);
919 return d_data[SIZE - 1];
920}
921
922template <class VALUE_TYPE, size_t SIZE>
926{
927#if !defined(BSLSTL_ARRAY_DISABLE_CONSTEXPR_CONTRACTS)
928 BSLS_ASSERT(SIZE > 0);
929#endif
930
931 return d_data[SIZE - 1];
932}
933
934template <class VALUE_TYPE, size_t SIZE>
941
942template <class VALUE_TYPE, size_t SIZE>
946{
947 return d_data;
948}
949
950// HASH SPECIALIZATIONS
951
952// suppress comparison of 'unsigned' expression is always false warnings
953#ifdef BSLS_PLATFORM_HAS_PRAGMA_GCC_DIAGNOSTIC
954#pragma GCC diagnostic push
955#pragma GCC diagnostic ignored "-Wtype-limits"
956#endif
957
958template <class HASH_ALGORITHM, class TYPE, size_t SIZE>
959void hashAppend(HASH_ALGORITHM& hashAlgorithm, const array<TYPE, SIZE>& input)
960{
961 using ::BloombergLP::bslh::hashAppend;
962
963 hashAppend(hashAlgorithm, SIZE);
964 for (size_t i = 0; i < SIZE; ++i)
965 {
966 hashAppend(hashAlgorithm, input[i]);
967 }
968}
969
970// suppress comparison of 'unsigned' expression is always false warnings
971#ifdef BSLS_PLATFORM_HAS_PRAGMA_GCC_DIAGNOSTIC
972#pragma GCC diagnostic pop
973#endif
974} // close namespace bsl
975
976// FREE OPERATORS
977template <class VALUE_TYPE, size_t SIZE>
978bool bsl::operator==(const array<VALUE_TYPE, SIZE>& lhs,
979 const array<VALUE_TYPE, SIZE>& rhs)
980{
981 return BloombergLP::bslalg::RangeCompare::equal(lhs.begin(),
982 lhs.end(),
983 lhs.size(),
984 rhs.begin(),
985 rhs.end(),
986 rhs.size());
987}
988
989#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
990
991template <class VALUE_TYPE, size_t SIZE>
992bool bsl::operator!=(const array<VALUE_TYPE, SIZE>& lhs,
993 const array<VALUE_TYPE, SIZE>& rhs)
994{
995 return !(lhs == rhs);
996}
997
998#endif // BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
999
1000#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
1001
1002template <class VALUE_TYPE, size_t SIZE>
1003BloombergLP::bslalg::SynthThreeWayUtil::Result<VALUE_TYPE> bsl::operator<=>(
1004 const array<VALUE_TYPE, SIZE>& lhs,
1005 const array<VALUE_TYPE, SIZE>& rhs)
1006{
1007 return bsl::lexicographical_compare_three_way(
1008 lhs.begin(),
1009 lhs.end(),
1010 rhs.begin(),
1011 rhs.end(),
1012 BloombergLP::bslalg::SynthThreeWayUtil::compare);
1013}
1014
1015#else
1016
1017template <class VALUE_TYPE, size_t SIZE>
1018bool bsl::operator<(const array<VALUE_TYPE, SIZE>& lhs,
1019 const array<VALUE_TYPE, SIZE>& rhs)
1020{
1021 return 0 > BloombergLP::bslalg::RangeCompare::lexicographical(lhs.begin(),
1022 lhs.end(),
1023 lhs.size(),
1024 rhs.begin(),
1025 rhs.end(),
1026 rhs.size());
1027}
1028
1029template <class VALUE_TYPE, size_t SIZE>
1030bool bsl::operator>(const array<VALUE_TYPE, SIZE>& lhs,
1031 const array<VALUE_TYPE, SIZE>& rhs)
1032{
1033 return rhs < lhs;
1034}
1035
1036template <class VALUE_TYPE, size_t SIZE>
1037bool bsl::operator<=(const array<VALUE_TYPE, SIZE>& lhs,
1038 const array<VALUE_TYPE, SIZE>& rhs)
1039{
1040 return !(rhs < lhs);
1041}
1042
1043template <class VALUE_TYPE, size_t SIZE>
1044bool bsl::operator>=(const array<VALUE_TYPE, SIZE>& lhs,
1045 const array<VALUE_TYPE, SIZE>& rhs)
1046{
1047 return !(lhs < rhs);
1048}
1049
1050#endif // BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
1051
1052// FREE FUNCTIONS
1053template <class VALUE_TYPE, size_t SIZE>
1054void bsl::swap(array<VALUE_TYPE, SIZE>& lhs, array<VALUE_TYPE, SIZE>& rhs)
1055{
1056 lhs.swap(rhs);
1057}
1058
1059template<size_t INDEX, class TYPE, size_t SIZE>
1061TYPE& bsl::get(array<TYPE, SIZE>& a) BSLS_KEYWORD_NOEXCEPT
1062{
1063 return a.d_data[INDEX];
1064}
1065
1066template<size_t INDEX, class TYPE, size_t SIZE>
1068const TYPE& bsl::get(const array<TYPE, SIZE>& a) BSLS_KEYWORD_NOEXCEPT
1069{
1070 return a.d_data[INDEX];
1071}
1072
1073#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
1074template<size_t INDEX, class TYPE, size_t SIZE>
1076TYPE&& bsl::get(array<TYPE, SIZE>&& a) BSLS_KEYWORD_NOEXCEPT
1077{
1078 return BloombergLP::bslmf::MovableRefUtil::move(a.d_data[INDEX]);
1079}
1080
1081template<size_t INDEX, class TYPE, size_t SIZE>
1083const TYPE&& bsl::get(const array<TYPE, SIZE>&& a) BSLS_KEYWORD_NOEXCEPT
1084{
1085 return BloombergLP::bslmf::MovableRefUtil::move(a.d_data[INDEX]);
1086}
1087#endif // BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES
1088
1089
1090#endif // !BSLSTL_ARRAY_IS_ALIASED
1091
1092#ifdef BSLSTL_ARRAY_IS_ALIASED
1093
1094namespace bslh {
1095
1096// HASH SPECIALIZATIONS
1097template <class HASH_ALGORITHM, class TYPE, size_t SIZE>
1098void hashAppend(HASH_ALGORITHM& hashAlgorithm,
1099 const std::array<TYPE, SIZE>& input)
1100{
1101 using ::BloombergLP::bslh::hashAppend;
1102
1103 hashAppend(hashAlgorithm, SIZE);
1104 if BSLS_KEYWORD_CONSTEXPR_CPP17 (SIZE > 0) {
1105 for (size_t i = 0; i < SIZE; ++i) {
1106 hashAppend(hashAlgorithm, input[i]);
1107 }
1108 }
1109}
1110
1111} // close namespace bslh
1112
1113
1114#endif // BSLSTL_ARRAY_IS_ALIASED
1115
1116#if defined(BSLSTL_ARRAY_IS_ALIASED) \
1117 && defined(BSLS_LIBRARYFEATURES_HAS_CPP20_BASELINE_LIBRARY)
1118namespace bsl {
1119using std::to_array;
1120} // close namespace bsl
1121#else
1122namespace bsl {
1123
1124// FREE FUNCTIONS
1125
1126/// Creates an `array` from the specified `src` one-dimensional built-in
1127/// array by copying the corresponding elements. The template parameter `TYPE` shall not itself be a built-in array.
1128///
1129/// \note Note that `TYPE` must
1130/// be `CopyConstructible` and, in C++ versions prior to C++14, must also
1131/// be `DefaultConstructible`.
1132template< class TYPE, std::size_t SIZE >
1135
1136#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
1137template< class TYPE, std::size_t SIZE >
1139array<typename remove_cv<TYPE>::type, SIZE> to_array( TYPE (&&src)[SIZE] );
1140 // Creates an 'array' from the specified 'src' one-dimensional built-in
1141 // array by moving the corresponding elements. The template parameter
1142 // 'TYPE' shall not itself be a built-in array. Note that 'TYPE' must
1143 // be 'MoveConstructible' and, in C++ versions prior to C++14, must also
1144 // be 'DefaultConstructible'.
1145
1146#endif // BSLSTL_ARRAY_IS_ALIASED &&
1147 // BSLS_LIBRARYFEATURES_HAS_CPP20_BASELINE_LIBRARY
1148
1149} // close namespace bsl
1150
1151// FREE FUNCTIONS
1152
1153#if defined(BSLS_COMPILERFEATURES_SUPPORT_VARIADIC_TEMPLATES) \
1154 && defined(BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES)
1155
1156namespace bslstl_to_array_impl {
1157
1158template <class TYPE, std::size_t SIZE, std::size_t... INDICES>
1159inline
1161to_array_lvalue_builder(TYPE (&src)[SIZE], std::index_sequence<INDICES...>)
1162 // This implementation detail function copy constructs a 'bsl::array' from
1163 // the specified 'src' argument.
1164{
1165 return {{src[INDICES]...}};
1166}
1167
1168template <class TYPE, std::size_t SIZE, std::size_t... INDICES>
1169inline
1171to_array_rvalue_builder(TYPE(&&src)[SIZE], std::index_sequence<INDICES...>)
1172 // This implementation detail function move constructs a 'bsl::array' from
1173 // the specified 'src' argument.
1174{
1175 return {{std::move(src[INDICES])...}};
1176}
1177
1178} // close namespace bslstl_to_array_impl
1179
1180
1181template <class TYPE, std::size_t SIZE>
1182inline
1185bsl::to_array(TYPE (&src)[SIZE])
1186{
1189
1190 return BloombergLP::bslstl_to_array_impl::to_array_lvalue_builder(
1191 src,
1192 std::make_index_sequence<SIZE>());
1193}
1194
1195template <class TYPE, std::size_t SIZE>
1196inline
1199bsl::to_array(TYPE (&&src)[SIZE])
1200{
1202 BSLMF_ASSERT(std::is_move_constructible<TYPE>::value);
1203
1204 return BloombergLP::bslstl_to_array_impl::to_array_rvalue_builder(
1205 std::move(src),
1206 std::make_index_sequence<SIZE>());
1207}
1208
1209#else // ! ..._SUPPORT_{VARIADIC,VARIABLE}_TEMPLATES
1210
1211template <class TYPE, std::size_t SIZE>
1214bsl::to_array(TYPE (&src)[SIZE])
1215{
1218
1219 array<typename remove_cv<TYPE>::type, SIZE> result;
1220
1221 for (std::size_t i = 0; i < SIZE; ++i) {
1222 result[i] = src[i];
1223 }
1224
1225 return result;
1226}
1227
1228#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
1229template <class TYPE, std::size_t SIZE>
1232bsl::to_array(TYPE(&&src)[SIZE])
1233{
1235 BSLMF_ASSERT(std::is_move_constructible<TYPE>::value);
1236
1237 array<typename remove_cv<TYPE>::type, SIZE> result;
1238
1239 for (std::size_t i = 0; i < SIZE; ++i) {
1240 result[i] = std::move(src[i]);
1241 }
1242
1243 return result;
1244}
1245#endif // BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES
1246
1247
1248#endif // BSLS_COMPILERFEATURES_SUPPORT_VARIADIC_TEMPLATES
1249 // && BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES
1250
1251
1252#endif
1253// ============================================================================
1254// TYPE TRAITS
1255// ============================================================================
1256
1257
1258
1259namespace bslalg {
1260
1261template <class TYPE, size_t SIZE>
1262struct HasStlIterators<bsl::array<TYPE, SIZE> >
1264{};
1265
1266} // close namespace bslalg
1267
1268
1269
1270#endif
1271
1272// ----------------------------------------------------------------------------
1273// Copyright 2019 Bloomberg Finance L.P.
1274//
1275// Licensed under the Apache License, Version 2.0 (the "License");
1276// you may not use this file except in compliance with the License.
1277// You may obtain a copy of the License at
1278//
1279// http://www.apache.org/licenses/LICENSE-2.0
1280//
1281// Unless required by applicable law or agreed to in writing, software
1282// distributed under the License is distributed on an "AS IS" BASIS,
1283// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1284// See the License for the specific language governing permissions and
1285// limitations under the License.
1286// ----------------------------- END-OF-FILE ----------------------------------
1287
1288/** @} */
1289/** @} */
1290/** @} */
Definition bdlb_pcgrandomgenerator.h:242
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:231
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_CONSTEXPR_CPP14
Definition bsls_keyword.h:631
#define BSLS_KEYWORD_CONSTEXPR_CPP17
Definition bsls_keyword.h:639
#define BSLS_KEYWORD_CONSTEXPR
Definition bsls_keyword.h:624
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:674
#define BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...)
Definition bsls_keyword.h:676
void hashAppend(HASH_ALGORITHM &hashAlgorithm, const BigEndianInt16 &object)
Definition bdlat_valuetypefunctions.h:939
void swap(array< VALUE_TYPE, SIZE > &lhs, array< VALUE_TYPE, SIZE > &rhs)
bool operator<(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
void hashAppend(HASH_ALGORITHM &hashAlgorithm, const array< TYPE, SIZE > &input)
Pass the specified input to the specified hashAlgorithm
Definition bslstl_array.h:959
bool operator>(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
BSLS_KEYWORD_CONSTEXPR_CPP14 TYPE & get(array< TYPE, SIZE > &a) BSLS_KEYWORD_NOEXCEPT
bool operator>=(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
bool operator<=(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
bool operator==(const memory_resource &a, const memory_resource &b)
ALLOCATOR & lhs
Definition bslstl_string.h:3917
BSLS_KEYWORD_CONSTEXPR_CPP14 array< typename remove_cv< TYPE >::type, SIZE > to_array(TYPE(&src)[SIZE])
bool operator!=(const memory_resource &a, const memory_resource &b)
Definition bdlc_flathashmap.h:2218
Definition bslh_defaulthashalgorithm.h:339
Definition bdldfp_decimal.h:5549
Definition bslstl_array.h:293
BSLS_KEYWORD_CONSTEXPR_CPP14 reference front()
Definition bslstl_array.h:895
size_t size_type
Definition bslstl_array.h:309
void fill(const VALUE_TYPE &value)
Definition bslstl_array.h:706
BSLS_KEYWORD_CONSTEXPR size_type max_size() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_array.h:842
VALUE_TYPE d_data[(0==SIZE) ? 1 :SIZE]
Definition bslstl_array.h:299
BSLS_KEYWORD_CONSTEXPR_CPP14 pointer data() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_array.h:937
bsl::reverse_iterator< iterator > reverse_iterator
Definition bslstl_array.h:313
BSLS_KEYWORD_CONSTEXPR_CPP14 const_iterator cend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_array.h:805
VALUE_TYPE * pointer
Definition bslstl_array.h:305
array(const array &original)=default
array(array &&original)=default
const VALUE_TYPE & const_reference
Definition bslstl_array.h:308
VALUE_TYPE value_type
Definition bslstl_array.h:304
BSLS_KEYWORD_CONSTEXPR_CPP17 const_reverse_iterator crend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_array.h:821
ptrdiff_t difference_type
Definition bslstl_array.h:310
BSLS_KEYWORD_CONSTEXPR_CPP14 reference back()
Definition bslstl_array.h:916
BSLS_KEYWORD_CONSTEXPR_CPP14 iterator end() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_array.h:749
BSLS_KEYWORD_CONSTEXPR_CPP17 reverse_iterator rend() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_array.h:781
BSLS_KEYWORD_CONSTEXPR_CPP14 reference operator[](size_type position)
Definition bslstl_array.h:850
BSLS_KEYWORD_CONSTEXPR bool empty() const BSLS_KEYWORD_NOEXCEPT
Return true if the array has size 0, and false otherwise.
Definition bslstl_array.h:828
bsl::reverse_iterator< const_iterator > const_reverse_iterator
Definition bslstl_array.h:314
BSLS_KEYWORD_CONSTEXPR_CPP17 reverse_iterator rbegin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_array.h:765
~array()=default
void swap(array &rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(bsl BSLS_KEYWORD_CONSTEXPR_CPP14 iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_array.h:357
const VALUE_TYPE * const_pointer
Definition bslstl_array.h:306
VALUE_TYPE & reference
Definition bslstl_array.h:307
BSLS_KEYWORD_CONSTEXPR_CPP14 reference at(size_type position)
Definition bslstl_array.h:870
BSLS_KEYWORD_CONSTEXPR_CPP17 const_reverse_iterator crbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_array.h:813
const_pointer const_iterator
Definition bslstl_array.h:312
array()=default
pointer iterator
Definition bslstl_array.h:311
BSLS_KEYWORD_CONSTEXPR size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this array.
Definition bslstl_array.h:835
BSLS_KEYWORD_CONSTEXPR_CPP14 const_iterator cbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_array.h:797
Definition bslmf_isarray.h:168
Definition bslmf_iscopyconstructible.h:242
Definition bslalg_hasstliterators.h:99