xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/valarray_array.h (revision 95059079af47f9a66a175f374f2da1a5020e3255)
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