xref: /openbsd-src/gnu/gcc/libstdc++-v3/include/bits/valarray_array.h (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
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