100db7afdSDavid E. O'Brien // The template and inlines for the -*- C++ -*- internal _Array helper class.
200db7afdSDavid E. O'Brien 
3*f8a1b7d9SAlexander Kabaev // Copyright (C) 1997, 1998, 1999, 2000, 2003, 2004, 2005, 2006
4ffeaf689SAlexander Kabaev //  Free Software Foundation, Inc.
500db7afdSDavid E. O'Brien //
600db7afdSDavid E. O'Brien // This file is part of the GNU ISO C++ Library.  This library is free
700db7afdSDavid E. O'Brien // software; you can redistribute it and/or modify it under the
800db7afdSDavid E. O'Brien // terms of the GNU General Public License as published by the
900db7afdSDavid E. O'Brien // Free Software Foundation; either version 2, or (at your option)
1000db7afdSDavid E. O'Brien // any later version.
1100db7afdSDavid E. O'Brien 
1200db7afdSDavid E. O'Brien // This library is distributed in the hope that it will be useful,
1300db7afdSDavid E. O'Brien // but WITHOUT ANY WARRANTY; without even the implied warranty of
1400db7afdSDavid E. O'Brien // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1500db7afdSDavid E. O'Brien // GNU General Public License for more details.
1600db7afdSDavid E. O'Brien 
1700db7afdSDavid E. O'Brien // You should have received a copy of the GNU General Public License along
1800db7afdSDavid E. O'Brien // with this library; see the file COPYING.  If not, write to the Free
19*f8a1b7d9SAlexander Kabaev // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
2000db7afdSDavid E. O'Brien // USA.
2100db7afdSDavid E. O'Brien 
2200db7afdSDavid E. O'Brien // As a special exception, you may use this file as part of a free software
2300db7afdSDavid E. O'Brien // library without restriction.  Specifically, if other files instantiate
2400db7afdSDavid E. O'Brien // templates or use macros or inline functions from this file, or you compile
2500db7afdSDavid E. O'Brien // this file and link it with other files to produce an executable, this
2600db7afdSDavid E. O'Brien // file does not by itself cause the resulting executable to be covered by
2700db7afdSDavid E. O'Brien // the GNU General Public License.  This exception does not however
2800db7afdSDavid E. O'Brien // invalidate any other reasons why the executable file might be covered by
2900db7afdSDavid E. O'Brien // the GNU General Public License.
3000db7afdSDavid E. O'Brien 
3100db7afdSDavid E. O'Brien /** @file valarray_array.h
3200db7afdSDavid E. O'Brien  *  This is an internal header file, included by other library headers.
3300db7afdSDavid E. O'Brien  *  You should not attempt to use it directly.
3400db7afdSDavid E. O'Brien  */
3500db7afdSDavid E. O'Brien 
36*f8a1b7d9SAlexander Kabaev // Written by Gabriel Dos Reis <[email protected]>
37*f8a1b7d9SAlexander Kabaev 
38ffeaf689SAlexander Kabaev #ifndef _VALARRAY_ARRAY_H
39ffeaf689SAlexander Kabaev #define _VALARRAY_ARRAY_H 1
4000db7afdSDavid E. O'Brien 
4100db7afdSDavid E. O'Brien #pragma GCC system_header
4200db7afdSDavid E. O'Brien 
4300db7afdSDavid E. O'Brien #include <bits/c++config.h>
4400db7afdSDavid E. O'Brien #include <bits/cpp_type_traits.h>
4500db7afdSDavid E. O'Brien #include <cstdlib>
4600db7afdSDavid E. O'Brien #include <cstring>
4700db7afdSDavid E. O'Brien #include <new>
4800db7afdSDavid E. O'Brien 
_GLIBCXX_BEGIN_NAMESPACE(std)49*f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NAMESPACE(std)
50*f8a1b7d9SAlexander Kabaev 
5100db7afdSDavid E. O'Brien   //
5200db7afdSDavid E. O'Brien   // Helper functions on raw pointers
5300db7afdSDavid E. O'Brien   //
5400db7afdSDavid E. O'Brien 
5500db7afdSDavid E. O'Brien   // We get memory by the old fashion way
5600db7afdSDavid E. O'Brien   inline void*
5700db7afdSDavid E. O'Brien   __valarray_get_memory(size_t __n)
5800db7afdSDavid E. O'Brien   { return operator new(__n); }
5900db7afdSDavid E. O'Brien 
6000db7afdSDavid E. O'Brien   template<typename _Tp>
6100db7afdSDavid E. O'Brien     inline _Tp*__restrict__
__valarray_get_storage(size_t __n)6200db7afdSDavid E. O'Brien     __valarray_get_storage(size_t __n)
6300db7afdSDavid E. O'Brien     {
6400db7afdSDavid E. O'Brien       return static_cast<_Tp*__restrict__>
65ffeaf689SAlexander Kabaev 	(std::__valarray_get_memory(__n * sizeof(_Tp)));
6600db7afdSDavid E. O'Brien     }
6700db7afdSDavid E. O'Brien 
6800db7afdSDavid E. O'Brien   // Return memory to the system
6900db7afdSDavid E. O'Brien   inline void
__valarray_release_memory(void * __p)7000db7afdSDavid E. O'Brien   __valarray_release_memory(void* __p)
7100db7afdSDavid E. O'Brien   { operator delete(__p); }
7200db7afdSDavid E. O'Brien 
7300db7afdSDavid E. O'Brien   // Turn a raw-memory into an array of _Tp filled with _Tp()
7400db7afdSDavid E. O'Brien   // This is required in 'valarray<T> v(n);'
7500db7afdSDavid E. O'Brien   template<typename _Tp, bool>
7600db7afdSDavid E. O'Brien     struct _Array_default_ctor
7700db7afdSDavid E. O'Brien     {
7800db7afdSDavid E. O'Brien       // Please note that this isn't exception safe.  But
7900db7afdSDavid E. O'Brien       // valarrays aren't required to be exception safe.
8000db7afdSDavid E. O'Brien       inline static void
_S_do_it_Array_default_ctor8100db7afdSDavid E. O'Brien       _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
82*f8a1b7d9SAlexander Kabaev       {
83*f8a1b7d9SAlexander Kabaev 	while (__b != __e)
84*f8a1b7d9SAlexander Kabaev 	  new(__b++) _Tp();
85*f8a1b7d9SAlexander Kabaev       }
8600db7afdSDavid E. O'Brien     };
8700db7afdSDavid E. O'Brien 
8800db7afdSDavid E. O'Brien   template<typename _Tp>
8900db7afdSDavid E. O'Brien     struct _Array_default_ctor<_Tp, true>
9000db7afdSDavid E. O'Brien     {
9100db7afdSDavid E. O'Brien       // For fundamental types, it suffices to say 'memset()'
9200db7afdSDavid E. O'Brien       inline static void
9300db7afdSDavid E. O'Brien       _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
94ffeaf689SAlexander Kabaev       { std::memset(__b, 0, (__e - __b) * sizeof(_Tp)); }
9500db7afdSDavid E. O'Brien     };
9600db7afdSDavid E. O'Brien 
9700db7afdSDavid E. O'Brien   template<typename _Tp>
9800db7afdSDavid E. O'Brien     inline void
9900db7afdSDavid E. O'Brien     __valarray_default_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
10000db7afdSDavid E. O'Brien     {
101*f8a1b7d9SAlexander Kabaev       _Array_default_ctor<_Tp, __is_pod<_Tp>::__value>::_S_do_it(__b, __e);
10200db7afdSDavid E. O'Brien     }
10300db7afdSDavid E. O'Brien 
10400db7afdSDavid E. O'Brien   // Turn a raw-memory into an array of _Tp filled with __t
10500db7afdSDavid E. O'Brien   // This is the required in valarray<T> v(n, t).  Also
10600db7afdSDavid E. O'Brien   // used in valarray<>::resize().
10700db7afdSDavid E. O'Brien   template<typename _Tp, bool>
10800db7afdSDavid E. O'Brien     struct _Array_init_ctor
10900db7afdSDavid E. O'Brien     {
11000db7afdSDavid E. O'Brien       // Please note that this isn't exception safe.  But
11100db7afdSDavid E. O'Brien       // valarrays aren't required to be exception safe.
11200db7afdSDavid E. O'Brien       inline static void
11300db7afdSDavid E. O'Brien       _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t)
114*f8a1b7d9SAlexander Kabaev       {
115*f8a1b7d9SAlexander Kabaev 	while (__b != __e)
116*f8a1b7d9SAlexander Kabaev 	  new(__b++) _Tp(__t);
117*f8a1b7d9SAlexander Kabaev       }
11800db7afdSDavid E. O'Brien     };
11900db7afdSDavid E. O'Brien 
12000db7afdSDavid E. O'Brien   template<typename _Tp>
12100db7afdSDavid E. O'Brien     struct _Array_init_ctor<_Tp, true>
12200db7afdSDavid E. O'Brien     {
12300db7afdSDavid E. O'Brien       inline static void
12400db7afdSDavid E. O'Brien       _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e,  const _Tp __t)
125*f8a1b7d9SAlexander Kabaev       {
126*f8a1b7d9SAlexander Kabaev 	while (__b != __e)
127*f8a1b7d9SAlexander Kabaev 	  *__b++ = __t;
128*f8a1b7d9SAlexander Kabaev       }
12900db7afdSDavid E. O'Brien     };
13000db7afdSDavid E. O'Brien 
13100db7afdSDavid E. O'Brien   template<typename _Tp>
13200db7afdSDavid E. O'Brien     inline void
13300db7afdSDavid E. O'Brien     __valarray_fill_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e,
13400db7afdSDavid E. O'Brien 			      const _Tp __t)
13500db7afdSDavid E. O'Brien     {
136*f8a1b7d9SAlexander Kabaev       _Array_init_ctor<_Tp, __is_pod<_Tp>::__value>::_S_do_it(__b, __e, __t);
13700db7afdSDavid E. O'Brien     }
13800db7afdSDavid E. O'Brien 
13900db7afdSDavid E. O'Brien   //
14000db7afdSDavid E. O'Brien   // copy-construct raw array [__o, *) from plain array [__b, __e)
14100db7afdSDavid E. O'Brien   // We can't just say 'memcpy()'
14200db7afdSDavid E. O'Brien   //
14300db7afdSDavid E. O'Brien   template<typename _Tp, bool>
14400db7afdSDavid E. O'Brien     struct _Array_copy_ctor
14500db7afdSDavid E. O'Brien     {
14600db7afdSDavid E. O'Brien       // Please note that this isn't exception safe.  But
14700db7afdSDavid E. O'Brien       // valarrays aren't required to be exception safe.
14800db7afdSDavid E. O'Brien       inline static void
14900db7afdSDavid E. O'Brien       _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e,
15000db7afdSDavid E. O'Brien 	       _Tp* __restrict__ __o)
151*f8a1b7d9SAlexander Kabaev       {
152*f8a1b7d9SAlexander Kabaev 	while (__b != __e)
153*f8a1b7d9SAlexander Kabaev 	  new(__o++) _Tp(*__b++);
154*f8a1b7d9SAlexander Kabaev       }
15500db7afdSDavid E. O'Brien     };
15600db7afdSDavid E. O'Brien 
15700db7afdSDavid E. O'Brien   template<typename _Tp>
15800db7afdSDavid E. O'Brien     struct _Array_copy_ctor<_Tp, true>
15900db7afdSDavid E. O'Brien     {
16000db7afdSDavid E. O'Brien       inline static void
16100db7afdSDavid E. O'Brien       _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e,
16200db7afdSDavid E. O'Brien 	       _Tp* __restrict__ __o)
163ffeaf689SAlexander Kabaev       { std::memcpy(__o, __b, (__e - __b)*sizeof(_Tp)); }
16400db7afdSDavid E. O'Brien     };
16500db7afdSDavid E. O'Brien 
16600db7afdSDavid E. O'Brien   template<typename _Tp>
16700db7afdSDavid E. O'Brien     inline void
16800db7afdSDavid E. O'Brien     __valarray_copy_construct(const _Tp* __restrict__ __b,
16900db7afdSDavid E. O'Brien 			      const _Tp* __restrict__ __e,
17000db7afdSDavid E. O'Brien 			      _Tp* __restrict__ __o)
17100db7afdSDavid E. O'Brien     {
172*f8a1b7d9SAlexander Kabaev       _Array_copy_ctor<_Tp, __is_pod<_Tp>::__value>::_S_do_it(__b, __e, __o);
17300db7afdSDavid E. O'Brien     }
17400db7afdSDavid E. O'Brien 
17500db7afdSDavid E. O'Brien   // copy-construct raw array [__o, *) from strided array __a[<__n : __s>]
17600db7afdSDavid E. O'Brien   template<typename _Tp>
17700db7afdSDavid E. O'Brien     inline void
17800db7afdSDavid E. O'Brien     __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n,
17900db7afdSDavid E. O'Brien 			       size_t __s, _Tp* __restrict__ __o)
18000db7afdSDavid E. O'Brien     {
181*f8a1b7d9SAlexander Kabaev       if (__is_pod<_Tp>::__value)
182*f8a1b7d9SAlexander Kabaev 	while (__n--)
183*f8a1b7d9SAlexander Kabaev 	  {
184*f8a1b7d9SAlexander Kabaev 	    *__o++ = *__a;
185*f8a1b7d9SAlexander Kabaev 	    __a += __s;
186*f8a1b7d9SAlexander Kabaev 	  }
18700db7afdSDavid E. O'Brien       else
188*f8a1b7d9SAlexander Kabaev 	while (__n--)
189*f8a1b7d9SAlexander Kabaev 	  {
190*f8a1b7d9SAlexander Kabaev 	    new(__o++) _Tp(*__a);
191*f8a1b7d9SAlexander Kabaev 	    __a += __s;
192*f8a1b7d9SAlexander Kabaev 	  }
19300db7afdSDavid E. O'Brien     }
19400db7afdSDavid E. O'Brien 
19500db7afdSDavid E. O'Brien   // copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]]
19600db7afdSDavid E. O'Brien   template<typename _Tp>
19700db7afdSDavid E. O'Brien     inline void
19800db7afdSDavid E. O'Brien     __valarray_copy_construct (const _Tp* __restrict__ __a,
19900db7afdSDavid E. O'Brien 			       const size_t* __restrict__ __i,
20000db7afdSDavid E. O'Brien 			       _Tp* __restrict__ __o, size_t __n)
20100db7afdSDavid E. O'Brien     {
202*f8a1b7d9SAlexander Kabaev       if (__is_pod<_Tp>::__value)
203*f8a1b7d9SAlexander Kabaev 	while (__n--)
204*f8a1b7d9SAlexander Kabaev 	  *__o++ = __a[*__i++];
20500db7afdSDavid E. O'Brien       else
206*f8a1b7d9SAlexander Kabaev 	while (__n--)
207*f8a1b7d9SAlexander Kabaev 	  new (__o++) _Tp(__a[*__i++]);
20800db7afdSDavid E. O'Brien     }
20900db7afdSDavid E. O'Brien 
21000db7afdSDavid E. O'Brien   // Do the necessary cleanup when we're done with arrays.
21100db7afdSDavid E. O'Brien   template<typename _Tp>
21200db7afdSDavid E. O'Brien     inline void
21300db7afdSDavid E. O'Brien     __valarray_destroy_elements(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
21400db7afdSDavid E. O'Brien     {
215*f8a1b7d9SAlexander Kabaev       if (!__is_pod<_Tp>::__value)
216*f8a1b7d9SAlexander Kabaev 	while (__b != __e)
217*f8a1b7d9SAlexander Kabaev 	  {
218*f8a1b7d9SAlexander Kabaev 	    __b->~_Tp();
219*f8a1b7d9SAlexander Kabaev 	    ++__b;
220*f8a1b7d9SAlexander Kabaev 	  }
22100db7afdSDavid E. O'Brien     }
22200db7afdSDavid E. O'Brien 
22300db7afdSDavid E. O'Brien   // Fill a plain array __a[<__n>] with __t
22400db7afdSDavid E. O'Brien   template<typename _Tp>
22500db7afdSDavid E. O'Brien     inline void
22600db7afdSDavid E. O'Brien     __valarray_fill(_Tp* __restrict__ __a, size_t __n, const _Tp& __t)
227*f8a1b7d9SAlexander Kabaev     {
228*f8a1b7d9SAlexander Kabaev       while (__n--)
229*f8a1b7d9SAlexander Kabaev 	*__a++ = __t;
230*f8a1b7d9SAlexander Kabaev     }
23100db7afdSDavid E. O'Brien 
23200db7afdSDavid E. O'Brien   // fill strided array __a[<__n-1 : __s>] with __t
23300db7afdSDavid E. O'Brien   template<typename _Tp>
23400db7afdSDavid E. O'Brien     inline void
23500db7afdSDavid E. O'Brien     __valarray_fill(_Tp* __restrict__ __a, size_t __n,
23600db7afdSDavid E. O'Brien 		    size_t __s, const _Tp& __t)
237*f8a1b7d9SAlexander Kabaev     {
238*f8a1b7d9SAlexander Kabaev       for (size_t __i = 0; __i < __n; ++__i, __a += __s)
239*f8a1b7d9SAlexander Kabaev 	*__a = __t;
240*f8a1b7d9SAlexander Kabaev     }
24100db7afdSDavid E. O'Brien 
24200db7afdSDavid E. O'Brien   // fill indir   ect array __a[__i[<__n>]] with __i
24300db7afdSDavid E. O'Brien   template<typename _Tp>
24400db7afdSDavid E. O'Brien     inline void
24500db7afdSDavid E. O'Brien     __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i,
24600db7afdSDavid E. O'Brien 		    size_t __n, const _Tp& __t)
247*f8a1b7d9SAlexander Kabaev     {
248*f8a1b7d9SAlexander Kabaev       for (size_t __j = 0; __j < __n; ++__j, ++__i)
249*f8a1b7d9SAlexander Kabaev 	__a[*__i] = __t;
250*f8a1b7d9SAlexander Kabaev     }
25100db7afdSDavid E. O'Brien 
25200db7afdSDavid E. O'Brien   // copy plain array __a[<__n>] in __b[<__n>]
25300db7afdSDavid E. O'Brien   // For non-fundamental types, it is wrong to say 'memcpy()'
25400db7afdSDavid E. O'Brien   template<typename _Tp, bool>
25500db7afdSDavid E. O'Brien     struct _Array_copier
25600db7afdSDavid E. O'Brien     {
25700db7afdSDavid E. O'Brien       inline static void
25800db7afdSDavid E. O'Brien       _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
259*f8a1b7d9SAlexander Kabaev       {
260*f8a1b7d9SAlexander Kabaev 	while(__n--)
261*f8a1b7d9SAlexander Kabaev 	  *__b++ = *__a++;
262*f8a1b7d9SAlexander Kabaev       }
26300db7afdSDavid E. O'Brien     };
26400db7afdSDavid E. O'Brien 
26500db7afdSDavid E. O'Brien   template<typename _Tp>
26600db7afdSDavid E. O'Brien     struct _Array_copier<_Tp, true>
26700db7afdSDavid E. O'Brien     {
26800db7afdSDavid E. O'Brien       inline static void
26900db7afdSDavid E. O'Brien       _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
270ffeaf689SAlexander Kabaev       { std::memcpy (__b, __a, __n * sizeof (_Tp)); }
27100db7afdSDavid E. O'Brien     };
27200db7afdSDavid E. O'Brien 
27300db7afdSDavid E. O'Brien   // Copy a plain array __a[<__n>] into a play array __b[<>]
27400db7afdSDavid E. O'Brien   template<typename _Tp>
27500db7afdSDavid E. O'Brien     inline void
27600db7afdSDavid E. O'Brien     __valarray_copy(const _Tp* __restrict__ __a, size_t __n,
27700db7afdSDavid E. O'Brien 		    _Tp* __restrict__ __b)
27800db7afdSDavid E. O'Brien     {
279*f8a1b7d9SAlexander Kabaev       _Array_copier<_Tp, __is_pod<_Tp>::__value>::_S_do_it(__a, __n, __b);
28000db7afdSDavid E. O'Brien     }
28100db7afdSDavid E. O'Brien 
28200db7afdSDavid E. O'Brien   // Copy strided array __a[<__n : __s>] in plain __b[<__n>]
28300db7afdSDavid E. O'Brien   template<typename _Tp>
28400db7afdSDavid E. O'Brien     inline void
28500db7afdSDavid E. O'Brien     __valarray_copy(const _Tp* __restrict__ __a, size_t __n, size_t __s,
28600db7afdSDavid E. O'Brien 		    _Tp* __restrict__ __b)
287*f8a1b7d9SAlexander Kabaev     {
288*f8a1b7d9SAlexander Kabaev       for (size_t __i = 0; __i < __n; ++__i, ++__b, __a += __s)
289*f8a1b7d9SAlexander Kabaev 	*__b = *__a;
290*f8a1b7d9SAlexander Kabaev     }
29100db7afdSDavid E. O'Brien 
29200db7afdSDavid E. O'Brien   // Copy a plain array  __a[<__n>] into a strided array __b[<__n : __s>]
29300db7afdSDavid E. O'Brien   template<typename _Tp>
29400db7afdSDavid E. O'Brien     inline void
29500db7afdSDavid E. O'Brien     __valarray_copy(const _Tp* __restrict__ __a, _Tp* __restrict__ __b,
29600db7afdSDavid E. O'Brien 		    size_t __n, size_t __s)
297*f8a1b7d9SAlexander Kabaev     {
298*f8a1b7d9SAlexander Kabaev       for (size_t __i = 0; __i < __n; ++__i, ++__a, __b += __s)
299*f8a1b7d9SAlexander Kabaev 	*__b = *__a;
300*f8a1b7d9SAlexander Kabaev     }
30100db7afdSDavid E. O'Brien 
30200db7afdSDavid E. O'Brien   // Copy strided array __src[<__n : __s1>] into another
30300db7afdSDavid E. O'Brien   // strided array __dst[< : __s2>].  Their sizes must match.
30400db7afdSDavid E. O'Brien   template<typename _Tp>
30500db7afdSDavid E. O'Brien     inline void
30600db7afdSDavid E. O'Brien     __valarray_copy(const _Tp* __restrict__ __src, size_t __n, size_t __s1,
30700db7afdSDavid E. O'Brien 		    _Tp* __restrict__ __dst, size_t __s2)
30800db7afdSDavid E. O'Brien     {
30900db7afdSDavid E. O'Brien       for (size_t __i = 0; __i < __n; ++__i)
31000db7afdSDavid E. O'Brien 	__dst[__i * __s2] = __src[__i * __s1];
31100db7afdSDavid E. O'Brien     }
31200db7afdSDavid E. O'Brien 
31300db7afdSDavid E. O'Brien   // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>]
31400db7afdSDavid E. O'Brien   template<typename _Tp>
31500db7afdSDavid E. O'Brien     inline void
31600db7afdSDavid E. O'Brien     __valarray_copy(const _Tp* __restrict__ __a,
31700db7afdSDavid E. O'Brien 		    const size_t* __restrict__ __i,
31800db7afdSDavid E. O'Brien 		    _Tp* __restrict__ __b, size_t __n)
319*f8a1b7d9SAlexander Kabaev     {
320*f8a1b7d9SAlexander Kabaev       for (size_t __j = 0; __j < __n; ++__j, ++__b, ++__i)
321*f8a1b7d9SAlexander Kabaev 	*__b = __a[*__i];
322*f8a1b7d9SAlexander Kabaev     }
32300db7afdSDavid E. O'Brien 
32400db7afdSDavid E. O'Brien   // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]]
32500db7afdSDavid E. O'Brien   template<typename _Tp>
32600db7afdSDavid E. O'Brien     inline void
32700db7afdSDavid E. O'Brien     __valarray_copy(const _Tp* __restrict__ __a, size_t __n,
32800db7afdSDavid E. O'Brien 		    _Tp* __restrict__ __b, const size_t* __restrict__ __i)
329*f8a1b7d9SAlexander Kabaev     {
330*f8a1b7d9SAlexander Kabaev       for (size_t __j = 0; __j < __n; ++__j, ++__a, ++__i)
331*f8a1b7d9SAlexander Kabaev 	__b[*__i] = *__a;
332*f8a1b7d9SAlexander Kabaev     }
33300db7afdSDavid E. O'Brien 
33400db7afdSDavid E. O'Brien   // Copy the __n first elements of an indexed array __src[<__i>] into
33500db7afdSDavid E. O'Brien   // another indexed array __dst[<__j>].
33600db7afdSDavid E. O'Brien   template<typename _Tp>
33700db7afdSDavid E. O'Brien     inline void
33800db7afdSDavid E. O'Brien     __valarray_copy(const _Tp* __restrict__ __src, size_t __n,
33900db7afdSDavid E. O'Brien 		    const size_t* __restrict__ __i,
34000db7afdSDavid E. O'Brien 		    _Tp* __restrict__ __dst, const size_t* __restrict__ __j)
34100db7afdSDavid E. O'Brien     {
34200db7afdSDavid E. O'Brien       for (size_t __k = 0; __k < __n; ++__k)
34300db7afdSDavid E. O'Brien 	__dst[*__j++] = __src[*__i++];
34400db7afdSDavid E. O'Brien     }
34500db7afdSDavid E. O'Brien 
34600db7afdSDavid E. O'Brien   //
34700db7afdSDavid E. O'Brien   // Compute the sum of elements in range [__f, __l)
34800db7afdSDavid E. O'Brien   // This is a naive algorithm.  It suffers from cancelling.
34900db7afdSDavid E. O'Brien   // In the future try to specialize
35000db7afdSDavid E. O'Brien   // for _Tp = float, double, long double using a more accurate
35100db7afdSDavid E. O'Brien   // algorithm.
35200db7afdSDavid E. O'Brien   //
35300db7afdSDavid E. O'Brien   template<typename _Tp>
35400db7afdSDavid E. O'Brien     inline _Tp
35500db7afdSDavid E. O'Brien     __valarray_sum(const _Tp* __restrict__ __f, const _Tp* __restrict__ __l)
35600db7afdSDavid E. O'Brien     {
35700db7afdSDavid E. O'Brien       _Tp __r = _Tp();
358*f8a1b7d9SAlexander Kabaev       while (__f != __l)
359*f8a1b7d9SAlexander Kabaev 	__r += *__f++;
36000db7afdSDavid E. O'Brien       return __r;
36100db7afdSDavid E. O'Brien     }
36200db7afdSDavid E. O'Brien 
36300db7afdSDavid E. O'Brien   // Compute the product of all elements in range [__f, __l)
36400db7afdSDavid E. O'Brien   template<typename _Tp>
36500db7afdSDavid E. O'Brien     inline _Tp
36600db7afdSDavid E. O'Brien     __valarray_product(const _Tp* __restrict__ __f,
36700db7afdSDavid E. O'Brien 		       const _Tp* __restrict__ __l)
36800db7afdSDavid E. O'Brien     {
36900db7afdSDavid E. O'Brien       _Tp __r = _Tp(1);
370*f8a1b7d9SAlexander Kabaev       while (__f != __l)
371*f8a1b7d9SAlexander Kabaev 	__r = __r * *__f++;
37200db7afdSDavid E. O'Brien       return __r;
37300db7afdSDavid E. O'Brien     }
37400db7afdSDavid E. O'Brien 
37500db7afdSDavid E. O'Brien   // Compute the min/max of an array-expression
37600db7afdSDavid E. O'Brien   template<typename _Ta>
37700db7afdSDavid E. O'Brien     inline typename _Ta::value_type
37800db7afdSDavid E. O'Brien     __valarray_min(const _Ta& __a)
37900db7afdSDavid E. O'Brien     {
38000db7afdSDavid E. O'Brien       size_t __s = __a.size();
38100db7afdSDavid E. O'Brien       typedef typename _Ta::value_type _Value_type;
38200db7afdSDavid E. O'Brien       _Value_type __r = __s == 0 ? _Value_type() : __a[0];
38300db7afdSDavid E. O'Brien       for (size_t __i = 1; __i < __s; ++__i)
38400db7afdSDavid E. O'Brien 	{
38500db7afdSDavid E. O'Brien 	  _Value_type __t = __a[__i];
38600db7afdSDavid E. O'Brien 	  if (__t < __r)
38700db7afdSDavid E. O'Brien 	    __r = __t;
38800db7afdSDavid E. O'Brien 	}
38900db7afdSDavid E. O'Brien       return __r;
39000db7afdSDavid E. O'Brien     }
39100db7afdSDavid E. O'Brien 
39200db7afdSDavid E. O'Brien   template<typename _Ta>
39300db7afdSDavid E. O'Brien     inline typename _Ta::value_type
39400db7afdSDavid E. O'Brien     __valarray_max(const _Ta& __a)
39500db7afdSDavid E. O'Brien     {
39600db7afdSDavid E. O'Brien       size_t __s = __a.size();
39700db7afdSDavid E. O'Brien       typedef typename _Ta::value_type _Value_type;
39800db7afdSDavid E. O'Brien       _Value_type __r = __s == 0 ? _Value_type() : __a[0];
39900db7afdSDavid E. O'Brien       for (size_t __i = 1; __i < __s; ++__i)
40000db7afdSDavid E. O'Brien 	{
40100db7afdSDavid E. O'Brien 	  _Value_type __t = __a[__i];
40200db7afdSDavid E. O'Brien 	  if (__t > __r)
40300db7afdSDavid E. O'Brien 	    __r = __t;
40400db7afdSDavid E. O'Brien 	}
40500db7afdSDavid E. O'Brien       return __r;
40600db7afdSDavid E. O'Brien     }
40700db7afdSDavid E. O'Brien 
40800db7afdSDavid E. O'Brien   //
40900db7afdSDavid E. O'Brien   // Helper class _Array, first layer of valarray abstraction.
41000db7afdSDavid E. O'Brien   // All operations on valarray should be forwarded to this class
41100db7afdSDavid E. O'Brien   // whenever possible. -- gdr
41200db7afdSDavid E. O'Brien   //
41300db7afdSDavid E. O'Brien 
41400db7afdSDavid E. O'Brien   template<typename _Tp>
41500db7afdSDavid E. O'Brien     struct _Array
41600db7afdSDavid E. O'Brien     {
41700db7afdSDavid E. O'Brien       explicit _Array(size_t);
41800db7afdSDavid E. O'Brien       explicit _Array(_Tp* const __restrict__);
41900db7afdSDavid E. O'Brien       explicit _Array(const valarray<_Tp>&);
42000db7afdSDavid E. O'Brien       _Array(const _Tp* __restrict__, size_t);
42100db7afdSDavid E. O'Brien 
42200db7afdSDavid E. O'Brien       _Tp* begin() const;
42300db7afdSDavid E. O'Brien 
42400db7afdSDavid E. O'Brien       _Tp* const __restrict__ _M_data;
42500db7afdSDavid E. O'Brien     };
42600db7afdSDavid E. O'Brien 
427*f8a1b7d9SAlexander Kabaev 
428*f8a1b7d9SAlexander Kabaev   // Copy-construct plain array __b[<__n>] from indexed array __a[__i[<__n>]]
429*f8a1b7d9SAlexander Kabaev   template<typename _Tp>
430*f8a1b7d9SAlexander Kabaev     inline void
431*f8a1b7d9SAlexander Kabaev     __valarray_copy_construct(_Array<_Tp> __a, _Array<size_t> __i,
432*f8a1b7d9SAlexander Kabaev 			      _Array<_Tp> __b, size_t __n)
433*f8a1b7d9SAlexander Kabaev     { std::__valarray_copy_construct(__a._M_data, __i._M_data,
434*f8a1b7d9SAlexander Kabaev 				     __b._M_data, __n); }
435*f8a1b7d9SAlexander Kabaev 
436*f8a1b7d9SAlexander Kabaev   // Copy-construct plain array __b[<__n>] from strided array __a[<__n : __s>]
437*f8a1b7d9SAlexander Kabaev   template<typename _Tp>
438*f8a1b7d9SAlexander Kabaev     inline void
439*f8a1b7d9SAlexander Kabaev     __valarray_copy_construct(_Array<_Tp> __a, size_t __n, size_t __s,
440*f8a1b7d9SAlexander Kabaev 			      _Array<_Tp> __b)
441*f8a1b7d9SAlexander Kabaev     { std::__valarray_copy_construct(__a._M_data, __n, __s, __b._M_data); }
442*f8a1b7d9SAlexander Kabaev 
44300db7afdSDavid E. O'Brien   template<typename _Tp>
44400db7afdSDavid E. O'Brien     inline void
44500db7afdSDavid E. O'Brien     __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t)
446ffeaf689SAlexander Kabaev     { std::__valarray_fill(__a._M_data, __n, __t); }
44700db7afdSDavid E. O'Brien 
44800db7afdSDavid E. O'Brien   template<typename _Tp>
44900db7afdSDavid E. O'Brien     inline void
45000db7afdSDavid E. O'Brien     __valarray_fill(_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t)
451ffeaf689SAlexander Kabaev     { std::__valarray_fill(__a._M_data, __n, __s, __t); }
45200db7afdSDavid E. O'Brien 
45300db7afdSDavid E. O'Brien   template<typename _Tp>
45400db7afdSDavid E. O'Brien     inline void
45500db7afdSDavid E. O'Brien     __valarray_fill(_Array<_Tp> __a, _Array<size_t> __i,
45600db7afdSDavid E. O'Brien 		    size_t __n, const _Tp& __t)
457ffeaf689SAlexander Kabaev     { std::__valarray_fill(__a._M_data, __i._M_data, __n, __t); }
45800db7afdSDavid E. O'Brien 
45900db7afdSDavid E. O'Brien   // Copy a plain array __a[<__n>] into a play array __b[<>]
46000db7afdSDavid E. O'Brien   template<typename _Tp>
46100db7afdSDavid E. O'Brien     inline void
46200db7afdSDavid E. O'Brien     __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b)
463ffeaf689SAlexander Kabaev     { std::__valarray_copy(__a._M_data, __n, __b._M_data); }
46400db7afdSDavid E. O'Brien 
46500db7afdSDavid E. O'Brien   // Copy strided array __a[<__n : __s>] in plain __b[<__n>]
46600db7afdSDavid E. O'Brien   template<typename _Tp>
46700db7afdSDavid E. O'Brien     inline void
46800db7afdSDavid E. O'Brien     __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b)
469ffeaf689SAlexander Kabaev     { std::__valarray_copy(__a._M_data, __n, __s, __b._M_data); }
47000db7afdSDavid E. O'Brien 
47100db7afdSDavid E. O'Brien   // Copy a plain array  __a[<__n>] into a strided array __b[<__n : __s>]
47200db7afdSDavid E. O'Brien   template<typename _Tp>
47300db7afdSDavid E. O'Brien     inline void
47400db7afdSDavid E. O'Brien     __valarray_copy(_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s)
47500db7afdSDavid E. O'Brien     { __valarray_copy(__a._M_data, __b._M_data, __n, __s); }
47600db7afdSDavid E. O'Brien 
47700db7afdSDavid E. O'Brien   // Copy strided array __src[<__n : __s1>] into another
47800db7afdSDavid E. O'Brien   // strided array __dst[< : __s2>].  Their sizes must match.
47900db7afdSDavid E. O'Brien   template<typename _Tp>
48000db7afdSDavid E. O'Brien     inline void
48100db7afdSDavid E. O'Brien     __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s1,
48200db7afdSDavid E. O'Brien                     _Array<_Tp> __b, size_t __s2)
483ffeaf689SAlexander Kabaev     { std::__valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); }
48400db7afdSDavid E. O'Brien 
48500db7afdSDavid E. O'Brien   // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>]
48600db7afdSDavid E. O'Brien   template<typename _Tp>
48700db7afdSDavid E. O'Brien     inline void
48800db7afdSDavid E. O'Brien     __valarray_copy(_Array<_Tp> __a, _Array<size_t> __i,
48900db7afdSDavid E. O'Brien 		    _Array<_Tp> __b, size_t __n)
490ffeaf689SAlexander Kabaev     { std::__valarray_copy(__a._M_data, __i._M_data, __b._M_data, __n); }
49100db7afdSDavid E. O'Brien 
49200db7afdSDavid E. O'Brien   // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]]
49300db7afdSDavid E. O'Brien   template<typename _Tp>
49400db7afdSDavid E. O'Brien     inline void
49500db7afdSDavid E. O'Brien     __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b,
49600db7afdSDavid E. O'Brien 		    _Array<size_t> __i)
497ffeaf689SAlexander Kabaev     { std::__valarray_copy(__a._M_data, __n, __b._M_data, __i._M_data); }
49800db7afdSDavid E. O'Brien 
49900db7afdSDavid E. O'Brien   // Copy the __n first elements of an indexed array __src[<__i>] into
50000db7afdSDavid E. O'Brien   // another indexed array __dst[<__j>].
50100db7afdSDavid E. O'Brien   template<typename _Tp>
50200db7afdSDavid E. O'Brien     inline void
50300db7afdSDavid E. O'Brien     __valarray_copy(_Array<_Tp> __src, size_t __n, _Array<size_t> __i,
50400db7afdSDavid E. O'Brien                     _Array<_Tp> __dst, _Array<size_t> __j)
50500db7afdSDavid E. O'Brien     {
506ffeaf689SAlexander Kabaev       std::__valarray_copy(__src._M_data, __n, __i._M_data,
50700db7afdSDavid E. O'Brien 		    __dst._M_data, __j._M_data);
50800db7afdSDavid E. O'Brien     }
50900db7afdSDavid E. O'Brien 
51000db7afdSDavid E. O'Brien   template<typename _Tp>
51100db7afdSDavid E. O'Brien     inline
51200db7afdSDavid E. O'Brien     _Array<_Tp>::_Array(size_t __n)
51300db7afdSDavid E. O'Brien     : _M_data(__valarray_get_storage<_Tp>(__n))
514ffeaf689SAlexander Kabaev     { std::__valarray_default_construct(_M_data, _M_data + __n); }
51500db7afdSDavid E. O'Brien 
51600db7afdSDavid E. O'Brien   template<typename _Tp>
51700db7afdSDavid E. O'Brien     inline
518*f8a1b7d9SAlexander Kabaev     _Array<_Tp>::_Array(_Tp* const __restrict__ __p)
519*f8a1b7d9SAlexander Kabaev     : _M_data (__p) {}
52000db7afdSDavid E. O'Brien 
52100db7afdSDavid E. O'Brien   template<typename _Tp>
522*f8a1b7d9SAlexander Kabaev     inline
523*f8a1b7d9SAlexander Kabaev     _Array<_Tp>::_Array(const valarray<_Tp>& __v)
52400db7afdSDavid E. O'Brien     : _M_data (__v._M_data) {}
52500db7afdSDavid E. O'Brien 
52600db7afdSDavid E. O'Brien   template<typename _Tp>
52700db7afdSDavid E. O'Brien     inline
52800db7afdSDavid E. O'Brien     _Array<_Tp>::_Array(const _Tp* __restrict__ __b, size_t __s)
52900db7afdSDavid E. O'Brien     : _M_data(__valarray_get_storage<_Tp>(__s))
530ffeaf689SAlexander Kabaev     { std::__valarray_copy_construct(__b, __s, _M_data); }
53100db7afdSDavid E. O'Brien 
53200db7afdSDavid E. O'Brien   template<typename _Tp>
53300db7afdSDavid E. O'Brien     inline _Tp*
53400db7afdSDavid E. O'Brien     _Array<_Tp>::begin () const
53500db7afdSDavid E. O'Brien     { return _M_data; }
53600db7afdSDavid E. O'Brien 
53700db7afdSDavid E. O'Brien #define _DEFINE_ARRAY_FUNCTION(_Op, _Name)				\
53800db7afdSDavid E. O'Brien   template<typename _Tp>		        			\
53900db7afdSDavid E. O'Brien     inline void								\
54000db7afdSDavid E. O'Brien     _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, const _Tp& __t) \
54100db7afdSDavid E. O'Brien     {									\
54200db7afdSDavid E. O'Brien       for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; ++__p)	\
54300db7afdSDavid E. O'Brien         *__p _Op##= __t;						\
54400db7afdSDavid E. O'Brien     }									\
54500db7afdSDavid E. O'Brien 									\
54600db7afdSDavid E. O'Brien   template<typename _Tp>						\
54700db7afdSDavid E. O'Brien     inline void								\
54800db7afdSDavid E. O'Brien     _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \
54900db7afdSDavid E. O'Brien     {									\
55000db7afdSDavid E. O'Brien       _Tp* __p = __a._M_data;						\
55100db7afdSDavid E. O'Brien       for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; ++__p, ++__q) \
55200db7afdSDavid E. O'Brien         *__p _Op##= *__q;						\
55300db7afdSDavid E. O'Brien     }									\
55400db7afdSDavid E. O'Brien 									\
55500db7afdSDavid E. O'Brien   template<typename _Tp, class _Dom>					\
55600db7afdSDavid E. O'Brien     void								\
55700db7afdSDavid E. O'Brien     _Array_augmented_##_Name(_Array<_Tp> __a,	        		\
55800db7afdSDavid E. O'Brien                              const _Expr<_Dom, _Tp>& __e, size_t __n)	\
55900db7afdSDavid E. O'Brien     {									\
56000db7afdSDavid E. O'Brien       _Tp* __p(__a._M_data);						\
561*f8a1b7d9SAlexander Kabaev       for (size_t __i = 0; __i < __n; ++__i, ++__p)                     \
562*f8a1b7d9SAlexander Kabaev         *__p _Op##= __e[__i];                                          	\
56300db7afdSDavid E. O'Brien     }									\
56400db7afdSDavid E. O'Brien 									\
56500db7afdSDavid E. O'Brien   template<typename _Tp>						\
56600db7afdSDavid E. O'Brien     inline void								\
56700db7afdSDavid E. O'Brien     _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, size_t __s,	\
56800db7afdSDavid E. O'Brien 	                     _Array<_Tp> __b)				\
56900db7afdSDavid E. O'Brien     {									\
57000db7afdSDavid E. O'Brien       _Tp* __q(__b._M_data);						\
571*f8a1b7d9SAlexander Kabaev       for (_Tp* __p = __a._M_data; __p < __a._M_data + __s * __n;       \
572*f8a1b7d9SAlexander Kabaev 	   __p += __s, ++__q)                                           \
57300db7afdSDavid E. O'Brien         *__p _Op##= *__q;						\
57400db7afdSDavid E. O'Brien     }									\
57500db7afdSDavid E. O'Brien 									\
57600db7afdSDavid E. O'Brien   template<typename _Tp>						\
57700db7afdSDavid E. O'Brien     inline void								\
57800db7afdSDavid E. O'Brien     _Array_augmented_##_Name(_Array<_Tp> __a, _Array<_Tp> __b,		\
57900db7afdSDavid E. O'Brien 		             size_t __n, size_t __s)			\
58000db7afdSDavid E. O'Brien     {									\
58100db7afdSDavid E. O'Brien       _Tp* __q(__b._M_data);						\
582*f8a1b7d9SAlexander Kabaev       for (_Tp* __p = __a._M_data; __p < __a._M_data + __n;             \
583*f8a1b7d9SAlexander Kabaev 	   ++__p, __q += __s)                                           \
58400db7afdSDavid E. O'Brien         *__p _Op##= *__q;						\
58500db7afdSDavid E. O'Brien     }									\
58600db7afdSDavid E. O'Brien 									\
58700db7afdSDavid E. O'Brien   template<typename _Tp, class _Dom>					\
58800db7afdSDavid E. O'Brien     void								\
58900db7afdSDavid E. O'Brien     _Array_augmented_##_Name(_Array<_Tp> __a, size_t __s,		\
59000db7afdSDavid E. O'Brien                              const _Expr<_Dom, _Tp>& __e, size_t __n)	\
59100db7afdSDavid E. O'Brien     {									\
59200db7afdSDavid E. O'Brien       _Tp* __p(__a._M_data);						\
593*f8a1b7d9SAlexander Kabaev       for (size_t __i = 0; __i < __n; ++__i, __p += __s)                \
594*f8a1b7d9SAlexander Kabaev         *__p _Op##= __e[__i];                                          	\
59500db7afdSDavid E. O'Brien     }									\
59600db7afdSDavid E. O'Brien 									\
59700db7afdSDavid E. O'Brien   template<typename _Tp>						\
59800db7afdSDavid E. O'Brien     inline void								\
59900db7afdSDavid E. O'Brien     _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i,	\
60000db7afdSDavid E. O'Brien                              _Array<_Tp> __b, size_t __n)		\
60100db7afdSDavid E. O'Brien     {									\
60200db7afdSDavid E. O'Brien       _Tp* __q(__b._M_data);						\
603*f8a1b7d9SAlexander Kabaev       for (size_t* __j = __i._M_data; __j < __i._M_data + __n;          \
604*f8a1b7d9SAlexander Kabaev            ++__j, ++__q)                                                \
60500db7afdSDavid E. O'Brien         __a._M_data[*__j] _Op##= *__q;					\
60600db7afdSDavid E. O'Brien     }									\
60700db7afdSDavid E. O'Brien 									\
60800db7afdSDavid E. O'Brien   template<typename _Tp>						\
60900db7afdSDavid E. O'Brien     inline void					        		\
61000db7afdSDavid E. O'Brien     _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n,		\
61100db7afdSDavid E. O'Brien                              _Array<_Tp> __b, _Array<size_t> __i)	\
61200db7afdSDavid E. O'Brien     {									\
61300db7afdSDavid E. O'Brien       _Tp* __p(__a._M_data);						\
614*f8a1b7d9SAlexander Kabaev       for (size_t* __j = __i._M_data; __j<__i._M_data + __n;            \
615*f8a1b7d9SAlexander Kabaev 	   ++__j, ++__p)                                                \
61600db7afdSDavid E. O'Brien         *__p _Op##= __b._M_data[*__j];					\
61700db7afdSDavid E. O'Brien     }									\
61800db7afdSDavid E. O'Brien 									\
61900db7afdSDavid E. O'Brien   template<typename _Tp, class _Dom>					\
62000db7afdSDavid E. O'Brien     void								\
62100db7afdSDavid E. O'Brien     _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i,	\
62200db7afdSDavid E. O'Brien                              const _Expr<_Dom, _Tp>& __e, size_t __n)	\
62300db7afdSDavid E. O'Brien     {									\
62400db7afdSDavid E. O'Brien       size_t* __j(__i._M_data);	        				\
62500db7afdSDavid E. O'Brien       for (size_t __k = 0; __k<__n; ++__k, ++__j)			\
62600db7afdSDavid E. O'Brien         __a._M_data[*__j] _Op##= __e[__k];				\
62700db7afdSDavid E. O'Brien     }									\
62800db7afdSDavid E. O'Brien 									\
62900db7afdSDavid E. O'Brien   template<typename _Tp>						\
63000db7afdSDavid E. O'Brien     void								\
63100db7afdSDavid E. O'Brien     _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m,         \
63200db7afdSDavid E. O'Brien                              _Array<_Tp> __b, size_t __n)		\
63300db7afdSDavid E. O'Brien     {									\
634*f8a1b7d9SAlexander Kabaev       bool* __ok(__m._M_data);						\
63500db7afdSDavid E. O'Brien       _Tp* __p(__a._M_data);						\
636*f8a1b7d9SAlexander Kabaev       for (_Tp* __q = __b._M_data; __q < __b._M_data + __n;             \
637*f8a1b7d9SAlexander Kabaev 	   ++__q, ++__ok, ++__p)                                        \
638*f8a1b7d9SAlexander Kabaev         {                                                               \
639*f8a1b7d9SAlexander Kabaev           while (! *__ok)                                               \
640*f8a1b7d9SAlexander Kabaev             {						        	\
641*f8a1b7d9SAlexander Kabaev               ++__ok;							\
64200db7afdSDavid E. O'Brien               ++__p;							\
64300db7afdSDavid E. O'Brien             }								\
64400db7afdSDavid E. O'Brien           *__p _Op##= *__q;						\
64500db7afdSDavid E. O'Brien         }								\
64600db7afdSDavid E. O'Brien     }									\
64700db7afdSDavid E. O'Brien 									\
64800db7afdSDavid E. O'Brien   template<typename _Tp>						\
64900db7afdSDavid E. O'Brien     void								\
65000db7afdSDavid E. O'Brien     _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n,		\
65100db7afdSDavid E. O'Brien                              _Array<_Tp> __b, _Array<bool> __m)   	\
65200db7afdSDavid E. O'Brien     {									\
653*f8a1b7d9SAlexander Kabaev       bool* __ok(__m._M_data);						\
65400db7afdSDavid E. O'Brien       _Tp* __q(__b._M_data);						\
655*f8a1b7d9SAlexander Kabaev       for (_Tp* __p = __a._M_data; __p < __a._M_data + __n;             \
656*f8a1b7d9SAlexander Kabaev 	   ++__p, ++__ok, ++__q)                                        \
657*f8a1b7d9SAlexander Kabaev         {                                                               \
658*f8a1b7d9SAlexander Kabaev           while (! *__ok)                                               \
659*f8a1b7d9SAlexander Kabaev             {					        		\
660*f8a1b7d9SAlexander Kabaev               ++__ok;							\
66100db7afdSDavid E. O'Brien               ++__q;							\
66200db7afdSDavid E. O'Brien             }								\
66300db7afdSDavid E. O'Brien           *__p _Op##= *__q;						\
66400db7afdSDavid E. O'Brien         }								\
66500db7afdSDavid E. O'Brien     }									\
66600db7afdSDavid E. O'Brien 									\
66700db7afdSDavid E. O'Brien   template<typename _Tp, class _Dom>					\
66800db7afdSDavid E. O'Brien     void								\
66900db7afdSDavid E. O'Brien     _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m,  	\
67000db7afdSDavid E. O'Brien                              const _Expr<_Dom, _Tp>& __e, size_t __n)	\
67100db7afdSDavid E. O'Brien     {									\
672*f8a1b7d9SAlexander Kabaev       bool* __ok(__m._M_data);						\
67300db7afdSDavid E. O'Brien       _Tp* __p(__a._M_data);						\
674*f8a1b7d9SAlexander Kabaev       for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p)             \
675*f8a1b7d9SAlexander Kabaev         {	                                           		\
676*f8a1b7d9SAlexander Kabaev           while (! *__ok)                                               \
677*f8a1b7d9SAlexander Kabaev             {		         					\
678*f8a1b7d9SAlexander Kabaev 	      ++__ok;							\
67900db7afdSDavid E. O'Brien               ++__p;							\
68000db7afdSDavid E. O'Brien             }								\
68100db7afdSDavid E. O'Brien           *__p _Op##= __e[__i];						\
68200db7afdSDavid E. O'Brien         }								\
68300db7afdSDavid E. O'Brien     }
68400db7afdSDavid E. O'Brien 
6851b86b14eSAlexander Kabaev    _DEFINE_ARRAY_FUNCTION(+, __plus)
6861b86b14eSAlexander Kabaev    _DEFINE_ARRAY_FUNCTION(-, __minus)
6871b86b14eSAlexander Kabaev    _DEFINE_ARRAY_FUNCTION(*, __multiplies)
6881b86b14eSAlexander Kabaev    _DEFINE_ARRAY_FUNCTION(/, __divides)
6891b86b14eSAlexander Kabaev    _DEFINE_ARRAY_FUNCTION(%, __modulus)
6901b86b14eSAlexander Kabaev    _DEFINE_ARRAY_FUNCTION(^, __bitwise_xor)
6911b86b14eSAlexander Kabaev    _DEFINE_ARRAY_FUNCTION(|, __bitwise_or)
6921b86b14eSAlexander Kabaev    _DEFINE_ARRAY_FUNCTION(&, __bitwise_and)
6931b86b14eSAlexander Kabaev    _DEFINE_ARRAY_FUNCTION(<<, __shift_left)
6941b86b14eSAlexander Kabaev    _DEFINE_ARRAY_FUNCTION(>>, __shift_right)
69500db7afdSDavid E. O'Brien 
696*f8a1b7d9SAlexander Kabaev #undef _DEFINE_ARRAY_FUNCTION
697*f8a1b7d9SAlexander Kabaev 
698*f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NAMESPACE
69900db7afdSDavid E. O'Brien 
700ffeaf689SAlexander Kabaev #ifndef _GLIBCXX_EXPORT_TEMPLATE
70100db7afdSDavid E. O'Brien # include <bits/valarray_array.tcc>
70200db7afdSDavid E. O'Brien #endif
70300db7afdSDavid E. O'Brien 
704ffeaf689SAlexander Kabaev #endif /* _ARRAY_H */
705