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, 2004 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 // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>] 00318 template<typename _Tp> 00319 inline void 00320 __valarray_copy(const _Tp* __restrict__ __a, 00321 const size_t* __restrict__ __i, 00322 _Tp* __restrict__ __b, size_t __n) 00323 { 00324 for (size_t __j = 0; __j < __n; ++__j, ++__b, ++__i) 00325 *__b = __a[*__i]; 00326 } 00327 00328 // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]] 00329 template<typename _Tp> 00330 inline void 00331 __valarray_copy(const _Tp* __restrict__ __a, size_t __n, 00332 _Tp* __restrict__ __b, const size_t* __restrict__ __i) 00333 { 00334 for (size_t __j = 0; __j < __n; ++__j, ++__a, ++__i) 00335 __b[*__i] = *__a; 00336 } 00337 00338 // Copy the __n first elements of an indexed array __src[<__i>] into 00339 // another indexed array __dst[<__j>]. 00340 template<typename _Tp> 00341 inline void 00342 __valarray_copy(const _Tp* __restrict__ __src, size_t __n, 00343 const size_t* __restrict__ __i, 00344 _Tp* __restrict__ __dst, const size_t* __restrict__ __j) 00345 { 00346 for (size_t __k = 0; __k < __n; ++__k) 00347 __dst[*__j++] = __src[*__i++]; 00348 } 00349 00350 // 00351 // Compute the sum of elements in range [__f, __l) 00352 // This is a naive algorithm. It suffers from cancelling. 00353 // In the future try to specialize 00354 // for _Tp = float, double, long double using a more accurate 00355 // algorithm. 00356 // 00357 template<typename _Tp> 00358 inline _Tp 00359 __valarray_sum(const _Tp* __restrict__ __f, const _Tp* __restrict__ __l) 00360 { 00361 _Tp __r = _Tp(); 00362 while (__f != __l) 00363 __r += *__f++; 00364 return __r; 00365 } 00366 00367 // Compute the product of all elements in range [__f, __l) 00368 template<typename _Tp> 00369 inline _Tp 00370 __valarray_product(const _Tp* __restrict__ __f, 00371 const _Tp* __restrict__ __l) 00372 { 00373 _Tp __r = _Tp(1); 00374 while (__f != __l) 00375 __r = __r * *__f++; 00376 return __r; 00377 } 00378 00379 // Compute the min/max of an array-expression 00380 template<typename _Ta> 00381 inline typename _Ta::value_type 00382 __valarray_min(const _Ta& __a) 00383 { 00384 size_t __s = __a.size(); 00385 typedef typename _Ta::value_type _Value_type; 00386 _Value_type __r = __s == 0 ? _Value_type() : __a[0]; 00387 for (size_t __i = 1; __i < __s; ++__i) 00388 { 00389 _Value_type __t = __a[__i]; 00390 if (__t < __r) 00391 __r = __t; 00392 } 00393 return __r; 00394 } 00395 00396 template<typename _Ta> 00397 inline typename _Ta::value_type 00398 __valarray_max(const _Ta& __a) 00399 { 00400 size_t __s = __a.size(); 00401 typedef typename _Ta::value_type _Value_type; 00402 _Value_type __r = __s == 0 ? _Value_type() : __a[0]; 00403 for (size_t __i = 1; __i < __s; ++__i) 00404 { 00405 _Value_type __t = __a[__i]; 00406 if (__t > __r) 00407 __r = __t; 00408 } 00409 return __r; 00410 } 00411 00412 // 00413 // Helper class _Array, first layer of valarray abstraction. 00414 // All operations on valarray should be forwarded to this class 00415 // whenever possible. -- gdr 00416 // 00417 00418 template<typename _Tp> 00419 struct _Array 00420 { 00421 explicit _Array(size_t); 00422 explicit _Array(_Tp* const __restrict__); 00423 explicit _Array(const valarray<_Tp>&); 00424 _Array(const _Tp* __restrict__, size_t); 00425 00426 _Tp* begin() const; 00427 00428 _Tp* const __restrict__ _M_data; 00429 }; 00430 00431 template<typename _Tp> 00432 inline void 00433 __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t) 00434 { std::__valarray_fill(__a._M_data, __n, __t); } 00435 00436 template<typename _Tp> 00437 inline void 00438 __valarray_fill(_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t) 00439 { std::__valarray_fill(__a._M_data, __n, __s, __t); } 00440 00441 template<typename _Tp> 00442 inline void 00443 __valarray_fill(_Array<_Tp> __a, _Array<size_t> __i, 00444 size_t __n, const _Tp& __t) 00445 { std::__valarray_fill(__a._M_data, __i._M_data, __n, __t); } 00446 00447 // Copy a plain array __a[<__n>] into a play array __b[<>] 00448 template<typename _Tp> 00449 inline void 00450 __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) 00451 { std::__valarray_copy(__a._M_data, __n, __b._M_data); } 00452 00453 // Copy strided array __a[<__n : __s>] in plain __b[<__n>] 00454 template<typename _Tp> 00455 inline void 00456 __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b) 00457 { std::__valarray_copy(__a._M_data, __n, __s, __b._M_data); } 00458 00459 // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>] 00460 template<typename _Tp> 00461 inline void 00462 __valarray_copy(_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s) 00463 { __valarray_copy(__a._M_data, __b._M_data, __n, __s); } 00464 00465 // Copy strided array __src[<__n : __s1>] into another 00466 // strided array __dst[< : __s2>]. Their sizes must match. 00467 template<typename _Tp> 00468 inline void 00469 __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s1, 00470 _Array<_Tp> __b, size_t __s2) 00471 { std::__valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); } 00472 00473 // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>] 00474 template<typename _Tp> 00475 inline void 00476 __valarray_copy(_Array<_Tp> __a, _Array<size_t> __i, 00477 _Array<_Tp> __b, size_t __n) 00478 { std::__valarray_copy(__a._M_data, __i._M_data, __b._M_data, __n); } 00479 00480 // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]] 00481 template<typename _Tp> 00482 inline void 00483 __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, 00484 _Array<size_t> __i) 00485 { std::__valarray_copy(__a._M_data, __n, __b._M_data, __i._M_data); } 00486 00487 // Copy the __n first elements of an indexed array __src[<__i>] into 00488 // another indexed array __dst[<__j>]. 00489 template<typename _Tp> 00490 inline void 00491 __valarray_copy(_Array<_Tp> __src, size_t __n, _Array<size_t> __i, 00492 _Array<_Tp> __dst, _Array<size_t> __j) 00493 { 00494 std::__valarray_copy(__src._M_data, __n, __i._M_data, 00495 __dst._M_data, __j._M_data); 00496 } 00497 00498 template<typename _Tp> 00499 inline 00500 _Array<_Tp>::_Array(size_t __n) 00501 : _M_data(__valarray_get_storage<_Tp>(__n)) 00502 { std::__valarray_default_construct(_M_data, _M_data + __n); } 00503 00504 template<typename _Tp> 00505 inline 00506 _Array<_Tp>::_Array(_Tp* const __restrict__ __p) 00507 : _M_data (__p) {} 00508 00509 template<typename _Tp> 00510 inline 00511 _Array<_Tp>::_Array(const valarray<_Tp>& __v) 00512 : _M_data (__v._M_data) {} 00513 00514 template<typename _Tp> 00515 inline 00516 _Array<_Tp>::_Array(const _Tp* __restrict__ __b, size_t __s) 00517 : _M_data(__valarray_get_storage<_Tp>(__s)) 00518 { std::__valarray_copy_construct(__b, __s, _M_data); } 00519 00520 template<typename _Tp> 00521 inline _Tp* 00522 _Array<_Tp>::begin () const 00523 { return _M_data; } 00524 00525 #define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \ 00526 template<typename _Tp> \ 00527 inline void \ 00528 _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, const _Tp& __t) \ 00529 { \ 00530 for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; ++__p) \ 00531 *__p _Op##= __t; \ 00532 } \ 00533 \ 00534 template<typename _Tp> \ 00535 inline void \ 00536 _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \ 00537 { \ 00538 _Tp* __p = __a._M_data; \ 00539 for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; ++__p, ++__q) \ 00540 *__p _Op##= *__q; \ 00541 } \ 00542 \ 00543 template<typename _Tp, class _Dom> \ 00544 void \ 00545 _Array_augmented_##_Name(_Array<_Tp> __a, \ 00546 const _Expr<_Dom, _Tp>& __e, size_t __n) \ 00547 { \ 00548 _Tp* __p(__a._M_data); \ 00549 for (size_t __i = 0; __i < __n; ++__i, ++__p) \ 00550 *__p _Op##= __e[__i]; \ 00551 } \ 00552 \ 00553 template<typename _Tp> \ 00554 inline void \ 00555 _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, size_t __s, \ 00556 _Array<_Tp> __b) \ 00557 { \ 00558 _Tp* __q(__b._M_data); \ 00559 for (_Tp* __p = __a._M_data; __p < __a._M_data + __s * __n; \ 00560 __p += __s, ++__q) \ 00561 *__p _Op##= *__q; \ 00562 } \ 00563 \ 00564 template<typename _Tp> \ 00565 inline void \ 00566 _Array_augmented_##_Name(_Array<_Tp> __a, _Array<_Tp> __b, \ 00567 size_t __n, size_t __s) \ 00568 { \ 00569 _Tp* __q(__b._M_data); \ 00570 for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; \ 00571 ++__p, __q += __s) \ 00572 *__p _Op##= *__q; \ 00573 } \ 00574 \ 00575 template<typename _Tp, class _Dom> \ 00576 void \ 00577 _Array_augmented_##_Name(_Array<_Tp> __a, size_t __s, \ 00578 const _Expr<_Dom, _Tp>& __e, size_t __n) \ 00579 { \ 00580 _Tp* __p(__a._M_data); \ 00581 for (size_t __i = 0; __i < __n; ++__i, __p += __s) \ 00582 *__p _Op##= __e[__i]; \ 00583 } \ 00584 \ 00585 template<typename _Tp> \ 00586 inline void \ 00587 _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i, \ 00588 _Array<_Tp> __b, size_t __n) \ 00589 { \ 00590 _Tp* __q(__b._M_data); \ 00591 for (size_t* __j = __i._M_data; __j < __i._M_data + __n; \ 00592 ++__j, ++__q) \ 00593 __a._M_data[*__j] _Op##= *__q; \ 00594 } \ 00595 \ 00596 template<typename _Tp> \ 00597 inline void \ 00598 _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, \ 00599 _Array<_Tp> __b, _Array<size_t> __i) \ 00600 { \ 00601 _Tp* __p(__a._M_data); \ 00602 for (size_t* __j = __i._M_data; __j<__i._M_data + __n; \ 00603 ++__j, ++__p) \ 00604 *__p _Op##= __b._M_data[*__j]; \ 00605 } \ 00606 \ 00607 template<typename _Tp, class _Dom> \ 00608 void \ 00609 _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i, \ 00610 const _Expr<_Dom, _Tp>& __e, size_t __n) \ 00611 { \ 00612 size_t* __j(__i._M_data); \ 00613 for (size_t __k = 0; __k<__n; ++__k, ++__j) \ 00614 __a._M_data[*__j] _Op##= __e[__k]; \ 00615 } \ 00616 \ 00617 template<typename _Tp> \ 00618 void \ 00619 _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m, \ 00620 _Array<_Tp> __b, size_t __n) \ 00621 { \ 00622 bool* __ok(__m._M_data); \ 00623 _Tp* __p(__a._M_data); \ 00624 for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; \ 00625 ++__q, ++__ok, ++__p) \ 00626 { \ 00627 while (! *__ok) \ 00628 { \ 00629 ++__ok; \ 00630 ++__p; \ 00631 } \ 00632 *__p _Op##= *__q; \ 00633 } \ 00634 } \ 00635 \ 00636 template<typename _Tp> \ 00637 void \ 00638 _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, \ 00639 _Array<_Tp> __b, _Array<bool> __m) \ 00640 { \ 00641 bool* __ok(__m._M_data); \ 00642 _Tp* __q(__b._M_data); \ 00643 for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; \ 00644 ++__p, ++__ok, ++__q) \ 00645 { \ 00646 while (! *__ok) \ 00647 { \ 00648 ++__ok; \ 00649 ++__q; \ 00650 } \ 00651 *__p _Op##= *__q; \ 00652 } \ 00653 } \ 00654 \ 00655 template<typename _Tp, class _Dom> \ 00656 void \ 00657 _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m, \ 00658 const _Expr<_Dom, _Tp>& __e, size_t __n) \ 00659 { \ 00660 bool* __ok(__m._M_data); \ 00661 _Tp* __p(__a._M_data); \ 00662 for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p) \ 00663 { \ 00664 while (! *__ok) \ 00665 { \ 00666 ++__ok; \ 00667 ++__p; \ 00668 } \ 00669 *__p _Op##= __e[__i]; \ 00670 } \ 00671 } 00672 00673 _DEFINE_ARRAY_FUNCTION(+, __plus) 00674 _DEFINE_ARRAY_FUNCTION(-, __minus) 00675 _DEFINE_ARRAY_FUNCTION(*, __multiplies) 00676 _DEFINE_ARRAY_FUNCTION(/, __divides) 00677 _DEFINE_ARRAY_FUNCTION(%, __modulus) 00678 _DEFINE_ARRAY_FUNCTION(^, __bitwise_xor) 00679 _DEFINE_ARRAY_FUNCTION(|, __bitwise_or) 00680 _DEFINE_ARRAY_FUNCTION(&, __bitwise_and) 00681 _DEFINE_ARRAY_FUNCTION(<<, __shift_left) 00682 _DEFINE_ARRAY_FUNCTION(>>, __shift_right) 00683 00684 #undef _DEFINE_VALARRAY_FUNCTION 00685 } // namespace std 00686 00687 #ifndef _GLIBCXX_EXPORT_TEMPLATE 00688 # include <bits/valarray_array.tcc> 00689 #endif 00690 00691 #endif /* _ARRAY_H */

Generated on Sun Sep 12 15:49:59 2004 for libstdc++ source by doxygen 1.3.8