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