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