1*e4b17023SJohn Marino // The template and inlines for the -*- C++ -*- internal _Array helper class. 2*e4b17023SJohn Marino 3*e4b17023SJohn Marino // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4*e4b17023SJohn Marino // 2006, 2007, 2008, 2009, 2010, 2011 5*e4b17023SJohn Marino // Free Software Foundation, Inc. 6*e4b17023SJohn Marino // 7*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library. This library is free 8*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the 9*e4b17023SJohn Marino // terms of the GNU General Public License as published by the 10*e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option) 11*e4b17023SJohn Marino // any later version. 12*e4b17023SJohn Marino 13*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful, 14*e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of 15*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*e4b17023SJohn Marino // GNU General Public License for more details. 17*e4b17023SJohn Marino 18*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional 19*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version 20*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation. 21*e4b17023SJohn Marino 22*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and 23*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program; 24*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 25*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>. 26*e4b17023SJohn Marino 27*e4b17023SJohn Marino /** @file bits/valarray_array.h 28*e4b17023SJohn Marino * This is an internal header file, included by other library headers. 29*e4b17023SJohn Marino * Do not attempt to use it directly. @headername{valarray} 30*e4b17023SJohn Marino */ 31*e4b17023SJohn Marino 32*e4b17023SJohn Marino // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> 33*e4b17023SJohn Marino 34*e4b17023SJohn Marino #ifndef _VALARRAY_ARRAY_H 35*e4b17023SJohn Marino #define _VALARRAY_ARRAY_H 1 36*e4b17023SJohn Marino 37*e4b17023SJohn Marino #pragma GCC system_header 38*e4b17023SJohn Marino 39*e4b17023SJohn Marino #include <bits/c++config.h> 40*e4b17023SJohn Marino #include <bits/cpp_type_traits.h> 41*e4b17023SJohn Marino #include <cstdlib> 42*e4b17023SJohn Marino #include <new> 43*e4b17023SJohn Marino 44*e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default) 45*e4b17023SJohn Marino { 46*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION 47*e4b17023SJohn Marino 48*e4b17023SJohn Marino // 49*e4b17023SJohn Marino // Helper functions on raw pointers 50*e4b17023SJohn Marino // 51*e4b17023SJohn Marino 52*e4b17023SJohn Marino // We get memory by the old fashion way 53*e4b17023SJohn Marino inline void* 54*e4b17023SJohn Marino __valarray_get_memory(size_t __n) 55*e4b17023SJohn Marino { return operator new(__n); } 56*e4b17023SJohn Marino 57*e4b17023SJohn Marino template<typename _Tp> 58*e4b17023SJohn Marino inline _Tp*__restrict__ 59*e4b17023SJohn Marino __valarray_get_storage(size_t __n) 60*e4b17023SJohn Marino { 61*e4b17023SJohn Marino return static_cast<_Tp*__restrict__> 62*e4b17023SJohn Marino (std::__valarray_get_memory(__n * sizeof(_Tp))); 63*e4b17023SJohn Marino } 64*e4b17023SJohn Marino 65*e4b17023SJohn Marino // Return memory to the system 66*e4b17023SJohn Marino inline void 67*e4b17023SJohn Marino __valarray_release_memory(void* __p) 68*e4b17023SJohn Marino { operator delete(__p); } 69*e4b17023SJohn Marino 70*e4b17023SJohn Marino // Turn a raw-memory into an array of _Tp filled with _Tp() 71*e4b17023SJohn Marino // This is required in 'valarray<T> v(n);' 72*e4b17023SJohn Marino template<typename _Tp, bool> 73*e4b17023SJohn Marino struct _Array_default_ctor 74*e4b17023SJohn Marino { 75*e4b17023SJohn Marino // Please note that this isn't exception safe. But 76*e4b17023SJohn Marino // valarrays aren't required to be exception safe. 77*e4b17023SJohn Marino inline static void 78*e4b17023SJohn Marino _S_do_it(_Tp* __b, _Tp* __e) 79*e4b17023SJohn Marino { 80*e4b17023SJohn Marino while (__b != __e) 81*e4b17023SJohn Marino new(__b++) _Tp(); 82*e4b17023SJohn Marino } 83*e4b17023SJohn Marino }; 84*e4b17023SJohn Marino 85*e4b17023SJohn Marino template<typename _Tp> 86*e4b17023SJohn Marino struct _Array_default_ctor<_Tp, true> 87*e4b17023SJohn Marino { 88*e4b17023SJohn Marino // For fundamental types, it suffices to say 'memset()' 89*e4b17023SJohn Marino inline static void 90*e4b17023SJohn Marino _S_do_it(_Tp* __b, _Tp* __e) 91*e4b17023SJohn Marino { __builtin_memset(__b, 0, (__e - __b) * sizeof(_Tp)); } 92*e4b17023SJohn Marino }; 93*e4b17023SJohn Marino 94*e4b17023SJohn Marino template<typename _Tp> 95*e4b17023SJohn Marino inline void 96*e4b17023SJohn Marino __valarray_default_construct(_Tp* __b, _Tp* __e) 97*e4b17023SJohn Marino { 98*e4b17023SJohn Marino _Array_default_ctor<_Tp, __is_scalar<_Tp>::__value>::_S_do_it(__b, __e); 99*e4b17023SJohn Marino } 100*e4b17023SJohn Marino 101*e4b17023SJohn Marino // Turn a raw-memory into an array of _Tp filled with __t 102*e4b17023SJohn Marino // This is the required in valarray<T> v(n, t). Also 103*e4b17023SJohn Marino // used in valarray<>::resize(). 104*e4b17023SJohn Marino template<typename _Tp, bool> 105*e4b17023SJohn Marino struct _Array_init_ctor 106*e4b17023SJohn Marino { 107*e4b17023SJohn Marino // Please note that this isn't exception safe. But 108*e4b17023SJohn Marino // valarrays aren't required to be exception safe. 109*e4b17023SJohn Marino inline static void 110*e4b17023SJohn Marino _S_do_it(_Tp* __b, _Tp* __e, const _Tp __t) 111*e4b17023SJohn Marino { 112*e4b17023SJohn Marino while (__b != __e) 113*e4b17023SJohn Marino new(__b++) _Tp(__t); 114*e4b17023SJohn Marino } 115*e4b17023SJohn Marino }; 116*e4b17023SJohn Marino 117*e4b17023SJohn Marino template<typename _Tp> 118*e4b17023SJohn Marino struct _Array_init_ctor<_Tp, true> 119*e4b17023SJohn Marino { 120*e4b17023SJohn Marino inline static void 121*e4b17023SJohn Marino _S_do_it(_Tp* __b, _Tp* __e, const _Tp __t) 122*e4b17023SJohn Marino { 123*e4b17023SJohn Marino while (__b != __e) 124*e4b17023SJohn Marino *__b++ = __t; 125*e4b17023SJohn Marino } 126*e4b17023SJohn Marino }; 127*e4b17023SJohn Marino 128*e4b17023SJohn Marino template<typename _Tp> 129*e4b17023SJohn Marino inline void 130*e4b17023SJohn Marino __valarray_fill_construct(_Tp* __b, _Tp* __e, const _Tp __t) 131*e4b17023SJohn Marino { 132*e4b17023SJohn Marino _Array_init_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __t); 133*e4b17023SJohn Marino } 134*e4b17023SJohn Marino 135*e4b17023SJohn Marino // 136*e4b17023SJohn Marino // copy-construct raw array [__o, *) from plain array [__b, __e) 137*e4b17023SJohn Marino // We can't just say 'memcpy()' 138*e4b17023SJohn Marino // 139*e4b17023SJohn Marino template<typename _Tp, bool> 140*e4b17023SJohn Marino struct _Array_copy_ctor 141*e4b17023SJohn Marino { 142*e4b17023SJohn Marino // Please note that this isn't exception safe. But 143*e4b17023SJohn Marino // valarrays aren't required to be exception safe. 144*e4b17023SJohn Marino inline static void 145*e4b17023SJohn Marino _S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o) 146*e4b17023SJohn Marino { 147*e4b17023SJohn Marino while (__b != __e) 148*e4b17023SJohn Marino new(__o++) _Tp(*__b++); 149*e4b17023SJohn Marino } 150*e4b17023SJohn Marino }; 151*e4b17023SJohn Marino 152*e4b17023SJohn Marino template<typename _Tp> 153*e4b17023SJohn Marino struct _Array_copy_ctor<_Tp, true> 154*e4b17023SJohn Marino { 155*e4b17023SJohn Marino inline static void 156*e4b17023SJohn Marino _S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o) 157*e4b17023SJohn Marino { __builtin_memcpy(__o, __b, (__e - __b) * sizeof(_Tp)); } 158*e4b17023SJohn Marino }; 159*e4b17023SJohn Marino 160*e4b17023SJohn Marino template<typename _Tp> 161*e4b17023SJohn Marino inline void 162*e4b17023SJohn Marino __valarray_copy_construct(const _Tp* __b, const _Tp* __e, 163*e4b17023SJohn Marino _Tp* __restrict__ __o) 164*e4b17023SJohn Marino { 165*e4b17023SJohn Marino _Array_copy_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __o); 166*e4b17023SJohn Marino } 167*e4b17023SJohn Marino 168*e4b17023SJohn Marino // copy-construct raw array [__o, *) from strided array __a[<__n : __s>] 169*e4b17023SJohn Marino template<typename _Tp> 170*e4b17023SJohn Marino inline void 171*e4b17023SJohn Marino __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n, 172*e4b17023SJohn Marino size_t __s, _Tp* __restrict__ __o) 173*e4b17023SJohn Marino { 174*e4b17023SJohn Marino if (__is_trivial(_Tp)) 175*e4b17023SJohn Marino while (__n--) 176*e4b17023SJohn Marino { 177*e4b17023SJohn Marino *__o++ = *__a; 178*e4b17023SJohn Marino __a += __s; 179*e4b17023SJohn Marino } 180*e4b17023SJohn Marino else 181*e4b17023SJohn Marino while (__n--) 182*e4b17023SJohn Marino { 183*e4b17023SJohn Marino new(__o++) _Tp(*__a); 184*e4b17023SJohn Marino __a += __s; 185*e4b17023SJohn Marino } 186*e4b17023SJohn Marino } 187*e4b17023SJohn Marino 188*e4b17023SJohn Marino // copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]] 189*e4b17023SJohn Marino template<typename _Tp> 190*e4b17023SJohn Marino inline void 191*e4b17023SJohn Marino __valarray_copy_construct (const _Tp* __restrict__ __a, 192*e4b17023SJohn Marino const size_t* __restrict__ __i, 193*e4b17023SJohn Marino _Tp* __restrict__ __o, size_t __n) 194*e4b17023SJohn Marino { 195*e4b17023SJohn Marino if (__is_trivial(_Tp)) 196*e4b17023SJohn Marino while (__n--) 197*e4b17023SJohn Marino *__o++ = __a[*__i++]; 198*e4b17023SJohn Marino else 199*e4b17023SJohn Marino while (__n--) 200*e4b17023SJohn Marino new (__o++) _Tp(__a[*__i++]); 201*e4b17023SJohn Marino } 202*e4b17023SJohn Marino 203*e4b17023SJohn Marino // Do the necessary cleanup when we're done with arrays. 204*e4b17023SJohn Marino template<typename _Tp> 205*e4b17023SJohn Marino inline void 206*e4b17023SJohn Marino __valarray_destroy_elements(_Tp* __b, _Tp* __e) 207*e4b17023SJohn Marino { 208*e4b17023SJohn Marino if (!__is_trivial(_Tp)) 209*e4b17023SJohn Marino while (__b != __e) 210*e4b17023SJohn Marino { 211*e4b17023SJohn Marino __b->~_Tp(); 212*e4b17023SJohn Marino ++__b; 213*e4b17023SJohn Marino } 214*e4b17023SJohn Marino } 215*e4b17023SJohn Marino 216*e4b17023SJohn Marino // Fill a plain array __a[<__n>] with __t 217*e4b17023SJohn Marino template<typename _Tp> 218*e4b17023SJohn Marino inline void 219*e4b17023SJohn Marino __valarray_fill(_Tp* __restrict__ __a, size_t __n, const _Tp& __t) 220*e4b17023SJohn Marino { 221*e4b17023SJohn Marino while (__n--) 222*e4b17023SJohn Marino *__a++ = __t; 223*e4b17023SJohn Marino } 224*e4b17023SJohn Marino 225*e4b17023SJohn Marino // fill strided array __a[<__n-1 : __s>] with __t 226*e4b17023SJohn Marino template<typename _Tp> 227*e4b17023SJohn Marino inline void 228*e4b17023SJohn Marino __valarray_fill(_Tp* __restrict__ __a, size_t __n, 229*e4b17023SJohn Marino size_t __s, const _Tp& __t) 230*e4b17023SJohn Marino { 231*e4b17023SJohn Marino for (size_t __i = 0; __i < __n; ++__i, __a += __s) 232*e4b17023SJohn Marino *__a = __t; 233*e4b17023SJohn Marino } 234*e4b17023SJohn Marino 235*e4b17023SJohn Marino // fill indirect array __a[__i[<__n>]] with __i 236*e4b17023SJohn Marino template<typename _Tp> 237*e4b17023SJohn Marino inline void 238*e4b17023SJohn Marino __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i, 239*e4b17023SJohn Marino size_t __n, const _Tp& __t) 240*e4b17023SJohn Marino { 241*e4b17023SJohn Marino for (size_t __j = 0; __j < __n; ++__j, ++__i) 242*e4b17023SJohn Marino __a[*__i] = __t; 243*e4b17023SJohn Marino } 244*e4b17023SJohn Marino 245*e4b17023SJohn Marino // copy plain array __a[<__n>] in __b[<__n>] 246*e4b17023SJohn Marino // For non-fundamental types, it is wrong to say 'memcpy()' 247*e4b17023SJohn Marino template<typename _Tp, bool> 248*e4b17023SJohn Marino struct _Array_copier 249*e4b17023SJohn Marino { 250*e4b17023SJohn Marino inline static void 251*e4b17023SJohn Marino _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) 252*e4b17023SJohn Marino { 253*e4b17023SJohn Marino while(__n--) 254*e4b17023SJohn Marino *__b++ = *__a++; 255*e4b17023SJohn Marino } 256*e4b17023SJohn Marino }; 257*e4b17023SJohn Marino 258*e4b17023SJohn Marino template<typename _Tp> 259*e4b17023SJohn Marino struct _Array_copier<_Tp, true> 260*e4b17023SJohn Marino { 261*e4b17023SJohn Marino inline static void 262*e4b17023SJohn Marino _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) 263*e4b17023SJohn Marino { __builtin_memcpy(__b, __a, __n * sizeof (_Tp)); } 264*e4b17023SJohn Marino }; 265*e4b17023SJohn Marino 266*e4b17023SJohn Marino // Copy a plain array __a[<__n>] into a play array __b[<>] 267*e4b17023SJohn Marino template<typename _Tp> 268*e4b17023SJohn Marino inline void 269*e4b17023SJohn Marino __valarray_copy(const _Tp* __restrict__ __a, size_t __n, 270*e4b17023SJohn Marino _Tp* __restrict__ __b) 271*e4b17023SJohn Marino { 272*e4b17023SJohn Marino _Array_copier<_Tp, __is_trivial(_Tp)>::_S_do_it(__a, __n, __b); 273*e4b17023SJohn Marino } 274*e4b17023SJohn Marino 275*e4b17023SJohn Marino // Copy strided array __a[<__n : __s>] in plain __b[<__n>] 276*e4b17023SJohn Marino template<typename _Tp> 277*e4b17023SJohn Marino inline void 278*e4b17023SJohn Marino __valarray_copy(const _Tp* __restrict__ __a, size_t __n, size_t __s, 279*e4b17023SJohn Marino _Tp* __restrict__ __b) 280*e4b17023SJohn Marino { 281*e4b17023SJohn Marino for (size_t __i = 0; __i < __n; ++__i, ++__b, __a += __s) 282*e4b17023SJohn Marino *__b = *__a; 283*e4b17023SJohn Marino } 284*e4b17023SJohn Marino 285*e4b17023SJohn Marino // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>] 286*e4b17023SJohn Marino template<typename _Tp> 287*e4b17023SJohn Marino inline void 288*e4b17023SJohn Marino __valarray_copy(const _Tp* __restrict__ __a, _Tp* __restrict__ __b, 289*e4b17023SJohn Marino size_t __n, size_t __s) 290*e4b17023SJohn Marino { 291*e4b17023SJohn Marino for (size_t __i = 0; __i < __n; ++__i, ++__a, __b += __s) 292*e4b17023SJohn Marino *__b = *__a; 293*e4b17023SJohn Marino } 294*e4b17023SJohn Marino 295*e4b17023SJohn Marino // Copy strided array __src[<__n : __s1>] into another 296*e4b17023SJohn Marino // strided array __dst[< : __s2>]. Their sizes must match. 297*e4b17023SJohn Marino template<typename _Tp> 298*e4b17023SJohn Marino inline void 299*e4b17023SJohn Marino __valarray_copy(const _Tp* __restrict__ __src, size_t __n, size_t __s1, 300*e4b17023SJohn Marino _Tp* __restrict__ __dst, size_t __s2) 301*e4b17023SJohn Marino { 302*e4b17023SJohn Marino for (size_t __i = 0; __i < __n; ++__i) 303*e4b17023SJohn Marino __dst[__i * __s2] = __src[__i * __s1]; 304*e4b17023SJohn Marino } 305*e4b17023SJohn Marino 306*e4b17023SJohn Marino // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>] 307*e4b17023SJohn Marino template<typename _Tp> 308*e4b17023SJohn Marino inline void 309*e4b17023SJohn Marino __valarray_copy(const _Tp* __restrict__ __a, 310*e4b17023SJohn Marino const size_t* __restrict__ __i, 311*e4b17023SJohn Marino _Tp* __restrict__ __b, size_t __n) 312*e4b17023SJohn Marino { 313*e4b17023SJohn Marino for (size_t __j = 0; __j < __n; ++__j, ++__b, ++__i) 314*e4b17023SJohn Marino *__b = __a[*__i]; 315*e4b17023SJohn Marino } 316*e4b17023SJohn Marino 317*e4b17023SJohn Marino // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]] 318*e4b17023SJohn Marino template<typename _Tp> 319*e4b17023SJohn Marino inline void 320*e4b17023SJohn Marino __valarray_copy(const _Tp* __restrict__ __a, size_t __n, 321*e4b17023SJohn Marino _Tp* __restrict__ __b, const size_t* __restrict__ __i) 322*e4b17023SJohn Marino { 323*e4b17023SJohn Marino for (size_t __j = 0; __j < __n; ++__j, ++__a, ++__i) 324*e4b17023SJohn Marino __b[*__i] = *__a; 325*e4b17023SJohn Marino } 326*e4b17023SJohn Marino 327*e4b17023SJohn Marino // Copy the __n first elements of an indexed array __src[<__i>] into 328*e4b17023SJohn Marino // another indexed array __dst[<__j>]. 329*e4b17023SJohn Marino template<typename _Tp> 330*e4b17023SJohn Marino inline void 331*e4b17023SJohn Marino __valarray_copy(const _Tp* __restrict__ __src, size_t __n, 332*e4b17023SJohn Marino const size_t* __restrict__ __i, 333*e4b17023SJohn Marino _Tp* __restrict__ __dst, const size_t* __restrict__ __j) 334*e4b17023SJohn Marino { 335*e4b17023SJohn Marino for (size_t __k = 0; __k < __n; ++__k) 336*e4b17023SJohn Marino __dst[*__j++] = __src[*__i++]; 337*e4b17023SJohn Marino } 338*e4b17023SJohn Marino 339*e4b17023SJohn Marino // 340*e4b17023SJohn Marino // Compute the sum of elements in range [__f, __l) 341*e4b17023SJohn Marino // This is a naive algorithm. It suffers from cancelling. 342*e4b17023SJohn Marino // In the future try to specialize 343*e4b17023SJohn Marino // for _Tp = float, double, long double using a more accurate 344*e4b17023SJohn Marino // algorithm. 345*e4b17023SJohn Marino // 346*e4b17023SJohn Marino template<typename _Tp> 347*e4b17023SJohn Marino inline _Tp 348*e4b17023SJohn Marino __valarray_sum(const _Tp* __f, const _Tp* __l) 349*e4b17023SJohn Marino { 350*e4b17023SJohn Marino _Tp __r = _Tp(); 351*e4b17023SJohn Marino while (__f != __l) 352*e4b17023SJohn Marino __r += *__f++; 353*e4b17023SJohn Marino return __r; 354*e4b17023SJohn Marino } 355*e4b17023SJohn Marino 356*e4b17023SJohn Marino // Compute the product of all elements in range [__f, __l) 357*e4b17023SJohn Marino template<typename _Tp> 358*e4b17023SJohn Marino inline _Tp 359*e4b17023SJohn Marino __valarray_product(const _Tp* __f, const _Tp* __l) 360*e4b17023SJohn Marino { 361*e4b17023SJohn Marino _Tp __r = _Tp(1); 362*e4b17023SJohn Marino while (__f != __l) 363*e4b17023SJohn Marino __r = __r * *__f++; 364*e4b17023SJohn Marino return __r; 365*e4b17023SJohn Marino } 366*e4b17023SJohn Marino 367*e4b17023SJohn Marino // Compute the min/max of an array-expression 368*e4b17023SJohn Marino template<typename _Ta> 369*e4b17023SJohn Marino inline typename _Ta::value_type 370*e4b17023SJohn Marino __valarray_min(const _Ta& __a) 371*e4b17023SJohn Marino { 372*e4b17023SJohn Marino size_t __s = __a.size(); 373*e4b17023SJohn Marino typedef typename _Ta::value_type _Value_type; 374*e4b17023SJohn Marino _Value_type __r = __s == 0 ? _Value_type() : __a[0]; 375*e4b17023SJohn Marino for (size_t __i = 1; __i < __s; ++__i) 376*e4b17023SJohn Marino { 377*e4b17023SJohn Marino _Value_type __t = __a[__i]; 378*e4b17023SJohn Marino if (__t < __r) 379*e4b17023SJohn Marino __r = __t; 380*e4b17023SJohn Marino } 381*e4b17023SJohn Marino return __r; 382*e4b17023SJohn Marino } 383*e4b17023SJohn Marino 384*e4b17023SJohn Marino template<typename _Ta> 385*e4b17023SJohn Marino inline typename _Ta::value_type 386*e4b17023SJohn Marino __valarray_max(const _Ta& __a) 387*e4b17023SJohn Marino { 388*e4b17023SJohn Marino size_t __s = __a.size(); 389*e4b17023SJohn Marino typedef typename _Ta::value_type _Value_type; 390*e4b17023SJohn Marino _Value_type __r = __s == 0 ? _Value_type() : __a[0]; 391*e4b17023SJohn Marino for (size_t __i = 1; __i < __s; ++__i) 392*e4b17023SJohn Marino { 393*e4b17023SJohn Marino _Value_type __t = __a[__i]; 394*e4b17023SJohn Marino if (__t > __r) 395*e4b17023SJohn Marino __r = __t; 396*e4b17023SJohn Marino } 397*e4b17023SJohn Marino return __r; 398*e4b17023SJohn Marino } 399*e4b17023SJohn Marino 400*e4b17023SJohn Marino // 401*e4b17023SJohn Marino // Helper class _Array, first layer of valarray abstraction. 402*e4b17023SJohn Marino // All operations on valarray should be forwarded to this class 403*e4b17023SJohn Marino // whenever possible. -- gdr 404*e4b17023SJohn Marino // 405*e4b17023SJohn Marino 406*e4b17023SJohn Marino template<typename _Tp> 407*e4b17023SJohn Marino struct _Array 408*e4b17023SJohn Marino { 409*e4b17023SJohn Marino explicit _Array(size_t); 410*e4b17023SJohn Marino explicit _Array(_Tp* const __restrict__); 411*e4b17023SJohn Marino explicit _Array(const valarray<_Tp>&); 412*e4b17023SJohn Marino _Array(const _Tp* __restrict__, size_t); 413*e4b17023SJohn Marino 414*e4b17023SJohn Marino _Tp* begin() const; 415*e4b17023SJohn Marino 416*e4b17023SJohn Marino _Tp* const __restrict__ _M_data; 417*e4b17023SJohn Marino }; 418*e4b17023SJohn Marino 419*e4b17023SJohn Marino 420*e4b17023SJohn Marino // Copy-construct plain array __b[<__n>] from indexed array __a[__i[<__n>]] 421*e4b17023SJohn Marino template<typename _Tp> 422*e4b17023SJohn Marino inline void 423*e4b17023SJohn Marino __valarray_copy_construct(_Array<_Tp> __a, _Array<size_t> __i, 424*e4b17023SJohn Marino _Array<_Tp> __b, size_t __n) 425*e4b17023SJohn Marino { std::__valarray_copy_construct(__a._M_data, __i._M_data, 426*e4b17023SJohn Marino __b._M_data, __n); } 427*e4b17023SJohn Marino 428*e4b17023SJohn Marino // Copy-construct plain array __b[<__n>] from strided array __a[<__n : __s>] 429*e4b17023SJohn Marino template<typename _Tp> 430*e4b17023SJohn Marino inline void 431*e4b17023SJohn Marino __valarray_copy_construct(_Array<_Tp> __a, size_t __n, size_t __s, 432*e4b17023SJohn Marino _Array<_Tp> __b) 433*e4b17023SJohn Marino { std::__valarray_copy_construct(__a._M_data, __n, __s, __b._M_data); } 434*e4b17023SJohn Marino 435*e4b17023SJohn Marino template<typename _Tp> 436*e4b17023SJohn Marino inline void 437*e4b17023SJohn Marino __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t) 438*e4b17023SJohn Marino { std::__valarray_fill(__a._M_data, __n, __t); } 439*e4b17023SJohn Marino 440*e4b17023SJohn Marino template<typename _Tp> 441*e4b17023SJohn Marino inline void 442*e4b17023SJohn Marino __valarray_fill(_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t) 443*e4b17023SJohn Marino { std::__valarray_fill(__a._M_data, __n, __s, __t); } 444*e4b17023SJohn Marino 445*e4b17023SJohn Marino template<typename _Tp> 446*e4b17023SJohn Marino inline void 447*e4b17023SJohn Marino __valarray_fill(_Array<_Tp> __a, _Array<size_t> __i, 448*e4b17023SJohn Marino size_t __n, const _Tp& __t) 449*e4b17023SJohn Marino { std::__valarray_fill(__a._M_data, __i._M_data, __n, __t); } 450*e4b17023SJohn Marino 451*e4b17023SJohn Marino // Copy a plain array __a[<__n>] into a play array __b[<>] 452*e4b17023SJohn Marino template<typename _Tp> 453*e4b17023SJohn Marino inline void 454*e4b17023SJohn Marino __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) 455*e4b17023SJohn Marino { std::__valarray_copy(__a._M_data, __n, __b._M_data); } 456*e4b17023SJohn Marino 457*e4b17023SJohn Marino // Copy strided array __a[<__n : __s>] in plain __b[<__n>] 458*e4b17023SJohn Marino template<typename _Tp> 459*e4b17023SJohn Marino inline void 460*e4b17023SJohn Marino __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b) 461*e4b17023SJohn Marino { std::__valarray_copy(__a._M_data, __n, __s, __b._M_data); } 462*e4b17023SJohn Marino 463*e4b17023SJohn Marino // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>] 464*e4b17023SJohn Marino template<typename _Tp> 465*e4b17023SJohn Marino inline void 466*e4b17023SJohn Marino __valarray_copy(_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s) 467*e4b17023SJohn Marino { __valarray_copy(__a._M_data, __b._M_data, __n, __s); } 468*e4b17023SJohn Marino 469*e4b17023SJohn Marino // Copy strided array __src[<__n : __s1>] into another 470*e4b17023SJohn Marino // strided array __dst[< : __s2>]. Their sizes must match. 471*e4b17023SJohn Marino template<typename _Tp> 472*e4b17023SJohn Marino inline void 473*e4b17023SJohn Marino __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s1, 474*e4b17023SJohn Marino _Array<_Tp> __b, size_t __s2) 475*e4b17023SJohn Marino { std::__valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); } 476*e4b17023SJohn Marino 477*e4b17023SJohn Marino // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>] 478*e4b17023SJohn Marino template<typename _Tp> 479*e4b17023SJohn Marino inline void 480*e4b17023SJohn Marino __valarray_copy(_Array<_Tp> __a, _Array<size_t> __i, 481*e4b17023SJohn Marino _Array<_Tp> __b, size_t __n) 482*e4b17023SJohn Marino { std::__valarray_copy(__a._M_data, __i._M_data, __b._M_data, __n); } 483*e4b17023SJohn Marino 484*e4b17023SJohn Marino // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]] 485*e4b17023SJohn Marino template<typename _Tp> 486*e4b17023SJohn Marino inline void 487*e4b17023SJohn Marino __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, 488*e4b17023SJohn Marino _Array<size_t> __i) 489*e4b17023SJohn Marino { std::__valarray_copy(__a._M_data, __n, __b._M_data, __i._M_data); } 490*e4b17023SJohn Marino 491*e4b17023SJohn Marino // Copy the __n first elements of an indexed array __src[<__i>] into 492*e4b17023SJohn Marino // another indexed array __dst[<__j>]. 493*e4b17023SJohn Marino template<typename _Tp> 494*e4b17023SJohn Marino inline void 495*e4b17023SJohn Marino __valarray_copy(_Array<_Tp> __src, size_t __n, _Array<size_t> __i, 496*e4b17023SJohn Marino _Array<_Tp> __dst, _Array<size_t> __j) 497*e4b17023SJohn Marino { 498*e4b17023SJohn Marino std::__valarray_copy(__src._M_data, __n, __i._M_data, 499*e4b17023SJohn Marino __dst._M_data, __j._M_data); 500*e4b17023SJohn Marino } 501*e4b17023SJohn Marino 502*e4b17023SJohn Marino template<typename _Tp> 503*e4b17023SJohn Marino inline 504*e4b17023SJohn Marino _Array<_Tp>::_Array(size_t __n) 505*e4b17023SJohn Marino : _M_data(__valarray_get_storage<_Tp>(__n)) 506*e4b17023SJohn Marino { std::__valarray_default_construct(_M_data, _M_data + __n); } 507*e4b17023SJohn Marino 508*e4b17023SJohn Marino template<typename _Tp> 509*e4b17023SJohn Marino inline 510*e4b17023SJohn Marino _Array<_Tp>::_Array(_Tp* const __restrict__ __p) 511*e4b17023SJohn Marino : _M_data (__p) {} 512*e4b17023SJohn Marino 513*e4b17023SJohn Marino template<typename _Tp> 514*e4b17023SJohn Marino inline 515*e4b17023SJohn Marino _Array<_Tp>::_Array(const valarray<_Tp>& __v) 516*e4b17023SJohn Marino : _M_data (__v._M_data) {} 517*e4b17023SJohn Marino 518*e4b17023SJohn Marino template<typename _Tp> 519*e4b17023SJohn Marino inline 520*e4b17023SJohn Marino _Array<_Tp>::_Array(const _Tp* __restrict__ __b, size_t __s) 521*e4b17023SJohn Marino : _M_data(__valarray_get_storage<_Tp>(__s)) 522*e4b17023SJohn Marino { std::__valarray_copy_construct(__b, __s, _M_data); } 523*e4b17023SJohn Marino 524*e4b17023SJohn Marino template<typename _Tp> 525*e4b17023SJohn Marino inline _Tp* 526*e4b17023SJohn Marino _Array<_Tp>::begin () const 527*e4b17023SJohn Marino { return _M_data; } 528*e4b17023SJohn Marino 529*e4b17023SJohn Marino #define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \ 530*e4b17023SJohn Marino template<typename _Tp> \ 531*e4b17023SJohn Marino inline void \ 532*e4b17023SJohn Marino _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, const _Tp& __t) \ 533*e4b17023SJohn Marino { \ 534*e4b17023SJohn Marino for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; ++__p) \ 535*e4b17023SJohn Marino *__p _Op##= __t; \ 536*e4b17023SJohn Marino } \ 537*e4b17023SJohn Marino \ 538*e4b17023SJohn Marino template<typename _Tp> \ 539*e4b17023SJohn Marino inline void \ 540*e4b17023SJohn Marino _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \ 541*e4b17023SJohn Marino { \ 542*e4b17023SJohn Marino _Tp* __p = __a._M_data; \ 543*e4b17023SJohn Marino for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; ++__p, ++__q) \ 544*e4b17023SJohn Marino *__p _Op##= *__q; \ 545*e4b17023SJohn Marino } \ 546*e4b17023SJohn Marino \ 547*e4b17023SJohn Marino template<typename _Tp, class _Dom> \ 548*e4b17023SJohn Marino void \ 549*e4b17023SJohn Marino _Array_augmented_##_Name(_Array<_Tp> __a, \ 550*e4b17023SJohn Marino const _Expr<_Dom, _Tp>& __e, size_t __n) \ 551*e4b17023SJohn Marino { \ 552*e4b17023SJohn Marino _Tp* __p(__a._M_data); \ 553*e4b17023SJohn Marino for (size_t __i = 0; __i < __n; ++__i, ++__p) \ 554*e4b17023SJohn Marino *__p _Op##= __e[__i]; \ 555*e4b17023SJohn Marino } \ 556*e4b17023SJohn Marino \ 557*e4b17023SJohn Marino template<typename _Tp> \ 558*e4b17023SJohn Marino inline void \ 559*e4b17023SJohn Marino _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, size_t __s, \ 560*e4b17023SJohn Marino _Array<_Tp> __b) \ 561*e4b17023SJohn Marino { \ 562*e4b17023SJohn Marino _Tp* __q(__b._M_data); \ 563*e4b17023SJohn Marino for (_Tp* __p = __a._M_data; __p < __a._M_data + __s * __n; \ 564*e4b17023SJohn Marino __p += __s, ++__q) \ 565*e4b17023SJohn Marino *__p _Op##= *__q; \ 566*e4b17023SJohn Marino } \ 567*e4b17023SJohn Marino \ 568*e4b17023SJohn Marino template<typename _Tp> \ 569*e4b17023SJohn Marino inline void \ 570*e4b17023SJohn Marino _Array_augmented_##_Name(_Array<_Tp> __a, _Array<_Tp> __b, \ 571*e4b17023SJohn Marino size_t __n, size_t __s) \ 572*e4b17023SJohn Marino { \ 573*e4b17023SJohn Marino _Tp* __q(__b._M_data); \ 574*e4b17023SJohn Marino for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; \ 575*e4b17023SJohn Marino ++__p, __q += __s) \ 576*e4b17023SJohn Marino *__p _Op##= *__q; \ 577*e4b17023SJohn Marino } \ 578*e4b17023SJohn Marino \ 579*e4b17023SJohn Marino template<typename _Tp, class _Dom> \ 580*e4b17023SJohn Marino void \ 581*e4b17023SJohn Marino _Array_augmented_##_Name(_Array<_Tp> __a, size_t __s, \ 582*e4b17023SJohn Marino const _Expr<_Dom, _Tp>& __e, size_t __n) \ 583*e4b17023SJohn Marino { \ 584*e4b17023SJohn Marino _Tp* __p(__a._M_data); \ 585*e4b17023SJohn Marino for (size_t __i = 0; __i < __n; ++__i, __p += __s) \ 586*e4b17023SJohn Marino *__p _Op##= __e[__i]; \ 587*e4b17023SJohn Marino } \ 588*e4b17023SJohn Marino \ 589*e4b17023SJohn Marino template<typename _Tp> \ 590*e4b17023SJohn Marino inline void \ 591*e4b17023SJohn Marino _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i, \ 592*e4b17023SJohn Marino _Array<_Tp> __b, size_t __n) \ 593*e4b17023SJohn Marino { \ 594*e4b17023SJohn Marino _Tp* __q(__b._M_data); \ 595*e4b17023SJohn Marino for (size_t* __j = __i._M_data; __j < __i._M_data + __n; \ 596*e4b17023SJohn Marino ++__j, ++__q) \ 597*e4b17023SJohn Marino __a._M_data[*__j] _Op##= *__q; \ 598*e4b17023SJohn Marino } \ 599*e4b17023SJohn Marino \ 600*e4b17023SJohn Marino template<typename _Tp> \ 601*e4b17023SJohn Marino inline void \ 602*e4b17023SJohn Marino _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, \ 603*e4b17023SJohn Marino _Array<_Tp> __b, _Array<size_t> __i) \ 604*e4b17023SJohn Marino { \ 605*e4b17023SJohn Marino _Tp* __p(__a._M_data); \ 606*e4b17023SJohn Marino for (size_t* __j = __i._M_data; __j<__i._M_data + __n; \ 607*e4b17023SJohn Marino ++__j, ++__p) \ 608*e4b17023SJohn Marino *__p _Op##= __b._M_data[*__j]; \ 609*e4b17023SJohn Marino } \ 610*e4b17023SJohn Marino \ 611*e4b17023SJohn Marino template<typename _Tp, class _Dom> \ 612*e4b17023SJohn Marino void \ 613*e4b17023SJohn Marino _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i, \ 614*e4b17023SJohn Marino const _Expr<_Dom, _Tp>& __e, size_t __n) \ 615*e4b17023SJohn Marino { \ 616*e4b17023SJohn Marino size_t* __j(__i._M_data); \ 617*e4b17023SJohn Marino for (size_t __k = 0; __k<__n; ++__k, ++__j) \ 618*e4b17023SJohn Marino __a._M_data[*__j] _Op##= __e[__k]; \ 619*e4b17023SJohn Marino } \ 620*e4b17023SJohn Marino \ 621*e4b17023SJohn Marino template<typename _Tp> \ 622*e4b17023SJohn Marino void \ 623*e4b17023SJohn Marino _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m, \ 624*e4b17023SJohn Marino _Array<_Tp> __b, size_t __n) \ 625*e4b17023SJohn Marino { \ 626*e4b17023SJohn Marino bool* __ok(__m._M_data); \ 627*e4b17023SJohn Marino _Tp* __p(__a._M_data); \ 628*e4b17023SJohn Marino for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; \ 629*e4b17023SJohn Marino ++__q, ++__ok, ++__p) \ 630*e4b17023SJohn Marino { \ 631*e4b17023SJohn Marino while (! *__ok) \ 632*e4b17023SJohn Marino { \ 633*e4b17023SJohn Marino ++__ok; \ 634*e4b17023SJohn Marino ++__p; \ 635*e4b17023SJohn Marino } \ 636*e4b17023SJohn Marino *__p _Op##= *__q; \ 637*e4b17023SJohn Marino } \ 638*e4b17023SJohn Marino } \ 639*e4b17023SJohn Marino \ 640*e4b17023SJohn Marino template<typename _Tp> \ 641*e4b17023SJohn Marino void \ 642*e4b17023SJohn Marino _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, \ 643*e4b17023SJohn Marino _Array<_Tp> __b, _Array<bool> __m) \ 644*e4b17023SJohn Marino { \ 645*e4b17023SJohn Marino bool* __ok(__m._M_data); \ 646*e4b17023SJohn Marino _Tp* __q(__b._M_data); \ 647*e4b17023SJohn Marino for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; \ 648*e4b17023SJohn Marino ++__p, ++__ok, ++__q) \ 649*e4b17023SJohn Marino { \ 650*e4b17023SJohn Marino while (! *__ok) \ 651*e4b17023SJohn Marino { \ 652*e4b17023SJohn Marino ++__ok; \ 653*e4b17023SJohn Marino ++__q; \ 654*e4b17023SJohn Marino } \ 655*e4b17023SJohn Marino *__p _Op##= *__q; \ 656*e4b17023SJohn Marino } \ 657*e4b17023SJohn Marino } \ 658*e4b17023SJohn Marino \ 659*e4b17023SJohn Marino template<typename _Tp, class _Dom> \ 660*e4b17023SJohn Marino void \ 661*e4b17023SJohn Marino _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m, \ 662*e4b17023SJohn Marino const _Expr<_Dom, _Tp>& __e, size_t __n) \ 663*e4b17023SJohn Marino { \ 664*e4b17023SJohn Marino bool* __ok(__m._M_data); \ 665*e4b17023SJohn Marino _Tp* __p(__a._M_data); \ 666*e4b17023SJohn Marino for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p) \ 667*e4b17023SJohn Marino { \ 668*e4b17023SJohn Marino while (! *__ok) \ 669*e4b17023SJohn Marino { \ 670*e4b17023SJohn Marino ++__ok; \ 671*e4b17023SJohn Marino ++__p; \ 672*e4b17023SJohn Marino } \ 673*e4b17023SJohn Marino *__p _Op##= __e[__i]; \ 674*e4b17023SJohn Marino } \ 675*e4b17023SJohn Marino } 676*e4b17023SJohn Marino 677*e4b17023SJohn Marino _DEFINE_ARRAY_FUNCTION(+, __plus) 678*e4b17023SJohn Marino _DEFINE_ARRAY_FUNCTION(-, __minus) 679*e4b17023SJohn Marino _DEFINE_ARRAY_FUNCTION(*, __multiplies) 680*e4b17023SJohn Marino _DEFINE_ARRAY_FUNCTION(/, __divides) 681*e4b17023SJohn Marino _DEFINE_ARRAY_FUNCTION(%, __modulus) 682*e4b17023SJohn Marino _DEFINE_ARRAY_FUNCTION(^, __bitwise_xor) 683*e4b17023SJohn Marino _DEFINE_ARRAY_FUNCTION(|, __bitwise_or) 684*e4b17023SJohn Marino _DEFINE_ARRAY_FUNCTION(&, __bitwise_and) 685*e4b17023SJohn Marino _DEFINE_ARRAY_FUNCTION(<<, __shift_left) 686*e4b17023SJohn Marino _DEFINE_ARRAY_FUNCTION(>>, __shift_right) 687*e4b17023SJohn Marino 688*e4b17023SJohn Marino #undef _DEFINE_ARRAY_FUNCTION 689*e4b17023SJohn Marino 690*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION 691*e4b17023SJohn Marino } // namespace 692*e4b17023SJohn Marino 693*e4b17023SJohn Marino # include <bits/valarray_array.tcc> 694*e4b17023SJohn Marino 695*e4b17023SJohn Marino #endif /* _ARRAY_H */ 696