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