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