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