xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/bits/valarray_array.h (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg // The template and inlines for the -*- C++ -*- internal _Array helper class.
21debfc3dSmrg 
3*8feb0f0bSmrg // Copyright (C) 1997-2020 Free Software Foundation, Inc.
41debfc3dSmrg //
51debfc3dSmrg // This file is part of the GNU ISO C++ Library.  This library is free
61debfc3dSmrg // software; you can redistribute it and/or modify it under the
71debfc3dSmrg // terms of the GNU General Public License as published by the
81debfc3dSmrg // Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg // any later version.
101debfc3dSmrg 
111debfc3dSmrg // This library is distributed in the hope that it will be useful,
121debfc3dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
141debfc3dSmrg // GNU General Public License for more details.
151debfc3dSmrg 
161debfc3dSmrg // Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg // permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg // 3.1, as published by the Free Software Foundation.
191debfc3dSmrg 
201debfc3dSmrg // You should have received a copy of the GNU General Public License and
211debfc3dSmrg // a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
231debfc3dSmrg // <http://www.gnu.org/licenses/>.
241debfc3dSmrg 
251debfc3dSmrg /** @file bits/valarray_array.h
261debfc3dSmrg  *  This is an internal header file, included by other library headers.
271debfc3dSmrg  *  Do not attempt to use it directly. @headername{valarray}
281debfc3dSmrg  */
291debfc3dSmrg 
301debfc3dSmrg // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
311debfc3dSmrg 
321debfc3dSmrg #ifndef _VALARRAY_ARRAY_H
331debfc3dSmrg #define _VALARRAY_ARRAY_H 1
341debfc3dSmrg 
351debfc3dSmrg #pragma GCC system_header
361debfc3dSmrg 
371debfc3dSmrg #include <bits/c++config.h>
381debfc3dSmrg #include <bits/cpp_type_traits.h>
391debfc3dSmrg #include <cstdlib>
401debfc3dSmrg #include <new>
411debfc3dSmrg 
_GLIBCXX_VISIBILITY(default)421debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default)
431debfc3dSmrg {
441debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
451debfc3dSmrg 
461debfc3dSmrg   //
471debfc3dSmrg   // Helper functions on raw pointers
481debfc3dSmrg   //
491debfc3dSmrg 
50c0a68be4Smrg   // We get memory the old fashioned way
51c0a68be4Smrg   template<typename _Tp>
52c0a68be4Smrg     _Tp*
53c0a68be4Smrg     __valarray_get_storage(size_t) __attribute__((__malloc__));
541debfc3dSmrg 
551debfc3dSmrg   template<typename _Tp>
56c0a68be4Smrg     inline _Tp*
571debfc3dSmrg     __valarray_get_storage(size_t __n)
58c0a68be4Smrg     { return static_cast<_Tp*>(operator new(__n * sizeof(_Tp))); }
591debfc3dSmrg 
601debfc3dSmrg   // Return memory to the system
611debfc3dSmrg   inline void
621debfc3dSmrg   __valarray_release_memory(void* __p)
631debfc3dSmrg   { operator delete(__p); }
641debfc3dSmrg 
651debfc3dSmrg   // Turn a raw-memory into an array of _Tp filled with _Tp()
661debfc3dSmrg   // This is required in 'valarray<T> v(n);'
671debfc3dSmrg   template<typename _Tp, bool>
681debfc3dSmrg     struct _Array_default_ctor
691debfc3dSmrg     {
701debfc3dSmrg       // Please note that this isn't exception safe.  But
711debfc3dSmrg       // valarrays aren't required to be exception safe.
721debfc3dSmrg       inline static void
731debfc3dSmrg       _S_do_it(_Tp* __b, _Tp* __e)
741debfc3dSmrg       {
751debfc3dSmrg 	while (__b != __e)
761debfc3dSmrg 	  new(__b++) _Tp();
771debfc3dSmrg       }
781debfc3dSmrg     };
791debfc3dSmrg 
801debfc3dSmrg   template<typename _Tp>
811debfc3dSmrg     struct _Array_default_ctor<_Tp, true>
821debfc3dSmrg     {
831debfc3dSmrg       // For fundamental types, it suffices to say 'memset()'
841debfc3dSmrg       inline static void
851debfc3dSmrg       _S_do_it(_Tp* __b, _Tp* __e)
861debfc3dSmrg       { __builtin_memset(__b, 0, (__e - __b) * sizeof(_Tp)); }
871debfc3dSmrg     };
881debfc3dSmrg 
891debfc3dSmrg   template<typename _Tp>
901debfc3dSmrg     inline void
911debfc3dSmrg     __valarray_default_construct(_Tp* __b, _Tp* __e)
921debfc3dSmrg     {
931debfc3dSmrg       _Array_default_ctor<_Tp, __is_scalar<_Tp>::__value>::_S_do_it(__b, __e);
941debfc3dSmrg     }
951debfc3dSmrg 
961debfc3dSmrg   // Turn a raw-memory into an array of _Tp filled with __t
971debfc3dSmrg   // This is the required in valarray<T> v(n, t).  Also
981debfc3dSmrg   // used in valarray<>::resize().
991debfc3dSmrg   template<typename _Tp, bool>
1001debfc3dSmrg     struct _Array_init_ctor
1011debfc3dSmrg     {
1021debfc3dSmrg       // Please note that this isn't exception safe.  But
1031debfc3dSmrg       // valarrays aren't required to be exception safe.
1041debfc3dSmrg       inline static void
1051debfc3dSmrg       _S_do_it(_Tp* __b, _Tp* __e, const _Tp __t)
1061debfc3dSmrg       {
1071debfc3dSmrg 	while (__b != __e)
1081debfc3dSmrg 	  new(__b++) _Tp(__t);
1091debfc3dSmrg       }
1101debfc3dSmrg     };
1111debfc3dSmrg 
1121debfc3dSmrg   template<typename _Tp>
1131debfc3dSmrg     struct _Array_init_ctor<_Tp, true>
1141debfc3dSmrg     {
1151debfc3dSmrg       inline static void
1161debfc3dSmrg       _S_do_it(_Tp* __b, _Tp* __e, const _Tp __t)
1171debfc3dSmrg       {
1181debfc3dSmrg 	while (__b != __e)
1191debfc3dSmrg 	  *__b++ = __t;
1201debfc3dSmrg       }
1211debfc3dSmrg     };
1221debfc3dSmrg 
1231debfc3dSmrg   template<typename _Tp>
1241debfc3dSmrg     inline void
1251debfc3dSmrg     __valarray_fill_construct(_Tp* __b, _Tp* __e, const _Tp __t)
1261debfc3dSmrg     {
1271debfc3dSmrg       _Array_init_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __t);
1281debfc3dSmrg     }
1291debfc3dSmrg 
1301debfc3dSmrg   //
1311debfc3dSmrg   // copy-construct raw array [__o, *) from plain array [__b, __e)
1321debfc3dSmrg   // We can't just say 'memcpy()'
1331debfc3dSmrg   //
1341debfc3dSmrg   template<typename _Tp, bool>
1351debfc3dSmrg     struct _Array_copy_ctor
1361debfc3dSmrg     {
1371debfc3dSmrg       // Please note that this isn't exception safe.  But
1381debfc3dSmrg       // valarrays aren't required to be exception safe.
1391debfc3dSmrg       inline static void
1401debfc3dSmrg       _S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o)
1411debfc3dSmrg       {
1421debfc3dSmrg 	while (__b != __e)
1431debfc3dSmrg 	  new(__o++) _Tp(*__b++);
1441debfc3dSmrg       }
1451debfc3dSmrg     };
1461debfc3dSmrg 
1471debfc3dSmrg   template<typename _Tp>
1481debfc3dSmrg     struct _Array_copy_ctor<_Tp, true>
1491debfc3dSmrg     {
1501debfc3dSmrg       inline static void
1511debfc3dSmrg       _S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o)
1521debfc3dSmrg       {
1531debfc3dSmrg 	if (__b)
1541debfc3dSmrg 	  __builtin_memcpy(__o, __b, (__e - __b) * sizeof(_Tp));
1551debfc3dSmrg       }
1561debfc3dSmrg     };
1571debfc3dSmrg 
1581debfc3dSmrg   template<typename _Tp>
1591debfc3dSmrg     inline void
1601debfc3dSmrg     __valarray_copy_construct(const _Tp* __b, const _Tp* __e,
1611debfc3dSmrg 			      _Tp* __restrict__ __o)
1621debfc3dSmrg     {
1631debfc3dSmrg       _Array_copy_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __o);
1641debfc3dSmrg     }
1651debfc3dSmrg 
1661debfc3dSmrg   // copy-construct raw array [__o, *) from strided array __a[<__n : __s>]
1671debfc3dSmrg   template<typename _Tp>
1681debfc3dSmrg     inline void
1691debfc3dSmrg     __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n,
1701debfc3dSmrg 			       size_t __s, _Tp* __restrict__ __o)
1711debfc3dSmrg     {
1721debfc3dSmrg       if (__is_trivial(_Tp))
1731debfc3dSmrg 	while (__n--)
1741debfc3dSmrg 	  {
1751debfc3dSmrg 	    *__o++ = *__a;
1761debfc3dSmrg 	    __a += __s;
1771debfc3dSmrg 	  }
1781debfc3dSmrg       else
1791debfc3dSmrg 	while (__n--)
1801debfc3dSmrg 	  {
1811debfc3dSmrg 	    new(__o++) _Tp(*__a);
1821debfc3dSmrg 	    __a += __s;
1831debfc3dSmrg 	  }
1841debfc3dSmrg     }
1851debfc3dSmrg 
1861debfc3dSmrg   // copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]]
1871debfc3dSmrg   template<typename _Tp>
1881debfc3dSmrg     inline void
1891debfc3dSmrg     __valarray_copy_construct (const _Tp* __restrict__ __a,
1901debfc3dSmrg 			       const size_t* __restrict__ __i,
1911debfc3dSmrg 			       _Tp* __restrict__ __o, size_t __n)
1921debfc3dSmrg     {
1931debfc3dSmrg       if (__is_trivial(_Tp))
1941debfc3dSmrg 	while (__n--)
1951debfc3dSmrg 	  *__o++ = __a[*__i++];
1961debfc3dSmrg       else
1971debfc3dSmrg 	while (__n--)
1981debfc3dSmrg 	  new (__o++) _Tp(__a[*__i++]);
1991debfc3dSmrg     }
2001debfc3dSmrg 
2011debfc3dSmrg   // Do the necessary cleanup when we're done with arrays.
2021debfc3dSmrg   template<typename _Tp>
2031debfc3dSmrg     inline void
2041debfc3dSmrg     __valarray_destroy_elements(_Tp* __b, _Tp* __e)
2051debfc3dSmrg     {
2061debfc3dSmrg       if (!__is_trivial(_Tp))
2071debfc3dSmrg 	while (__b != __e)
2081debfc3dSmrg 	  {
2091debfc3dSmrg 	    __b->~_Tp();
2101debfc3dSmrg 	    ++__b;
2111debfc3dSmrg 	  }
2121debfc3dSmrg     }
2131debfc3dSmrg 
2141debfc3dSmrg   // Fill a plain array __a[<__n>] with __t
2151debfc3dSmrg   template<typename _Tp>
2161debfc3dSmrg     inline void
2171debfc3dSmrg     __valarray_fill(_Tp* __restrict__ __a, size_t __n, const _Tp& __t)
2181debfc3dSmrg     {
2191debfc3dSmrg       while (__n--)
2201debfc3dSmrg 	*__a++ = __t;
2211debfc3dSmrg     }
2221debfc3dSmrg 
2231debfc3dSmrg   // fill strided array __a[<__n-1 : __s>] with __t
2241debfc3dSmrg   template<typename _Tp>
2251debfc3dSmrg     inline void
2261debfc3dSmrg     __valarray_fill(_Tp* __restrict__ __a, size_t __n,
2271debfc3dSmrg 		    size_t __s, const _Tp& __t)
2281debfc3dSmrg     {
2291debfc3dSmrg       for (size_t __i = 0; __i < __n; ++__i, __a += __s)
2301debfc3dSmrg 	*__a = __t;
2311debfc3dSmrg     }
2321debfc3dSmrg 
2331debfc3dSmrg   // fill indirect array __a[__i[<__n>]] with __i
2341debfc3dSmrg   template<typename _Tp>
2351debfc3dSmrg     inline void
2361debfc3dSmrg     __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i,
2371debfc3dSmrg 		    size_t __n, const _Tp& __t)
2381debfc3dSmrg     {
2391debfc3dSmrg       for (size_t __j = 0; __j < __n; ++__j, ++__i)
2401debfc3dSmrg 	__a[*__i] = __t;
2411debfc3dSmrg     }
2421debfc3dSmrg 
2431debfc3dSmrg   // copy plain array __a[<__n>] in __b[<__n>]
2441debfc3dSmrg   // For non-fundamental types, it is wrong to say 'memcpy()'
2451debfc3dSmrg   template<typename _Tp, bool>
2461debfc3dSmrg     struct _Array_copier
2471debfc3dSmrg     {
2481debfc3dSmrg       inline static void
2491debfc3dSmrg       _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
2501debfc3dSmrg       {
2511debfc3dSmrg 	while(__n--)
2521debfc3dSmrg 	  *__b++ = *__a++;
2531debfc3dSmrg       }
2541debfc3dSmrg     };
2551debfc3dSmrg 
2561debfc3dSmrg   template<typename _Tp>
2571debfc3dSmrg     struct _Array_copier<_Tp, true>
2581debfc3dSmrg     {
2591debfc3dSmrg       inline static void
2601debfc3dSmrg       _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
2611debfc3dSmrg       {
2621debfc3dSmrg 	if (__n != 0)
2631debfc3dSmrg 	  __builtin_memcpy(__b, __a, __n * sizeof (_Tp));
2641debfc3dSmrg       }
2651debfc3dSmrg     };
2661debfc3dSmrg 
2671debfc3dSmrg   // Copy a plain array __a[<__n>] into a play array __b[<>]
2681debfc3dSmrg   template<typename _Tp>
2691debfc3dSmrg     inline void
2701debfc3dSmrg     __valarray_copy(const _Tp* __restrict__ __a, size_t __n,
2711debfc3dSmrg 		    _Tp* __restrict__ __b)
2721debfc3dSmrg     {
2731debfc3dSmrg       _Array_copier<_Tp, __is_trivial(_Tp)>::_S_do_it(__a, __n, __b);
2741debfc3dSmrg     }
2751debfc3dSmrg 
2761debfc3dSmrg   // Copy strided array __a[<__n : __s>] in plain __b[<__n>]
2771debfc3dSmrg   template<typename _Tp>
2781debfc3dSmrg     inline void
2791debfc3dSmrg     __valarray_copy(const _Tp* __restrict__ __a, size_t __n, size_t __s,
2801debfc3dSmrg 		    _Tp* __restrict__ __b)
2811debfc3dSmrg     {
2821debfc3dSmrg       for (size_t __i = 0; __i < __n; ++__i, ++__b, __a += __s)
2831debfc3dSmrg 	*__b = *__a;
2841debfc3dSmrg     }
2851debfc3dSmrg 
2861debfc3dSmrg   // Copy a plain array  __a[<__n>] into a strided array __b[<__n : __s>]
2871debfc3dSmrg   template<typename _Tp>
2881debfc3dSmrg     inline void
2891debfc3dSmrg     __valarray_copy(const _Tp* __restrict__ __a, _Tp* __restrict__ __b,
2901debfc3dSmrg 		    size_t __n, size_t __s)
2911debfc3dSmrg     {
2921debfc3dSmrg       for (size_t __i = 0; __i < __n; ++__i, ++__a, __b += __s)
2931debfc3dSmrg 	*__b = *__a;
2941debfc3dSmrg     }
2951debfc3dSmrg 
2961debfc3dSmrg   // Copy strided array __src[<__n : __s1>] into another
2971debfc3dSmrg   // strided array __dst[< : __s2>].  Their sizes must match.
2981debfc3dSmrg   template<typename _Tp>
2991debfc3dSmrg     inline void
3001debfc3dSmrg     __valarray_copy(const _Tp* __restrict__ __src, size_t __n, size_t __s1,
3011debfc3dSmrg 		    _Tp* __restrict__ __dst, size_t __s2)
3021debfc3dSmrg     {
3031debfc3dSmrg       for (size_t __i = 0; __i < __n; ++__i)
3041debfc3dSmrg 	__dst[__i * __s2] = __src[__i * __s1];
3051debfc3dSmrg     }
3061debfc3dSmrg 
3071debfc3dSmrg   // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>]
3081debfc3dSmrg   template<typename _Tp>
3091debfc3dSmrg     inline void
3101debfc3dSmrg     __valarray_copy(const _Tp* __restrict__ __a,
3111debfc3dSmrg 		    const size_t* __restrict__ __i,
3121debfc3dSmrg 		    _Tp* __restrict__ __b, size_t __n)
3131debfc3dSmrg     {
3141debfc3dSmrg       for (size_t __j = 0; __j < __n; ++__j, ++__b, ++__i)
3151debfc3dSmrg 	*__b = __a[*__i];
3161debfc3dSmrg     }
3171debfc3dSmrg 
3181debfc3dSmrg   // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]]
3191debfc3dSmrg   template<typename _Tp>
3201debfc3dSmrg     inline void
3211debfc3dSmrg     __valarray_copy(const _Tp* __restrict__ __a, size_t __n,
3221debfc3dSmrg 		    _Tp* __restrict__ __b, const size_t* __restrict__ __i)
3231debfc3dSmrg     {
3241debfc3dSmrg       for (size_t __j = 0; __j < __n; ++__j, ++__a, ++__i)
3251debfc3dSmrg 	__b[*__i] = *__a;
3261debfc3dSmrg     }
3271debfc3dSmrg 
3281debfc3dSmrg   // Copy the __n first elements of an indexed array __src[<__i>] into
3291debfc3dSmrg   // another indexed array __dst[<__j>].
3301debfc3dSmrg   template<typename _Tp>
3311debfc3dSmrg     inline void
3321debfc3dSmrg     __valarray_copy(const _Tp* __restrict__ __src, size_t __n,
3331debfc3dSmrg 		    const size_t* __restrict__ __i,
3341debfc3dSmrg 		    _Tp* __restrict__ __dst, const size_t* __restrict__ __j)
3351debfc3dSmrg     {
3361debfc3dSmrg       for (size_t __k = 0; __k < __n; ++__k)
3371debfc3dSmrg 	__dst[*__j++] = __src[*__i++];
3381debfc3dSmrg     }
3391debfc3dSmrg 
3401debfc3dSmrg   //
3411debfc3dSmrg   // Compute the sum of elements in range [__f, __l) which must not be empty.
3421debfc3dSmrg   // This is a naive algorithm.  It suffers from cancelling.
3431debfc3dSmrg   // In the future try to specialize for _Tp = float, double, long double
3441debfc3dSmrg   // using a more accurate algorithm.
3451debfc3dSmrg   //
3461debfc3dSmrg   template<typename _Tp>
3471debfc3dSmrg     inline _Tp
3481debfc3dSmrg     __valarray_sum(const _Tp* __f, const _Tp* __l)
3491debfc3dSmrg     {
3501debfc3dSmrg       _Tp __r = *__f++;
3511debfc3dSmrg       while (__f != __l)
3521debfc3dSmrg 	__r += *__f++;
3531debfc3dSmrg       return __r;
3541debfc3dSmrg     }
3551debfc3dSmrg 
3561debfc3dSmrg   // Compute the min/max of an array-expression
3571debfc3dSmrg   template<typename _Ta>
3581debfc3dSmrg     inline typename _Ta::value_type
3591debfc3dSmrg     __valarray_min(const _Ta& __a)
3601debfc3dSmrg     {
3611debfc3dSmrg       size_t __s = __a.size();
3621debfc3dSmrg       typedef typename _Ta::value_type _Value_type;
3631debfc3dSmrg       _Value_type __r = __s == 0 ? _Value_type() : __a[0];
3641debfc3dSmrg       for (size_t __i = 1; __i < __s; ++__i)
3651debfc3dSmrg 	{
3661debfc3dSmrg 	  _Value_type __t = __a[__i];
3671debfc3dSmrg 	  if (__t < __r)
3681debfc3dSmrg 	    __r = __t;
3691debfc3dSmrg 	}
3701debfc3dSmrg       return __r;
3711debfc3dSmrg     }
3721debfc3dSmrg 
3731debfc3dSmrg   template<typename _Ta>
3741debfc3dSmrg     inline typename _Ta::value_type
3751debfc3dSmrg     __valarray_max(const _Ta& __a)
3761debfc3dSmrg     {
3771debfc3dSmrg       size_t __s = __a.size();
3781debfc3dSmrg       typedef typename _Ta::value_type _Value_type;
3791debfc3dSmrg       _Value_type __r = __s == 0 ? _Value_type() : __a[0];
3801debfc3dSmrg       for (size_t __i = 1; __i < __s; ++__i)
3811debfc3dSmrg 	{
3821debfc3dSmrg 	  _Value_type __t = __a[__i];
3831debfc3dSmrg 	  if (__t > __r)
3841debfc3dSmrg 	    __r = __t;
3851debfc3dSmrg 	}
3861debfc3dSmrg       return __r;
3871debfc3dSmrg     }
3881debfc3dSmrg 
3891debfc3dSmrg   //
3901debfc3dSmrg   // Helper class _Array, first layer of valarray abstraction.
3911debfc3dSmrg   // All operations on valarray should be forwarded to this class
3921debfc3dSmrg   // whenever possible. -- gdr
3931debfc3dSmrg   //
3941debfc3dSmrg 
3951debfc3dSmrg   template<typename _Tp>
3961debfc3dSmrg     struct _Array
3971debfc3dSmrg     {
3981debfc3dSmrg       explicit _Array(_Tp* const __restrict__);
3991debfc3dSmrg       explicit _Array(const valarray<_Tp>&);
4001debfc3dSmrg       _Array(const _Tp* __restrict__, size_t);
4011debfc3dSmrg 
4021debfc3dSmrg       _Tp* begin() const;
4031debfc3dSmrg 
4041debfc3dSmrg       _Tp* const __restrict__ _M_data;
4051debfc3dSmrg     };
4061debfc3dSmrg 
4071debfc3dSmrg 
4081debfc3dSmrg   // Copy-construct plain array __b[<__n>] from indexed array __a[__i[<__n>]]
4091debfc3dSmrg   template<typename _Tp>
4101debfc3dSmrg     inline void
4111debfc3dSmrg     __valarray_copy_construct(_Array<_Tp> __a, _Array<size_t> __i,
4121debfc3dSmrg 			      _Array<_Tp> __b, size_t __n)
4131debfc3dSmrg     { std::__valarray_copy_construct(__a._M_data, __i._M_data,
4141debfc3dSmrg 				     __b._M_data, __n); }
4151debfc3dSmrg 
4161debfc3dSmrg   // Copy-construct plain array __b[<__n>] from strided array __a[<__n : __s>]
4171debfc3dSmrg   template<typename _Tp>
4181debfc3dSmrg     inline void
4191debfc3dSmrg     __valarray_copy_construct(_Array<_Tp> __a, size_t __n, size_t __s,
4201debfc3dSmrg 			      _Array<_Tp> __b)
4211debfc3dSmrg     { std::__valarray_copy_construct(__a._M_data, __n, __s, __b._M_data); }
4221debfc3dSmrg 
4231debfc3dSmrg   template<typename _Tp>
4241debfc3dSmrg     inline void
4251debfc3dSmrg     __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t)
4261debfc3dSmrg     { std::__valarray_fill(__a._M_data, __n, __t); }
4271debfc3dSmrg 
4281debfc3dSmrg   template<typename _Tp>
4291debfc3dSmrg     inline void
4301debfc3dSmrg     __valarray_fill(_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t)
4311debfc3dSmrg     { std::__valarray_fill(__a._M_data, __n, __s, __t); }
4321debfc3dSmrg 
4331debfc3dSmrg   template<typename _Tp>
4341debfc3dSmrg     inline void
4351debfc3dSmrg     __valarray_fill(_Array<_Tp> __a, _Array<size_t> __i,
4361debfc3dSmrg 		    size_t __n, const _Tp& __t)
4371debfc3dSmrg     { std::__valarray_fill(__a._M_data, __i._M_data, __n, __t); }
4381debfc3dSmrg 
4391debfc3dSmrg   // Copy a plain array __a[<__n>] into a play array __b[<>]
4401debfc3dSmrg   template<typename _Tp>
4411debfc3dSmrg     inline void
4421debfc3dSmrg     __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b)
4431debfc3dSmrg     { std::__valarray_copy(__a._M_data, __n, __b._M_data); }
4441debfc3dSmrg 
4451debfc3dSmrg   // Copy strided array __a[<__n : __s>] in plain __b[<__n>]
4461debfc3dSmrg   template<typename _Tp>
4471debfc3dSmrg     inline void
4481debfc3dSmrg     __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b)
4491debfc3dSmrg     { std::__valarray_copy(__a._M_data, __n, __s, __b._M_data); }
4501debfc3dSmrg 
4511debfc3dSmrg   // Copy a plain array  __a[<__n>] into a strided array __b[<__n : __s>]
4521debfc3dSmrg   template<typename _Tp>
4531debfc3dSmrg     inline void
4541debfc3dSmrg     __valarray_copy(_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s)
4551debfc3dSmrg     { __valarray_copy(__a._M_data, __b._M_data, __n, __s); }
4561debfc3dSmrg 
4571debfc3dSmrg   // Copy strided array __src[<__n : __s1>] into another
4581debfc3dSmrg   // strided array __dst[< : __s2>].  Their sizes must match.
4591debfc3dSmrg   template<typename _Tp>
4601debfc3dSmrg     inline void
4611debfc3dSmrg     __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s1,
4621debfc3dSmrg                     _Array<_Tp> __b, size_t __s2)
4631debfc3dSmrg     { std::__valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); }
4641debfc3dSmrg 
4651debfc3dSmrg   // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>]
4661debfc3dSmrg   template<typename _Tp>
4671debfc3dSmrg     inline void
4681debfc3dSmrg     __valarray_copy(_Array<_Tp> __a, _Array<size_t> __i,
4691debfc3dSmrg 		    _Array<_Tp> __b, size_t __n)
4701debfc3dSmrg     { std::__valarray_copy(__a._M_data, __i._M_data, __b._M_data, __n); }
4711debfc3dSmrg 
4721debfc3dSmrg   // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]]
4731debfc3dSmrg   template<typename _Tp>
4741debfc3dSmrg     inline void
4751debfc3dSmrg     __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b,
4761debfc3dSmrg 		    _Array<size_t> __i)
4771debfc3dSmrg     { std::__valarray_copy(__a._M_data, __n, __b._M_data, __i._M_data); }
4781debfc3dSmrg 
4791debfc3dSmrg   // Copy the __n first elements of an indexed array __src[<__i>] into
4801debfc3dSmrg   // another indexed array __dst[<__j>].
4811debfc3dSmrg   template<typename _Tp>
4821debfc3dSmrg     inline void
4831debfc3dSmrg     __valarray_copy(_Array<_Tp> __src, size_t __n, _Array<size_t> __i,
4841debfc3dSmrg                     _Array<_Tp> __dst, _Array<size_t> __j)
4851debfc3dSmrg     {
4861debfc3dSmrg       std::__valarray_copy(__src._M_data, __n, __i._M_data,
4871debfc3dSmrg 		    __dst._M_data, __j._M_data);
4881debfc3dSmrg     }
4891debfc3dSmrg 
4901debfc3dSmrg   template<typename _Tp>
4911debfc3dSmrg     inline
4921debfc3dSmrg     _Array<_Tp>::_Array(_Tp* const __restrict__ __p)
4931debfc3dSmrg     : _M_data (__p) {}
4941debfc3dSmrg 
4951debfc3dSmrg   template<typename _Tp>
4961debfc3dSmrg     inline
4971debfc3dSmrg     _Array<_Tp>::_Array(const valarray<_Tp>& __v)
4981debfc3dSmrg     : _M_data (__v._M_data) {}
4991debfc3dSmrg 
5001debfc3dSmrg   template<typename _Tp>
5011debfc3dSmrg     inline
5021debfc3dSmrg     _Array<_Tp>::_Array(const _Tp* __restrict__ __b, size_t __s)
5031debfc3dSmrg     : _M_data(__valarray_get_storage<_Tp>(__s))
5041debfc3dSmrg     { std::__valarray_copy_construct(__b, __s, _M_data); }
5051debfc3dSmrg 
5061debfc3dSmrg   template<typename _Tp>
5071debfc3dSmrg     inline _Tp*
5081debfc3dSmrg     _Array<_Tp>::begin () const
5091debfc3dSmrg     { return _M_data; }
5101debfc3dSmrg 
5111debfc3dSmrg #define _DEFINE_ARRAY_FUNCTION(_Op, _Name)				\
5121debfc3dSmrg   template<typename _Tp>		        			\
5131debfc3dSmrg     inline void								\
5141debfc3dSmrg     _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, const _Tp& __t) \
5151debfc3dSmrg     {									\
5161debfc3dSmrg       for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; ++__p)	\
5171debfc3dSmrg         *__p _Op##= __t;						\
5181debfc3dSmrg     }									\
5191debfc3dSmrg 									\
5201debfc3dSmrg   template<typename _Tp>						\
5211debfc3dSmrg     inline void								\
5221debfc3dSmrg     _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \
5231debfc3dSmrg     {									\
5241debfc3dSmrg       _Tp* __p = __a._M_data;						\
5251debfc3dSmrg       for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; ++__p, ++__q) \
5261debfc3dSmrg         *__p _Op##= *__q;						\
5271debfc3dSmrg     }									\
5281debfc3dSmrg 									\
5291debfc3dSmrg   template<typename _Tp, class _Dom>					\
5301debfc3dSmrg     void								\
5311debfc3dSmrg     _Array_augmented_##_Name(_Array<_Tp> __a,	        		\
5321debfc3dSmrg                              const _Expr<_Dom, _Tp>& __e, size_t __n)	\
5331debfc3dSmrg     {									\
5341debfc3dSmrg       _Tp* __p(__a._M_data);						\
5351debfc3dSmrg       for (size_t __i = 0; __i < __n; ++__i, ++__p)                     \
5361debfc3dSmrg         *__p _Op##= __e[__i];                                          	\
5371debfc3dSmrg     }									\
5381debfc3dSmrg 									\
5391debfc3dSmrg   template<typename _Tp>						\
5401debfc3dSmrg     inline void								\
5411debfc3dSmrg     _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, size_t __s,	\
5421debfc3dSmrg 	                     _Array<_Tp> __b)				\
5431debfc3dSmrg     {									\
5441debfc3dSmrg       _Tp* __q(__b._M_data);						\
5451debfc3dSmrg       for (_Tp* __p = __a._M_data; __p < __a._M_data + __s * __n;       \
5461debfc3dSmrg 	   __p += __s, ++__q)                                           \
5471debfc3dSmrg         *__p _Op##= *__q;						\
5481debfc3dSmrg     }									\
5491debfc3dSmrg 									\
5501debfc3dSmrg   template<typename _Tp>						\
5511debfc3dSmrg     inline void								\
5521debfc3dSmrg     _Array_augmented_##_Name(_Array<_Tp> __a, _Array<_Tp> __b,		\
5531debfc3dSmrg 		             size_t __n, size_t __s)			\
5541debfc3dSmrg     {									\
5551debfc3dSmrg       _Tp* __q(__b._M_data);						\
5561debfc3dSmrg       for (_Tp* __p = __a._M_data; __p < __a._M_data + __n;             \
5571debfc3dSmrg 	   ++__p, __q += __s)                                           \
5581debfc3dSmrg         *__p _Op##= *__q;						\
5591debfc3dSmrg     }									\
5601debfc3dSmrg 									\
5611debfc3dSmrg   template<typename _Tp, class _Dom>					\
5621debfc3dSmrg     void								\
5631debfc3dSmrg     _Array_augmented_##_Name(_Array<_Tp> __a, size_t __s,		\
5641debfc3dSmrg                              const _Expr<_Dom, _Tp>& __e, size_t __n)	\
5651debfc3dSmrg     {									\
5661debfc3dSmrg       _Tp* __p(__a._M_data);						\
5671debfc3dSmrg       for (size_t __i = 0; __i < __n; ++__i, __p += __s)                \
5681debfc3dSmrg         *__p _Op##= __e[__i];                                          	\
5691debfc3dSmrg     }									\
5701debfc3dSmrg 									\
5711debfc3dSmrg   template<typename _Tp>						\
5721debfc3dSmrg     inline void								\
5731debfc3dSmrg     _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i,	\
5741debfc3dSmrg                              _Array<_Tp> __b, size_t __n)		\
5751debfc3dSmrg     {									\
5761debfc3dSmrg       _Tp* __q(__b._M_data);						\
5771debfc3dSmrg       for (size_t* __j = __i._M_data; __j < __i._M_data + __n;          \
5781debfc3dSmrg            ++__j, ++__q)                                                \
5791debfc3dSmrg         __a._M_data[*__j] _Op##= *__q;					\
5801debfc3dSmrg     }									\
5811debfc3dSmrg 									\
5821debfc3dSmrg   template<typename _Tp>						\
5831debfc3dSmrg     inline void					        		\
5841debfc3dSmrg     _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n,		\
5851debfc3dSmrg                              _Array<_Tp> __b, _Array<size_t> __i)	\
5861debfc3dSmrg     {									\
5871debfc3dSmrg       _Tp* __p(__a._M_data);						\
5881debfc3dSmrg       for (size_t* __j = __i._M_data; __j<__i._M_data + __n;            \
5891debfc3dSmrg 	   ++__j, ++__p)                                                \
5901debfc3dSmrg         *__p _Op##= __b._M_data[*__j];					\
5911debfc3dSmrg     }									\
5921debfc3dSmrg 									\
5931debfc3dSmrg   template<typename _Tp, class _Dom>					\
5941debfc3dSmrg     void								\
5951debfc3dSmrg     _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i,	\
5961debfc3dSmrg                              const _Expr<_Dom, _Tp>& __e, size_t __n)	\
5971debfc3dSmrg     {									\
5981debfc3dSmrg       size_t* __j(__i._M_data);	        				\
5991debfc3dSmrg       for (size_t __k = 0; __k<__n; ++__k, ++__j)			\
6001debfc3dSmrg         __a._M_data[*__j] _Op##= __e[__k];				\
6011debfc3dSmrg     }									\
6021debfc3dSmrg 									\
6031debfc3dSmrg   template<typename _Tp>						\
6041debfc3dSmrg     void								\
6051debfc3dSmrg     _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m,         \
6061debfc3dSmrg                              _Array<_Tp> __b, size_t __n)		\
6071debfc3dSmrg     {									\
6081debfc3dSmrg       bool* __ok(__m._M_data);						\
6091debfc3dSmrg       _Tp* __p(__a._M_data);						\
6101debfc3dSmrg       for (_Tp* __q = __b._M_data; __q < __b._M_data + __n;             \
6111debfc3dSmrg 	   ++__q, ++__ok, ++__p)                                        \
6121debfc3dSmrg         {                                                               \
6131debfc3dSmrg           while (! *__ok)                                               \
6141debfc3dSmrg             {						        	\
6151debfc3dSmrg               ++__ok;							\
6161debfc3dSmrg               ++__p;							\
6171debfc3dSmrg             }								\
6181debfc3dSmrg           *__p _Op##= *__q;						\
6191debfc3dSmrg         }								\
6201debfc3dSmrg     }									\
6211debfc3dSmrg 									\
6221debfc3dSmrg   template<typename _Tp>						\
6231debfc3dSmrg     void								\
6241debfc3dSmrg     _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n,		\
6251debfc3dSmrg                              _Array<_Tp> __b, _Array<bool> __m)   	\
6261debfc3dSmrg     {									\
6271debfc3dSmrg       bool* __ok(__m._M_data);						\
6281debfc3dSmrg       _Tp* __q(__b._M_data);						\
6291debfc3dSmrg       for (_Tp* __p = __a._M_data; __p < __a._M_data + __n;             \
6301debfc3dSmrg 	   ++__p, ++__ok, ++__q)                                        \
6311debfc3dSmrg         {                                                               \
6321debfc3dSmrg           while (! *__ok)                                               \
6331debfc3dSmrg             {					        		\
6341debfc3dSmrg               ++__ok;							\
6351debfc3dSmrg               ++__q;							\
6361debfc3dSmrg             }								\
6371debfc3dSmrg           *__p _Op##= *__q;						\
6381debfc3dSmrg         }								\
6391debfc3dSmrg     }									\
6401debfc3dSmrg 									\
6411debfc3dSmrg   template<typename _Tp, class _Dom>					\
6421debfc3dSmrg     void								\
6431debfc3dSmrg     _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m,  	\
6441debfc3dSmrg                              const _Expr<_Dom, _Tp>& __e, size_t __n)	\
6451debfc3dSmrg     {									\
6461debfc3dSmrg       bool* __ok(__m._M_data);						\
6471debfc3dSmrg       _Tp* __p(__a._M_data);						\
6481debfc3dSmrg       for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p)             \
6491debfc3dSmrg         {	                                           		\
6501debfc3dSmrg           while (! *__ok)                                               \
6511debfc3dSmrg             {		         					\
6521debfc3dSmrg 	      ++__ok;							\
6531debfc3dSmrg               ++__p;							\
6541debfc3dSmrg             }								\
6551debfc3dSmrg           *__p _Op##= __e[__i];						\
6561debfc3dSmrg         }								\
6571debfc3dSmrg     }
6581debfc3dSmrg 
6591debfc3dSmrg    _DEFINE_ARRAY_FUNCTION(+, __plus)
6601debfc3dSmrg    _DEFINE_ARRAY_FUNCTION(-, __minus)
6611debfc3dSmrg    _DEFINE_ARRAY_FUNCTION(*, __multiplies)
6621debfc3dSmrg    _DEFINE_ARRAY_FUNCTION(/, __divides)
6631debfc3dSmrg    _DEFINE_ARRAY_FUNCTION(%, __modulus)
6641debfc3dSmrg    _DEFINE_ARRAY_FUNCTION(^, __bitwise_xor)
6651debfc3dSmrg    _DEFINE_ARRAY_FUNCTION(|, __bitwise_or)
6661debfc3dSmrg    _DEFINE_ARRAY_FUNCTION(&, __bitwise_and)
6671debfc3dSmrg    _DEFINE_ARRAY_FUNCTION(<<, __shift_left)
6681debfc3dSmrg    _DEFINE_ARRAY_FUNCTION(>>, __shift_right)
6691debfc3dSmrg 
6701debfc3dSmrg #undef _DEFINE_ARRAY_FUNCTION
6711debfc3dSmrg 
6721debfc3dSmrg _GLIBCXX_END_NAMESPACE_VERSION
6731debfc3dSmrg } // namespace
6741debfc3dSmrg 
6751debfc3dSmrg # include <bits/valarray_array.tcc>
6761debfc3dSmrg 
6771debfc3dSmrg #endif /* _ARRAY_H */
678