Whole document tree valarray_array.hGo to the documentation of this file.00001 // The template and inlines for the -*- C++ -*- internal _Array helper class. 00002 00003 // Copyright (C) 1997-2000 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 2, 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 // You should have received a copy of the GNU General Public License along 00017 // with this library; see the file COPYING. If not, write to the Free 00018 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00019 // USA. 00020 00021 // As a special exception, you may use this file as part of a free software 00022 // library without restriction. Specifically, if other files instantiate 00023 // templates or use macros or inline functions from this file, or you compile 00024 // this file and link it with other files to produce an executable, this 00025 // file does not by itself cause the resulting executable to be covered by 00026 // the GNU General Public License. This exception does not however 00027 // invalidate any other reasons why the executable file might be covered by 00028 // the GNU General Public License. 00029 00030 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> 00031 00032 #ifndef _CPP_BITS_ARRAY_H 00033 #define _CPP_BITS_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 <bits/std_cstdlib.h> 00040 #include <bits/std_cstring.h> 00041 #include <new> 00042 00043 namespace std 00044 { 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 (__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* __restrict__ __b, _Tp* __restrict__ __e) 00077 { while (__b != __e) new(__b++) _Tp(); } 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* __restrict__ __b, _Tp* __restrict__ __e) 00086 { memset(__b, 0, (__e - __b)*sizeof(_Tp)); } 00087 }; 00088 00089 template<typename _Tp> 00090 inline void 00091 __valarray_default_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e) 00092 { 00093 _Array_default_ctor<_Tp, __is_fundamental<_Tp>::_M_type>:: 00094 _S_do_it(__b, __e); 00095 } 00096 00097 // Turn a raw-memory into an array of _Tp filled with __t 00098 // This is the required in valarray<T> v(n, t). Also 00099 // used in valarray<>::resize(). 00100 template<typename _Tp, bool> 00101 struct _Array_init_ctor 00102 { 00103 // Please note that this isn't exception safe. But 00104 // valarrays aren't required to be exception safe. 00105 inline static void 00106 _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t) 00107 { while (__b != __e) new(__b++) _Tp(__t); } 00108 }; 00109 00110 template<typename _Tp> 00111 struct _Array_init_ctor<_Tp, true> 00112 { 00113 inline static void 00114 _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t) 00115 { while (__b != __e) *__b++ = __t; } 00116 }; 00117 00118 template<typename _Tp> 00119 inline void 00120 __valarray_fill_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e, 00121 const _Tp __t) 00122 { 00123 _Array_init_ctor<_Tp, __is_fundamental<_Tp>::_M_type>:: 00124 _S_do_it(__b, __e, __t); 00125 } 00126 00127 // 00128 // copy-construct raw array [__o, *) from plain array [__b, __e) 00129 // We can't just say 'memcpy()' 00130 // 00131 template<typename _Tp, bool> 00132 struct _Array_copy_ctor 00133 { 00134 // Please note that this isn't exception safe. But 00135 // valarrays aren't required to be exception safe. 00136 inline static void 00137 _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e, 00138 _Tp* __restrict__ __o) 00139 { while (__b != __e) new(__o++) _Tp(*__b++); } 00140 }; 00141 00142 template<typename _Tp> 00143 struct _Array_copy_ctor<_Tp, true> 00144 { 00145 inline static void 00146 _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e, 00147 _Tp* __restrict__ __o) 00148 { memcpy(__o, __b, (__e - __b)*sizeof(_Tp)); } 00149 }; 00150 00151 template<typename _Tp> 00152 inline void 00153 __valarray_copy_construct(const _Tp* __restrict__ __b, 00154 const _Tp* __restrict__ __e, 00155 _Tp* __restrict__ __o) 00156 { 00157 _Array_copy_ctor<_Tp, __is_fundamental<_Tp>::_M_type>:: 00158 _S_do_it(__b, __e, __o); 00159 } 00160 00161 // copy-construct raw array [__o, *) from strided array __a[<__n : __s>] 00162 template<typename _Tp> 00163 inline void 00164 __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n, 00165 size_t __s, _Tp* __restrict__ __o) 00166 { 00167 if (__is_fundamental<_Tp>::_M_type) 00168 while (__n--) { *__o++ = *__a; __a += __s; } 00169 else 00170 while (__n--) { new(__o++) _Tp(*__a); __a += __s; } 00171 } 00172 00173 // copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]] 00174 template<typename _Tp> 00175 inline void 00176 __valarray_copy_construct (const _Tp* __restrict__ __a, 00177 const size_t* __restrict__ __i, 00178 _Tp* __restrict__ __o, size_t __n) 00179 { 00180 if (__is_fundamental<_Tp>::_M_type) 00181 while (__n--) *__o++ = __a[*__i++]; 00182 else 00183 while (__n--) new (__o++) _Tp(__a[*__i++]); 00184 } 00185 00186 // Do the necessary cleanup when we're done with arrays. 00187 template<typename _Tp> 00188 inline void 00189 __valarray_destroy_elements(_Tp* __restrict__ __b, _Tp* __restrict__ __e) 00190 { 00191 if (!__is_fundamental<_Tp>::_M_type) 00192 while (__b != __e) { __b->~_Tp(); ++__b; } 00193 } 00194 00195 // fill plain array __a[<__n>] with __t 00196 template<typename _Tp> 00197 void 00198 __valarray_fill (_Tp* __restrict__ __a, size_t __n, const _Tp& __t) 00199 { while (__n--) *__a++ = __t; } 00200 00201 // fill strided array __a[<__n-1 : __s>] with __t 00202 template<typename _Tp> 00203 inline void 00204 __valarray_fill (_Tp* __restrict__ __a, size_t __n, 00205 size_t __s, const _Tp& __t) 00206 { for (size_t __i=0; __i<__n; ++__i, __a+=__s) *__a = __t; } 00207 00208 // fill indir ect array __a[__i[<__n>]] with __i 00209 template<typename _Tp> 00210 inline void 00211 __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i, 00212 size_t __n, const _Tp& __t) 00213 { for (size_t __j=0; __j<__n; ++__j, ++__i) __a[*__i] = __t; } 00214 00215 // copy plain array __a[<__n>] in __b[<__n>] 00216 // For non-fundamental types, it is wrong to say 'memcpy()' 00217 template<typename _Tp, bool> 00218 struct _Array_copier 00219 { 00220 inline static void 00221 _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) 00222 { while (__n--) *__b++ = *__a++; } 00223 }; 00224 00225 template<typename _Tp> 00226 struct _Array_copier<_Tp, true> 00227 { 00228 inline static void 00229 _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) 00230 { memcpy (__b, __a, __n * sizeof (_Tp)); } 00231 }; 00232 00233 template<typename _Tp> 00234 inline void 00235 __valarray_copy (const _Tp* __restrict__ __a, size_t __n, 00236 _Tp* __restrict__ __b) 00237 { 00238 _Array_copier<_Tp, __is_fundamental<_Tp>::_M_type>:: 00239 _S_do_it(__a, __n, __b); 00240 } 00241 00242 // copy strided array __a[<__n : __s>] in plain __b[<__n>] 00243 template<typename _Tp> 00244 inline void 00245 __valarray_copy (const _Tp* __restrict__ __a, size_t __n, size_t __s, 00246 _Tp* __restrict__ __b) 00247 { for (size_t __i=0; __i<__n; ++__i, ++__b, __a += __s) *__b = *__a; } 00248 00249 // copy plain __a[<__n>] in strided __b[<__n : __s>] 00250 template<typename _Tp> 00251 inline void 00252 __valarray_copy (const _Tp* __restrict__ __a, _Tp* __restrict__ __b, 00253 size_t __n, size_t __s) 00254 { for (size_t __i=0; __i<__n; ++__i, ++__a, __b+=__s) *__b = *__a; } 00255 00256 // copy indexed __a[__i[<__n>]] in plain __b[<__n>] 00257 template<typename _Tp> 00258 inline void 00259 __valarray_copy (const _Tp* __restrict__ __a, 00260 const size_t* __restrict__ __i, 00261 _Tp* __restrict__ __b, size_t __n) 00262 { for (size_t __j=0; __j<__n; ++__j, ++__b, ++__i) *__b = __a[*__i]; } 00263 00264 // copy plain __a[<__n>] in indexed __b[__i[<__n>]] 00265 template<typename _Tp> 00266 inline void 00267 __valarray_copy (const _Tp* __restrict__ __a, size_t __n, 00268 _Tp* __restrict__ __b, const size_t* __restrict__ __i) 00269 { for (size_t __j=0; __j<__n; ++__j, ++__a, ++__i) __b[*__i] = *__a; } 00270 00271 00272 // 00273 // Compute the sum of elements in range [__f, __l) 00274 // This is a naive algorithm. It suffers from cancelling. 00275 // In the future try to specialize 00276 // for _Tp = float, double, long double using a more accurate 00277 // algorithm. 00278 // 00279 template<typename _Tp> 00280 inline _Tp 00281 __valarray_sum(const _Tp* __restrict__ __f, const _Tp* __restrict__ __l) 00282 { 00283 _Tp __r = _Tp(); 00284 while (__f != __l) __r += *__f++; 00285 return __r; 00286 } 00287 00288 // Compute the product of all elements in range [__f, __l) 00289 template<typename _Tp> 00290 inline _Tp 00291 __valarray_product(const _Tp* __restrict__ __f, 00292 const _Tp* __restrict__ __l) 00293 { 00294 _Tp __r = _Tp(1); 00295 while (__f != __l) __r = __r * *__f++; 00296 return __r; 00297 } 00298 00299 // Compute the min/max of an array-expression 00300 template<typename _Ta> 00301 inline typename _Ta::value_type 00302 __valarray_min(const _Ta& __a) 00303 { 00304 size_t __s = __a.size(); 00305 typedef typename _Ta::value_type _Value_type; 00306 _Value_type __r = __s == 0 ? _Value_type() : __a[0]; 00307 for (size_t __i = 1; __i < __s; ++__i) 00308 { 00309 _Value_type __t = __a[__i]; 00310 if (__t < __r) 00311 __r = __t; 00312 } 00313 return __r; 00314 } 00315 00316 template<typename _Ta> 00317 inline typename _Ta::value_type 00318 __valarray_max(const _Ta& __a) 00319 { 00320 size_t __s = __a.size(); 00321 typedef typename _Ta::value_type _Value_type; 00322 _Value_type __r = __s == 0 ? _Value_type() : __a[0]; 00323 for (size_t __i = 1; __i < __s; ++__i) 00324 { 00325 _Value_type __t = __a[__i]; 00326 if (__t > __r) 00327 __r = __t; 00328 } 00329 return __r; 00330 } 00331 00332 // 00333 // Helper class _Array, first layer of valarray abstraction. 00334 // All operations on valarray should be forwarded to this class 00335 // whenever possible. -- gdr 00336 // 00337 00338 template<typename _Tp> 00339 struct _Array 00340 { 00341 explicit _Array (size_t); 00342 explicit _Array (_Tp* const __restrict__); 00343 explicit _Array (const valarray<_Tp>&); 00344 _Array (const _Tp* __restrict__, size_t); 00345 00346 _Tp* begin () const; 00347 00348 _Tp* const __restrict__ _M_data; 00349 }; 00350 00351 template<typename _Tp> 00352 inline void 00353 __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t) 00354 { __valarray_fill (__a._M_data, __n, __t); } 00355 00356 template<typename _Tp> 00357 inline void 00358 __valarray_fill (_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t) 00359 { __valarray_fill (__a._M_data, __n, __s, __t); } 00360 00361 template<typename _Tp> 00362 inline void 00363 __valarray_fill (_Array<_Tp> __a, _Array<size_t> __i, 00364 size_t __n, const _Tp& __t) 00365 { __valarray_fill (__a._M_data, __i._M_data, __n, __t); } 00366 00367 template<typename _Tp> 00368 inline void 00369 __valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) 00370 { __valarray_copy (__a._M_data, __n, __b._M_data); } 00371 00372 template<typename _Tp> 00373 inline void 00374 __valarray_copy (_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b) 00375 { __valarray_copy(__a._M_data, __n, __s, __b._M_data); } 00376 00377 template<typename _Tp> 00378 inline void 00379 __valarray_copy (_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s) 00380 { __valarray_copy (__a._M_data, __b._M_data, __n, __s); } 00381 00382 template<typename _Tp> 00383 inline void 00384 __valarray_copy (_Array<_Tp> __a, _Array<size_t> __i, 00385 _Array<_Tp> __b, size_t __n) 00386 { __valarray_copy (__a._M_data, __i._M_data, __b._M_data, __n); } 00387 00388 template<typename _Tp> 00389 inline void 00390 __valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, 00391 _Array<size_t> __i) 00392 { __valarray_copy (__a._M_data, __n, __b._M_data, __i._M_data); } 00393 00394 template<typename _Tp> 00395 inline 00396 _Array<_Tp>::_Array (size_t __n) 00397 : _M_data(__valarray_get_storage<_Tp>(__n)) 00398 { __valarray_default_construct(_M_data, _M_data + __n); } 00399 00400 template<typename _Tp> 00401 inline 00402 _Array<_Tp>::_Array (_Tp* const __restrict__ __p) : _M_data (__p) {} 00403 00404 template<typename _Tp> 00405 inline _Array<_Tp>::_Array (const valarray<_Tp>& __v) 00406 : _M_data (__v._M_data) {} 00407 00408 template<typename _Tp> 00409 inline 00410 _Array<_Tp>::_Array (const _Tp* __restrict__ __b, size_t __s) 00411 : _M_data(__valarray_get_storage<_Tp>(__s)) 00412 { __valarray_copy_construct(__b, __s, _M_data); } 00413 00414 template<typename _Tp> 00415 inline _Tp* 00416 _Array<_Tp>::begin () const 00417 { return _M_data; } 00418 00419 #define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \ 00420 template<typename _Tp> \ 00421 inline void \ 00422 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, const _Tp& __t) \ 00423 { \ 00424 for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p) \ 00425 *__p _Op##= __t; \ 00426 } \ 00427 \ 00428 template<typename _Tp> \ 00429 inline void \ 00430 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \ 00431 { \ 00432 _Tp* __p = __a._M_data; \ 00433 for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__p, ++__q) \ 00434 *__p _Op##= *__q; \ 00435 } \ 00436 \ 00437 template<typename _Tp, class _Dom> \ 00438 void \ 00439 _Array_augmented_##_Name (_Array<_Tp> __a, \ 00440 const _Expr<_Dom,_Tp>& __e, size_t __n) \ 00441 { \ 00442 _Tp* __p (__a._M_data); \ 00443 for (size_t __i=0; __i<__n; ++__i, ++__p) *__p _Op##= __e[__i]; \ 00444 } \ 00445 \ 00446 template<typename _Tp> \ 00447 inline void \ 00448 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, size_t __s, \ 00449 _Array<_Tp> __b) \ 00450 { \ 00451 _Tp* __q (__b._M_data); \ 00452 for (_Tp* __p=__a._M_data; __p<__a._M_data+__s*__n; __p+=__s, ++__q) \ 00453 *__p _Op##= *__q; \ 00454 } \ 00455 \ 00456 template<typename _Tp> \ 00457 inline void \ 00458 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<_Tp> __b, \ 00459 size_t __n, size_t __s) \ 00460 { \ 00461 _Tp* __q (__b._M_data); \ 00462 for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, __q+=__s) \ 00463 *__p _Op##= *__q; \ 00464 } \ 00465 \ 00466 template<typename _Tp, class _Dom> \ 00467 void \ 00468 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __s, \ 00469 const _Expr<_Dom,_Tp>& __e, size_t __n) \ 00470 { \ 00471 _Tp* __p (__a._M_data); \ 00472 for (size_t __i=0; __i<__n; ++__i, __p+=__s) *__p _Op##= __e[__i]; \ 00473 } \ 00474 \ 00475 template<typename _Tp> \ 00476 inline void \ 00477 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i, \ 00478 _Array<_Tp> __b, size_t __n) \ 00479 { \ 00480 _Tp* __q (__b._M_data); \ 00481 for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__q) \ 00482 __a._M_data[*__j] _Op##= *__q; \ 00483 } \ 00484 \ 00485 template<typename _Tp> \ 00486 inline void \ 00487 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \ 00488 _Array<_Tp> __b, _Array<size_t> __i) \ 00489 { \ 00490 _Tp* __p (__a._M_data); \ 00491 for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__p) \ 00492 *__p _Op##= __b._M_data[*__j]; \ 00493 } \ 00494 \ 00495 template<typename _Tp, class _Dom> \ 00496 void \ 00497 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i, \ 00498 const _Expr<_Dom, _Tp>& __e, size_t __n) \ 00499 { \ 00500 size_t* __j (__i._M_data); \ 00501 for (size_t __k=0; __k<__n; ++__k, ++__j) \ 00502 __a._M_data[*__j] _Op##= __e[__k]; \ 00503 } \ 00504 \ 00505 template<typename _Tp> \ 00506 void \ 00507 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m, \ 00508 _Array<_Tp> __b, size_t __n) \ 00509 { \ 00510 bool* ok (__m._M_data); \ 00511 _Tp* __p (__a._M_data); \ 00512 for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__q, ++ok, ++__p) { \ 00513 while (! *ok) { \ 00514 ++ok; \ 00515 ++__p; \ 00516 } \ 00517 *__p _Op##= *__q; \ 00518 } \ 00519 } \ 00520 \ 00521 template<typename _Tp> \ 00522 void \ 00523 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \ 00524 _Array<_Tp> __b, _Array<bool> __m) \ 00525 { \ 00526 bool* ok (__m._M_data); \ 00527 _Tp* __q (__b._M_data); \ 00528 for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, ++ok, ++__q) { \ 00529 while (! *ok) { \ 00530 ++ok; \ 00531 ++__q; \ 00532 } \ 00533 *__p _Op##= *__q; \ 00534 } \ 00535 } \ 00536 \ 00537 template<typename _Tp, class _Dom> \ 00538 void \ 00539 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m, \ 00540 const _Expr<_Dom, _Tp>& __e, size_t __n) \ 00541 { \ 00542 bool* ok(__m._M_data); \ 00543 _Tp* __p (__a._M_data); \ 00544 for (size_t __i=0; __i<__n; ++__i, ++ok, ++__p) { \ 00545 while (! *ok) { \ 00546 ++ok; \ 00547 ++__p; \ 00548 } \ 00549 *__p _Op##= __e[__i]; \ 00550 } \ 00551 } 00552 00553 _DEFINE_ARRAY_FUNCTION(+, plus) 00554 _DEFINE_ARRAY_FUNCTION(-, minus) 00555 _DEFINE_ARRAY_FUNCTION(*, multiplies) 00556 _DEFINE_ARRAY_FUNCTION(/, divides) 00557 _DEFINE_ARRAY_FUNCTION(%, modulus) 00558 _DEFINE_ARRAY_FUNCTION(^, xor) 00559 _DEFINE_ARRAY_FUNCTION(|, or) 00560 _DEFINE_ARRAY_FUNCTION(&, and) 00561 _DEFINE_ARRAY_FUNCTION(<<, shift_left) 00562 _DEFINE_ARRAY_FUNCTION(>>, shift_right) 00563 00564 #undef _DEFINE_VALARRAY_FUNCTION 00565 00566 } // std:: 00567 00568 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT 00569 # define export 00570 # include <bits/valarray_array.tcc> 00571 #endif 00572 00573 #endif /* _CPP_BITS_ARRAY_H */ 00574 00575 // Local Variables: 00576 // mode:c++ 00577 // End: Generated on Mon Apr 8 03:11:47 2002 for libstdc++-v3 Source by ![]() |