]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libstdc++-v3/contrib/libstdc++-v3-4.7/include/std/valarray
update
[l4.git] / l4 / pkg / libstdc++-v3 / contrib / libstdc++-v3-4.7 / include / std / valarray
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
46 namespace std _GLIBCXX_VISIBILITY(default)
47 {
48 _GLIBCXX_BEGIN_NAMESPACE_VERSION
49
50   template<class _Clos, typename _Tp> 
51     class _Expr;
52
53   template<typename _Tp1, typename _Tp2> 
54     class _ValArray;    
55
56   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   
94 namespace 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
596 namespace 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 */