1 // The template and inlines for the -*- C++ -*- internal _Meta class. 2 3 // Copyright (C) 1997-2013 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file bits/valarray_before.h 26 * This is an internal header file, included by other library headers. 27 * Do not attempt to use it directly. @headername{valarray} 28 */ 29 30 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis (at) cmla.ens-cachan.fr> 31 32 #ifndef _VALARRAY_BEFORE_H 33 #define _VALARRAY_BEFORE_H 1 34 35 #pragma GCC system_header 36 37 #include <bits/slice_array.h> 38 39 namespace std _GLIBCXX_VISIBILITY(default) 40 { 41 _GLIBCXX_BEGIN_NAMESPACE_VERSION 42 43 // 44 // Implementing a loosened valarray return value is tricky. 45 // First we need to meet 26.3.1/3: we should not add more than 46 // two levels of template nesting. Therefore we resort to template 47 // template to "flatten" loosened return value types. 48 // At some point we use partial specialization to remove one level 49 // template nesting due to _Expr<> 50 // 51 52 // This class is NOT defined. It doesn't need to. 53 template<typename _Tp1, typename _Tp2> class _Constant; 54 55 // Implementations of unary functions applied to valarray<>s. 56 // I use hard-coded object functions here instead of a generic 57 // approach like pointers to function: 58 // 1) correctness: some functions take references, others values. 59 // we can't deduce the correct type afterwards. 60 // 2) efficiency -- object functions can be easily inlined 61 // 3) be Koenig-lookup-friendly 62 63 struct _Abs 64 { 65 template<typename _Tp> 66 _Tp operator()(const _Tp& __t) const 67 { return abs(__t); } 68 }; 69 70 struct _Cos 71 { 72 template<typename _Tp> 73 _Tp operator()(const _Tp& __t) const 74 { return cos(__t); } 75 }; 76 77 struct _Acos 78 { 79 template<typename _Tp> 80 _Tp operator()(const _Tp& __t) const 81 { return acos(__t); } 82 }; 83 84 struct _Cosh 85 { 86 template<typename _Tp> 87 _Tp operator()(const _Tp& __t) const 88 { return cosh(__t); } 89 }; 90 91 struct _Sin 92 { 93 template<typename _Tp> 94 _Tp operator()(const _Tp& __t) const 95 { return sin(__t); } 96 }; 97 98 struct _Asin 99 { 100 template<typename _Tp> 101 _Tp operator()(const _Tp& __t) const 102 { return asin(__t); } 103 }; 104 105 struct _Sinh 106 { 107 template<typename _Tp> 108 _Tp operator()(const _Tp& __t) const 109 { return sinh(__t); } 110 }; 111 112 struct _Tan 113 { 114 template<typename _Tp> 115 _Tp operator()(const _Tp& __t) const 116 { return tan(__t); } 117 }; 118 119 struct _Atan 120 { 121 template<typename _Tp> 122 _Tp operator()(const _Tp& __t) const 123 { return atan(__t); } 124 }; 125 126 struct _Tanh 127 { 128 template<typename _Tp> 129 _Tp operator()(const _Tp& __t) const 130 { return tanh(__t); } 131 }; 132 133 struct _Exp 134 { 135 template<typename _Tp> 136 _Tp operator()(const _Tp& __t) const 137 { return exp(__t); } 138 }; 139 140 struct _Log 141 { 142 template<typename _Tp> 143 _Tp operator()(const _Tp& __t) const 144 { return log(__t); } 145 }; 146 147 struct _Log10 148 { 149 template<typename _Tp> 150 _Tp operator()(const _Tp& __t) const 151 { return log10(__t); } 152 }; 153 154 struct _Sqrt 155 { 156 template<typename _Tp> 157 _Tp operator()(const _Tp& __t) const 158 { return sqrt(__t); } 159 }; 160 161 // In the past, we used to tailor operator applications semantics 162 // to the specialization of standard function objects (i.e. plus<>, etc.) 163 // That is incorrect. Therefore we provide our own surrogates. 164 165 struct __unary_plus 166 { 167 template<typename _Tp> 168 _Tp operator()(const _Tp& __t) const 169 { return +__t; } 170 }; 171 172 struct __negate 173 { 174 template<typename _Tp> 175 _Tp operator()(const _Tp& __t) const 176 { return -__t; } 177 }; 178 179 struct __bitwise_not 180 { 181 template<typename _Tp> 182 _Tp operator()(const _Tp& __t) const 183 { return ~__t; } 184 }; 185 186 struct __plus 187 { 188 template<typename _Tp> 189 _Tp operator()(const _Tp& __x, const _Tp& __y) const 190 { return __x + __y; } 191 }; 192 193 struct __minus 194 { 195 template<typename _Tp> 196 _Tp operator()(const _Tp& __x, const _Tp& __y) const 197 { return __x - __y; } 198 }; 199 200 struct __multiplies 201 { 202 template<typename _Tp> 203 _Tp operator()(const _Tp& __x, const _Tp& __y) const 204 { return __x * __y; } 205 }; 206 207 struct __divides 208 { 209 template<typename _Tp> 210 _Tp operator()(const _Tp& __x, const _Tp& __y) const 211 { return __x / __y; } 212 }; 213 214 struct __modulus 215 { 216 template<typename _Tp> 217 _Tp operator()(const _Tp& __x, const _Tp& __y) const 218 { return __x % __y; } 219 }; 220 221 struct __bitwise_xor 222 { 223 template<typename _Tp> 224 _Tp operator()(const _Tp& __x, const _Tp& __y) const 225 { return __x ^ __y; } 226 }; 227 228 struct __bitwise_and 229 { 230 template<typename _Tp> 231 _Tp operator()(const _Tp& __x, const _Tp& __y) const 232 { return __x & __y; } 233 }; 234 235 struct __bitwise_or 236 { 237 template<typename _Tp> 238 _Tp operator()(const _Tp& __x, const _Tp& __y) const 239 { return __x | __y; } 240 }; 241 242 struct __shift_left 243 { 244 template<typename _Tp> 245 _Tp operator()(const _Tp& __x, const _Tp& __y) const 246 { return __x << __y; } 247 }; 248 249 struct __shift_right 250 { 251 template<typename _Tp> 252 _Tp operator()(const _Tp& __x, const _Tp& __y) const 253 { return __x >> __y; } 254 }; 255 256 struct __logical_and 257 { 258 template<typename _Tp> 259 bool operator()(const _Tp& __x, const _Tp& __y) const 260 { return __x && __y; } 261 }; 262 263 struct __logical_or 264 { 265 template<typename _Tp> 266 bool operator()(const _Tp& __x, const _Tp& __y) const 267 { return __x || __y; } 268 }; 269 270 struct __logical_not 271 { 272 template<typename _Tp> 273 bool operator()(const _Tp& __x) const 274 { return !__x; } 275 }; 276 277 struct __equal_to 278 { 279 template<typename _Tp> 280 bool operator()(const _Tp& __x, const _Tp& __y) const 281 { return __x == __y; } 282 }; 283 284 struct __not_equal_to 285 { 286 template<typename _Tp> 287 bool operator()(const _Tp& __x, const _Tp& __y) const 288 { return __x != __y; } 289 }; 290 291 struct __less 292 { 293 template<typename _Tp> 294 bool operator()(const _Tp& __x, const _Tp& __y) const 295 { return __x < __y; } 296 }; 297 298 struct __greater 299 { 300 template<typename _Tp> 301 bool operator()(const _Tp& __x, const _Tp& __y) const 302 { return __x > __y; } 303 }; 304 305 struct __less_equal 306 { 307 template<typename _Tp> 308 bool operator()(const _Tp& __x, const _Tp& __y) const 309 { return __x <= __y; } 310 }; 311 312 struct __greater_equal 313 { 314 template<typename _Tp> 315 bool operator()(const _Tp& __x, const _Tp& __y) const 316 { return __x >= __y; } 317 }; 318 319 // The few binary functions we miss. 320 struct _Atan2 321 { 322 template<typename _Tp> 323 _Tp operator()(const _Tp& __x, const _Tp& __y) const 324 { return atan2(__x, __y); } 325 }; 326 327 struct _Pow 328 { 329 template<typename _Tp> 330 _Tp operator()(const _Tp& __x, const _Tp& __y) const 331 { return pow(__x, __y); } 332 }; 333 334 335 // We need these bits in order to recover the return type of 336 // some functions/operators now that we're no longer using 337 // function templates. 338 template<typename, typename _Tp> 339 struct __fun 340 { 341 typedef _Tp result_type; 342 }; 343 344 // several specializations for relational operators. 345 template<typename _Tp> 346 struct __fun<__logical_not, _Tp> 347 { 348 typedef bool result_type; 349 }; 350 351 template<typename _Tp> 352 struct __fun<__logical_and, _Tp> 353 { 354 typedef bool result_type; 355 }; 356 357 template<typename _Tp> 358 struct __fun<__logical_or, _Tp> 359 { 360 typedef bool result_type; 361 }; 362 363 template<typename _Tp> 364 struct __fun<__less, _Tp> 365 { 366 typedef bool result_type; 367 }; 368 369 template<typename _Tp> 370 struct __fun<__greater, _Tp> 371 { 372 typedef bool result_type; 373 }; 374 375 template<typename _Tp> 376 struct __fun<__less_equal, _Tp> 377 { 378 typedef bool result_type; 379 }; 380 381 template<typename _Tp> 382 struct __fun<__greater_equal, _Tp> 383 { 384 typedef bool result_type; 385 }; 386 387 template<typename _Tp> 388 struct __fun<__equal_to, _Tp> 389 { 390 typedef bool result_type; 391 }; 392 393 template<typename _Tp> 394 struct __fun<__not_equal_to, _Tp> 395 { 396 typedef bool result_type; 397 }; 398 399 // 400 // Apply function taking a value/const reference closure 401 // 402 403 template<typename _Dom, typename _Arg> 404 class _FunBase 405 { 406 public: 407 typedef typename _Dom::value_type value_type; 408 409 _FunBase(const _Dom& __e, value_type __f(_Arg)) 410 : _M_expr(__e), _M_func(__f) {} 411 412 value_type operator[](size_t __i) const 413 { return _M_func (_M_expr[__i]); } 414 415 size_t size() const { return _M_expr.size ();} 416 417 private: 418 const _Dom& _M_expr; 419 value_type (*_M_func)(_Arg); 420 }; 421 422 template<class _Dom> 423 struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type> 424 { 425 typedef _FunBase<_Dom, typename _Dom::value_type> _Base; 426 typedef typename _Base::value_type value_type; 427 typedef value_type _Tp; 428 429 _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {} 430 }; 431 432 template<typename _Tp> 433 struct _ValFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, _Tp> 434 { 435 typedef _FunBase<valarray<_Tp>, _Tp> _Base; 436 typedef _Tp value_type; 437 438 _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {} 439 }; 440 441 template<class _Dom> 442 struct _RefFunClos<_Expr, _Dom> 443 : _FunBase<_Dom, const typename _Dom::value_type&> 444 { 445 typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base; 446 typedef typename _Base::value_type value_type; 447 typedef value_type _Tp; 448 449 _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&)) 450 : _Base(__e, __f) {} 451 }; 452 453 template<typename _Tp> 454 struct _RefFunClos<_ValArray, _Tp> 455 : _FunBase<valarray<_Tp>, const _Tp&> 456 { 457 typedef _FunBase<valarray<_Tp>, const _Tp&> _Base; 458 typedef _Tp value_type; 459 460 _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&)) 461 : _Base(__v, __f) {} 462 }; 463 464 // 465 // Unary expression closure. 466 // 467 468 template<class _Oper, class _Arg> 469 class _UnBase 470 { 471 public: 472 typedef typename _Arg::value_type _Vt; 473 typedef typename __fun<_Oper, _Vt>::result_type value_type; 474 475 _UnBase(const _Arg& __e) : _M_expr(__e) {} 476 477 value_type operator[](size_t __i) const 478 { return _Oper()(_M_expr[__i]); } 479 480 size_t size() const { return _M_expr.size(); } 481 482 private: 483 const _Arg& _M_expr; 484 }; 485 486 template<class _Oper, class _Dom> 487 struct _UnClos<_Oper, _Expr, _Dom> 488 : _UnBase<_Oper, _Dom> 489 { 490 typedef _Dom _Arg; 491 typedef _UnBase<_Oper, _Dom> _Base; 492 typedef typename _Base::value_type value_type; 493 494 _UnClos(const _Arg& __e) : _Base(__e) {} 495 }; 496 497 template<class _Oper, typename _Tp> 498 struct _UnClos<_Oper, _ValArray, _Tp> 499 : _UnBase<_Oper, valarray<_Tp> > 500 { 501 typedef valarray<_Tp> _Arg; 502 typedef _UnBase<_Oper, valarray<_Tp> > _Base; 503 typedef typename _Base::value_type value_type; 504 505 _UnClos(const _Arg& __e) : _Base(__e) {} 506 }; 507 508 509 // 510 // Binary expression closure. 511 // 512 513 template<class _Oper, class _FirstArg, class _SecondArg> 514 class _BinBase 515 { 516 public: 517 typedef typename _FirstArg::value_type _Vt; 518 typedef typename __fun<_Oper, _Vt>::result_type value_type; 519 520 _BinBase(const _FirstArg& __e1, const _SecondArg& __e2) 521 : _M_expr1(__e1), _M_expr2(__e2) {} 522 523 value_type operator[](size_t __i) const 524 { return _Oper()(_M_expr1[__i], _M_expr2[__i]); } 525 526 size_t size() const { return _M_expr1.size(); } 527 528 private: 529 const _FirstArg& _M_expr1; 530 const _SecondArg& _M_expr2; 531 }; 532 533 534 template<class _Oper, class _Clos> 535 class _BinBase2 536 { 537 public: 538 typedef typename _Clos::value_type _Vt; 539 typedef typename __fun<_Oper, _Vt>::result_type value_type; 540 541 _BinBase2(const _Clos& __e, const _Vt& __t) 542 : _M_expr1(__e), _M_expr2(__t) {} 543 544 value_type operator[](size_t __i) const 545 { return _Oper()(_M_expr1[__i], _M_expr2); } 546 547 size_t size() const { return _M_expr1.size(); } 548 549 private: 550 const _Clos& _M_expr1; 551 const _Vt& _M_expr2; 552 }; 553 554 template<class _Oper, class _Clos> 555 class _BinBase1 556 { 557 public: 558 typedef typename _Clos::value_type _Vt; 559 typedef typename __fun<_Oper, _Vt>::result_type value_type; 560 561 _BinBase1(const _Vt& __t, const _Clos& __e) 562 : _M_expr1(__t), _M_expr2(__e) {} 563 564 value_type operator[](size_t __i) const 565 { return _Oper()(_M_expr1, _M_expr2[__i]); } 566 567 size_t size() const { return _M_expr2.size(); } 568 569 private: 570 const _Vt& _M_expr1; 571 const _Clos& _M_expr2; 572 }; 573 574 template<class _Oper, class _Dom1, class _Dom2> 575 struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2> 576 : _BinBase<_Oper, _Dom1, _Dom2> 577 { 578 typedef _BinBase<_Oper, _Dom1, _Dom2> _Base; 579 typedef typename _Base::value_type value_type; 580 581 _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {} 582 }; 583 584 template<class _Oper, typename _Tp> 585 struct _BinClos<_Oper,_ValArray, _ValArray, _Tp, _Tp> 586 : _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > 587 { 588 typedef _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > _Base; 589 typedef typename _Base::value_type value_type; 590 591 _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w) 592 : _Base(__v, __w) {} 593 }; 594 595 template<class _Oper, class _Dom> 596 struct _BinClos<_Oper, _Expr, _ValArray, _Dom, typename _Dom::value_type> 597 : _BinBase<_Oper, _Dom, valarray<typename _Dom::value_type> > 598 { 599 typedef typename _Dom::value_type _Tp; 600 typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base; 601 typedef typename _Base::value_type value_type; 602 603 _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2) 604 : _Base(__e1, __e2) {} 605 }; 606 607 template<class _Oper, class _Dom> 608 struct _BinClos<_Oper, _ValArray, _Expr, typename _Dom::value_type, _Dom> 609 : _BinBase<_Oper, valarray<typename _Dom::value_type>,_Dom> 610 { 611 typedef typename _Dom::value_type _Tp; 612 typedef _BinBase<_Oper, valarray<_Tp>, _Dom> _Base; 613 typedef typename _Base::value_type value_type; 614 615 _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2) 616 : _Base(__e1, __e2) {} 617 }; 618 619 template<class _Oper, class _Dom> 620 struct _BinClos<_Oper, _Expr, _Constant, _Dom, typename _Dom::value_type> 621 : _BinBase2<_Oper, _Dom> 622 { 623 typedef typename _Dom::value_type _Tp; 624 typedef _BinBase2<_Oper,_Dom> _Base; 625 typedef typename _Base::value_type value_type; 626 627 _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {} 628 }; 629 630 template<class _Oper, class _Dom> 631 struct _BinClos<_Oper, _Constant, _Expr, typename _Dom::value_type, _Dom> 632 : _BinBase1<_Oper, _Dom> 633 { 634 typedef typename _Dom::value_type _Tp; 635 typedef _BinBase1<_Oper, _Dom> _Base; 636 typedef typename _Base::value_type value_type; 637 638 _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {} 639 }; 640 641 template<class _Oper, typename _Tp> 642 struct _BinClos<_Oper, _ValArray, _Constant, _Tp, _Tp> 643 : _BinBase2<_Oper, valarray<_Tp> > 644 { 645 typedef _BinBase2<_Oper,valarray<_Tp> > _Base; 646 typedef typename _Base::value_type value_type; 647 648 _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {} 649 }; 650 651 template<class _Oper, typename _Tp> 652 struct _BinClos<_Oper, _Constant, _ValArray, _Tp, _Tp> 653 : _BinBase1<_Oper, valarray<_Tp> > 654 { 655 typedef _BinBase1<_Oper, valarray<_Tp> > _Base; 656 typedef typename _Base::value_type value_type; 657 658 _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {} 659 }; 660 661 // 662 // slice_array closure. 663 // 664 template<typename _Dom> 665 class _SBase 666 { 667 public: 668 typedef typename _Dom::value_type value_type; 669 670 _SBase (const _Dom& __e, const slice& __s) 671 : _M_expr (__e), _M_slice (__s) {} 672 673 value_type 674 operator[] (size_t __i) const 675 { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; } 676 677 size_t 678 size() const 679 { return _M_slice.size (); } 680 681 private: 682 const _Dom& _M_expr; 683 const slice& _M_slice; 684 }; 685 686 template<typename _Tp> 687 class _SBase<_Array<_Tp> > 688 { 689 public: 690 typedef _Tp value_type; 691 692 _SBase (_Array<_Tp> __a, const slice& __s) 693 : _M_array (__a._M_data+__s.start()), _M_size (__s.size()), 694 _M_stride (__s.stride()) {} 695 696 value_type 697 operator[] (size_t __i) const 698 { return _M_array._M_data[__i * _M_stride]; } 699 700 size_t 701 size() const 702 { return _M_size; } 703 704 private: 705 const _Array<_Tp> _M_array; 706 const size_t _M_size; 707 const size_t _M_stride; 708 }; 709 710 template<class _Dom> 711 struct _SClos<_Expr, _Dom> 712 : _SBase<_Dom> 713 { 714 typedef _SBase<_Dom> _Base; 715 typedef typename _Base::value_type value_type; 716 717 _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {} 718 }; 719 720 template<typename _Tp> 721 struct _SClos<_ValArray, _Tp> 722 : _SBase<_Array<_Tp> > 723 { 724 typedef _SBase<_Array<_Tp> > _Base; 725 typedef _Tp value_type; 726 727 _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {} 728 }; 729 730 _GLIBCXX_END_NAMESPACE_VERSION 731 } // namespace 732 733 #endif /* _CPP_VALARRAY_BEFORE_H */ 734