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