libstdc++
valarray
1 // The template and inlines for the -*- C++ -*- valarray class.
2 
3 // Copyright (C) 1997-2014 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/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  template<typename _Tp>
567  inline const _Tp&
568  valarray<_Tp>::operator[](size_t __i) const
569  {
570  __glibcxx_requires_subscript(__i);
571  return _M_data[__i];
572  }
573 
574  template<typename _Tp>
575  inline _Tp&
576  valarray<_Tp>::operator[](size_t __i)
577  {
578  __glibcxx_requires_subscript(__i);
579  return _M_data[__i];
580  }
581 
582  // @} group numeric_arrays
583 
584 _GLIBCXX_END_NAMESPACE_VERSION
585 } // namespace
586 
587 #include <bits/valarray_after.h>
588 #include <bits/slice_array.h>
589 #include <bits/gslice.h>
590 #include <bits/gslice_array.h>
591 #include <bits/mask_array.h>
592 #include <bits/indirect_array.h>
593 
594 namespace std _GLIBCXX_VISIBILITY(default)
595 {
596 _GLIBCXX_BEGIN_NAMESPACE_VERSION
597 
598  /**
599  * @addtogroup numeric_arrays
600  * @{
601  */
602 
603  template<typename _Tp>
604  inline
605  valarray<_Tp>::valarray() : _M_size(0), _M_data(0) {}
606 
607  template<typename _Tp>
608  inline
609  valarray<_Tp>::valarray(size_t __n)
610  : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
611  { std::__valarray_default_construct(_M_data, _M_data + __n); }
612 
613  template<typename _Tp>
614  inline
615  valarray<_Tp>::valarray(const _Tp& __t, size_t __n)
616  : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
617  { std::__valarray_fill_construct(_M_data, _M_data + __n, __t); }
618 
619  template<typename _Tp>
620  inline
621  valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n)
622  : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
623  {
624  _GLIBCXX_DEBUG_ASSERT(__p != 0 || __n == 0);
625  std::__valarray_copy_construct(__p, __p + __n, _M_data);
626  }
627 
628  template<typename _Tp>
629  inline
630  valarray<_Tp>::valarray(const valarray<_Tp>& __v)
631  : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size))
632  { std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size,
633  _M_data); }
634 
635 #if __cplusplus >= 201103L
636  template<typename _Tp>
637  inline
638  valarray<_Tp>::valarray(valarray<_Tp>&& __v) noexcept
639  : _M_size(__v._M_size), _M_data(__v._M_data)
640  {
641  __v._M_size = 0;
642  __v._M_data = 0;
643  }
644 #endif
645 
646  template<typename _Tp>
647  inline
648  valarray<_Tp>::valarray(const slice_array<_Tp>& __sa)
649  : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz))
650  {
651  std::__valarray_copy_construct
652  (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data));
653  }
654 
655  template<typename _Tp>
656  inline
657  valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga)
658  : _M_size(__ga._M_index.size()),
659  _M_data(__valarray_get_storage<_Tp>(_M_size))
660  {
661  std::__valarray_copy_construct
662  (__ga._M_array, _Array<size_t>(__ga._M_index),
663  _Array<_Tp>(_M_data), _M_size);
664  }
665 
666  template<typename _Tp>
667  inline
668  valarray<_Tp>::valarray(const mask_array<_Tp>& __ma)
669  : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz))
670  {
671  std::__valarray_copy_construct
672  (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size);
673  }
674 
675  template<typename _Tp>
676  inline
677  valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia)
678  : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz))
679  {
680  std::__valarray_copy_construct
681  (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size);
682  }
683 
684 #if __cplusplus >= 201103L
685  template<typename _Tp>
686  inline
687  valarray<_Tp>::valarray(initializer_list<_Tp> __l)
688  : _M_size(__l.size()), _M_data(__valarray_get_storage<_Tp>(__l.size()))
689  { std::__valarray_copy_construct(__l.begin(), __l.end(), _M_data); }
690 #endif
691 
692  template<typename _Tp> template<class _Dom>
693  inline
694  valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e)
695  : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size))
696  { std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data)); }
697 
698  template<typename _Tp>
699  inline
700  valarray<_Tp>::~valarray() _GLIBCXX_NOEXCEPT
701  {
702  std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
703  std::__valarray_release_memory(_M_data);
704  }
705 
706  template<typename _Tp>
707  inline valarray<_Tp>&
708  valarray<_Tp>::operator=(const valarray<_Tp>& __v)
709  {
710  // _GLIBCXX_RESOLVE_LIB_DEFECTS
711  // 630. arrays of valarray.
712  if (_M_size == __v._M_size)
713  std::__valarray_copy(__v._M_data, _M_size, _M_data);
714  else
715  {
716  if (_M_data)
717  {
718  std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
719  std::__valarray_release_memory(_M_data);
720  }
721  _M_size = __v._M_size;
722  _M_data = __valarray_get_storage<_Tp>(_M_size);
723  std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size,
724  _M_data);
725  }
726  return *this;
727  }
728 
729 #if __cplusplus >= 201103L
730  template<typename _Tp>
731  inline valarray<_Tp>&
732  valarray<_Tp>::operator=(valarray<_Tp>&& __v) noexcept
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 = __v._M_data;
741  __v._M_size = 0;
742  __v._M_data = 0;
743  return *this;
744  }
745 
746  template<typename _Tp>
747  inline valarray<_Tp>&
748  valarray<_Tp>::operator=(initializer_list<_Tp> __l)
749  {
750  // _GLIBCXX_RESOLVE_LIB_DEFECTS
751  // 630. arrays of valarray.
752  if (_M_size == __l.size())
753  std::__valarray_copy(__l.begin(), __l.size(), _M_data);
754  else
755  {
756  if (_M_data)
757  {
758  std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
759  std::__valarray_release_memory(_M_data);
760  }
761  _M_size = __l.size();
762  _M_data = __valarray_get_storage<_Tp>(_M_size);
763  std::__valarray_copy_construct(__l.begin(), __l.begin() + _M_size,
764  _M_data);
765  }
766  return *this;
767  }
768 #endif
769 
770  template<typename _Tp>
771  inline valarray<_Tp>&
772  valarray<_Tp>::operator=(const _Tp& __t)
773  {
774  std::__valarray_fill(_M_data, _M_size, __t);
775  return *this;
776  }
777 
778  template<typename _Tp>
779  inline valarray<_Tp>&
780  valarray<_Tp>::operator=(const slice_array<_Tp>& __sa)
781  {
782  _GLIBCXX_DEBUG_ASSERT(_M_size == __sa._M_sz);
783  std::__valarray_copy(__sa._M_array, __sa._M_sz,
784  __sa._M_stride, _Array<_Tp>(_M_data));
785  return *this;
786  }
787 
788  template<typename _Tp>
789  inline valarray<_Tp>&
790  valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga)
791  {
792  _GLIBCXX_DEBUG_ASSERT(_M_size == __ga._M_index.size());
793  std::__valarray_copy(__ga._M_array, _Array<size_t>(__ga._M_index),
794  _Array<_Tp>(_M_data), _M_size);
795  return *this;
796  }
797 
798  template<typename _Tp>
799  inline valarray<_Tp>&
800  valarray<_Tp>::operator=(const mask_array<_Tp>& __ma)
801  {
802  _GLIBCXX_DEBUG_ASSERT(_M_size == __ma._M_sz);
803  std::__valarray_copy(__ma._M_array, __ma._M_mask,
804  _Array<_Tp>(_M_data), _M_size);
805  return *this;
806  }
807 
808  template<typename _Tp>
809  inline valarray<_Tp>&
810  valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia)
811  {
812  _GLIBCXX_DEBUG_ASSERT(_M_size == __ia._M_sz);
813  std::__valarray_copy(__ia._M_array, __ia._M_index,
814  _Array<_Tp>(_M_data), _M_size);
815  return *this;
816  }
817 
818  template<typename _Tp> template<class _Dom>
819  inline valarray<_Tp>&
820  valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e)
821  {
822  // _GLIBCXX_RESOLVE_LIB_DEFECTS
823  // 630. arrays of valarray.
824  if (_M_size == __e.size())
825  std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data));
826  else
827  {
828  if (_M_data)
829  {
830  std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
831  std::__valarray_release_memory(_M_data);
832  }
833  _M_size = __e.size();
834  _M_data = __valarray_get_storage<_Tp>(_M_size);
835  std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data));
836  }
837  return *this;
838  }
839 
840  template<typename _Tp>
841  inline _Expr<_SClos<_ValArray,_Tp>, _Tp>
842  valarray<_Tp>::operator[](slice __s) const
843  {
844  typedef _SClos<_ValArray,_Tp> _Closure;
845  return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s));
846  }
847 
848  template<typename _Tp>
849  inline slice_array<_Tp>
850  valarray<_Tp>::operator[](slice __s)
851  { return slice_array<_Tp>(_Array<_Tp>(_M_data), __s); }
852 
853  template<typename _Tp>
854  inline _Expr<_GClos<_ValArray,_Tp>, _Tp>
855  valarray<_Tp>::operator[](const gslice& __gs) const
856  {
857  typedef _GClos<_ValArray,_Tp> _Closure;
858  return _Expr<_Closure, _Tp>
859  (_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index));
860  }
861 
862  template<typename _Tp>
863  inline gslice_array<_Tp>
864  valarray<_Tp>::operator[](const gslice& __gs)
865  {
866  return gslice_array<_Tp>
867  (_Array<_Tp>(_M_data), __gs._M_index->_M_index);
868  }
869 
870  template<typename _Tp>
871  inline valarray<_Tp>
872  valarray<_Tp>::operator[](const valarray<bool>& __m) const
873  {
874  size_t __s = 0;
875  size_t __e = __m.size();
876  for (size_t __i=0; __i<__e; ++__i)
877  if (__m[__i]) ++__s;
878  return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s,
879  _Array<bool> (__m)));
880  }
881 
882  template<typename _Tp>
883  inline mask_array<_Tp>
884  valarray<_Tp>::operator[](const valarray<bool>& __m)
885  {
886  size_t __s = 0;
887  size_t __e = __m.size();
888  for (size_t __i=0; __i<__e; ++__i)
889  if (__m[__i]) ++__s;
890  return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array<bool>(__m));
891  }
892 
893  template<typename _Tp>
894  inline _Expr<_IClos<_ValArray,_Tp>, _Tp>
895  valarray<_Tp>::operator[](const valarray<size_t>& __i) const
896  {
897  typedef _IClos<_ValArray,_Tp> _Closure;
898  return _Expr<_Closure, _Tp>(_Closure(*this, __i));
899  }
900 
901  template<typename _Tp>
902  inline indirect_array<_Tp>
903  valarray<_Tp>::operator[](const valarray<size_t>& __i)
904  {
905  return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(),
906  _Array<size_t>(__i));
907  }
908 
909 #if __cplusplus >= 201103L
910  template<class _Tp>
911  inline void
912  valarray<_Tp>::swap(valarray<_Tp>& __v) noexcept
913  {
914  std::swap(_M_size, __v._M_size);
915  std::swap(_M_data, __v._M_data);
916  }
917 #endif
918 
919  template<class _Tp>
920  inline size_t
921  valarray<_Tp>::size() const
922  { return _M_size; }
923 
924  template<class _Tp>
925  inline _Tp
926  valarray<_Tp>::sum() const
927  {
928  _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
929  return std::__valarray_sum(_M_data, _M_data + _M_size);
930  }
931 
932  template<class _Tp>
933  inline valarray<_Tp>
934  valarray<_Tp>::shift(int __n) const
935  {
936  valarray<_Tp> __ret;
937 
938  if (_M_size == 0)
939  return __ret;
940 
941  _Tp* __restrict__ __tmp_M_data =
942  std::__valarray_get_storage<_Tp>(_M_size);
943 
944  if (__n == 0)
945  std::__valarray_copy_construct(_M_data,
946  _M_data + _M_size, __tmp_M_data);
947  else if (__n > 0) // shift left
948  {
949  if (size_t(__n) > _M_size)
950  __n = int(_M_size);
951 
952  std::__valarray_copy_construct(_M_data + __n,
953  _M_data + _M_size, __tmp_M_data);
954  std::__valarray_default_construct(__tmp_M_data + _M_size - __n,
955  __tmp_M_data + _M_size);
956  }
957  else // shift right
958  {
959  if (-size_t(__n) > _M_size)
960  __n = -int(_M_size);
961 
962  std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n,
963  __tmp_M_data - __n);
964  std::__valarray_default_construct(__tmp_M_data,
965  __tmp_M_data - __n);
966  }
967 
968  __ret._M_size = _M_size;
969  __ret._M_data = __tmp_M_data;
970  return __ret;
971  }
972 
973  template<class _Tp>
974  inline valarray<_Tp>
975  valarray<_Tp>::cshift(int __n) const
976  {
977  valarray<_Tp> __ret;
978 
979  if (_M_size == 0)
980  return __ret;
981 
982  _Tp* __restrict__ __tmp_M_data =
983  std::__valarray_get_storage<_Tp>(_M_size);
984 
985  if (__n == 0)
986  std::__valarray_copy_construct(_M_data,
987  _M_data + _M_size, __tmp_M_data);
988  else if (__n > 0) // cshift left
989  {
990  if (size_t(__n) > _M_size)
991  __n = int(__n % _M_size);
992 
993  std::__valarray_copy_construct(_M_data, _M_data + __n,
994  __tmp_M_data + _M_size - __n);
995  std::__valarray_copy_construct(_M_data + __n, _M_data + _M_size,
996  __tmp_M_data);
997  }
998  else // cshift right
999  {
1000  if (-size_t(__n) > _M_size)
1001  __n = -int(-size_t(__n) % _M_size);
1002 
1003  std::__valarray_copy_construct(_M_data + _M_size + __n,
1004  _M_data + _M_size, __tmp_M_data);
1005  std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n,
1006  __tmp_M_data - __n);
1007  }
1008 
1009  __ret._M_size = _M_size;
1010  __ret._M_data = __tmp_M_data;
1011  return __ret;
1012  }
1013 
1014  template<class _Tp>
1015  inline void
1016  valarray<_Tp>::resize(size_t __n, _Tp __c)
1017  {
1018  // This complication is so to make valarray<valarray<T> > work
1019  // even though it is not required by the standard. Nobody should
1020  // be saying valarray<valarray<T> > anyway. See the specs.
1021  std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
1022  if (_M_size != __n)
1023  {
1024  std::__valarray_release_memory(_M_data);
1025  _M_size = __n;
1026  _M_data = __valarray_get_storage<_Tp>(__n);
1027  }
1028  std::__valarray_fill_construct(_M_data, _M_data + __n, __c);
1029  }
1030 
1031  template<typename _Tp>
1032  inline _Tp
1033  valarray<_Tp>::min() const
1034  {
1035  _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
1036  return *std::min_element(_M_data, _M_data + _M_size);
1037  }
1038 
1039  template<typename _Tp>
1040  inline _Tp
1041  valarray<_Tp>::max() const
1042  {
1043  _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
1044  return *std::max_element(_M_data, _M_data + _M_size);
1045  }
1046 
1047  template<class _Tp>
1048  inline _Expr<_ValFunClos<_ValArray, _Tp>, _Tp>
1049  valarray<_Tp>::apply(_Tp func(_Tp)) const
1050  {
1051  typedef _ValFunClos<_ValArray, _Tp> _Closure;
1052  return _Expr<_Closure, _Tp>(_Closure(*this, func));
1053  }
1054 
1055  template<class _Tp>
1056  inline _Expr<_RefFunClos<_ValArray, _Tp>, _Tp>
1057  valarray<_Tp>::apply(_Tp func(const _Tp &)) const
1058  {
1059  typedef _RefFunClos<_ValArray, _Tp> _Closure;
1060  return _Expr<_Closure, _Tp>(_Closure(*this, func));
1061  }
1062 
1063 #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name) \
1064  template<typename _Tp> \
1065  inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt \
1066  valarray<_Tp>::operator _Op() const \
1067  { \
1068  typedef _UnClos<_Name, _ValArray, _Tp> _Closure; \
1069  typedef typename __fun<_Name, _Tp>::result_type _Rt; \
1070  return _Expr<_Closure, _Rt>(_Closure(*this)); \
1071  }
1072 
1073  _DEFINE_VALARRAY_UNARY_OPERATOR(+, __unary_plus)
1074  _DEFINE_VALARRAY_UNARY_OPERATOR(-, __negate)
1075  _DEFINE_VALARRAY_UNARY_OPERATOR(~, __bitwise_not)
1076  _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not)
1077 
1078 #undef _DEFINE_VALARRAY_UNARY_OPERATOR
1079 
1080 #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name) \
1081  template<class _Tp> \
1082  inline valarray<_Tp>& \
1083  valarray<_Tp>::operator _Op##=(const _Tp &__t) \
1084  { \
1085  _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t); \
1086  return *this; \
1087  } \
1088  \
1089  template<class _Tp> \
1090  inline valarray<_Tp>& \
1091  valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v) \
1092  { \
1093  _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size); \
1094  _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, \
1095  _Array<_Tp>(__v._M_data)); \
1096  return *this; \
1097  }
1098 
1099 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus)
1100 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus)
1101 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies)
1102 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides)
1103 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus)
1104 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
1105 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
1106 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
1107 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left)
1108 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right)
1109 
1110 #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT
1111 
1112 #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name) \
1113  template<class _Tp> template<class _Dom> \
1114  inline valarray<_Tp>& \
1115  valarray<_Tp>::operator _Op##=(const _Expr<_Dom, _Tp>& __e) \
1116  { \
1117  _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size); \
1118  return *this; \
1119  }
1120 
1121 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus)
1122 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus)
1123 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies)
1124 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides)
1125 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus)
1126 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
1127 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
1128 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
1129 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left)
1130 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right)
1131 
1132 #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT
1133 
1134 
1135 #define _DEFINE_BINARY_OPERATOR(_Op, _Name) \
1136  template<typename _Tp> \
1137  inline _Expr<_BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp>, \
1138  typename __fun<_Name, _Tp>::result_type> \
1139  operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \
1140  { \
1141  _GLIBCXX_DEBUG_ASSERT(__v.size() == __w.size()); \
1142  typedef _BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp> _Closure; \
1143  typedef typename __fun<_Name, _Tp>::result_type _Rt; \
1144  return _Expr<_Closure, _Rt>(_Closure(__v, __w)); \
1145  } \
1146  \
1147  template<typename _Tp> \
1148  inline _Expr<_BinClos<_Name, _ValArray,_Constant, _Tp, _Tp>, \
1149  typename __fun<_Name, _Tp>::result_type> \
1150  operator _Op(const valarray<_Tp>& __v, const _Tp& __t) \
1151  { \
1152  typedef _BinClos<_Name, _ValArray, _Constant, _Tp, _Tp> _Closure; \
1153  typedef typename __fun<_Name, _Tp>::result_type _Rt; \
1154  return _Expr<_Closure, _Rt>(_Closure(__v, __t)); \
1155  } \
1156  \
1157  template<typename _Tp> \
1158  inline _Expr<_BinClos<_Name, _Constant, _ValArray, _Tp, _Tp>, \
1159  typename __fun<_Name, _Tp>::result_type> \
1160  operator _Op(const _Tp& __t, const valarray<_Tp>& __v) \
1161  { \
1162  typedef _BinClos<_Name, _Constant, _ValArray, _Tp, _Tp> _Closure; \
1163  typedef typename __fun<_Name, _Tp>::result_type _Rt; \
1164  return _Expr<_Closure, _Rt>(_Closure(__t, __v)); \
1165  }
1166 
1167 _DEFINE_BINARY_OPERATOR(+, __plus)
1168 _DEFINE_BINARY_OPERATOR(-, __minus)
1169 _DEFINE_BINARY_OPERATOR(*, __multiplies)
1170 _DEFINE_BINARY_OPERATOR(/, __divides)
1171 _DEFINE_BINARY_OPERATOR(%, __modulus)
1172 _DEFINE_BINARY_OPERATOR(^, __bitwise_xor)
1173 _DEFINE_BINARY_OPERATOR(&, __bitwise_and)
1174 _DEFINE_BINARY_OPERATOR(|, __bitwise_or)
1175 _DEFINE_BINARY_OPERATOR(<<, __shift_left)
1176 _DEFINE_BINARY_OPERATOR(>>, __shift_right)
1177 _DEFINE_BINARY_OPERATOR(&&, __logical_and)
1178 _DEFINE_BINARY_OPERATOR(||, __logical_or)
1179 _DEFINE_BINARY_OPERATOR(==, __equal_to)
1180 _DEFINE_BINARY_OPERATOR(!=, __not_equal_to)
1181 _DEFINE_BINARY_OPERATOR(<, __less)
1182 _DEFINE_BINARY_OPERATOR(>, __greater)
1183 _DEFINE_BINARY_OPERATOR(<=, __less_equal)
1184 _DEFINE_BINARY_OPERATOR(>=, __greater_equal)
1185 
1186 #undef _DEFINE_BINARY_OPERATOR
1187 
1188 #if __cplusplus >= 201103L
1189  /**
1190  * @brief Return an iterator pointing to the first element of
1191  * the valarray.
1192  * @param __va valarray.
1193  */
1194  template<class _Tp>
1195  inline _Tp*
1196  begin(valarray<_Tp>& __va)
1197  { return std::__addressof(__va[0]); }
1198 
1199  /**
1200  * @brief Return an iterator pointing to the first element of
1201  * the const valarray.
1202  * @param __va valarray.
1203  */
1204  template<class _Tp>
1205  inline const _Tp*
1206  begin(const valarray<_Tp>& __va)
1207  { return std::__addressof(__va[0]); }
1208 
1209  /**
1210  * @brief Return an iterator pointing to one past the last element of
1211  * the valarray.
1212  * @param __va valarray.
1213  */
1214  template<class _Tp>
1215  inline _Tp*
1216  end(valarray<_Tp>& __va)
1217  { return std::__addressof(__va[0]) + __va.size(); }
1218 
1219  /**
1220  * @brief Return an iterator pointing to one past the last element of
1221  * the const valarray.
1222  * @param __va valarray.
1223  */
1224  template<class _Tp>
1225  inline const _Tp*
1226  end(const valarray<_Tp>& __va)
1227  { return std::__addressof(__va[0]) + __va.size(); }
1228 #endif // C++11
1229 
1230  // @} group numeric_arrays
1231 
1232 _GLIBCXX_END_NAMESPACE_VERSION
1233 } // namespace
1234 
1235 #endif /* _GLIBCXX_VALARRAY */