libstdc++
|
00001 // The template and inlines for the -*- C++ -*- internal _Array helper class. 00002 00003 // Copyright (C) 1997-2019 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file bits/valarray_array.h 00026 * This is an internal header file, included by other library headers. 00027 * Do not attempt to use it directly. @headername{valarray} 00028 */ 00029 00030 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> 00031 00032 #ifndef _VALARRAY_ARRAY_H 00033 #define _VALARRAY_ARRAY_H 1 00034 00035 #pragma GCC system_header 00036 00037 #include <bits/c++config.h> 00038 #include <bits/cpp_type_traits.h> 00039 #include <cstdlib> 00040 #include <new> 00041 00042 namespace std _GLIBCXX_VISIBILITY(default) 00043 { 00044 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00045 00046 // 00047 // Helper functions on raw pointers 00048 // 00049 00050 // We get memory the old fashioned way 00051 template<typename _Tp> 00052 _Tp* 00053 __valarray_get_storage(size_t) __attribute__((__malloc__)); 00054 00055 template<typename _Tp> 00056 inline _Tp* 00057 __valarray_get_storage(size_t __n) 00058 { return static_cast<_Tp*>(operator new(__n * sizeof(_Tp))); } 00059 00060 // Return memory to the system 00061 inline void 00062 __valarray_release_memory(void* __p) 00063 { operator delete(__p); } 00064 00065 // Turn a raw-memory into an array of _Tp filled with _Tp() 00066 // This is required in 'valarray<T> v(n);' 00067 template<typename _Tp, bool> 00068 struct _Array_default_ctor 00069 { 00070 // Please note that this isn't exception safe. But 00071 // valarrays aren't required to be exception safe. 00072 inline static void 00073 _S_do_it(_Tp* __b, _Tp* __e) 00074 { 00075 while (__b != __e) 00076 new(__b++) _Tp(); 00077 } 00078 }; 00079 00080 template<typename _Tp> 00081 struct _Array_default_ctor<_Tp, true> 00082 { 00083 // For fundamental types, it suffices to say 'memset()' 00084 inline static void 00085 _S_do_it(_Tp* __b, _Tp* __e) 00086 { __builtin_memset(__b, 0, (__e - __b) * sizeof(_Tp)); } 00087 }; 00088 00089 template<typename _Tp> 00090 inline void 00091 __valarray_default_construct(_Tp* __b, _Tp* __e) 00092 { 00093 _Array_default_ctor<_Tp, __is_scalar<_Tp>::__value>::_S_do_it(__b, __e); 00094 } 00095 00096 // Turn a raw-memory into an array of _Tp filled with __t 00097 // This is the required in valarray<T> v(n, t). Also 00098 // used in valarray<>::resize(). 00099 template<typename _Tp, bool> 00100 struct _Array_init_ctor 00101 { 00102 // Please note that this isn't exception safe. But 00103 // valarrays aren't required to be exception safe. 00104 inline static void 00105 _S_do_it(_Tp* __b, _Tp* __e, const _Tp __t) 00106 { 00107 while (__b != __e) 00108 new(__b++) _Tp(__t); 00109 } 00110 }; 00111 00112 template<typename _Tp> 00113 struct _Array_init_ctor<_Tp, true> 00114 { 00115 inline static void 00116 _S_do_it(_Tp* __b, _Tp* __e, const _Tp __t) 00117 { 00118 while (__b != __e) 00119 *__b++ = __t; 00120 } 00121 }; 00122 00123 template<typename _Tp> 00124 inline void 00125 __valarray_fill_construct(_Tp* __b, _Tp* __e, const _Tp __t) 00126 { 00127 _Array_init_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __t); 00128 } 00129 00130 // 00131 // copy-construct raw array [__o, *) from plain array [__b, __e) 00132 // We can't just say 'memcpy()' 00133 // 00134 template<typename _Tp, bool> 00135 struct _Array_copy_ctor 00136 { 00137 // Please note that this isn't exception safe. But 00138 // valarrays aren't required to be exception safe. 00139 inline static void 00140 _S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o) 00141 { 00142 while (__b != __e) 00143 new(__o++) _Tp(*__b++); 00144 } 00145 }; 00146 00147 template<typename _Tp> 00148 struct _Array_copy_ctor<_Tp, true> 00149 { 00150 inline static void 00151 _S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o) 00152 { 00153 if (__b) 00154 __builtin_memcpy(__o, __b, (__e - __b) * sizeof(_Tp)); 00155 } 00156 }; 00157 00158 template<typename _Tp> 00159 inline void 00160 __valarray_copy_construct(const _Tp* __b, const _Tp* __e, 00161 _Tp* __restrict__ __o) 00162 { 00163 _Array_copy_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __o); 00164 } 00165 00166 // copy-construct raw array [__o, *) from strided array __a[<__n : __s>] 00167 template<typename _Tp> 00168 inline void 00169 __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n, 00170 size_t __s, _Tp* __restrict__ __o) 00171 { 00172 if (__is_trivial(_Tp)) 00173 while (__n--) 00174 { 00175 *__o++ = *__a; 00176 __a += __s; 00177 } 00178 else 00179 while (__n--) 00180 { 00181 new(__o++) _Tp(*__a); 00182 __a += __s; 00183 } 00184 } 00185 00186 // copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]] 00187 template<typename _Tp> 00188 inline void 00189 __valarray_copy_construct (const _Tp* __restrict__ __a, 00190 const size_t* __restrict__ __i, 00191 _Tp* __restrict__ __o, size_t __n) 00192 { 00193 if (__is_trivial(_Tp)) 00194 while (__n--) 00195 *__o++ = __a[*__i++]; 00196 else 00197 while (__n--) 00198 new (__o++) _Tp(__a[*__i++]); 00199 } 00200 00201 // Do the necessary cleanup when we're done with arrays. 00202 template<typename _Tp> 00203 inline void 00204 __valarray_destroy_elements(_Tp* __b, _Tp* __e) 00205 { 00206 if (!__is_trivial(_Tp)) 00207 while (__b != __e) 00208 { 00209 __b->~_Tp(); 00210 ++__b; 00211 } 00212 } 00213 00214 // Fill a plain array __a[<__n>] with __t 00215 template<typename _Tp> 00216 inline void 00217 __valarray_fill(_Tp* __restrict__ __a, size_t __n, const _Tp& __t) 00218 { 00219 while (__n--) 00220 *__a++ = __t; 00221 } 00222 00223 // fill strided array __a[<__n-1 : __s>] with __t 00224 template<typename _Tp> 00225 inline void 00226 __valarray_fill(_Tp* __restrict__ __a, size_t __n, 00227 size_t __s, const _Tp& __t) 00228 { 00229 for (size_t __i = 0; __i < __n; ++__i, __a += __s) 00230 *__a = __t; 00231 } 00232 00233 // fill indirect array __a[__i[<__n>]] with __i 00234 template<typename _Tp> 00235 inline void 00236 __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i, 00237 size_t __n, const _Tp& __t) 00238 { 00239 for (size_t __j = 0; __j < __n; ++__j, ++__i) 00240 __a[*__i] = __t; 00241 } 00242 00243 // copy plain array __a[<__n>] in __b[<__n>] 00244 // For non-fundamental types, it is wrong to say 'memcpy()' 00245 template<typename _Tp, bool> 00246 struct _Array_copier 00247 { 00248 inline static void 00249 _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) 00250 { 00251 while(__n--) 00252 *__b++ = *__a++; 00253 } 00254 }; 00255 00256 template<typename _Tp> 00257 struct _Array_copier<_Tp, true> 00258 { 00259 inline static void 00260 _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) 00261 { 00262 if (__n != 0) 00263 __builtin_memcpy(__b, __a, __n * sizeof (_Tp)); 00264 } 00265 }; 00266 00267 // Copy a plain array __a[<__n>] into a play array __b[<>] 00268 template<typename _Tp> 00269 inline void 00270 __valarray_copy(const _Tp* __restrict__ __a, size_t __n, 00271 _Tp* __restrict__ __b) 00272 { 00273 _Array_copier<_Tp, __is_trivial(_Tp)>::_S_do_it(__a, __n, __b); 00274 } 00275 00276 // Copy strided array __a[<__n : __s>] in plain __b[<__n>] 00277 template<typename _Tp> 00278 inline void 00279 __valarray_copy(const _Tp* __restrict__ __a, size_t __n, size_t __s, 00280 _Tp* __restrict__ __b) 00281 { 00282 for (size_t __i = 0; __i < __n; ++__i, ++__b, __a += __s) 00283 *__b = *__a; 00284 } 00285 00286 // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>] 00287 template<typename _Tp> 00288 inline void 00289 __valarray_copy(const _Tp* __restrict__ __a, _Tp* __restrict__ __b, 00290 size_t __n, size_t __s) 00291 { 00292 for (size_t __i = 0; __i < __n; ++__i, ++__a, __b += __s) 00293 *__b = *__a; 00294 } 00295 00296 // Copy strided array __src[<__n : __s1>] into another 00297 // strided array __dst[< : __s2>]. Their sizes must match. 00298 template<typename _Tp> 00299 inline void 00300 __valarray_copy(const _Tp* __restrict__ __src, size_t __n, size_t __s1, 00301 _Tp* __restrict__ __dst, size_t __s2) 00302 { 00303 for (size_t __i = 0; __i < __n; ++__i) 00304 __dst[__i * __s2] = __src[__i * __s1]; 00305 } 00306 00307 // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>] 00308 template<typename _Tp> 00309 inline void 00310 __valarray_copy(const _Tp* __restrict__ __a, 00311 const size_t* __restrict__ __i, 00312 _Tp* __restrict__ __b, size_t __n) 00313 { 00314 for (size_t __j = 0; __j < __n; ++__j, ++__b, ++__i) 00315 *__b = __a[*__i]; 00316 } 00317 00318 // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]] 00319 template<typename _Tp> 00320 inline void 00321 __valarray_copy(const _Tp* __restrict__ __a, size_t __n, 00322 _Tp* __restrict__ __b, const size_t* __restrict__ __i) 00323 { 00324 for (size_t __j = 0; __j < __n; ++__j, ++__a, ++__i) 00325 __b[*__i] = *__a; 00326 } 00327 00328 // Copy the __n first elements of an indexed array __src[<__i>] into 00329 // another indexed array __dst[<__j>]. 00330 template<typename _Tp> 00331 inline void 00332 __valarray_copy(const _Tp* __restrict__ __src, size_t __n, 00333 const size_t* __restrict__ __i, 00334 _Tp* __restrict__ __dst, const size_t* __restrict__ __j) 00335 { 00336 for (size_t __k = 0; __k < __n; ++__k) 00337 __dst[*__j++] = __src[*__i++]; 00338 } 00339 00340 // 00341 // Compute the sum of elements in range [__f, __l) which must not be empty. 00342 // This is a naive algorithm. It suffers from cancelling. 00343 // In the future try to specialize for _Tp = float, double, long double 00344 // using a more accurate algorithm. 00345 // 00346 template<typename _Tp> 00347 inline _Tp 00348 __valarray_sum(const _Tp* __f, const _Tp* __l) 00349 { 00350 _Tp __r = *__f++; 00351 while (__f != __l) 00352 __r += *__f++; 00353 return __r; 00354 } 00355 00356 // Compute the min/max of an array-expression 00357 template<typename _Ta> 00358 inline typename _Ta::value_type 00359 __valarray_min(const _Ta& __a) 00360 { 00361 size_t __s = __a.size(); 00362 typedef typename _Ta::value_type _Value_type; 00363 _Value_type __r = __s == 0 ? _Value_type() : __a[0]; 00364 for (size_t __i = 1; __i < __s; ++__i) 00365 { 00366 _Value_type __t = __a[__i]; 00367 if (__t < __r) 00368 __r = __t; 00369 } 00370 return __r; 00371 } 00372 00373 template<typename _Ta> 00374 inline typename _Ta::value_type 00375 __valarray_max(const _Ta& __a) 00376 { 00377 size_t __s = __a.size(); 00378 typedef typename _Ta::value_type _Value_type; 00379 _Value_type __r = __s == 0 ? _Value_type() : __a[0]; 00380 for (size_t __i = 1; __i < __s; ++__i) 00381 { 00382 _Value_type __t = __a[__i]; 00383 if (__t > __r) 00384 __r = __t; 00385 } 00386 return __r; 00387 } 00388 00389 // 00390 // Helper class _Array, first layer of valarray abstraction. 00391 // All operations on valarray should be forwarded to this class 00392 // whenever possible. -- gdr 00393 // 00394 00395 template<typename _Tp> 00396 struct _Array 00397 { 00398 explicit _Array(_Tp* const __restrict__); 00399 explicit _Array(const valarray<_Tp>&); 00400 _Array(const _Tp* __restrict__, size_t); 00401 00402 _Tp* begin() const; 00403 00404 _Tp* const __restrict__ _M_data; 00405 }; 00406 00407 00408 // Copy-construct plain array __b[<__n>] from indexed array __a[__i[<__n>]] 00409 template<typename _Tp> 00410 inline void 00411 __valarray_copy_construct(_Array<_Tp> __a, _Array<size_t> __i, 00412 _Array<_Tp> __b, size_t __n) 00413 { std::__valarray_copy_construct(__a._M_data, __i._M_data, 00414 __b._M_data, __n); } 00415 00416 // Copy-construct plain array __b[<__n>] from strided array __a[<__n : __s>] 00417 template<typename _Tp> 00418 inline void 00419 __valarray_copy_construct(_Array<_Tp> __a, size_t __n, size_t __s, 00420 _Array<_Tp> __b) 00421 { std::__valarray_copy_construct(__a._M_data, __n, __s, __b._M_data); } 00422 00423 template<typename _Tp> 00424 inline void 00425 __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t) 00426 { std::__valarray_fill(__a._M_data, __n, __t); } 00427 00428 template<typename _Tp> 00429 inline void 00430 __valarray_fill(_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t) 00431 { std::__valarray_fill(__a._M_data, __n, __s, __t); } 00432 00433 template<typename _Tp> 00434 inline void 00435 __valarray_fill(_Array<_Tp> __a, _Array<size_t> __i, 00436 size_t __n, const _Tp& __t) 00437 { std::__valarray_fill(__a._M_data, __i._M_data, __n, __t); } 00438 00439 // Copy a plain array __a[<__n>] into a play array __b[<>] 00440 template<typename _Tp> 00441 inline void 00442 __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) 00443 { std::__valarray_copy(__a._M_data, __n, __b._M_data); } 00444 00445 // Copy strided array __a[<__n : __s>] in plain __b[<__n>] 00446 template<typename _Tp> 00447 inline void 00448 __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b) 00449 { std::__valarray_copy(__a._M_data, __n, __s, __b._M_data); } 00450 00451 // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>] 00452 template<typename _Tp> 00453 inline void 00454 __valarray_copy(_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s) 00455 { __valarray_copy(__a._M_data, __b._M_data, __n, __s); } 00456 00457 // Copy strided array __src[<__n : __s1>] into another 00458 // strided array __dst[< : __s2>]. Their sizes must match. 00459 template<typename _Tp> 00460 inline void 00461 __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s1, 00462 _Array<_Tp> __b, size_t __s2) 00463 { std::__valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); } 00464 00465 // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>] 00466 template<typename _Tp> 00467 inline void 00468 __valarray_copy(_Array<_Tp> __a, _Array<size_t> __i, 00469 _Array<_Tp> __b, size_t __n) 00470 { std::__valarray_copy(__a._M_data, __i._M_data, __b._M_data, __n); } 00471 00472 // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]] 00473 template<typename _Tp> 00474 inline void 00475 __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, 00476 _Array<size_t> __i) 00477 { std::__valarray_copy(__a._M_data, __n, __b._M_data, __i._M_data); } 00478 00479 // Copy the __n first elements of an indexed array __src[<__i>] into 00480 // another indexed array __dst[<__j>]. 00481 template<typename _Tp> 00482 inline void 00483 __valarray_copy(_Array<_Tp> __src, size_t __n, _Array<size_t> __i, 00484 _Array<_Tp> __dst, _Array<size_t> __j) 00485 { 00486 std::__valarray_copy(__src._M_data, __n, __i._M_data, 00487 __dst._M_data, __j._M_data); 00488 } 00489 00490 template<typename _Tp> 00491 inline 00492 _Array<_Tp>::_Array(_Tp* const __restrict__ __p) 00493 : _M_data (__p) {} 00494 00495 template<typename _Tp> 00496 inline 00497 _Array<_Tp>::_Array(const valarray<_Tp>& __v) 00498 : _M_data (__v._M_data) {} 00499 00500 template<typename _Tp> 00501 inline 00502 _Array<_Tp>::_Array(const _Tp* __restrict__ __b, size_t __s) 00503 : _M_data(__valarray_get_storage<_Tp>(__s)) 00504 { std::__valarray_copy_construct(__b, __s, _M_data); } 00505 00506 template<typename _Tp> 00507 inline _Tp* 00508 _Array<_Tp>::begin () const 00509 { return _M_data; } 00510 00511 #define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \ 00512 template<typename _Tp> \ 00513 inline void \ 00514 _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, const _Tp& __t) \ 00515 { \ 00516 for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; ++__p) \ 00517 *__p _Op##= __t; \ 00518 } \ 00519 \ 00520 template<typename _Tp> \ 00521 inline void \ 00522 _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \ 00523 { \ 00524 _Tp* __p = __a._M_data; \ 00525 for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; ++__p, ++__q) \ 00526 *__p _Op##= *__q; \ 00527 } \ 00528 \ 00529 template<typename _Tp, class _Dom> \ 00530 void \ 00531 _Array_augmented_##_Name(_Array<_Tp> __a, \ 00532 const _Expr<_Dom, _Tp>& __e, size_t __n) \ 00533 { \ 00534 _Tp* __p(__a._M_data); \ 00535 for (size_t __i = 0; __i < __n; ++__i, ++__p) \ 00536 *__p _Op##= __e[__i]; \ 00537 } \ 00538 \ 00539 template<typename _Tp> \ 00540 inline void \ 00541 _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, size_t __s, \ 00542 _Array<_Tp> __b) \ 00543 { \ 00544 _Tp* __q(__b._M_data); \ 00545 for (_Tp* __p = __a._M_data; __p < __a._M_data + __s * __n; \ 00546 __p += __s, ++__q) \ 00547 *__p _Op##= *__q; \ 00548 } \ 00549 \ 00550 template<typename _Tp> \ 00551 inline void \ 00552 _Array_augmented_##_Name(_Array<_Tp> __a, _Array<_Tp> __b, \ 00553 size_t __n, size_t __s) \ 00554 { \ 00555 _Tp* __q(__b._M_data); \ 00556 for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; \ 00557 ++__p, __q += __s) \ 00558 *__p _Op##= *__q; \ 00559 } \ 00560 \ 00561 template<typename _Tp, class _Dom> \ 00562 void \ 00563 _Array_augmented_##_Name(_Array<_Tp> __a, size_t __s, \ 00564 const _Expr<_Dom, _Tp>& __e, size_t __n) \ 00565 { \ 00566 _Tp* __p(__a._M_data); \ 00567 for (size_t __i = 0; __i < __n; ++__i, __p += __s) \ 00568 *__p _Op##= __e[__i]; \ 00569 } \ 00570 \ 00571 template<typename _Tp> \ 00572 inline void \ 00573 _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i, \ 00574 _Array<_Tp> __b, size_t __n) \ 00575 { \ 00576 _Tp* __q(__b._M_data); \ 00577 for (size_t* __j = __i._M_data; __j < __i._M_data + __n; \ 00578 ++__j, ++__q) \ 00579 __a._M_data[*__j] _Op##= *__q; \ 00580 } \ 00581 \ 00582 template<typename _Tp> \ 00583 inline void \ 00584 _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, \ 00585 _Array<_Tp> __b, _Array<size_t> __i) \ 00586 { \ 00587 _Tp* __p(__a._M_data); \ 00588 for (size_t* __j = __i._M_data; __j<__i._M_data + __n; \ 00589 ++__j, ++__p) \ 00590 *__p _Op##= __b._M_data[*__j]; \ 00591 } \ 00592 \ 00593 template<typename _Tp, class _Dom> \ 00594 void \ 00595 _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i, \ 00596 const _Expr<_Dom, _Tp>& __e, size_t __n) \ 00597 { \ 00598 size_t* __j(__i._M_data); \ 00599 for (size_t __k = 0; __k<__n; ++__k, ++__j) \ 00600 __a._M_data[*__j] _Op##= __e[__k]; \ 00601 } \ 00602 \ 00603 template<typename _Tp> \ 00604 void \ 00605 _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m, \ 00606 _Array<_Tp> __b, size_t __n) \ 00607 { \ 00608 bool* __ok(__m._M_data); \ 00609 _Tp* __p(__a._M_data); \ 00610 for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; \ 00611 ++__q, ++__ok, ++__p) \ 00612 { \ 00613 while (! *__ok) \ 00614 { \ 00615 ++__ok; \ 00616 ++__p; \ 00617 } \ 00618 *__p _Op##= *__q; \ 00619 } \ 00620 } \ 00621 \ 00622 template<typename _Tp> \ 00623 void \ 00624 _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, \ 00625 _Array<_Tp> __b, _Array<bool> __m) \ 00626 { \ 00627 bool* __ok(__m._M_data); \ 00628 _Tp* __q(__b._M_data); \ 00629 for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; \ 00630 ++__p, ++__ok, ++__q) \ 00631 { \ 00632 while (! *__ok) \ 00633 { \ 00634 ++__ok; \ 00635 ++__q; \ 00636 } \ 00637 *__p _Op##= *__q; \ 00638 } \ 00639 } \ 00640 \ 00641 template<typename _Tp, class _Dom> \ 00642 void \ 00643 _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m, \ 00644 const _Expr<_Dom, _Tp>& __e, size_t __n) \ 00645 { \ 00646 bool* __ok(__m._M_data); \ 00647 _Tp* __p(__a._M_data); \ 00648 for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p) \ 00649 { \ 00650 while (! *__ok) \ 00651 { \ 00652 ++__ok; \ 00653 ++__p; \ 00654 } \ 00655 *__p _Op##= __e[__i]; \ 00656 } \ 00657 } 00658 00659 _DEFINE_ARRAY_FUNCTION(+, __plus) 00660 _DEFINE_ARRAY_FUNCTION(-, __minus) 00661 _DEFINE_ARRAY_FUNCTION(*, __multiplies) 00662 _DEFINE_ARRAY_FUNCTION(/, __divides) 00663 _DEFINE_ARRAY_FUNCTION(%, __modulus) 00664 _DEFINE_ARRAY_FUNCTION(^, __bitwise_xor) 00665 _DEFINE_ARRAY_FUNCTION(|, __bitwise_or) 00666 _DEFINE_ARRAY_FUNCTION(&, __bitwise_and) 00667 _DEFINE_ARRAY_FUNCTION(<<, __shift_left) 00668 _DEFINE_ARRAY_FUNCTION(>>, __shift_right) 00669 00670 #undef _DEFINE_ARRAY_FUNCTION 00671 00672 _GLIBCXX_END_NAMESPACE_VERSION 00673 } // namespace 00674 00675 # include <bits/valarray_array.tcc> 00676 00677 #endif /* _ARRAY_H */