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