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