valarray_array.h

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

Generated on Sun Jul 25 00:12:34 2004 for libstdc++ source by doxygen 1.3.7