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