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