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