1*404b540aSrobert // The template and inlines for the -*- C++ -*- internal _Array helper class.
2*404b540aSrobert
3*404b540aSrobert // Copyright (C) 1997, 1998, 1999, 2000, 2003, 2004, 2005, 2006
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_array.h
32*404b540aSrobert * This is an internal header file, included by other library headers.
33*404b540aSrobert * You should not attempt to use it directly.
34*404b540aSrobert */
35*404b540aSrobert
36*404b540aSrobert // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
37*404b540aSrobert
38*404b540aSrobert #ifndef _VALARRAY_ARRAY_H
39*404b540aSrobert #define _VALARRAY_ARRAY_H 1
40*404b540aSrobert
41*404b540aSrobert #pragma GCC system_header
42*404b540aSrobert
43*404b540aSrobert #include <bits/c++config.h>
44*404b540aSrobert #include <bits/cpp_type_traits.h>
45*404b540aSrobert #include <cstdlib>
46*404b540aSrobert #include <cstring>
47*404b540aSrobert #include <new>
48*404b540aSrobert
_GLIBCXX_BEGIN_NAMESPACE(std)49*404b540aSrobert _GLIBCXX_BEGIN_NAMESPACE(std)
50*404b540aSrobert
51*404b540aSrobert //
52*404b540aSrobert // Helper functions on raw pointers
53*404b540aSrobert //
54*404b540aSrobert
55*404b540aSrobert // We get memory by the old fashion way
56*404b540aSrobert inline void*
57*404b540aSrobert __valarray_get_memory(size_t __n)
58*404b540aSrobert { return operator new(__n); }
59*404b540aSrobert
60*404b540aSrobert template<typename _Tp>
61*404b540aSrobert inline _Tp*__restrict__
__valarray_get_storage(size_t __n)62*404b540aSrobert __valarray_get_storage(size_t __n)
63*404b540aSrobert {
64*404b540aSrobert return static_cast<_Tp*__restrict__>
65*404b540aSrobert (std::__valarray_get_memory(__n * sizeof(_Tp)));
66*404b540aSrobert }
67*404b540aSrobert
68*404b540aSrobert // Return memory to the system
69*404b540aSrobert inline void
__valarray_release_memory(void * __p)70*404b540aSrobert __valarray_release_memory(void* __p)
71*404b540aSrobert { operator delete(__p); }
72*404b540aSrobert
73*404b540aSrobert // Turn a raw-memory into an array of _Tp filled with _Tp()
74*404b540aSrobert // This is required in 'valarray<T> v(n);'
75*404b540aSrobert template<typename _Tp, bool>
76*404b540aSrobert struct _Array_default_ctor
77*404b540aSrobert {
78*404b540aSrobert // Please note that this isn't exception safe. But
79*404b540aSrobert // valarrays aren't required to be exception safe.
80*404b540aSrobert inline static void
_S_do_it_Array_default_ctor81*404b540aSrobert _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
82*404b540aSrobert {
83*404b540aSrobert while (__b != __e)
84*404b540aSrobert new(__b++) _Tp();
85*404b540aSrobert }
86*404b540aSrobert };
87*404b540aSrobert
88*404b540aSrobert template<typename _Tp>
89*404b540aSrobert struct _Array_default_ctor<_Tp, true>
90*404b540aSrobert {
91*404b540aSrobert // For fundamental types, it suffices to say 'memset()'
92*404b540aSrobert inline static void
93*404b540aSrobert _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
94*404b540aSrobert { std::memset(__b, 0, (__e - __b) * sizeof(_Tp)); }
95*404b540aSrobert };
96*404b540aSrobert
97*404b540aSrobert template<typename _Tp>
98*404b540aSrobert inline void
99*404b540aSrobert __valarray_default_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
100*404b540aSrobert {
101*404b540aSrobert _Array_default_ctor<_Tp, __is_pod<_Tp>::__value>::_S_do_it(__b, __e);
102*404b540aSrobert }
103*404b540aSrobert
104*404b540aSrobert // Turn a raw-memory into an array of _Tp filled with __t
105*404b540aSrobert // This is the required in valarray<T> v(n, t). Also
106*404b540aSrobert // used in valarray<>::resize().
107*404b540aSrobert template<typename _Tp, bool>
108*404b540aSrobert struct _Array_init_ctor
109*404b540aSrobert {
110*404b540aSrobert // Please note that this isn't exception safe. But
111*404b540aSrobert // valarrays aren't required to be exception safe.
112*404b540aSrobert inline static void
113*404b540aSrobert _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t)
114*404b540aSrobert {
115*404b540aSrobert while (__b != __e)
116*404b540aSrobert new(__b++) _Tp(__t);
117*404b540aSrobert }
118*404b540aSrobert };
119*404b540aSrobert
120*404b540aSrobert template<typename _Tp>
121*404b540aSrobert struct _Array_init_ctor<_Tp, true>
122*404b540aSrobert {
123*404b540aSrobert inline static void
124*404b540aSrobert _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t)
125*404b540aSrobert {
126*404b540aSrobert while (__b != __e)
127*404b540aSrobert *__b++ = __t;
128*404b540aSrobert }
129*404b540aSrobert };
130*404b540aSrobert
131*404b540aSrobert template<typename _Tp>
132*404b540aSrobert inline void
133*404b540aSrobert __valarray_fill_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e,
134*404b540aSrobert const _Tp __t)
135*404b540aSrobert {
136*404b540aSrobert _Array_init_ctor<_Tp, __is_pod<_Tp>::__value>::_S_do_it(__b, __e, __t);
137*404b540aSrobert }
138*404b540aSrobert
139*404b540aSrobert //
140*404b540aSrobert // copy-construct raw array [__o, *) from plain array [__b, __e)
141*404b540aSrobert // We can't just say 'memcpy()'
142*404b540aSrobert //
143*404b540aSrobert template<typename _Tp, bool>
144*404b540aSrobert struct _Array_copy_ctor
145*404b540aSrobert {
146*404b540aSrobert // Please note that this isn't exception safe. But
147*404b540aSrobert // valarrays aren't required to be exception safe.
148*404b540aSrobert inline static void
149*404b540aSrobert _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e,
150*404b540aSrobert _Tp* __restrict__ __o)
151*404b540aSrobert {
152*404b540aSrobert while (__b != __e)
153*404b540aSrobert new(__o++) _Tp(*__b++);
154*404b540aSrobert }
155*404b540aSrobert };
156*404b540aSrobert
157*404b540aSrobert template<typename _Tp>
158*404b540aSrobert struct _Array_copy_ctor<_Tp, true>
159*404b540aSrobert {
160*404b540aSrobert inline static void
161*404b540aSrobert _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e,
162*404b540aSrobert _Tp* __restrict__ __o)
163*404b540aSrobert { std::memcpy(__o, __b, (__e - __b)*sizeof(_Tp)); }
164*404b540aSrobert };
165*404b540aSrobert
166*404b540aSrobert template<typename _Tp>
167*404b540aSrobert inline void
168*404b540aSrobert __valarray_copy_construct(const _Tp* __restrict__ __b,
169*404b540aSrobert const _Tp* __restrict__ __e,
170*404b540aSrobert _Tp* __restrict__ __o)
171*404b540aSrobert {
172*404b540aSrobert _Array_copy_ctor<_Tp, __is_pod<_Tp>::__value>::_S_do_it(__b, __e, __o);
173*404b540aSrobert }
174*404b540aSrobert
175*404b540aSrobert // copy-construct raw array [__o, *) from strided array __a[<__n : __s>]
176*404b540aSrobert template<typename _Tp>
177*404b540aSrobert inline void
178*404b540aSrobert __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n,
179*404b540aSrobert size_t __s, _Tp* __restrict__ __o)
180*404b540aSrobert {
181*404b540aSrobert if (__is_pod<_Tp>::__value)
182*404b540aSrobert while (__n--)
183*404b540aSrobert {
184*404b540aSrobert *__o++ = *__a;
185*404b540aSrobert __a += __s;
186*404b540aSrobert }
187*404b540aSrobert else
188*404b540aSrobert while (__n--)
189*404b540aSrobert {
190*404b540aSrobert new(__o++) _Tp(*__a);
191*404b540aSrobert __a += __s;
192*404b540aSrobert }
193*404b540aSrobert }
194*404b540aSrobert
195*404b540aSrobert // copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]]
196*404b540aSrobert template<typename _Tp>
197*404b540aSrobert inline void
198*404b540aSrobert __valarray_copy_construct (const _Tp* __restrict__ __a,
199*404b540aSrobert const size_t* __restrict__ __i,
200*404b540aSrobert _Tp* __restrict__ __o, size_t __n)
201*404b540aSrobert {
202*404b540aSrobert if (__is_pod<_Tp>::__value)
203*404b540aSrobert while (__n--)
204*404b540aSrobert *__o++ = __a[*__i++];
205*404b540aSrobert else
206*404b540aSrobert while (__n--)
207*404b540aSrobert new (__o++) _Tp(__a[*__i++]);
208*404b540aSrobert }
209*404b540aSrobert
210*404b540aSrobert // Do the necessary cleanup when we're done with arrays.
211*404b540aSrobert template<typename _Tp>
212*404b540aSrobert inline void
213*404b540aSrobert __valarray_destroy_elements(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
214*404b540aSrobert {
215*404b540aSrobert if (!__is_pod<_Tp>::__value)
216*404b540aSrobert while (__b != __e)
217*404b540aSrobert {
218*404b540aSrobert __b->~_Tp();
219*404b540aSrobert ++__b;
220*404b540aSrobert }
221*404b540aSrobert }
222*404b540aSrobert
223*404b540aSrobert // Fill a plain array __a[<__n>] with __t
224*404b540aSrobert template<typename _Tp>
225*404b540aSrobert inline void
226*404b540aSrobert __valarray_fill(_Tp* __restrict__ __a, size_t __n, const _Tp& __t)
227*404b540aSrobert {
228*404b540aSrobert while (__n--)
229*404b540aSrobert *__a++ = __t;
230*404b540aSrobert }
231*404b540aSrobert
232*404b540aSrobert // fill strided array __a[<__n-1 : __s>] with __t
233*404b540aSrobert template<typename _Tp>
234*404b540aSrobert inline void
235*404b540aSrobert __valarray_fill(_Tp* __restrict__ __a, size_t __n,
236*404b540aSrobert size_t __s, const _Tp& __t)
237*404b540aSrobert {
238*404b540aSrobert for (size_t __i = 0; __i < __n; ++__i, __a += __s)
239*404b540aSrobert *__a = __t;
240*404b540aSrobert }
241*404b540aSrobert
242*404b540aSrobert // fill indir ect array __a[__i[<__n>]] with __i
243*404b540aSrobert template<typename _Tp>
244*404b540aSrobert inline void
245*404b540aSrobert __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i,
246*404b540aSrobert size_t __n, const _Tp& __t)
247*404b540aSrobert {
248*404b540aSrobert for (size_t __j = 0; __j < __n; ++__j, ++__i)
249*404b540aSrobert __a[*__i] = __t;
250*404b540aSrobert }
251*404b540aSrobert
252*404b540aSrobert // copy plain array __a[<__n>] in __b[<__n>]
253*404b540aSrobert // For non-fundamental types, it is wrong to say 'memcpy()'
254*404b540aSrobert template<typename _Tp, bool>
255*404b540aSrobert struct _Array_copier
256*404b540aSrobert {
257*404b540aSrobert inline static void
258*404b540aSrobert _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
259*404b540aSrobert {
260*404b540aSrobert while(__n--)
261*404b540aSrobert *__b++ = *__a++;
262*404b540aSrobert }
263*404b540aSrobert };
264*404b540aSrobert
265*404b540aSrobert template<typename _Tp>
266*404b540aSrobert struct _Array_copier<_Tp, true>
267*404b540aSrobert {
268*404b540aSrobert inline static void
269*404b540aSrobert _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
270*404b540aSrobert { std::memcpy (__b, __a, __n * sizeof (_Tp)); }
271*404b540aSrobert };
272*404b540aSrobert
273*404b540aSrobert // Copy a plain array __a[<__n>] into a play array __b[<>]
274*404b540aSrobert template<typename _Tp>
275*404b540aSrobert inline void
276*404b540aSrobert __valarray_copy(const _Tp* __restrict__ __a, size_t __n,
277*404b540aSrobert _Tp* __restrict__ __b)
278*404b540aSrobert {
279*404b540aSrobert _Array_copier<_Tp, __is_pod<_Tp>::__value>::_S_do_it(__a, __n, __b);
280*404b540aSrobert }
281*404b540aSrobert
282*404b540aSrobert // Copy strided array __a[<__n : __s>] in plain __b[<__n>]
283*404b540aSrobert template<typename _Tp>
284*404b540aSrobert inline void
285*404b540aSrobert __valarray_copy(const _Tp* __restrict__ __a, size_t __n, size_t __s,
286*404b540aSrobert _Tp* __restrict__ __b)
287*404b540aSrobert {
288*404b540aSrobert for (size_t __i = 0; __i < __n; ++__i, ++__b, __a += __s)
289*404b540aSrobert *__b = *__a;
290*404b540aSrobert }
291*404b540aSrobert
292*404b540aSrobert // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>]
293*404b540aSrobert template<typename _Tp>
294*404b540aSrobert inline void
295*404b540aSrobert __valarray_copy(const _Tp* __restrict__ __a, _Tp* __restrict__ __b,
296*404b540aSrobert size_t __n, size_t __s)
297*404b540aSrobert {
298*404b540aSrobert for (size_t __i = 0; __i < __n; ++__i, ++__a, __b += __s)
299*404b540aSrobert *__b = *__a;
300*404b540aSrobert }
301*404b540aSrobert
302*404b540aSrobert // Copy strided array __src[<__n : __s1>] into another
303*404b540aSrobert // strided array __dst[< : __s2>]. Their sizes must match.
304*404b540aSrobert template<typename _Tp>
305*404b540aSrobert inline void
306*404b540aSrobert __valarray_copy(const _Tp* __restrict__ __src, size_t __n, size_t __s1,
307*404b540aSrobert _Tp* __restrict__ __dst, size_t __s2)
308*404b540aSrobert {
309*404b540aSrobert for (size_t __i = 0; __i < __n; ++__i)
310*404b540aSrobert __dst[__i * __s2] = __src[__i * __s1];
311*404b540aSrobert }
312*404b540aSrobert
313*404b540aSrobert // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>]
314*404b540aSrobert template<typename _Tp>
315*404b540aSrobert inline void
316*404b540aSrobert __valarray_copy(const _Tp* __restrict__ __a,
317*404b540aSrobert const size_t* __restrict__ __i,
318*404b540aSrobert _Tp* __restrict__ __b, size_t __n)
319*404b540aSrobert {
320*404b540aSrobert for (size_t __j = 0; __j < __n; ++__j, ++__b, ++__i)
321*404b540aSrobert *__b = __a[*__i];
322*404b540aSrobert }
323*404b540aSrobert
324*404b540aSrobert // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]]
325*404b540aSrobert template<typename _Tp>
326*404b540aSrobert inline void
327*404b540aSrobert __valarray_copy(const _Tp* __restrict__ __a, size_t __n,
328*404b540aSrobert _Tp* __restrict__ __b, const size_t* __restrict__ __i)
329*404b540aSrobert {
330*404b540aSrobert for (size_t __j = 0; __j < __n; ++__j, ++__a, ++__i)
331*404b540aSrobert __b[*__i] = *__a;
332*404b540aSrobert }
333*404b540aSrobert
334*404b540aSrobert // Copy the __n first elements of an indexed array __src[<__i>] into
335*404b540aSrobert // another indexed array __dst[<__j>].
336*404b540aSrobert template<typename _Tp>
337*404b540aSrobert inline void
338*404b540aSrobert __valarray_copy(const _Tp* __restrict__ __src, size_t __n,
339*404b540aSrobert const size_t* __restrict__ __i,
340*404b540aSrobert _Tp* __restrict__ __dst, const size_t* __restrict__ __j)
341*404b540aSrobert {
342*404b540aSrobert for (size_t __k = 0; __k < __n; ++__k)
343*404b540aSrobert __dst[*__j++] = __src[*__i++];
344*404b540aSrobert }
345*404b540aSrobert
346*404b540aSrobert //
347*404b540aSrobert // Compute the sum of elements in range [__f, __l)
348*404b540aSrobert // This is a naive algorithm. It suffers from cancelling.
349*404b540aSrobert // In the future try to specialize
350*404b540aSrobert // for _Tp = float, double, long double using a more accurate
351*404b540aSrobert // algorithm.
352*404b540aSrobert //
353*404b540aSrobert template<typename _Tp>
354*404b540aSrobert inline _Tp
355*404b540aSrobert __valarray_sum(const _Tp* __restrict__ __f, const _Tp* __restrict__ __l)
356*404b540aSrobert {
357*404b540aSrobert _Tp __r = _Tp();
358*404b540aSrobert while (__f != __l)
359*404b540aSrobert __r += *__f++;
360*404b540aSrobert return __r;
361*404b540aSrobert }
362*404b540aSrobert
363*404b540aSrobert // Compute the product of all elements in range [__f, __l)
364*404b540aSrobert template<typename _Tp>
365*404b540aSrobert inline _Tp
366*404b540aSrobert __valarray_product(const _Tp* __restrict__ __f,
367*404b540aSrobert const _Tp* __restrict__ __l)
368*404b540aSrobert {
369*404b540aSrobert _Tp __r = _Tp(1);
370*404b540aSrobert while (__f != __l)
371*404b540aSrobert __r = __r * *__f++;
372*404b540aSrobert return __r;
373*404b540aSrobert }
374*404b540aSrobert
375*404b540aSrobert // Compute the min/max of an array-expression
376*404b540aSrobert template<typename _Ta>
377*404b540aSrobert inline typename _Ta::value_type
378*404b540aSrobert __valarray_min(const _Ta& __a)
379*404b540aSrobert {
380*404b540aSrobert size_t __s = __a.size();
381*404b540aSrobert typedef typename _Ta::value_type _Value_type;
382*404b540aSrobert _Value_type __r = __s == 0 ? _Value_type() : __a[0];
383*404b540aSrobert for (size_t __i = 1; __i < __s; ++__i)
384*404b540aSrobert {
385*404b540aSrobert _Value_type __t = __a[__i];
386*404b540aSrobert if (__t < __r)
387*404b540aSrobert __r = __t;
388*404b540aSrobert }
389*404b540aSrobert return __r;
390*404b540aSrobert }
391*404b540aSrobert
392*404b540aSrobert template<typename _Ta>
393*404b540aSrobert inline typename _Ta::value_type
394*404b540aSrobert __valarray_max(const _Ta& __a)
395*404b540aSrobert {
396*404b540aSrobert size_t __s = __a.size();
397*404b540aSrobert typedef typename _Ta::value_type _Value_type;
398*404b540aSrobert _Value_type __r = __s == 0 ? _Value_type() : __a[0];
399*404b540aSrobert for (size_t __i = 1; __i < __s; ++__i)
400*404b540aSrobert {
401*404b540aSrobert _Value_type __t = __a[__i];
402*404b540aSrobert if (__t > __r)
403*404b540aSrobert __r = __t;
404*404b540aSrobert }
405*404b540aSrobert return __r;
406*404b540aSrobert }
407*404b540aSrobert
408*404b540aSrobert //
409*404b540aSrobert // Helper class _Array, first layer of valarray abstraction.
410*404b540aSrobert // All operations on valarray should be forwarded to this class
411*404b540aSrobert // whenever possible. -- gdr
412*404b540aSrobert //
413*404b540aSrobert
414*404b540aSrobert template<typename _Tp>
415*404b540aSrobert struct _Array
416*404b540aSrobert {
417*404b540aSrobert explicit _Array(size_t);
418*404b540aSrobert explicit _Array(_Tp* const __restrict__);
419*404b540aSrobert explicit _Array(const valarray<_Tp>&);
420*404b540aSrobert _Array(const _Tp* __restrict__, size_t);
421*404b540aSrobert
422*404b540aSrobert _Tp* begin() const;
423*404b540aSrobert
424*404b540aSrobert _Tp* const __restrict__ _M_data;
425*404b540aSrobert };
426*404b540aSrobert
427*404b540aSrobert
428*404b540aSrobert // Copy-construct plain array __b[<__n>] from indexed array __a[__i[<__n>]]
429*404b540aSrobert template<typename _Tp>
430*404b540aSrobert inline void
431*404b540aSrobert __valarray_copy_construct(_Array<_Tp> __a, _Array<size_t> __i,
432*404b540aSrobert _Array<_Tp> __b, size_t __n)
433*404b540aSrobert { std::__valarray_copy_construct(__a._M_data, __i._M_data,
434*404b540aSrobert __b._M_data, __n); }
435*404b540aSrobert
436*404b540aSrobert // Copy-construct plain array __b[<__n>] from strided array __a[<__n : __s>]
437*404b540aSrobert template<typename _Tp>
438*404b540aSrobert inline void
439*404b540aSrobert __valarray_copy_construct(_Array<_Tp> __a, size_t __n, size_t __s,
440*404b540aSrobert _Array<_Tp> __b)
441*404b540aSrobert { std::__valarray_copy_construct(__a._M_data, __n, __s, __b._M_data); }
442*404b540aSrobert
443*404b540aSrobert template<typename _Tp>
444*404b540aSrobert inline void
445*404b540aSrobert __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t)
446*404b540aSrobert { std::__valarray_fill(__a._M_data, __n, __t); }
447*404b540aSrobert
448*404b540aSrobert template<typename _Tp>
449*404b540aSrobert inline void
450*404b540aSrobert __valarray_fill(_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t)
451*404b540aSrobert { std::__valarray_fill(__a._M_data, __n, __s, __t); }
452*404b540aSrobert
453*404b540aSrobert template<typename _Tp>
454*404b540aSrobert inline void
455*404b540aSrobert __valarray_fill(_Array<_Tp> __a, _Array<size_t> __i,
456*404b540aSrobert size_t __n, const _Tp& __t)
457*404b540aSrobert { std::__valarray_fill(__a._M_data, __i._M_data, __n, __t); }
458*404b540aSrobert
459*404b540aSrobert // Copy a plain array __a[<__n>] into a play array __b[<>]
460*404b540aSrobert template<typename _Tp>
461*404b540aSrobert inline void
462*404b540aSrobert __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b)
463*404b540aSrobert { std::__valarray_copy(__a._M_data, __n, __b._M_data); }
464*404b540aSrobert
465*404b540aSrobert // Copy strided array __a[<__n : __s>] in plain __b[<__n>]
466*404b540aSrobert template<typename _Tp>
467*404b540aSrobert inline void
468*404b540aSrobert __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b)
469*404b540aSrobert { std::__valarray_copy(__a._M_data, __n, __s, __b._M_data); }
470*404b540aSrobert
471*404b540aSrobert // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>]
472*404b540aSrobert template<typename _Tp>
473*404b540aSrobert inline void
474*404b540aSrobert __valarray_copy(_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s)
475*404b540aSrobert { __valarray_copy(__a._M_data, __b._M_data, __n, __s); }
476*404b540aSrobert
477*404b540aSrobert // Copy strided array __src[<__n : __s1>] into another
478*404b540aSrobert // strided array __dst[< : __s2>]. Their sizes must match.
479*404b540aSrobert template<typename _Tp>
480*404b540aSrobert inline void
481*404b540aSrobert __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s1,
482*404b540aSrobert _Array<_Tp> __b, size_t __s2)
483*404b540aSrobert { std::__valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); }
484*404b540aSrobert
485*404b540aSrobert // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>]
486*404b540aSrobert template<typename _Tp>
487*404b540aSrobert inline void
488*404b540aSrobert __valarray_copy(_Array<_Tp> __a, _Array<size_t> __i,
489*404b540aSrobert _Array<_Tp> __b, size_t __n)
490*404b540aSrobert { std::__valarray_copy(__a._M_data, __i._M_data, __b._M_data, __n); }
491*404b540aSrobert
492*404b540aSrobert // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]]
493*404b540aSrobert template<typename _Tp>
494*404b540aSrobert inline void
495*404b540aSrobert __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b,
496*404b540aSrobert _Array<size_t> __i)
497*404b540aSrobert { std::__valarray_copy(__a._M_data, __n, __b._M_data, __i._M_data); }
498*404b540aSrobert
499*404b540aSrobert // Copy the __n first elements of an indexed array __src[<__i>] into
500*404b540aSrobert // another indexed array __dst[<__j>].
501*404b540aSrobert template<typename _Tp>
502*404b540aSrobert inline void
503*404b540aSrobert __valarray_copy(_Array<_Tp> __src, size_t __n, _Array<size_t> __i,
504*404b540aSrobert _Array<_Tp> __dst, _Array<size_t> __j)
505*404b540aSrobert {
506*404b540aSrobert std::__valarray_copy(__src._M_data, __n, __i._M_data,
507*404b540aSrobert __dst._M_data, __j._M_data);
508*404b540aSrobert }
509*404b540aSrobert
510*404b540aSrobert template<typename _Tp>
511*404b540aSrobert inline
512*404b540aSrobert _Array<_Tp>::_Array(size_t __n)
513*404b540aSrobert : _M_data(__valarray_get_storage<_Tp>(__n))
514*404b540aSrobert { std::__valarray_default_construct(_M_data, _M_data + __n); }
515*404b540aSrobert
516*404b540aSrobert template<typename _Tp>
517*404b540aSrobert inline
518*404b540aSrobert _Array<_Tp>::_Array(_Tp* const __restrict__ __p)
519*404b540aSrobert : _M_data (__p) {}
520*404b540aSrobert
521*404b540aSrobert template<typename _Tp>
522*404b540aSrobert inline
523*404b540aSrobert _Array<_Tp>::_Array(const valarray<_Tp>& __v)
524*404b540aSrobert : _M_data (__v._M_data) {}
525*404b540aSrobert
526*404b540aSrobert template<typename _Tp>
527*404b540aSrobert inline
528*404b540aSrobert _Array<_Tp>::_Array(const _Tp* __restrict__ __b, size_t __s)
529*404b540aSrobert : _M_data(__valarray_get_storage<_Tp>(__s))
530*404b540aSrobert { std::__valarray_copy_construct(__b, __s, _M_data); }
531*404b540aSrobert
532*404b540aSrobert template<typename _Tp>
533*404b540aSrobert inline _Tp*
534*404b540aSrobert _Array<_Tp>::begin () const
535*404b540aSrobert { return _M_data; }
536*404b540aSrobert
537*404b540aSrobert #define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \
538*404b540aSrobert template<typename _Tp> \
539*404b540aSrobert inline void \
540*404b540aSrobert _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, const _Tp& __t) \
541*404b540aSrobert { \
542*404b540aSrobert for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; ++__p) \
543*404b540aSrobert *__p _Op##= __t; \
544*404b540aSrobert } \
545*404b540aSrobert \
546*404b540aSrobert template<typename _Tp> \
547*404b540aSrobert inline void \
548*404b540aSrobert _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \
549*404b540aSrobert { \
550*404b540aSrobert _Tp* __p = __a._M_data; \
551*404b540aSrobert for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; ++__p, ++__q) \
552*404b540aSrobert *__p _Op##= *__q; \
553*404b540aSrobert } \
554*404b540aSrobert \
555*404b540aSrobert template<typename _Tp, class _Dom> \
556*404b540aSrobert void \
557*404b540aSrobert _Array_augmented_##_Name(_Array<_Tp> __a, \
558*404b540aSrobert const _Expr<_Dom, _Tp>& __e, size_t __n) \
559*404b540aSrobert { \
560*404b540aSrobert _Tp* __p(__a._M_data); \
561*404b540aSrobert for (size_t __i = 0; __i < __n; ++__i, ++__p) \
562*404b540aSrobert *__p _Op##= __e[__i]; \
563*404b540aSrobert } \
564*404b540aSrobert \
565*404b540aSrobert template<typename _Tp> \
566*404b540aSrobert inline void \
567*404b540aSrobert _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, size_t __s, \
568*404b540aSrobert _Array<_Tp> __b) \
569*404b540aSrobert { \
570*404b540aSrobert _Tp* __q(__b._M_data); \
571*404b540aSrobert for (_Tp* __p = __a._M_data; __p < __a._M_data + __s * __n; \
572*404b540aSrobert __p += __s, ++__q) \
573*404b540aSrobert *__p _Op##= *__q; \
574*404b540aSrobert } \
575*404b540aSrobert \
576*404b540aSrobert template<typename _Tp> \
577*404b540aSrobert inline void \
578*404b540aSrobert _Array_augmented_##_Name(_Array<_Tp> __a, _Array<_Tp> __b, \
579*404b540aSrobert size_t __n, size_t __s) \
580*404b540aSrobert { \
581*404b540aSrobert _Tp* __q(__b._M_data); \
582*404b540aSrobert for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; \
583*404b540aSrobert ++__p, __q += __s) \
584*404b540aSrobert *__p _Op##= *__q; \
585*404b540aSrobert } \
586*404b540aSrobert \
587*404b540aSrobert template<typename _Tp, class _Dom> \
588*404b540aSrobert void \
589*404b540aSrobert _Array_augmented_##_Name(_Array<_Tp> __a, size_t __s, \
590*404b540aSrobert const _Expr<_Dom, _Tp>& __e, size_t __n) \
591*404b540aSrobert { \
592*404b540aSrobert _Tp* __p(__a._M_data); \
593*404b540aSrobert for (size_t __i = 0; __i < __n; ++__i, __p += __s) \
594*404b540aSrobert *__p _Op##= __e[__i]; \
595*404b540aSrobert } \
596*404b540aSrobert \
597*404b540aSrobert template<typename _Tp> \
598*404b540aSrobert inline void \
599*404b540aSrobert _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i, \
600*404b540aSrobert _Array<_Tp> __b, size_t __n) \
601*404b540aSrobert { \
602*404b540aSrobert _Tp* __q(__b._M_data); \
603*404b540aSrobert for (size_t* __j = __i._M_data; __j < __i._M_data + __n; \
604*404b540aSrobert ++__j, ++__q) \
605*404b540aSrobert __a._M_data[*__j] _Op##= *__q; \
606*404b540aSrobert } \
607*404b540aSrobert \
608*404b540aSrobert template<typename _Tp> \
609*404b540aSrobert inline void \
610*404b540aSrobert _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, \
611*404b540aSrobert _Array<_Tp> __b, _Array<size_t> __i) \
612*404b540aSrobert { \
613*404b540aSrobert _Tp* __p(__a._M_data); \
614*404b540aSrobert for (size_t* __j = __i._M_data; __j<__i._M_data + __n; \
615*404b540aSrobert ++__j, ++__p) \
616*404b540aSrobert *__p _Op##= __b._M_data[*__j]; \
617*404b540aSrobert } \
618*404b540aSrobert \
619*404b540aSrobert template<typename _Tp, class _Dom> \
620*404b540aSrobert void \
621*404b540aSrobert _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i, \
622*404b540aSrobert const _Expr<_Dom, _Tp>& __e, size_t __n) \
623*404b540aSrobert { \
624*404b540aSrobert size_t* __j(__i._M_data); \
625*404b540aSrobert for (size_t __k = 0; __k<__n; ++__k, ++__j) \
626*404b540aSrobert __a._M_data[*__j] _Op##= __e[__k]; \
627*404b540aSrobert } \
628*404b540aSrobert \
629*404b540aSrobert template<typename _Tp> \
630*404b540aSrobert void \
631*404b540aSrobert _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m, \
632*404b540aSrobert _Array<_Tp> __b, size_t __n) \
633*404b540aSrobert { \
634*404b540aSrobert bool* __ok(__m._M_data); \
635*404b540aSrobert _Tp* __p(__a._M_data); \
636*404b540aSrobert for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; \
637*404b540aSrobert ++__q, ++__ok, ++__p) \
638*404b540aSrobert { \
639*404b540aSrobert while (! *__ok) \
640*404b540aSrobert { \
641*404b540aSrobert ++__ok; \
642*404b540aSrobert ++__p; \
643*404b540aSrobert } \
644*404b540aSrobert *__p _Op##= *__q; \
645*404b540aSrobert } \
646*404b540aSrobert } \
647*404b540aSrobert \
648*404b540aSrobert template<typename _Tp> \
649*404b540aSrobert void \
650*404b540aSrobert _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, \
651*404b540aSrobert _Array<_Tp> __b, _Array<bool> __m) \
652*404b540aSrobert { \
653*404b540aSrobert bool* __ok(__m._M_data); \
654*404b540aSrobert _Tp* __q(__b._M_data); \
655*404b540aSrobert for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; \
656*404b540aSrobert ++__p, ++__ok, ++__q) \
657*404b540aSrobert { \
658*404b540aSrobert while (! *__ok) \
659*404b540aSrobert { \
660*404b540aSrobert ++__ok; \
661*404b540aSrobert ++__q; \
662*404b540aSrobert } \
663*404b540aSrobert *__p _Op##= *__q; \
664*404b540aSrobert } \
665*404b540aSrobert } \
666*404b540aSrobert \
667*404b540aSrobert template<typename _Tp, class _Dom> \
668*404b540aSrobert void \
669*404b540aSrobert _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m, \
670*404b540aSrobert const _Expr<_Dom, _Tp>& __e, size_t __n) \
671*404b540aSrobert { \
672*404b540aSrobert bool* __ok(__m._M_data); \
673*404b540aSrobert _Tp* __p(__a._M_data); \
674*404b540aSrobert for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p) \
675*404b540aSrobert { \
676*404b540aSrobert while (! *__ok) \
677*404b540aSrobert { \
678*404b540aSrobert ++__ok; \
679*404b540aSrobert ++__p; \
680*404b540aSrobert } \
681*404b540aSrobert *__p _Op##= __e[__i]; \
682*404b540aSrobert } \
683*404b540aSrobert }
684*404b540aSrobert
685*404b540aSrobert _DEFINE_ARRAY_FUNCTION(+, __plus)
686*404b540aSrobert _DEFINE_ARRAY_FUNCTION(-, __minus)
687*404b540aSrobert _DEFINE_ARRAY_FUNCTION(*, __multiplies)
688*404b540aSrobert _DEFINE_ARRAY_FUNCTION(/, __divides)
689*404b540aSrobert _DEFINE_ARRAY_FUNCTION(%, __modulus)
690*404b540aSrobert _DEFINE_ARRAY_FUNCTION(^, __bitwise_xor)
691*404b540aSrobert _DEFINE_ARRAY_FUNCTION(|, __bitwise_or)
692*404b540aSrobert _DEFINE_ARRAY_FUNCTION(&, __bitwise_and)
693*404b540aSrobert _DEFINE_ARRAY_FUNCTION(<<, __shift_left)
694*404b540aSrobert _DEFINE_ARRAY_FUNCTION(>>, __shift_right)
695*404b540aSrobert
696*404b540aSrobert #undef _DEFINE_ARRAY_FUNCTION
697*404b540aSrobert
698*404b540aSrobert _GLIBCXX_END_NAMESPACE
699*404b540aSrobert
700*404b540aSrobert #ifndef _GLIBCXX_EXPORT_TEMPLATE
701*404b540aSrobert # include <bits/valarray_array.tcc>
702*404b540aSrobert #endif
703*404b540aSrobert
704*404b540aSrobert #endif /* _ARRAY_H */
705