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

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