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