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