libstdc++
valarray
Go to the documentation of this file.
1 // The template and inlines for the -*- C++ -*- valarray class.
2 
3 // Copyright (C) 1997-2025 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file include/valarray
26  * This is a Standard C++ Library header.
27  */
28 
29 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
30 
31 #ifndef _GLIBCXX_VALARRAY
32 #define _GLIBCXX_VALARRAY 1
33 
34 #ifdef _GLIBCXX_SYSHDR
35 #pragma GCC system_header
36 #endif
37 
38 #include <bits/requires_hosted.h> // <cmath> dependant
39 
40 #include <bits/c++config.h>
41 #include <cmath>
42 #include <algorithm>
43 #include <debug/debug.h>
44 #if __cplusplus >= 201103L
45 #include <initializer_list>
46 #endif
47 
48 namespace std _GLIBCXX_VISIBILITY(default)
49 {
50 _GLIBCXX_BEGIN_NAMESPACE_VERSION
51 
52  template<class _Clos, typename _Tp>
53  class _Expr;
54 
55  template<typename _Tp1, typename _Tp2>
56  class _ValArray;
57 
58 namespace __detail
59 {
60  template<class _Oper, template<class, class> class _Meta, class _Dom>
61  struct _UnClos;
62 
63  template<class _Oper,
64  template<class, class> class _Meta1,
65  template<class, class> class _Meta2,
66  class _Dom1, class _Dom2>
67  struct _BinClos;
68 
69  template<template<class, class> class _Meta, class _Dom>
70  struct _SClos;
71 
72  template<template<class, class> class _Meta, class _Dom>
73  struct _GClos;
74 
75  template<template<class, class> class _Meta, class _Dom>
76  struct _IClos;
77 
78  template<template<class, class> class _Meta, class _Dom>
79  struct _ValFunClos;
80 
81  template<template<class, class> class _Meta, class _Dom>
82  struct _RefFunClos;
83 } // namespace __detail
84 
85  using __detail::_UnClos;
86  using __detail::_BinClos;
87  using __detail::_SClos;
88  using __detail::_GClos;
89  using __detail::_IClos;
90  using __detail::_ValFunClos;
91  using __detail::_RefFunClos;
92 
93  template<class _Tp> class valarray; // An array of type _Tp
94  class slice; // BLAS-like slice out of an array
95  template<class _Tp> class slice_array;
96  class gslice; // generalized slice out of an array
97  template<class _Tp> class gslice_array;
98  template<class _Tp> class mask_array; // masked array
99  template<class _Tp> class indirect_array; // indirected array
100 
101 _GLIBCXX_END_NAMESPACE_VERSION
102 } // namespace
103 
104 #include <bits/valarray_array.h>
105 #include <bits/valarray_before.h>
106 
107 namespace std _GLIBCXX_VISIBILITY(default)
108 {
109 _GLIBCXX_BEGIN_NAMESPACE_VERSION
110 
111  /**
112  * @defgroup numeric_arrays Numeric Arrays
113  * @ingroup numerics
114  *
115  * Classes and functions for representing and manipulating arrays of elements.
116  * @{
117  */
118 
119  /**
120  * @brief Smart array designed to support numeric processing.
121  *
122  * A valarray is an array that provides constraints intended to allow for
123  * effective optimization of numeric array processing by reducing the
124  * aliasing that can result from pointer representations. It represents a
125  * one-dimensional array from which different multidimensional subsets can
126  * be accessed and modified.
127  *
128  * @tparam _Tp Type of object in the array.
129  */
130  template<class _Tp>
131  class valarray
132  {
133  template<class _Op>
134  struct _UnaryOp
135  {
136  typedef typename __fun<_Op, _Tp>::result_type __rt;
137  typedef _Expr<_UnClos<_Op, _ValArray, _Tp>, __rt> _Rt;
138  };
139  public:
140  typedef _Tp value_type;
141 
142  // _lib.valarray.cons_ construct/destroy:
143  /// Construct an empty array.
144  valarray() _GLIBCXX_NOTHROW;
145 
146  /// Construct an array with @a n elements.
147  explicit valarray(size_t);
148 
149  /// Construct an array with @a n elements initialized to @a t.
150  valarray(const _Tp&, size_t);
151 
152  /// Construct an array initialized to the first @a n elements of @a t.
153  valarray(const _Tp* __restrict__, size_t);
154 
155  /// Copy constructor.
156  valarray(const valarray&);
157 
158 #if __cplusplus >= 201103L
159  /// Move constructor.
160  valarray(valarray&&) noexcept;
161 #endif
162 
163  /// Construct an array with the same size and values in @a sa.
164  valarray(const slice_array<_Tp>&);
165 
166  /// Construct an array with the same size and values in @a ga.
167  valarray(const gslice_array<_Tp>&);
168 
169  /// Construct an array with the same size and values in @a ma.
170  valarray(const mask_array<_Tp>&);
171 
172  /// Construct an array with the same size and values in @a ia.
173  valarray(const indirect_array<_Tp>&);
174 
175 #if __cplusplus >= 201103L
176  /// Construct an array with an initializer_list of values.
177  valarray(initializer_list<_Tp>);
178 #endif
179 
180  template<class _Dom>
181  valarray(const _Expr<_Dom, _Tp>& __e);
182 
183  ~valarray() _GLIBCXX_NOEXCEPT;
184 
185  // _lib.valarray.assign_ assignment:
186  /**
187  * @brief Assign elements to an array.
188  *
189  * Assign elements of array to values in @a v.
190  *
191  * @param __v Valarray to get values from.
192  */
193  valarray<_Tp>& operator=(const valarray<_Tp>& __v);
194 
195 #if __cplusplus >= 201103L
196  /**
197  * @brief Move assign elements to an array.
198  *
199  * Move assign elements of array to values in @a v.
200  *
201  * @param __v Valarray to get values from.
202  */
203  valarray<_Tp>& operator=(valarray<_Tp>&& __v) noexcept;
204 #endif
205 
206  /**
207  * @brief Assign elements to a value.
208  *
209  * Assign all elements of array to @a t.
210  *
211  * @param __t Value for elements.
212  */
213  valarray<_Tp>& operator=(const _Tp& __t);
214 
215  /**
216  * @brief Assign elements to an array subset.
217  *
218  * Assign elements of array to values in @a sa. Results are undefined
219  * if @a sa does not have the same size as this array.
220  *
221  * @param __sa Array slice to get values from.
222  */
223  valarray<_Tp>& operator=(const slice_array<_Tp>& __sa);
224 
225  /**
226  * @brief Assign elements to an array subset.
227  *
228  * Assign elements of array to values in @a ga. Results are undefined
229  * if @a ga does not have the same size as this array.
230  *
231  * @param __ga Array slice to get values from.
232  */
233  valarray<_Tp>& operator=(const gslice_array<_Tp>& __ga);
234 
235  /**
236  * @brief Assign elements to an array subset.
237  *
238  * Assign elements of array to values in @a ma. Results are undefined
239  * if @a ma does not have the same size as this array.
240  *
241  * @param __ma Array slice to get values from.
242  */
243  valarray<_Tp>& operator=(const mask_array<_Tp>& __ma);
244 
245  /**
246  * @brief Assign elements to an array subset.
247  *
248  * Assign elements of array to values in @a ia. Results are undefined
249  * if @a ia does not have the same size as this array.
250  *
251  * @param __ia Array slice to get values from.
252  */
253  valarray<_Tp>& operator=(const indirect_array<_Tp>& __ia);
254 
255 #if __cplusplus >= 201103L
256  /**
257  * @brief Assign elements to an initializer_list.
258  *
259  * Assign elements of array to values in @a __l. Results are undefined
260  * if @a __l does not have the same size as this array.
261  *
262  * @param __l initializer_list to get values from.
263  */
264  valarray& operator=(initializer_list<_Tp> __l);
265 #endif
266 
267  template<class _Dom> valarray<_Tp>&
268  operator= (const _Expr<_Dom, _Tp>&);
269 
270  // _lib.valarray.access_ element access:
271  /**
272  * Return a reference to the i'th array element.
273  *
274  * @param __i Index of element to return.
275  * @return Reference to the i'th element.
276  */
277  _Tp& operator[](size_t __i) _GLIBCXX_NOTHROW;
278 
279  // _GLIBCXX_RESOLVE_LIB_DEFECTS
280  // 389. Const overload of valarray::operator[] returns by value.
281  const _Tp& operator[](size_t) const _GLIBCXX_NOTHROW;
282 
283  // _lib.valarray.sub_ subset operations:
284  /**
285  * @brief Return an array subset.
286  *
287  * Returns a new valarray containing the elements of the array
288  * indicated by the slice argument. The new valarray has the same size
289  * as the input slice. @see slice.
290  *
291  * @param __s The source slice.
292  * @return New valarray containing elements in @a __s.
293  */
294  _Expr<_SClos<_ValArray, _Tp>, _Tp> operator[](slice __s) const;
295 
296  /**
297  * @brief Return a reference to an array subset.
298  *
299  * Returns a new valarray containing the elements of the array
300  * indicated by the slice argument. The new valarray has the same size
301  * as the input slice. @see slice.
302  *
303  * @param __s The source slice.
304  * @return New valarray containing elements in @a __s.
305  */
306  slice_array<_Tp> operator[](slice __s);
307 
308  /**
309  * @brief Return an array subset.
310  *
311  * Returns a slice_array referencing the elements of the array
312  * indicated by the slice argument. @see gslice.
313  *
314  * @param __s The source slice.
315  * @return Slice_array referencing elements indicated by @a __s.
316  */
317  _Expr<_GClos<_ValArray, _Tp>, _Tp> operator[](const gslice& __s) const;
318 
319  /**
320  * @brief Return a reference to an array subset.
321  *
322  * Returns a new valarray containing the elements of the array
323  * indicated by the gslice argument. The new valarray has
324  * the same size as the input gslice. @see gslice.
325  *
326  * @param __s The source gslice.
327  * @return New valarray containing elements in @a __s.
328  */
329  gslice_array<_Tp> operator[](const gslice& __s);
330 
331  /**
332  * @brief Return an array subset.
333  *
334  * Returns a new valarray containing the elements of the array
335  * indicated by the argument. The input is a valarray of bool which
336  * represents a bitmask indicating which elements should be copied into
337  * the new valarray. Each element of the array is added to the return
338  * valarray if the corresponding element of the argument is true.
339  *
340  * @param __m The valarray bitmask.
341  * @return New valarray containing elements indicated by @a __m.
342  */
343  valarray<_Tp> operator[](const valarray<bool>& __m) const;
344 
345  /**
346  * @brief Return a reference to an array subset.
347  *
348  * Returns a new mask_array referencing the elements of the array
349  * indicated by the argument. The input is a valarray of bool which
350  * represents a bitmask indicating which elements are part of the
351  * subset. Elements of the array are part of the subset if the
352  * corresponding element of the argument is true.
353  *
354  * @param __m The valarray bitmask.
355  * @return New valarray containing elements indicated by @a __m.
356  */
357  mask_array<_Tp> operator[](const valarray<bool>& __m);
358 
359  /**
360  * @brief Return an array subset.
361  *
362  * Returns a new valarray containing the elements of the array
363  * indicated by the argument. The elements in the argument are
364  * interpreted as the indices of elements of this valarray to copy to
365  * the return valarray.
366  *
367  * @param __i The valarray element index list.
368  * @return New valarray containing elements in @a __s.
369  */
370  _Expr<_IClos<_ValArray, _Tp>, _Tp>
371  operator[](const valarray<size_t>& __i) const;
372 
373  /**
374  * @brief Return a reference to an array subset.
375  *
376  * Returns an indirect_array referencing the elements of the array
377  * indicated by the argument. The elements in the argument are
378  * interpreted as the indices of elements of this valarray to include
379  * in the subset. The returned indirect_array refers to these
380  * elements.
381  *
382  * @param __i The valarray element index list.
383  * @return Indirect_array referencing elements in @a __i.
384  */
385  indirect_array<_Tp> operator[](const valarray<size_t>& __i);
386 
387  // _lib.valarray.unary_ unary operators:
388  /// Return a new valarray by applying unary + to each element.
389  typename _UnaryOp<__unary_plus>::_Rt operator+() const;
390 
391  /// Return a new valarray by applying unary - to each element.
392  typename _UnaryOp<__negate>::_Rt operator-() const;
393 
394  /// Return a new valarray by applying unary ~ to each element.
395  typename _UnaryOp<__bitwise_not>::_Rt operator~() const;
396 
397  /// Return a new valarray by applying unary ! to each element.
398  typename _UnaryOp<__logical_not>::_Rt operator!() const;
399 
400  // _lib.valarray.cassign_ computed assignment:
401  /// Multiply each element of array by @a t.
402  valarray<_Tp>& operator*=(const _Tp&);
403 
404  /// Divide each element of array by @a t.
405  valarray<_Tp>& operator/=(const _Tp&);
406 
407  /// Set each element e of array to e % @a t.
408  valarray<_Tp>& operator%=(const _Tp&);
409 
410  /// Add @a t to each element of array.
411  valarray<_Tp>& operator+=(const _Tp&);
412 
413  /// Subtract @a t to each element of array.
414  valarray<_Tp>& operator-=(const _Tp&);
415 
416  /// Set each element e of array to e ^ @a t.
417  valarray<_Tp>& operator^=(const _Tp&);
418 
419  /// Set each element e of array to e & @a t.
420  valarray<_Tp>& operator&=(const _Tp&);
421 
422  /// Set each element e of array to e | @a t.
423  valarray<_Tp>& operator|=(const _Tp&);
424 
425  /// Left shift each element e of array by @a t bits.
426  valarray<_Tp>& operator<<=(const _Tp&);
427 
428  /// Right shift each element e of array by @a t bits.
429  valarray<_Tp>& operator>>=(const _Tp&);
430 
431  /// Multiply elements of array by corresponding elements of @a v.
432  valarray<_Tp>& operator*=(const valarray<_Tp>&);
433 
434  /// Divide elements of array by corresponding elements of @a v.
435  valarray<_Tp>& operator/=(const valarray<_Tp>&);
436 
437  /// Modulo elements of array by corresponding elements of @a v.
438  valarray<_Tp>& operator%=(const valarray<_Tp>&);
439 
440  /// Add corresponding elements of @a v to elements of array.
441  valarray<_Tp>& operator+=(const valarray<_Tp>&);
442 
443  /// Subtract corresponding elements of @a v from elements of array.
444  valarray<_Tp>& operator-=(const valarray<_Tp>&);
445 
446  /// Logical xor corresponding elements of @a v with elements of array.
447  valarray<_Tp>& operator^=(const valarray<_Tp>&);
448 
449  /// Logical or corresponding elements of @a v with elements of array.
450  valarray<_Tp>& operator|=(const valarray<_Tp>&);
451 
452  /// Logical and corresponding elements of @a v with elements of array.
453  valarray<_Tp>& operator&=(const valarray<_Tp>&);
454 
455  /// Left shift elements of array by corresponding elements of @a v.
456  valarray<_Tp>& operator<<=(const valarray<_Tp>&);
457 
458  /// Right shift elements of array by corresponding elements of @a v.
459  valarray<_Tp>& operator>>=(const valarray<_Tp>&);
460 
461  template<class _Dom>
462  valarray<_Tp>& operator*=(const _Expr<_Dom, _Tp>&);
463  template<class _Dom>
464  valarray<_Tp>& operator/=(const _Expr<_Dom, _Tp>&);
465  template<class _Dom>
466  valarray<_Tp>& operator%=(const _Expr<_Dom, _Tp>&);
467  template<class _Dom>
468  valarray<_Tp>& operator+=(const _Expr<_Dom, _Tp>&);
469  template<class _Dom>
470  valarray<_Tp>& operator-=(const _Expr<_Dom, _Tp>&);
471  template<class _Dom>
472  valarray<_Tp>& operator^=(const _Expr<_Dom, _Tp>&);
473  template<class _Dom>
474  valarray<_Tp>& operator|=(const _Expr<_Dom, _Tp>&);
475  template<class _Dom>
476  valarray<_Tp>& operator&=(const _Expr<_Dom, _Tp>&);
477  template<class _Dom>
478  valarray<_Tp>& operator<<=(const _Expr<_Dom, _Tp>&);
479  template<class _Dom>
480  valarray<_Tp>& operator>>=(const _Expr<_Dom, _Tp>&);
481 
482  // _lib.valarray.members_ member functions:
483 #if __cplusplus >= 201103L
484  /// Swap.
485  void swap(valarray<_Tp>& __v) noexcept;
486 #endif
487 
488  /// Return the number of elements in array.
489  size_t size() const;
490 
491  /**
492  * @brief Return the sum of all elements in the array.
493  *
494  * Accumulates the sum of all elements into a Tp using +=. The order
495  * of adding the elements is unspecified.
496  */
497  _Tp sum() const;
498 
499  /// Return the minimum element using operator<().
500  _Tp min() const;
501 
502  /// Return the maximum element using operator<().
503  _Tp max() const;
504 
505  /**
506  * @brief Return a shifted array.
507  *
508  * A new valarray is constructed as a copy of this array with elements
509  * in shifted positions. For an element with index i, the new position
510  * is i - n. The new valarray has the same size as the current one.
511  * New elements without a value are set to 0. Elements whose new
512  * position is outside the bounds of the array are discarded.
513  *
514  * Positive arguments shift toward index 0, discarding elements [0, n).
515  * Negative arguments discard elements from the top of the array.
516  *
517  * @param __n Number of element positions to shift.
518  * @return New valarray with elements in shifted positions.
519  */
520  valarray<_Tp> shift (int __n) const;
521 
522  /**
523  * @brief Return a rotated array.
524  *
525  * A new valarray is constructed as a copy of this array with elements
526  * in shifted positions. For an element with index i, the new position
527  * is (i - n) % size(). The new valarray has the same size as the
528  * current one. Elements that are shifted beyond the array bounds are
529  * shifted into the other end of the array. No elements are lost.
530  *
531  * Positive arguments shift toward index 0, wrapping around the top.
532  * Negative arguments shift towards the top, wrapping around to 0.
533  *
534  * @param __n Number of element positions to rotate.
535  * @return New valarray with elements in shifted positions.
536  */
537  valarray<_Tp> cshift(int __n) const;
538 
539  /**
540  * @brief Apply a function to the array.
541  *
542  * Returns a new valarray with elements assigned to the result of
543  * applying __func to the corresponding element of this array. The new
544  * array has the same size as this one.
545  *
546  * @param __func Function of Tp returning Tp to apply.
547  * @return New valarray with transformed elements.
548  */
549  _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> apply(_Tp __func(_Tp)) const;
550 
551  /**
552  * @brief Apply a function to the array.
553  *
554  * Returns a new valarray with elements assigned to the result of
555  * applying __func to the corresponding element of this array. The new
556  * array has the same size as this one.
557  *
558  * @param __func Function of const Tp& returning Tp to apply.
559  * @return New valarray with transformed elements.
560  */
561  _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> apply(_Tp __func(const _Tp&)) const;
562 
563  /**
564  * @brief Resize array.
565  *
566  * Resize this array to @a size and set all elements to @a c. All
567  * references and iterators are invalidated.
568  *
569  * @param __size New array size.
570  * @param __c New value for all elements.
571  */
572  void resize(size_t __size, _Tp __c = _Tp());
573 
574  private:
575  size_t _M_size;
576  _Tp* __restrict__ _M_data;
577 
578  friend struct _Array<_Tp>;
579  };
580 
581 #if __cpp_deduction_guides >= 201606
582  template<typename _Tp, size_t _Nm>
583  valarray(const _Tp(&)[_Nm], size_t) -> valarray<_Tp>;
584 #endif
585 
586  template<typename _Tp>
587  inline const _Tp&
588  valarray<_Tp>::operator[](size_t __i) const _GLIBCXX_NOTHROW
589  {
590  __glibcxx_requires_subscript(__i);
591  return _M_data[__i];
592  }
593 
594  template<typename _Tp>
595  inline _Tp&
596  valarray<_Tp>::operator[](size_t __i) _GLIBCXX_NOTHROW
597  {
598  __glibcxx_requires_subscript(__i);
599  return _M_data[__i];
600  }
601 
602  /// @} group numeric_arrays
603 
604 _GLIBCXX_END_NAMESPACE_VERSION
605 } // namespace
606 
607 #include <bits/valarray_after.h>
608 #include <bits/slice_array.h>
609 #include <bits/gslice.h>
610 #include <bits/gslice_array.h>
611 #include <bits/mask_array.h>
612 #include <bits/indirect_array.h>
613 
614 namespace std _GLIBCXX_VISIBILITY(default)
615 {
616 _GLIBCXX_BEGIN_NAMESPACE_VERSION
617 
618  /**
619  * @addtogroup numeric_arrays
620  * @{
621  */
622 
623  template<typename _Tp>
624  inline
625  valarray<_Tp>::valarray() _GLIBCXX_NOTHROW : _M_size(0), _M_data(0) {}
626 
627  template<typename _Tp>
628  inline
629  valarray<_Tp>::valarray(size_t __n)
630  : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
631  { std::__valarray_default_construct(_M_data, _M_data + __n); }
632 
633  template<typename _Tp>
634  inline
635  valarray<_Tp>::valarray(const _Tp& __t, size_t __n)
636  : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
637  { std::__valarray_fill_construct(_M_data, _M_data + __n, __t); }
638 
639  template<typename _Tp>
640  inline
641  valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n)
642  : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
643  {
644  __glibcxx_assert(__p != 0 || __n == 0);
645  std::__valarray_copy_construct(__p, __p + __n, _M_data);
646  }
647 
648  template<typename _Tp>
649  inline
650  valarray<_Tp>::valarray(const valarray<_Tp>& __v)
651  : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size))
652  { std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size,
653  _M_data); }
654 
655 #if __cplusplus >= 201103L
656  template<typename _Tp>
657  inline
658  valarray<_Tp>::valarray(valarray<_Tp>&& __v) noexcept
659  : _M_size(__v._M_size), _M_data(__v._M_data)
660  {
661  __v._M_size = 0;
662  __v._M_data = 0;
663  }
664 #endif
665 
666  template<typename _Tp>
667  inline
668  valarray<_Tp>::valarray(const slice_array<_Tp>& __sa)
669  : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz))
670  {
671  std::__valarray_copy_construct
672  (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data));
673  }
674 
675  template<typename _Tp>
676  inline
677  valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga)
678  : _M_size(__ga._M_index.size()),
679  _M_data(__valarray_get_storage<_Tp>(_M_size))
680  {
681  std::__valarray_copy_construct
682  (__ga._M_array, _Array<size_t>(__ga._M_index),
683  _Array<_Tp>(_M_data), _M_size);
684  }
685 
686  template<typename _Tp>
687  inline
688  valarray<_Tp>::valarray(const mask_array<_Tp>& __ma)
689  : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz))
690  {
691  std::__valarray_copy_construct
692  (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size);
693  }
694 
695  template<typename _Tp>
696  inline
697  valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia)
698  : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz))
699  {
700  std::__valarray_copy_construct
701  (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size);
702  }
703 
704 #if __cplusplus >= 201103L
705  template<typename _Tp>
706  inline
707  valarray<_Tp>::valarray(initializer_list<_Tp> __l)
708  : _M_size(__l.size()), _M_data(__valarray_get_storage<_Tp>(__l.size()))
709  { std::__valarray_copy_construct(__l.begin(), __l.end(), _M_data); }
710 #endif
711 
712  template<typename _Tp> template<class _Dom>
713  inline
714  valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e)
715  : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size))
716  { std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data)); }
717 
718  template<typename _Tp>
719  inline
720  valarray<_Tp>::~valarray() _GLIBCXX_NOEXCEPT
721  {
722  std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
723  std::__valarray_release_memory(_M_data);
724  }
725 
726  template<typename _Tp>
727  inline valarray<_Tp>&
728  valarray<_Tp>::operator=(const valarray<_Tp>& __v)
729  {
730  // _GLIBCXX_RESOLVE_LIB_DEFECTS
731  // 630. arrays of valarray.
732  if (_M_size == __v._M_size)
733  std::__valarray_copy(__v._M_data, _M_size, _M_data);
734  else
735  {
736  if (_M_data)
737  {
738  std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
739  std::__valarray_release_memory(_M_data);
740  }
741  _M_size = __v._M_size;
742  _M_data = __valarray_get_storage<_Tp>(_M_size);
743  std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size,
744  _M_data);
745  }
746  return *this;
747  }
748 
749 #if __cplusplus >= 201103L
750  template<typename _Tp>
751  inline valarray<_Tp>&
752  valarray<_Tp>::operator=(valarray<_Tp>&& __v) noexcept
753  {
754  if (_M_data)
755  {
756  std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
757  std::__valarray_release_memory(_M_data);
758  }
759  _M_size = __v._M_size;
760  _M_data = __v._M_data;
761  __v._M_size = 0;
762  __v._M_data = 0;
763  return *this;
764  }
765 
766  template<typename _Tp>
767  inline valarray<_Tp>&
768  valarray<_Tp>::operator=(initializer_list<_Tp> __l)
769  {
770  // _GLIBCXX_RESOLVE_LIB_DEFECTS
771  // 630. arrays of valarray.
772  if (_M_size == __l.size())
773  std::__valarray_copy(__l.begin(), __l.size(), _M_data);
774  else
775  {
776  if (_M_data)
777  {
778  std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
779  std::__valarray_release_memory(_M_data);
780  }
781  _M_size = __l.size();
782  _M_data = __valarray_get_storage<_Tp>(_M_size);
783  std::__valarray_copy_construct(__l.begin(), __l.begin() + _M_size,
784  _M_data);
785  }
786  return *this;
787  }
788 #endif
789 
790  template<typename _Tp>
791  inline valarray<_Tp>&
792  valarray<_Tp>::operator=(const _Tp& __t)
793  {
794  std::__valarray_fill(_M_data, _M_size, __t);
795  return *this;
796  }
797 
798  template<typename _Tp>
799  inline valarray<_Tp>&
800  valarray<_Tp>::operator=(const slice_array<_Tp>& __sa)
801  {
802  __glibcxx_assert(_M_size == __sa._M_sz);
803  std::__valarray_copy(__sa._M_array, __sa._M_sz,
804  __sa._M_stride, _Array<_Tp>(_M_data));
805  return *this;
806  }
807 
808  template<typename _Tp>
809  inline valarray<_Tp>&
810  valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga)
811  {
812  __glibcxx_assert(_M_size == __ga._M_index.size());
813  std::__valarray_copy(__ga._M_array, _Array<size_t>(__ga._M_index),
814  _Array<_Tp>(_M_data), _M_size);
815  return *this;
816  }
817 
818  template<typename _Tp>
819  inline valarray<_Tp>&
820  valarray<_Tp>::operator=(const mask_array<_Tp>& __ma)
821  {
822  __glibcxx_assert(_M_size == __ma._M_sz);
823  std::__valarray_copy(__ma._M_array, __ma._M_mask,
824  _Array<_Tp>(_M_data), _M_size);
825  return *this;
826  }
827 
828  template<typename _Tp>
829  inline valarray<_Tp>&
830  valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia)
831  {
832  __glibcxx_assert(_M_size == __ia._M_sz);
833  std::__valarray_copy(__ia._M_array, __ia._M_index,
834  _Array<_Tp>(_M_data), _M_size);
835  return *this;
836  }
837 
838  template<typename _Tp> template<class _Dom>
839  inline valarray<_Tp>&
840  valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e)
841  {
842  // _GLIBCXX_RESOLVE_LIB_DEFECTS
843  // 630. arrays of valarray.
844  if (_M_size == __e.size())
845  {
846  // Copy manually instead of using __valarray_copy, because __e might
847  // alias _M_data and the _Array param type of __valarray_copy uses
848  // restrict which doesn't allow aliasing.
849  for (size_t __i = 0; __i < _M_size; ++__i)
850  _M_data[__i] = __e[__i];
851  }
852  else
853  {
854  if (_M_data)
855  {
856  std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
857  std::__valarray_release_memory(_M_data);
858  }
859  _M_size = __e.size();
860  _M_data = __valarray_get_storage<_Tp>(_M_size);
861  std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data));
862  }
863  return *this;
864  }
865 
866  template<typename _Tp>
867  inline _Expr<_SClos<_ValArray,_Tp>, _Tp>
868  valarray<_Tp>::operator[](slice __s) const
869  {
870  typedef _SClos<_ValArray,_Tp> _Closure;
871  return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s));
872  }
873 
874  template<typename _Tp>
875  inline slice_array<_Tp>
876  valarray<_Tp>::operator[](slice __s)
877  { return slice_array<_Tp>(_Array<_Tp>(_M_data), __s); }
878 
879  template<typename _Tp>
880  inline _Expr<_GClos<_ValArray,_Tp>, _Tp>
881  valarray<_Tp>::operator[](const gslice& __gs) const
882  {
883  typedef _GClos<_ValArray,_Tp> _Closure;
884  return _Expr<_Closure, _Tp>
885  (_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index));
886  }
887 
888  template<typename _Tp>
889  inline gslice_array<_Tp>
890  valarray<_Tp>::operator[](const gslice& __gs)
891  {
892  return gslice_array<_Tp>
893  (_Array<_Tp>(_M_data), __gs._M_index->_M_index);
894  }
895 
896  template<typename _Tp>
897  inline valarray<_Tp>
898  valarray<_Tp>::operator[](const valarray<bool>& __m) const
899  {
900  size_t __s = 0;
901  size_t __e = __m.size();
902  for (size_t __i=0; __i<__e; ++__i)
903  if (__m[__i]) ++__s;
904  __glibcxx_assert(__s <= _M_size);
905  return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s,
906  _Array<bool> (__m)));
907  }
908 
909  template<typename _Tp>
910  inline mask_array<_Tp>
911  valarray<_Tp>::operator[](const valarray<bool>& __m)
912  {
913  size_t __s = 0;
914  size_t __e = __m.size();
915  for (size_t __i=0; __i<__e; ++__i)
916  if (__m[__i]) ++__s;
917  __glibcxx_assert(__s <= _M_size);
918  return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array<bool>(__m));
919  }
920 
921  template<typename _Tp>
922  inline _Expr<_IClos<_ValArray,_Tp>, _Tp>
923  valarray<_Tp>::operator[](const valarray<size_t>& __i) const
924  {
925  typedef _IClos<_ValArray,_Tp> _Closure;
926  return _Expr<_Closure, _Tp>(_Closure(*this, __i));
927  }
928 
929  template<typename _Tp>
930  inline indirect_array<_Tp>
931  valarray<_Tp>::operator[](const valarray<size_t>& __i)
932  {
933  return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(),
934  _Array<size_t>(__i));
935  }
936 
937 #if __cplusplus >= 201103L
938  template<class _Tp>
939  inline void
940  valarray<_Tp>::swap(valarray<_Tp>& __v) noexcept
941  {
942  std::swap(_M_size, __v._M_size);
943  std::swap(_M_data, __v._M_data);
944  }
945 #endif
946 
947  template<class _Tp>
948  inline size_t
949  valarray<_Tp>::size() const
950  { return _M_size; }
951 
952  template<class _Tp>
953  inline _Tp
954  valarray<_Tp>::sum() const
955  {
956  __glibcxx_assert(_M_size > 0);
957  return std::__valarray_sum(_M_data, _M_data + _M_size);
958  }
959 
960  template<class _Tp>
961  inline valarray<_Tp>
962  valarray<_Tp>::shift(int __n) const
963  {
964  valarray<_Tp> __ret;
965 
966  if (_M_size == 0)
967  return __ret;
968 
969  _Tp* __restrict__ __tmp_M_data =
970  std::__valarray_get_storage<_Tp>(_M_size);
971 
972  if (__n == 0)
973  std::__valarray_copy_construct(_M_data,
974  _M_data + _M_size, __tmp_M_data);
975  else if (__n > 0) // shift left
976  {
977  if (size_t(__n) > _M_size)
978  __n = int(_M_size);
979 
980  std::__valarray_copy_construct(_M_data + __n,
981  _M_data + _M_size, __tmp_M_data);
982  std::__valarray_default_construct(__tmp_M_data + _M_size - __n,
983  __tmp_M_data + _M_size);
984  }
985  else // shift right
986  {
987  if (-size_t(__n) > _M_size)
988  __n = -int(_M_size);
989 
990  std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n,
991  __tmp_M_data - __n);
992  std::__valarray_default_construct(__tmp_M_data,
993  __tmp_M_data - __n);
994  }
995 
996  __ret._M_size = _M_size;
997  __ret._M_data = __tmp_M_data;
998  return __ret;
999  }
1000 
1001  template<class _Tp>
1002  inline valarray<_Tp>
1003  valarray<_Tp>::cshift(int __n) const
1004  {
1005  valarray<_Tp> __ret;
1006 
1007  if (_M_size == 0)
1008  return __ret;
1009 
1010  _Tp* __restrict__ __tmp_M_data =
1011  std::__valarray_get_storage<_Tp>(_M_size);
1012 
1013  if (__n == 0)
1014  std::__valarray_copy_construct(_M_data,
1015  _M_data + _M_size, __tmp_M_data);
1016  else if (__n > 0) // cshift left
1017  {
1018  if (size_t(__n) > _M_size)
1019  __n = int(__n % _M_size);
1020 
1021  std::__valarray_copy_construct(_M_data, _M_data + __n,
1022  __tmp_M_data + _M_size - __n);
1023  std::__valarray_copy_construct(_M_data + __n, _M_data + _M_size,
1024  __tmp_M_data);
1025  }
1026  else // cshift right
1027  {
1028  if (-size_t(__n) > _M_size)
1029  __n = -int(-size_t(__n) % _M_size);
1030 
1031  std::__valarray_copy_construct(_M_data + _M_size + __n,
1032  _M_data + _M_size, __tmp_M_data);
1033  std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n,
1034  __tmp_M_data - __n);
1035  }
1036 
1037  __ret._M_size = _M_size;
1038  __ret._M_data = __tmp_M_data;
1039  return __ret;
1040  }
1041 
1042  template<class _Tp>
1043  inline void
1044  valarray<_Tp>::resize(size_t __n, _Tp __c)
1045  {
1046  // This complication is so to make valarray<valarray<T> > work
1047  // even though it is not required by the standard. Nobody should
1048  // be saying valarray<valarray<T> > anyway. See the specs.
1049  std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
1050  if (_M_size != __n)
1051  {
1052  std::__valarray_release_memory(_M_data);
1053  _M_size = __n;
1054  _M_data = __valarray_get_storage<_Tp>(__n);
1055  }
1056  std::__valarray_fill_construct(_M_data, _M_data + __n, __c);
1057  }
1058 
1059  template<typename _Tp>
1060  inline _Tp
1061  valarray<_Tp>::min() const
1062  {
1063  __glibcxx_assert(_M_size > 0);
1064  return *std::min_element(_M_data, _M_data + _M_size);
1065  }
1066 
1067  template<typename _Tp>
1068  inline _Tp
1069  valarray<_Tp>::max() const
1070  {
1071  __glibcxx_assert(_M_size > 0);
1072  return *std::max_element(_M_data, _M_data + _M_size);
1073  }
1074 
1075  template<class _Tp>
1076  inline _Expr<_ValFunClos<_ValArray, _Tp>, _Tp>
1077  valarray<_Tp>::apply(_Tp __func(_Tp)) const
1078  {
1079  typedef _ValFunClos<_ValArray, _Tp> _Closure;
1080  return _Expr<_Closure, _Tp>(_Closure(*this, __func));
1081  }
1082 
1083  template<class _Tp>
1084  inline _Expr<_RefFunClos<_ValArray, _Tp>, _Tp>
1085  valarray<_Tp>::apply(_Tp __func(const _Tp &)) const
1086  {
1087  typedef _RefFunClos<_ValArray, _Tp> _Closure;
1088  return _Expr<_Closure, _Tp>(_Closure(*this, __func));
1089  }
1090 
1091  /// @cond undocumented
1092 #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name) \
1093  template<typename _Tp> \
1094  inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt \
1095  valarray<_Tp>::operator _Op() const \
1096  { \
1097  typedef _UnClos<_Name, _ValArray, _Tp> _Closure; \
1098  typedef typename __fun<_Name, _Tp>::result_type _Rt; \
1099  return _Expr<_Closure, _Rt>(_Closure(*this)); \
1100  }
1101 
1102  _DEFINE_VALARRAY_UNARY_OPERATOR(+, __unary_plus)
1103  _DEFINE_VALARRAY_UNARY_OPERATOR(-, __negate)
1104  _DEFINE_VALARRAY_UNARY_OPERATOR(~, __bitwise_not)
1105  _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not)
1106 
1107 #undef _DEFINE_VALARRAY_UNARY_OPERATOR
1108 
1109 #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name) \
1110  template<class _Tp> \
1111  inline valarray<_Tp>& \
1112  valarray<_Tp>::operator _Op##=(const _Tp &__t) \
1113  { \
1114  _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t); \
1115  return *this; \
1116  } \
1117  \
1118  template<class _Tp> \
1119  inline valarray<_Tp>& \
1120  valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v) \
1121  { \
1122  __glibcxx_assert(_M_size == __v._M_size); \
1123  _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, \
1124  _Array<_Tp>(__v._M_data)); \
1125  return *this; \
1126  }
1127 
1128 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus)
1129 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus)
1130 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies)
1131 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides)
1132 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus)
1133 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
1134 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
1135 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
1136 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left)
1137 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right)
1138 
1139 #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT
1140 
1141 #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name) \
1142  template<class _Tp> template<class _Dom> \
1143  inline valarray<_Tp>& \
1144  valarray<_Tp>::operator _Op##=(const _Expr<_Dom, _Tp>& __e) \
1145  { \
1146  _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size); \
1147  return *this; \
1148  }
1149 
1150 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus)
1151 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus)
1152 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies)
1153 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides)
1154 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus)
1155 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
1156 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
1157 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
1158 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left)
1159 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right)
1160 
1161 #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT
1162 
1163 
1164 #define _DEFINE_BINARY_OPERATOR(_Op, _Name) \
1165  template<typename _Tp> \
1166  inline _Expr<_BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp>, \
1167  typename __fun<_Name, _Tp>::result_type> \
1168  operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \
1169  { \
1170  __glibcxx_assert(__v.size() == __w.size()); \
1171  typedef _BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp> _Closure; \
1172  typedef typename __fun<_Name, _Tp>::result_type _Rt; \
1173  return _Expr<_Closure, _Rt>(_Closure(__v, __w)); \
1174  } \
1175  \
1176  template<typename _Tp> \
1177  inline _Expr<_BinClos<_Name, _ValArray,_Constant, _Tp, _Tp>, \
1178  typename __fun<_Name, _Tp>::result_type> \
1179  operator _Op(const valarray<_Tp>& __v, \
1180  const typename valarray<_Tp>::value_type& __t) \
1181  { \
1182  typedef _BinClos<_Name, _ValArray, _Constant, _Tp, _Tp> _Closure; \
1183  typedef typename __fun<_Name, _Tp>::result_type _Rt; \
1184  return _Expr<_Closure, _Rt>(_Closure(__v, __t)); \
1185  } \
1186  \
1187  template<typename _Tp> \
1188  inline _Expr<_BinClos<_Name, _Constant, _ValArray, _Tp, _Tp>, \
1189  typename __fun<_Name, _Tp>::result_type> \
1190  operator _Op(const typename valarray<_Tp>::value_type& __t, \
1191  const valarray<_Tp>& __v) \
1192  { \
1193  typedef _BinClos<_Name, _Constant, _ValArray, _Tp, _Tp> _Closure; \
1194  typedef typename __fun<_Name, _Tp>::result_type _Rt; \
1195  return _Expr<_Closure, _Rt>(_Closure(__t, __v)); \
1196  }
1197 
1198 _DEFINE_BINARY_OPERATOR(+, __plus)
1199 _DEFINE_BINARY_OPERATOR(-, __minus)
1200 _DEFINE_BINARY_OPERATOR(*, __multiplies)
1201 _DEFINE_BINARY_OPERATOR(/, __divides)
1202 _DEFINE_BINARY_OPERATOR(%, __modulus)
1203 _DEFINE_BINARY_OPERATOR(^, __bitwise_xor)
1204 _DEFINE_BINARY_OPERATOR(&, __bitwise_and)
1205 _DEFINE_BINARY_OPERATOR(|, __bitwise_or)
1206 _DEFINE_BINARY_OPERATOR(<<, __shift_left)
1207 _DEFINE_BINARY_OPERATOR(>>, __shift_right)
1208 _DEFINE_BINARY_OPERATOR(&&, __logical_and)
1209 _DEFINE_BINARY_OPERATOR(||, __logical_or)
1210 _DEFINE_BINARY_OPERATOR(==, __equal_to)
1211 _DEFINE_BINARY_OPERATOR(!=, __not_equal_to)
1212 _DEFINE_BINARY_OPERATOR(<, __less)
1213 _DEFINE_BINARY_OPERATOR(>, __greater)
1214 _DEFINE_BINARY_OPERATOR(<=, __less_equal)
1215 _DEFINE_BINARY_OPERATOR(>=, __greater_equal)
1216 
1217 #undef _DEFINE_BINARY_OPERATOR
1218  /// @endcond
1219 
1220 #if __cplusplus >= 201103L
1221  /**
1222  * @brief Return an iterator pointing to the first element of
1223  * the valarray.
1224  * @param __va valarray.
1225  */
1226  template<class _Tp>
1227  [[__nodiscard__]]
1228  inline _Tp*
1229  begin(valarray<_Tp>& __va) noexcept
1230  { return __va.size() ? std::__addressof(__va[0]) : nullptr; }
1231 
1232  /**
1233  * @brief Return an iterator pointing to the first element of
1234  * the const valarray.
1235  * @param __va valarray.
1236  */
1237  template<class _Tp>
1238  [[__nodiscard__]]
1239  inline const _Tp*
1240  begin(const valarray<_Tp>& __va) noexcept
1241  { return __va.size() ? std::__addressof(__va[0]) : nullptr; }
1242 
1243  /**
1244  * @brief Return an iterator pointing to one past the last element of
1245  * the valarray.
1246  * @param __va valarray.
1247  */
1248  template<class _Tp>
1249  [[__nodiscard__]]
1250  inline _Tp*
1251  end(valarray<_Tp>& __va) noexcept
1252  {
1253  if (auto __n = __va.size())
1254  return std::__addressof(__va[0]) + __n;
1255  else
1256  return nullptr;
1257  }
1258 
1259  /**
1260  * @brief Return an iterator pointing to one past the last element of
1261  * the const valarray.
1262  * @param __va valarray.
1263  */
1264  template<class _Tp>
1265  [[__nodiscard__]]
1266  inline const _Tp*
1267  end(const valarray<_Tp>& __va) noexcept
1268  {
1269  if (auto __n = __va.size())
1270  return std::__addressof(__va[0]) + __n;
1271  else
1272  return nullptr;
1273  }
1274 #endif // C++11
1275 
1276  /// @} group numeric_arrays
1277 
1278 _GLIBCXX_END_NAMESPACE_VERSION
1279 } // namespace
1280 
1281 #endif /* _GLIBCXX_VALARRAY */