valarray_before.h

00001 // The template and inlines for the -*- C++ -*- internal _Meta class. 00002 00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 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@cmla.ens-cachan.fr> 00031 00032 /** @file valarray_meta.h 00033 * This is an internal header file, included by other library headers. 00034 * You should not attempt to use it directly. 00035 */ 00036 00037 #ifndef _VALARRAY_BEFORE_H 00038 #define _VALARRAY_BEFORE_H 1 00039 00040 #pragma GCC system_header 00041 00042 #include <bits/slice_array.h> 00043 00044 namespace std 00045 { 00046 // 00047 // Implementing a loosened valarray return value is tricky. 00048 // First we need to meet 26.3.1/3: we should not add more than 00049 // two levels of template nesting. Therefore we resort to template 00050 // template to "flatten" loosened return value types. 00051 // At some point we use partial specialization to remove one level 00052 // template nesting due to _Expr<> 00053 // 00054 00055 // This class is NOT defined. It doesn't need to. 00056 template<typename _Tp1, typename _Tp2> class _Constant; 00057 00058 // Implementations of unary functions applied to valarray<>s. 00059 // I use hard-coded object functions here instead of a generic 00060 // approach like pointers to function: 00061 // 1) correctness: some functions take references, others values. 00062 // we can't deduce the correct type afterwards. 00063 // 2) efficiency -- object functions can be easily inlined 00064 // 3) be Koenig-lookup-friendly 00065 00066 struct __abs 00067 { 00068 template<typename _Tp> 00069 _Tp operator()(const _Tp& __t) const { return abs(__t); } 00070 }; 00071 00072 struct __cos 00073 { 00074 template<typename _Tp> 00075 _Tp operator()(const _Tp& __t) const { return cos(__t); } 00076 }; 00077 00078 struct __acos 00079 { 00080 template<typename _Tp> 00081 _Tp operator()(const _Tp& __t) const { return acos(__t); } 00082 }; 00083 00084 struct __cosh 00085 { 00086 template<typename _Tp> 00087 _Tp operator()(const _Tp& __t) const { return cosh(__t); } 00088 }; 00089 00090 struct __sin 00091 { 00092 template<typename _Tp> 00093 _Tp operator()(const _Tp& __t) const { return sin(__t); } 00094 }; 00095 00096 struct __asin 00097 { 00098 template<typename _Tp> 00099 _Tp operator()(const _Tp& __t) const { return asin(__t); } 00100 }; 00101 00102 struct __sinh 00103 { 00104 template<typename _Tp> 00105 _Tp operator()(const _Tp& __t) const { return sinh(__t); } 00106 }; 00107 00108 struct __tan 00109 { 00110 template<typename _Tp> 00111 _Tp operator()(const _Tp& __t) const { return tan(__t); } 00112 }; 00113 00114 struct __atan 00115 { 00116 template<typename _Tp> 00117 _Tp operator()(const _Tp& __t) const { return atan(__t); } 00118 }; 00119 00120 struct __tanh 00121 { 00122 template<typename _Tp> 00123 _Tp operator()(const _Tp& __t) const { return tanh(__t); } 00124 }; 00125 00126 struct __exp 00127 { 00128 template<typename _Tp> 00129 _Tp operator()(const _Tp& __t) const { return exp(__t); } 00130 }; 00131 00132 struct __log 00133 { 00134 template<typename _Tp> 00135 _Tp operator()(const _Tp& __t) const { return log(__t); } 00136 }; 00137 00138 struct __log10 00139 { 00140 template<typename _Tp> 00141 _Tp operator()(const _Tp& __t) const { return log10(__t); } 00142 }; 00143 00144 struct __sqrt 00145 { 00146 template<typename _Tp> 00147 _Tp operator()(const _Tp& __t) const { return sqrt(__t); } 00148 }; 00149 00150 // In the past, we used to tailor operator applications semantics 00151 // to the specialization of standard function objects (i.e. plus<>, etc.) 00152 // That is incorrect. Therefore we provide our own surrogates. 00153 00154 struct __unary_plus 00155 { 00156 template<typename _Tp> 00157 _Tp operator()(const _Tp& __t) const { return +__t; } 00158 }; 00159 00160 struct __negate 00161 { 00162 template<typename _Tp> 00163 _Tp operator()(const _Tp& __t) const { return -__t; } 00164 }; 00165 00166 struct __bitwise_not 00167 { 00168 template<typename _Tp> 00169 _Tp operator()(const _Tp& __t) const { return ~__t; } 00170 }; 00171 00172 struct __plus 00173 { 00174 template<typename _Tp> 00175 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00176 { return __x + __y; } 00177 }; 00178 00179 struct __minus 00180 { 00181 template<typename _Tp> 00182 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00183 { return __x - __y; } 00184 }; 00185 00186 struct __multiplies 00187 { 00188 template<typename _Tp> 00189 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00190 { return __x * __y; } 00191 }; 00192 00193 struct __divides 00194 { 00195 template<typename _Tp> 00196 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00197 { return __x / __y; } 00198 }; 00199 00200 struct __modulus 00201 { 00202 template<typename _Tp> 00203 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00204 { return __x % __y; } 00205 }; 00206 00207 struct __bitwise_xor 00208 { 00209 template<typename _Tp> 00210 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00211 { return __x ^ __y; } 00212 }; 00213 00214 struct __bitwise_and 00215 { 00216 template<typename _Tp> 00217 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00218 { return __x & __y; } 00219 }; 00220 00221 struct __bitwise_or 00222 { 00223 template<typename _Tp> 00224 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00225 { return __x | __y; } 00226 }; 00227 00228 struct __shift_left 00229 { 00230 template<typename _Tp> 00231 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00232 { return __x << __y; } 00233 }; 00234 00235 struct __shift_right 00236 { 00237 template<typename _Tp> 00238 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00239 { return __x >> __y; } 00240 }; 00241 00242 struct __logical_and 00243 { 00244 template<typename _Tp> 00245 bool operator()(const _Tp& __x, const _Tp& __y) const 00246 { return __x && __y; } 00247 }; 00248 00249 struct __logical_or 00250 { 00251 template<typename _Tp> 00252 bool operator()(const _Tp& __x, const _Tp& __y) const 00253 { return __x || __y; } 00254 }; 00255 00256 struct __logical_not 00257 { 00258 template<typename _Tp> 00259 bool operator()(const _Tp& __x) const { return !__x; } 00260 }; 00261 00262 struct __equal_to 00263 { 00264 template<typename _Tp> 00265 bool operator()(const _Tp& __x, const _Tp& __y) const 00266 { return __x == __y; } 00267 }; 00268 00269 struct __not_equal_to 00270 { 00271 template<typename _Tp> 00272 bool operator()(const _Tp& __x, const _Tp& __y) const 00273 { return __x != __y; } 00274 }; 00275 00276 struct __less 00277 { 00278 template<typename _Tp> 00279 bool operator()(const _Tp& __x, const _Tp& __y) const 00280 { return __x < __y; } 00281 }; 00282 00283 struct __greater 00284 { 00285 template<typename _Tp> 00286 bool operator()(const _Tp& __x, const _Tp& __y) const 00287 { return __x > __y; } 00288 }; 00289 00290 struct __less_equal 00291 { 00292 template<typename _Tp> 00293 bool operator()(const _Tp& __x, const _Tp& __y) const 00294 { return __x <= __y; } 00295 }; 00296 00297 struct __greater_equal 00298 { 00299 template<typename _Tp> 00300 bool operator()(const _Tp& __x, const _Tp& __y) const 00301 { return __x >= __y; } 00302 }; 00303 00304 // The few binary functions we miss. 00305 struct __atan2 00306 { 00307 template<typename _Tp> 00308 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00309 { return atan2(__x, __y); } 00310 }; 00311 00312 struct __pow 00313 { 00314 template<typename _Tp> 00315 _Tp operator()(const _Tp& __x, const _Tp& __y) const 00316 { return pow(__x, __y); } 00317 }; 00318 00319 00320 // We need these bits in order to recover the return type of 00321 // some functions/operators now that we're no longer using 00322 // function templates. 00323 template<typename, typename _Tp> 00324 struct __fun 00325 { 00326 typedef _Tp result_type; 00327 }; 00328 00329 // several specializations for relational operators. 00330 template<typename _Tp> 00331 struct __fun<__logical_not, _Tp> 00332 { 00333 typedef bool result_type; 00334 }; 00335 00336 template<typename _Tp> 00337 struct __fun<__logical_and, _Tp> 00338 { 00339 typedef bool result_type; 00340 }; 00341 00342 template<typename _Tp> 00343 struct __fun<__logical_or, _Tp> 00344 { 00345 typedef bool result_type; 00346 }; 00347 00348 template<typename _Tp> 00349 struct __fun<__less, _Tp> 00350 { 00351 typedef bool result_type; 00352 }; 00353 00354 template<typename _Tp> 00355 struct __fun<__greater, _Tp> 00356 { 00357 typedef bool result_type; 00358 }; 00359 00360 template<typename _Tp> 00361 struct __fun<__less_equal, _Tp> 00362 { 00363 typedef bool result_type; 00364 }; 00365 00366 template<typename _Tp> 00367 struct __fun<__greater_equal, _Tp> 00368 { 00369 typedef bool result_type; 00370 }; 00371 00372 template<typename _Tp> 00373 struct __fun<__equal_to, _Tp> 00374 { 00375 typedef bool result_type; 00376 }; 00377 00378 template<typename _Tp> 00379 struct __fun<__not_equal_to, _Tp> 00380 { 00381 typedef bool result_type; 00382 }; 00383 00384 // 00385 // Apply function taking a value/const reference closure 00386 // 00387 00388 template<typename _Dom, typename _Arg> 00389 class _FunBase 00390 { 00391 public: 00392 typedef typename _Dom::value_type value_type; 00393 00394 _FunBase(const _Dom& __e, value_type __f(_Arg)) 00395 : _M_expr(__e), _M_func(__f) {} 00396 00397 value_type operator[](size_t __i) const 00398 { return _M_func (_M_expr[__i]); } 00399 00400 size_t size() const { return _M_expr.size ();} 00401 00402 private: 00403 const _Dom& _M_expr; 00404 value_type (*_M_func)(_Arg); 00405 }; 00406 00407 template<class _Dom> 00408 struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type> 00409 { 00410 typedef _FunBase<_Dom, typename _Dom::value_type> _Base; 00411 typedef typename _Base::value_type value_type; 00412 typedef value_type _Tp; 00413 00414 _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {} 00415 }; 00416 00417 template<typename _Tp> 00418 struct _ValFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, _Tp> 00419 { 00420 typedef _FunBase<valarray<_Tp>, _Tp> _Base; 00421 typedef _Tp value_type; 00422 00423 _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {} 00424 }; 00425 00426 template<class _Dom> 00427 struct _RefFunClos<_Expr,_Dom> : 00428 _FunBase<_Dom, const typename _Dom::value_type&> 00429 { 00430 typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base; 00431 typedef typename _Base::value_type value_type; 00432 typedef value_type _Tp; 00433 00434 _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&)) 00435 : _Base(__e, __f) {} 00436 }; 00437 00438 template<typename _Tp> 00439 struct _RefFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, const _Tp&> 00440 { 00441 typedef _FunBase<valarray<_Tp>, const _Tp&> _Base; 00442 typedef _Tp value_type; 00443 00444 _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&)) 00445 : _Base(__v, __f) {} 00446 }; 00447 00448 // 00449 // Unary expression closure. 00450 // 00451 00452 template<class _Oper, class _Arg> 00453 class _UnBase 00454 { 00455 public: 00456 typedef typename _Arg::value_type _Vt; 00457 typedef typename __fun<_Oper, _Vt>::result_type value_type; 00458 00459 _UnBase(const _Arg& __e) : _M_expr(__e) {} 00460 00461 value_type operator[](size_t __i) const 00462 { return _Oper()(_M_expr[__i]); } 00463 00464 size_t size() const { return _M_expr.size(); } 00465 00466 private: 00467 const _Arg& _M_expr; 00468 }; 00469 00470 template<class _Oper, class _Dom> 00471 struct _UnClos<_Oper, _Expr, _Dom> : _UnBase<_Oper, _Dom> 00472 { 00473 typedef _Dom _Arg; 00474 typedef _UnBase<_Oper, _Dom> _Base; 00475 typedef typename _Base::value_type value_type; 00476 00477 _UnClos(const _Arg& __e) : _Base(__e) {} 00478 }; 00479 00480 template<class _Oper, typename _Tp> 00481 struct _UnClos<_Oper, _ValArray, _Tp> : _UnBase<_Oper, valarray<_Tp> > 00482 { 00483 typedef valarray<_Tp> _Arg; 00484 typedef _UnBase<_Oper, valarray<_Tp> > _Base; 00485 typedef typename _Base::value_type value_type; 00486 00487 _UnClos(const _Arg& __e) : _Base(__e) {} 00488 }; 00489 00490 00491 // 00492 // Binary expression closure. 00493 // 00494 00495 template<class _Oper, class _FirstArg, class _SecondArg> 00496 class _BinBase 00497 { 00498 public: 00499 typedef typename _FirstArg::value_type _Vt; 00500 typedef typename __fun<_Oper, _Vt>::result_type value_type; 00501 00502 _BinBase(const _FirstArg& __e1, const _SecondArg& __e2) 00503 : _M_expr1(__e1), _M_expr2(__e2) {} 00504 00505 value_type operator[](size_t __i) const 00506 { return _Oper()(_M_expr1[__i], _M_expr2[__i]); } 00507 00508 size_t size() const { return _M_expr1.size(); } 00509 00510 private: 00511 const _FirstArg& _M_expr1; 00512 const _SecondArg& _M_expr2; 00513 }; 00514 00515 00516 template<class _Oper, class _Clos> 00517 class _BinBase2 00518 { 00519 public: 00520 typedef typename _Clos::value_type _Vt; 00521 typedef typename __fun<_Oper, _Vt>::result_type value_type; 00522 00523 _BinBase2(const _Clos& __e, const _Vt& __t) 00524 : _M_expr1(__e), _M_expr2(__t) {} 00525 00526 value_type operator[](size_t __i) const 00527 { return _Oper()(_M_expr1[__i], _M_expr2); } 00528 00529 size_t size() const { return _M_expr1.size(); } 00530 00531 private: 00532 const _Clos& _M_expr1; 00533 const _Vt& _M_expr2; 00534 }; 00535 00536 template<class _Oper, class _Clos> 00537 class _BinBase1 00538 { 00539 public: 00540 typedef typename _Clos::value_type _Vt; 00541 typedef typename __fun<_Oper, _Vt>::result_type value_type; 00542 00543 _BinBase1(const _Vt& __t, const _Clos& __e) 00544 : _M_expr1(__t), _M_expr2(__e) {} 00545 00546 value_type operator[](size_t __i) const 00547 { return _Oper()(_M_expr1, _M_expr2[__i]); } 00548 00549 size_t size() const { return _M_expr2.size(); } 00550 00551 private: 00552 const _Vt& _M_expr1; 00553 const _Clos& _M_expr2; 00554 }; 00555 00556 template<class _Oper, class _Dom1, class _Dom2> 00557 struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2> 00558 : _BinBase<_Oper,_Dom1,_Dom2> 00559 { 00560 typedef _BinBase<_Oper,_Dom1,_Dom2> _Base; 00561 typedef typename _Base::value_type value_type; 00562 00563 _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {} 00564 }; 00565 00566 template<class _Oper, typename _Tp> 00567 struct _BinClos<_Oper,_ValArray,_ValArray,_Tp,_Tp> 00568 : _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > 00569 { 00570 typedef _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > _Base; 00571 typedef _Tp value_type; 00572 00573 _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w) 00574 : _Base(__v, __w) {} 00575 }; 00576 00577 template<class _Oper, class _Dom> 00578 struct _BinClos<_Oper,_Expr,_ValArray,_Dom,typename _Dom::value_type> 00579 : _BinBase<_Oper,_Dom,valarray<typename _Dom::value_type> > 00580 { 00581 typedef typename _Dom::value_type _Tp; 00582 typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base; 00583 typedef typename _Base::value_type value_type; 00584 00585 _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2) 00586 : _Base(__e1, __e2) {} 00587 }; 00588 00589 template<class _Oper, class _Dom> 00590 struct _BinClos<_Oper,_ValArray,_Expr,typename _Dom::value_type,_Dom> 00591 : _BinBase<_Oper,valarray<typename _Dom::value_type>,_Dom> 00592 { 00593 typedef typename _Dom::value_type _Tp; 00594 typedef _BinBase<_Oper,valarray<_Tp>,_Dom> _Base; 00595 typedef typename _Base::value_type value_type; 00596 00597 _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2) 00598 : _Base(__e1, __e2) {} 00599 }; 00600 00601 template<class _Oper, class _Dom> 00602 struct _BinClos<_Oper,_Expr,_Constant,_Dom,typename _Dom::value_type> 00603 : _BinBase2<_Oper,_Dom> 00604 { 00605 typedef typename _Dom::value_type _Tp; 00606 typedef _BinBase2<_Oper,_Dom> _Base; 00607 typedef typename _Base::value_type value_type; 00608 00609 _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {} 00610 }; 00611 00612 template<class _Oper, class _Dom> 00613 struct _BinClos<_Oper,_Constant,_Expr,typename _Dom::value_type,_Dom> 00614 : _BinBase1<_Oper,_Dom> 00615 { 00616 typedef typename _Dom::value_type _Tp; 00617 typedef _BinBase1<_Oper,_Dom> _Base; 00618 typedef typename _Base::value_type value_type; 00619 00620 _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {} 00621 }; 00622 00623 template<class _Oper, typename _Tp> 00624 struct _BinClos<_Oper,_ValArray,_Constant,_Tp,_Tp> 00625 : _BinBase2<_Oper,valarray<_Tp> > 00626 { 00627 typedef _BinBase2<_Oper,valarray<_Tp> > _Base; 00628 typedef typename _Base::value_type value_type; 00629 00630 _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {} 00631 }; 00632 00633 template<class _Oper, typename _Tp> 00634 struct _BinClos<_Oper,_Constant,_ValArray,_Tp,_Tp> 00635 : _BinBase1<_Oper,valarray<_Tp> > 00636 { 00637 typedef _BinBase1<_Oper,valarray<_Tp> > _Base; 00638 typedef typename _Base::value_type value_type; 00639 00640 _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {} 00641 }; 00642 00643 00644 // 00645 // slice_array closure. 00646 // 00647 template<typename _Dom> class _SBase { 00648 public: 00649 typedef typename _Dom::value_type value_type; 00650 00651 _SBase (const _Dom& __e, const slice& __s) 00652 : _M_expr (__e), _M_slice (__s) {} 00653 value_type operator[] (size_t __i) const 00654 { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; } 00655 size_t size() const { return _M_slice.size (); } 00656 00657 private: 00658 const _Dom& _M_expr; 00659 const slice& _M_slice; 00660 }; 00661 00662 template<typename _Tp> class _SBase<_Array<_Tp> > { 00663 public: 00664 typedef _Tp value_type; 00665 00666 _SBase (_Array<_Tp> __a, const slice& __s) 00667 : _M_array (__a._M_data+__s.start()), _M_size (__s.size()), 00668 _M_stride (__s.stride()) {} 00669 value_type operator[] (size_t __i) const 00670 { return _M_array._M_data[__i * _M_stride]; } 00671 size_t size() const { return _M_size; } 00672 00673 private: 00674 const _Array<_Tp> _M_array; 00675 const size_t _M_size; 00676 const size_t _M_stride; 00677 }; 00678 00679 template<class _Dom> struct _SClos<_Expr,_Dom> : _SBase<_Dom> { 00680 typedef _SBase<_Dom> _Base; 00681 typedef typename _Base::value_type value_type; 00682 00683 _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {} 00684 }; 00685 00686 template<typename _Tp> 00687 struct _SClos<_ValArray,_Tp> : _SBase<_Array<_Tp> > { 00688 typedef _SBase<_Array<_Tp> > _Base; 00689 typedef _Tp value_type; 00690 00691 _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {} 00692 }; 00693 00694 } // std:: 00695 00696 00697 #endif /* _CPP_VALARRAY_BEFORE_H */ 00698 00699 // Local Variables: 00700 // mode:c++ 00701 // End:

Generated on Tue Sep 7 10:05:24 2004 for libstdc++-v3 Source by doxygen 1.3.8