138fd1498Szrj // The template and inlines for the -*- C++ -*- internal _Array helper class.
238fd1498Szrj
338fd1498Szrj // Copyright (C) 1997-2018 Free Software Foundation, Inc.
438fd1498Szrj //
538fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free
638fd1498Szrj // software; you can redistribute it and/or modify it under the
738fd1498Szrj // terms of the GNU General Public License as published by the
838fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
938fd1498Szrj // any later version.
1038fd1498Szrj
1138fd1498Szrj // This library is distributed in the hope that it will be useful,
1238fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
1338fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1438fd1498Szrj // GNU General Public License for more details.
1538fd1498Szrj
1638fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
1738fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
1838fd1498Szrj // 3.1, as published by the Free Software Foundation.
1938fd1498Szrj
2038fd1498Szrj // You should have received a copy of the GNU General Public License and
2138fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
2238fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2338fd1498Szrj // <http://www.gnu.org/licenses/>.
2438fd1498Szrj
2538fd1498Szrj /** @file bits/valarray_array.h
2638fd1498Szrj * This is an internal header file, included by other library headers.
2738fd1498Szrj * Do not attempt to use it directly. @headername{valarray}
2838fd1498Szrj */
2938fd1498Szrj
3038fd1498Szrj // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
3138fd1498Szrj
3238fd1498Szrj #ifndef _VALARRAY_ARRAY_H
3338fd1498Szrj #define _VALARRAY_ARRAY_H 1
3438fd1498Szrj
3538fd1498Szrj #pragma GCC system_header
3638fd1498Szrj
3738fd1498Szrj #include <bits/c++config.h>
3838fd1498Szrj #include <bits/cpp_type_traits.h>
3938fd1498Szrj #include <cstdlib>
4038fd1498Szrj #include <new>
4138fd1498Szrj
_GLIBCXX_VISIBILITY(default)4238fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
4338fd1498Szrj {
4438fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
4538fd1498Szrj
4638fd1498Szrj //
4738fd1498Szrj // Helper functions on raw pointers
4838fd1498Szrj //
4938fd1498Szrj
5038fd1498Szrj // We get memory by the old fashion way
5138fd1498Szrj inline void*
5238fd1498Szrj __valarray_get_memory(size_t __n)
5338fd1498Szrj { return operator new(__n); }
5438fd1498Szrj
5538fd1498Szrj template<typename _Tp>
5638fd1498Szrj inline _Tp*__restrict__
5738fd1498Szrj __valarray_get_storage(size_t __n)
5838fd1498Szrj {
5938fd1498Szrj return static_cast<_Tp*__restrict__>
6038fd1498Szrj (std::__valarray_get_memory(__n * sizeof(_Tp)));
6138fd1498Szrj }
6238fd1498Szrj
6338fd1498Szrj // Return memory to the system
6438fd1498Szrj inline void
6538fd1498Szrj __valarray_release_memory(void* __p)
6638fd1498Szrj { operator delete(__p); }
6738fd1498Szrj
6838fd1498Szrj // Turn a raw-memory into an array of _Tp filled with _Tp()
6938fd1498Szrj // This is required in 'valarray<T> v(n);'
7038fd1498Szrj template<typename _Tp, bool>
7138fd1498Szrj struct _Array_default_ctor
7238fd1498Szrj {
7338fd1498Szrj // Please note that this isn't exception safe. But
7438fd1498Szrj // valarrays aren't required to be exception safe.
7538fd1498Szrj inline static void
7638fd1498Szrj _S_do_it(_Tp* __b, _Tp* __e)
7738fd1498Szrj {
7838fd1498Szrj while (__b != __e)
7938fd1498Szrj new(__b++) _Tp();
8038fd1498Szrj }
8138fd1498Szrj };
8238fd1498Szrj
8338fd1498Szrj template<typename _Tp>
8438fd1498Szrj struct _Array_default_ctor<_Tp, true>
8538fd1498Szrj {
8638fd1498Szrj // For fundamental types, it suffices to say 'memset()'
8738fd1498Szrj inline static void
8838fd1498Szrj _S_do_it(_Tp* __b, _Tp* __e)
8938fd1498Szrj { __builtin_memset(__b, 0, (__e - __b) * sizeof(_Tp)); }
9038fd1498Szrj };
9138fd1498Szrj
9238fd1498Szrj template<typename _Tp>
9338fd1498Szrj inline void
9438fd1498Szrj __valarray_default_construct(_Tp* __b, _Tp* __e)
9538fd1498Szrj {
9638fd1498Szrj _Array_default_ctor<_Tp, __is_scalar<_Tp>::__value>::_S_do_it(__b, __e);
9738fd1498Szrj }
9838fd1498Szrj
9938fd1498Szrj // Turn a raw-memory into an array of _Tp filled with __t
10038fd1498Szrj // This is the required in valarray<T> v(n, t). Also
10138fd1498Szrj // used in valarray<>::resize().
10238fd1498Szrj template<typename _Tp, bool>
10338fd1498Szrj struct _Array_init_ctor
10438fd1498Szrj {
10538fd1498Szrj // Please note that this isn't exception safe. But
10638fd1498Szrj // valarrays aren't required to be exception safe.
10738fd1498Szrj inline static void
10838fd1498Szrj _S_do_it(_Tp* __b, _Tp* __e, const _Tp __t)
10938fd1498Szrj {
11038fd1498Szrj while (__b != __e)
11138fd1498Szrj new(__b++) _Tp(__t);
11238fd1498Szrj }
11338fd1498Szrj };
11438fd1498Szrj
11538fd1498Szrj template<typename _Tp>
11638fd1498Szrj struct _Array_init_ctor<_Tp, true>
11738fd1498Szrj {
11838fd1498Szrj inline static void
11938fd1498Szrj _S_do_it(_Tp* __b, _Tp* __e, const _Tp __t)
12038fd1498Szrj {
12138fd1498Szrj while (__b != __e)
12238fd1498Szrj *__b++ = __t;
12338fd1498Szrj }
12438fd1498Szrj };
12538fd1498Szrj
12638fd1498Szrj template<typename _Tp>
12738fd1498Szrj inline void
12838fd1498Szrj __valarray_fill_construct(_Tp* __b, _Tp* __e, const _Tp __t)
12938fd1498Szrj {
13038fd1498Szrj _Array_init_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __t);
13138fd1498Szrj }
13238fd1498Szrj
13338fd1498Szrj //
13438fd1498Szrj // copy-construct raw array [__o, *) from plain array [__b, __e)
13538fd1498Szrj // We can't just say 'memcpy()'
13638fd1498Szrj //
13738fd1498Szrj template<typename _Tp, bool>
13838fd1498Szrj struct _Array_copy_ctor
13938fd1498Szrj {
14038fd1498Szrj // Please note that this isn't exception safe. But
14138fd1498Szrj // valarrays aren't required to be exception safe.
14238fd1498Szrj inline static void
14338fd1498Szrj _S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o)
14438fd1498Szrj {
14538fd1498Szrj while (__b != __e)
14638fd1498Szrj new(__o++) _Tp(*__b++);
14738fd1498Szrj }
14838fd1498Szrj };
14938fd1498Szrj
15038fd1498Szrj template<typename _Tp>
15138fd1498Szrj struct _Array_copy_ctor<_Tp, true>
15238fd1498Szrj {
15338fd1498Szrj inline static void
15438fd1498Szrj _S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o)
155*58e805e6Szrj {
156*58e805e6Szrj if (__b)
157*58e805e6Szrj __builtin_memcpy(__o, __b, (__e - __b) * sizeof(_Tp));
158*58e805e6Szrj }
15938fd1498Szrj };
16038fd1498Szrj
16138fd1498Szrj template<typename _Tp>
16238fd1498Szrj inline void
16338fd1498Szrj __valarray_copy_construct(const _Tp* __b, const _Tp* __e,
16438fd1498Szrj _Tp* __restrict__ __o)
16538fd1498Szrj {
16638fd1498Szrj _Array_copy_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __o);
16738fd1498Szrj }
16838fd1498Szrj
16938fd1498Szrj // copy-construct raw array [__o, *) from strided array __a[<__n : __s>]
17038fd1498Szrj template<typename _Tp>
17138fd1498Szrj inline void
17238fd1498Szrj __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n,
17338fd1498Szrj size_t __s, _Tp* __restrict__ __o)
17438fd1498Szrj {
17538fd1498Szrj if (__is_trivial(_Tp))
17638fd1498Szrj while (__n--)
17738fd1498Szrj {
17838fd1498Szrj *__o++ = *__a;
17938fd1498Szrj __a += __s;
18038fd1498Szrj }
18138fd1498Szrj else
18238fd1498Szrj while (__n--)
18338fd1498Szrj {
18438fd1498Szrj new(__o++) _Tp(*__a);
18538fd1498Szrj __a += __s;
18638fd1498Szrj }
18738fd1498Szrj }
18838fd1498Szrj
18938fd1498Szrj // copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]]
19038fd1498Szrj template<typename _Tp>
19138fd1498Szrj inline void
19238fd1498Szrj __valarray_copy_construct (const _Tp* __restrict__ __a,
19338fd1498Szrj const size_t* __restrict__ __i,
19438fd1498Szrj _Tp* __restrict__ __o, size_t __n)
19538fd1498Szrj {
19638fd1498Szrj if (__is_trivial(_Tp))
19738fd1498Szrj while (__n--)
19838fd1498Szrj *__o++ = __a[*__i++];
19938fd1498Szrj else
20038fd1498Szrj while (__n--)
20138fd1498Szrj new (__o++) _Tp(__a[*__i++]);
20238fd1498Szrj }
20338fd1498Szrj
20438fd1498Szrj // Do the necessary cleanup when we're done with arrays.
20538fd1498Szrj template<typename _Tp>
20638fd1498Szrj inline void
20738fd1498Szrj __valarray_destroy_elements(_Tp* __b, _Tp* __e)
20838fd1498Szrj {
20938fd1498Szrj if (!__is_trivial(_Tp))
21038fd1498Szrj while (__b != __e)
21138fd1498Szrj {
21238fd1498Szrj __b->~_Tp();
21338fd1498Szrj ++__b;
21438fd1498Szrj }
21538fd1498Szrj }
21638fd1498Szrj
21738fd1498Szrj // Fill a plain array __a[<__n>] with __t
21838fd1498Szrj template<typename _Tp>
21938fd1498Szrj inline void
22038fd1498Szrj __valarray_fill(_Tp* __restrict__ __a, size_t __n, const _Tp& __t)
22138fd1498Szrj {
22238fd1498Szrj while (__n--)
22338fd1498Szrj *__a++ = __t;
22438fd1498Szrj }
22538fd1498Szrj
22638fd1498Szrj // fill strided array __a[<__n-1 : __s>] with __t
22738fd1498Szrj template<typename _Tp>
22838fd1498Szrj inline void
22938fd1498Szrj __valarray_fill(_Tp* __restrict__ __a, size_t __n,
23038fd1498Szrj size_t __s, const _Tp& __t)
23138fd1498Szrj {
23238fd1498Szrj for (size_t __i = 0; __i < __n; ++__i, __a += __s)
23338fd1498Szrj *__a = __t;
23438fd1498Szrj }
23538fd1498Szrj
23638fd1498Szrj // fill indirect array __a[__i[<__n>]] with __i
23738fd1498Szrj template<typename _Tp>
23838fd1498Szrj inline void
23938fd1498Szrj __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i,
24038fd1498Szrj size_t __n, const _Tp& __t)
24138fd1498Szrj {
24238fd1498Szrj for (size_t __j = 0; __j < __n; ++__j, ++__i)
24338fd1498Szrj __a[*__i] = __t;
24438fd1498Szrj }
24538fd1498Szrj
24638fd1498Szrj // copy plain array __a[<__n>] in __b[<__n>]
24738fd1498Szrj // For non-fundamental types, it is wrong to say 'memcpy()'
24838fd1498Szrj template<typename _Tp, bool>
24938fd1498Szrj struct _Array_copier
25038fd1498Szrj {
25138fd1498Szrj inline static void
25238fd1498Szrj _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
25338fd1498Szrj {
25438fd1498Szrj while(__n--)
25538fd1498Szrj *__b++ = *__a++;
25638fd1498Szrj }
25738fd1498Szrj };
25838fd1498Szrj
25938fd1498Szrj template<typename _Tp>
26038fd1498Szrj struct _Array_copier<_Tp, true>
26138fd1498Szrj {
26238fd1498Szrj inline static void
26338fd1498Szrj _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
264*58e805e6Szrj {
265*58e805e6Szrj if (__n != 0)
266*58e805e6Szrj __builtin_memcpy(__b, __a, __n * sizeof (_Tp));
267*58e805e6Szrj }
26838fd1498Szrj };
26938fd1498Szrj
27038fd1498Szrj // Copy a plain array __a[<__n>] into a play array __b[<>]
27138fd1498Szrj template<typename _Tp>
27238fd1498Szrj inline void
27338fd1498Szrj __valarray_copy(const _Tp* __restrict__ __a, size_t __n,
27438fd1498Szrj _Tp* __restrict__ __b)
27538fd1498Szrj {
27638fd1498Szrj _Array_copier<_Tp, __is_trivial(_Tp)>::_S_do_it(__a, __n, __b);
27738fd1498Szrj }
27838fd1498Szrj
27938fd1498Szrj // Copy strided array __a[<__n : __s>] in plain __b[<__n>]
28038fd1498Szrj template<typename _Tp>
28138fd1498Szrj inline void
28238fd1498Szrj __valarray_copy(const _Tp* __restrict__ __a, size_t __n, size_t __s,
28338fd1498Szrj _Tp* __restrict__ __b)
28438fd1498Szrj {
28538fd1498Szrj for (size_t __i = 0; __i < __n; ++__i, ++__b, __a += __s)
28638fd1498Szrj *__b = *__a;
28738fd1498Szrj }
28838fd1498Szrj
28938fd1498Szrj // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>]
29038fd1498Szrj template<typename _Tp>
29138fd1498Szrj inline void
29238fd1498Szrj __valarray_copy(const _Tp* __restrict__ __a, _Tp* __restrict__ __b,
29338fd1498Szrj size_t __n, size_t __s)
29438fd1498Szrj {
29538fd1498Szrj for (size_t __i = 0; __i < __n; ++__i, ++__a, __b += __s)
29638fd1498Szrj *__b = *__a;
29738fd1498Szrj }
29838fd1498Szrj
29938fd1498Szrj // Copy strided array __src[<__n : __s1>] into another
30038fd1498Szrj // strided array __dst[< : __s2>]. Their sizes must match.
30138fd1498Szrj template<typename _Tp>
30238fd1498Szrj inline void
30338fd1498Szrj __valarray_copy(const _Tp* __restrict__ __src, size_t __n, size_t __s1,
30438fd1498Szrj _Tp* __restrict__ __dst, size_t __s2)
30538fd1498Szrj {
30638fd1498Szrj for (size_t __i = 0; __i < __n; ++__i)
30738fd1498Szrj __dst[__i * __s2] = __src[__i * __s1];
30838fd1498Szrj }
30938fd1498Szrj
31038fd1498Szrj // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>]
31138fd1498Szrj template<typename _Tp>
31238fd1498Szrj inline void
31338fd1498Szrj __valarray_copy(const _Tp* __restrict__ __a,
31438fd1498Szrj const size_t* __restrict__ __i,
31538fd1498Szrj _Tp* __restrict__ __b, size_t __n)
31638fd1498Szrj {
31738fd1498Szrj for (size_t __j = 0; __j < __n; ++__j, ++__b, ++__i)
31838fd1498Szrj *__b = __a[*__i];
31938fd1498Szrj }
32038fd1498Szrj
32138fd1498Szrj // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]]
32238fd1498Szrj template<typename _Tp>
32338fd1498Szrj inline void
32438fd1498Szrj __valarray_copy(const _Tp* __restrict__ __a, size_t __n,
32538fd1498Szrj _Tp* __restrict__ __b, const size_t* __restrict__ __i)
32638fd1498Szrj {
32738fd1498Szrj for (size_t __j = 0; __j < __n; ++__j, ++__a, ++__i)
32838fd1498Szrj __b[*__i] = *__a;
32938fd1498Szrj }
33038fd1498Szrj
33138fd1498Szrj // Copy the __n first elements of an indexed array __src[<__i>] into
33238fd1498Szrj // another indexed array __dst[<__j>].
33338fd1498Szrj template<typename _Tp>
33438fd1498Szrj inline void
33538fd1498Szrj __valarray_copy(const _Tp* __restrict__ __src, size_t __n,
33638fd1498Szrj const size_t* __restrict__ __i,
33738fd1498Szrj _Tp* __restrict__ __dst, const size_t* __restrict__ __j)
33838fd1498Szrj {
33938fd1498Szrj for (size_t __k = 0; __k < __n; ++__k)
34038fd1498Szrj __dst[*__j++] = __src[*__i++];
34138fd1498Szrj }
34238fd1498Szrj
34338fd1498Szrj //
344*58e805e6Szrj // Compute the sum of elements in range [__f, __l) which must not be empty.
34538fd1498Szrj // This is a naive algorithm. It suffers from cancelling.
346*58e805e6Szrj // In the future try to specialize for _Tp = float, double, long double
347*58e805e6Szrj // using a more accurate algorithm.
34838fd1498Szrj //
34938fd1498Szrj template<typename _Tp>
35038fd1498Szrj inline _Tp
35138fd1498Szrj __valarray_sum(const _Tp* __f, const _Tp* __l)
35238fd1498Szrj {
353*58e805e6Szrj _Tp __r = *__f++;
35438fd1498Szrj while (__f != __l)
35538fd1498Szrj __r += *__f++;
35638fd1498Szrj return __r;
35738fd1498Szrj }
35838fd1498Szrj
35938fd1498Szrj // Compute the product of all elements in range [__f, __l)
36038fd1498Szrj template<typename _Tp>
36138fd1498Szrj inline _Tp
36238fd1498Szrj __valarray_product(const _Tp* __f, const _Tp* __l)
36338fd1498Szrj {
36438fd1498Szrj _Tp __r = _Tp(1);
36538fd1498Szrj while (__f != __l)
36638fd1498Szrj __r = __r * *__f++;
36738fd1498Szrj return __r;
36838fd1498Szrj }
36938fd1498Szrj
37038fd1498Szrj // Compute the min/max of an array-expression
37138fd1498Szrj template<typename _Ta>
37238fd1498Szrj inline typename _Ta::value_type
37338fd1498Szrj __valarray_min(const _Ta& __a)
37438fd1498Szrj {
37538fd1498Szrj size_t __s = __a.size();
37638fd1498Szrj typedef typename _Ta::value_type _Value_type;
37738fd1498Szrj _Value_type __r = __s == 0 ? _Value_type() : __a[0];
37838fd1498Szrj for (size_t __i = 1; __i < __s; ++__i)
37938fd1498Szrj {
38038fd1498Szrj _Value_type __t = __a[__i];
38138fd1498Szrj if (__t < __r)
38238fd1498Szrj __r = __t;
38338fd1498Szrj }
38438fd1498Szrj return __r;
38538fd1498Szrj }
38638fd1498Szrj
38738fd1498Szrj template<typename _Ta>
38838fd1498Szrj inline typename _Ta::value_type
38938fd1498Szrj __valarray_max(const _Ta& __a)
39038fd1498Szrj {
39138fd1498Szrj size_t __s = __a.size();
39238fd1498Szrj typedef typename _Ta::value_type _Value_type;
39338fd1498Szrj _Value_type __r = __s == 0 ? _Value_type() : __a[0];
39438fd1498Szrj for (size_t __i = 1; __i < __s; ++__i)
39538fd1498Szrj {
39638fd1498Szrj _Value_type __t = __a[__i];
39738fd1498Szrj if (__t > __r)
39838fd1498Szrj __r = __t;
39938fd1498Szrj }
40038fd1498Szrj return __r;
40138fd1498Szrj }
40238fd1498Szrj
40338fd1498Szrj //
40438fd1498Szrj // Helper class _Array, first layer of valarray abstraction.
40538fd1498Szrj // All operations on valarray should be forwarded to this class
40638fd1498Szrj // whenever possible. -- gdr
40738fd1498Szrj //
40838fd1498Szrj
40938fd1498Szrj template<typename _Tp>
41038fd1498Szrj struct _Array
41138fd1498Szrj {
41238fd1498Szrj explicit _Array(size_t);
41338fd1498Szrj explicit _Array(_Tp* const __restrict__);
41438fd1498Szrj explicit _Array(const valarray<_Tp>&);
41538fd1498Szrj _Array(const _Tp* __restrict__, size_t);
41638fd1498Szrj
41738fd1498Szrj _Tp* begin() const;
41838fd1498Szrj
41938fd1498Szrj _Tp* const __restrict__ _M_data;
42038fd1498Szrj };
42138fd1498Szrj
42238fd1498Szrj
42338fd1498Szrj // Copy-construct plain array __b[<__n>] from indexed array __a[__i[<__n>]]
42438fd1498Szrj template<typename _Tp>
42538fd1498Szrj inline void
42638fd1498Szrj __valarray_copy_construct(_Array<_Tp> __a, _Array<size_t> __i,
42738fd1498Szrj _Array<_Tp> __b, size_t __n)
42838fd1498Szrj { std::__valarray_copy_construct(__a._M_data, __i._M_data,
42938fd1498Szrj __b._M_data, __n); }
43038fd1498Szrj
43138fd1498Szrj // Copy-construct plain array __b[<__n>] from strided array __a[<__n : __s>]
43238fd1498Szrj template<typename _Tp>
43338fd1498Szrj inline void
43438fd1498Szrj __valarray_copy_construct(_Array<_Tp> __a, size_t __n, size_t __s,
43538fd1498Szrj _Array<_Tp> __b)
43638fd1498Szrj { std::__valarray_copy_construct(__a._M_data, __n, __s, __b._M_data); }
43738fd1498Szrj
43838fd1498Szrj template<typename _Tp>
43938fd1498Szrj inline void
44038fd1498Szrj __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t)
44138fd1498Szrj { std::__valarray_fill(__a._M_data, __n, __t); }
44238fd1498Szrj
44338fd1498Szrj template<typename _Tp>
44438fd1498Szrj inline void
44538fd1498Szrj __valarray_fill(_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t)
44638fd1498Szrj { std::__valarray_fill(__a._M_data, __n, __s, __t); }
44738fd1498Szrj
44838fd1498Szrj template<typename _Tp>
44938fd1498Szrj inline void
45038fd1498Szrj __valarray_fill(_Array<_Tp> __a, _Array<size_t> __i,
45138fd1498Szrj size_t __n, const _Tp& __t)
45238fd1498Szrj { std::__valarray_fill(__a._M_data, __i._M_data, __n, __t); }
45338fd1498Szrj
45438fd1498Szrj // Copy a plain array __a[<__n>] into a play array __b[<>]
45538fd1498Szrj template<typename _Tp>
45638fd1498Szrj inline void
45738fd1498Szrj __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b)
45838fd1498Szrj { std::__valarray_copy(__a._M_data, __n, __b._M_data); }
45938fd1498Szrj
46038fd1498Szrj // Copy strided array __a[<__n : __s>] in plain __b[<__n>]
46138fd1498Szrj template<typename _Tp>
46238fd1498Szrj inline void
46338fd1498Szrj __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b)
46438fd1498Szrj { std::__valarray_copy(__a._M_data, __n, __s, __b._M_data); }
46538fd1498Szrj
46638fd1498Szrj // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>]
46738fd1498Szrj template<typename _Tp>
46838fd1498Szrj inline void
46938fd1498Szrj __valarray_copy(_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s)
47038fd1498Szrj { __valarray_copy(__a._M_data, __b._M_data, __n, __s); }
47138fd1498Szrj
47238fd1498Szrj // Copy strided array __src[<__n : __s1>] into another
47338fd1498Szrj // strided array __dst[< : __s2>]. Their sizes must match.
47438fd1498Szrj template<typename _Tp>
47538fd1498Szrj inline void
47638fd1498Szrj __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s1,
47738fd1498Szrj _Array<_Tp> __b, size_t __s2)
47838fd1498Szrj { std::__valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); }
47938fd1498Szrj
48038fd1498Szrj // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>]
48138fd1498Szrj template<typename _Tp>
48238fd1498Szrj inline void
48338fd1498Szrj __valarray_copy(_Array<_Tp> __a, _Array<size_t> __i,
48438fd1498Szrj _Array<_Tp> __b, size_t __n)
48538fd1498Szrj { std::__valarray_copy(__a._M_data, __i._M_data, __b._M_data, __n); }
48638fd1498Szrj
48738fd1498Szrj // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]]
48838fd1498Szrj template<typename _Tp>
48938fd1498Szrj inline void
49038fd1498Szrj __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b,
49138fd1498Szrj _Array<size_t> __i)
49238fd1498Szrj { std::__valarray_copy(__a._M_data, __n, __b._M_data, __i._M_data); }
49338fd1498Szrj
49438fd1498Szrj // Copy the __n first elements of an indexed array __src[<__i>] into
49538fd1498Szrj // another indexed array __dst[<__j>].
49638fd1498Szrj template<typename _Tp>
49738fd1498Szrj inline void
49838fd1498Szrj __valarray_copy(_Array<_Tp> __src, size_t __n, _Array<size_t> __i,
49938fd1498Szrj _Array<_Tp> __dst, _Array<size_t> __j)
50038fd1498Szrj {
50138fd1498Szrj std::__valarray_copy(__src._M_data, __n, __i._M_data,
50238fd1498Szrj __dst._M_data, __j._M_data);
50338fd1498Szrj }
50438fd1498Szrj
50538fd1498Szrj template<typename _Tp>
50638fd1498Szrj inline
50738fd1498Szrj _Array<_Tp>::_Array(size_t __n)
50838fd1498Szrj : _M_data(__valarray_get_storage<_Tp>(__n))
50938fd1498Szrj { std::__valarray_default_construct(_M_data, _M_data + __n); }
51038fd1498Szrj
51138fd1498Szrj template<typename _Tp>
51238fd1498Szrj inline
51338fd1498Szrj _Array<_Tp>::_Array(_Tp* const __restrict__ __p)
51438fd1498Szrj : _M_data (__p) {}
51538fd1498Szrj
51638fd1498Szrj template<typename _Tp>
51738fd1498Szrj inline
51838fd1498Szrj _Array<_Tp>::_Array(const valarray<_Tp>& __v)
51938fd1498Szrj : _M_data (__v._M_data) {}
52038fd1498Szrj
52138fd1498Szrj template<typename _Tp>
52238fd1498Szrj inline
52338fd1498Szrj _Array<_Tp>::_Array(const _Tp* __restrict__ __b, size_t __s)
52438fd1498Szrj : _M_data(__valarray_get_storage<_Tp>(__s))
52538fd1498Szrj { std::__valarray_copy_construct(__b, __s, _M_data); }
52638fd1498Szrj
52738fd1498Szrj template<typename _Tp>
52838fd1498Szrj inline _Tp*
52938fd1498Szrj _Array<_Tp>::begin () const
53038fd1498Szrj { return _M_data; }
53138fd1498Szrj
53238fd1498Szrj #define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \
53338fd1498Szrj template<typename _Tp> \
53438fd1498Szrj inline void \
53538fd1498Szrj _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, const _Tp& __t) \
53638fd1498Szrj { \
53738fd1498Szrj for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; ++__p) \
53838fd1498Szrj *__p _Op##= __t; \
53938fd1498Szrj } \
54038fd1498Szrj \
54138fd1498Szrj template<typename _Tp> \
54238fd1498Szrj inline void \
54338fd1498Szrj _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \
54438fd1498Szrj { \
54538fd1498Szrj _Tp* __p = __a._M_data; \
54638fd1498Szrj for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; ++__p, ++__q) \
54738fd1498Szrj *__p _Op##= *__q; \
54838fd1498Szrj } \
54938fd1498Szrj \
55038fd1498Szrj template<typename _Tp, class _Dom> \
55138fd1498Szrj void \
55238fd1498Szrj _Array_augmented_##_Name(_Array<_Tp> __a, \
55338fd1498Szrj const _Expr<_Dom, _Tp>& __e, size_t __n) \
55438fd1498Szrj { \
55538fd1498Szrj _Tp* __p(__a._M_data); \
55638fd1498Szrj for (size_t __i = 0; __i < __n; ++__i, ++__p) \
55738fd1498Szrj *__p _Op##= __e[__i]; \
55838fd1498Szrj } \
55938fd1498Szrj \
56038fd1498Szrj template<typename _Tp> \
56138fd1498Szrj inline void \
56238fd1498Szrj _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, size_t __s, \
56338fd1498Szrj _Array<_Tp> __b) \
56438fd1498Szrj { \
56538fd1498Szrj _Tp* __q(__b._M_data); \
56638fd1498Szrj for (_Tp* __p = __a._M_data; __p < __a._M_data + __s * __n; \
56738fd1498Szrj __p += __s, ++__q) \
56838fd1498Szrj *__p _Op##= *__q; \
56938fd1498Szrj } \
57038fd1498Szrj \
57138fd1498Szrj template<typename _Tp> \
57238fd1498Szrj inline void \
57338fd1498Szrj _Array_augmented_##_Name(_Array<_Tp> __a, _Array<_Tp> __b, \
57438fd1498Szrj size_t __n, size_t __s) \
57538fd1498Szrj { \
57638fd1498Szrj _Tp* __q(__b._M_data); \
57738fd1498Szrj for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; \
57838fd1498Szrj ++__p, __q += __s) \
57938fd1498Szrj *__p _Op##= *__q; \
58038fd1498Szrj } \
58138fd1498Szrj \
58238fd1498Szrj template<typename _Tp, class _Dom> \
58338fd1498Szrj void \
58438fd1498Szrj _Array_augmented_##_Name(_Array<_Tp> __a, size_t __s, \
58538fd1498Szrj const _Expr<_Dom, _Tp>& __e, size_t __n) \
58638fd1498Szrj { \
58738fd1498Szrj _Tp* __p(__a._M_data); \
58838fd1498Szrj for (size_t __i = 0; __i < __n; ++__i, __p += __s) \
58938fd1498Szrj *__p _Op##= __e[__i]; \
59038fd1498Szrj } \
59138fd1498Szrj \
59238fd1498Szrj template<typename _Tp> \
59338fd1498Szrj inline void \
59438fd1498Szrj _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i, \
59538fd1498Szrj _Array<_Tp> __b, size_t __n) \
59638fd1498Szrj { \
59738fd1498Szrj _Tp* __q(__b._M_data); \
59838fd1498Szrj for (size_t* __j = __i._M_data; __j < __i._M_data + __n; \
59938fd1498Szrj ++__j, ++__q) \
60038fd1498Szrj __a._M_data[*__j] _Op##= *__q; \
60138fd1498Szrj } \
60238fd1498Szrj \
60338fd1498Szrj template<typename _Tp> \
60438fd1498Szrj inline void \
60538fd1498Szrj _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, \
60638fd1498Szrj _Array<_Tp> __b, _Array<size_t> __i) \
60738fd1498Szrj { \
60838fd1498Szrj _Tp* __p(__a._M_data); \
60938fd1498Szrj for (size_t* __j = __i._M_data; __j<__i._M_data + __n; \
61038fd1498Szrj ++__j, ++__p) \
61138fd1498Szrj *__p _Op##= __b._M_data[*__j]; \
61238fd1498Szrj } \
61338fd1498Szrj \
61438fd1498Szrj template<typename _Tp, class _Dom> \
61538fd1498Szrj void \
61638fd1498Szrj _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i, \
61738fd1498Szrj const _Expr<_Dom, _Tp>& __e, size_t __n) \
61838fd1498Szrj { \
61938fd1498Szrj size_t* __j(__i._M_data); \
62038fd1498Szrj for (size_t __k = 0; __k<__n; ++__k, ++__j) \
62138fd1498Szrj __a._M_data[*__j] _Op##= __e[__k]; \
62238fd1498Szrj } \
62338fd1498Szrj \
62438fd1498Szrj template<typename _Tp> \
62538fd1498Szrj void \
62638fd1498Szrj _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m, \
62738fd1498Szrj _Array<_Tp> __b, size_t __n) \
62838fd1498Szrj { \
62938fd1498Szrj bool* __ok(__m._M_data); \
63038fd1498Szrj _Tp* __p(__a._M_data); \
63138fd1498Szrj for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; \
63238fd1498Szrj ++__q, ++__ok, ++__p) \
63338fd1498Szrj { \
63438fd1498Szrj while (! *__ok) \
63538fd1498Szrj { \
63638fd1498Szrj ++__ok; \
63738fd1498Szrj ++__p; \
63838fd1498Szrj } \
63938fd1498Szrj *__p _Op##= *__q; \
64038fd1498Szrj } \
64138fd1498Szrj } \
64238fd1498Szrj \
64338fd1498Szrj template<typename _Tp> \
64438fd1498Szrj void \
64538fd1498Szrj _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, \
64638fd1498Szrj _Array<_Tp> __b, _Array<bool> __m) \
64738fd1498Szrj { \
64838fd1498Szrj bool* __ok(__m._M_data); \
64938fd1498Szrj _Tp* __q(__b._M_data); \
65038fd1498Szrj for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; \
65138fd1498Szrj ++__p, ++__ok, ++__q) \
65238fd1498Szrj { \
65338fd1498Szrj while (! *__ok) \
65438fd1498Szrj { \
65538fd1498Szrj ++__ok; \
65638fd1498Szrj ++__q; \
65738fd1498Szrj } \
65838fd1498Szrj *__p _Op##= *__q; \
65938fd1498Szrj } \
66038fd1498Szrj } \
66138fd1498Szrj \
66238fd1498Szrj template<typename _Tp, class _Dom> \
66338fd1498Szrj void \
66438fd1498Szrj _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m, \
66538fd1498Szrj const _Expr<_Dom, _Tp>& __e, size_t __n) \
66638fd1498Szrj { \
66738fd1498Szrj bool* __ok(__m._M_data); \
66838fd1498Szrj _Tp* __p(__a._M_data); \
66938fd1498Szrj for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p) \
67038fd1498Szrj { \
67138fd1498Szrj while (! *__ok) \
67238fd1498Szrj { \
67338fd1498Szrj ++__ok; \
67438fd1498Szrj ++__p; \
67538fd1498Szrj } \
67638fd1498Szrj *__p _Op##= __e[__i]; \
67738fd1498Szrj } \
67838fd1498Szrj }
67938fd1498Szrj
68038fd1498Szrj _DEFINE_ARRAY_FUNCTION(+, __plus)
68138fd1498Szrj _DEFINE_ARRAY_FUNCTION(-, __minus)
68238fd1498Szrj _DEFINE_ARRAY_FUNCTION(*, __multiplies)
68338fd1498Szrj _DEFINE_ARRAY_FUNCTION(/, __divides)
68438fd1498Szrj _DEFINE_ARRAY_FUNCTION(%, __modulus)
68538fd1498Szrj _DEFINE_ARRAY_FUNCTION(^, __bitwise_xor)
68638fd1498Szrj _DEFINE_ARRAY_FUNCTION(|, __bitwise_or)
68738fd1498Szrj _DEFINE_ARRAY_FUNCTION(&, __bitwise_and)
68838fd1498Szrj _DEFINE_ARRAY_FUNCTION(<<, __shift_left)
68938fd1498Szrj _DEFINE_ARRAY_FUNCTION(>>, __shift_right)
69038fd1498Szrj
69138fd1498Szrj #undef _DEFINE_ARRAY_FUNCTION
69238fd1498Szrj
69338fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
69438fd1498Szrj } // namespace
69538fd1498Szrj
69638fd1498Szrj # include <bits/valarray_array.tcc>
69738fd1498Szrj
69838fd1498Szrj #endif /* _ARRAY_H */
699