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