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