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