1// The template and inlines for the -*- C++ -*- internal _Meta class. 2 3// Copyright (C) 1997, 1998, 1999, 2000, 2001 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 2, 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// You should have received a copy of the GNU General Public License along 17// with this library; see the file COPYING. If not, write to the Free 18// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 19// USA. 20 21// As a special exception, you may use this file as part of a free software 22// library without restriction. Specifically, if other files instantiate 23// templates or use macros or inline functions from this file, or you compile 24// this file and link it with other files to produce an executable, this 25// file does not by itself cause the resulting executable to be covered by 26// the GNU General Public License. This exception does not however 27// invalidate any other reasons why the executable file might be covered by 28// the GNU General Public License. 29 30// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr> 31 32/** @file valarray_meta.h 33 * This is an internal header file, included by other library headers. 34 * You should not attempt to use it directly. 35 */ 36 37#ifndef _CPP_VALARRAY_META_H 38#define _CPP_VALARRAY_META_H 1 39 40#pragma GCC system_header 41 42namespace std 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 { return abs(__t); } 68 }; 69 70 struct __cos 71 { 72 template<typename _Tp> 73 _Tp operator()(const _Tp& __t) const { return cos(__t); } 74 }; 75 76 struct __acos 77 { 78 template<typename _Tp> 79 _Tp operator()(const _Tp& __t) const { return acos(__t); } 80 }; 81 82 struct __cosh 83 { 84 template<typename _Tp> 85 _Tp operator()(const _Tp& __t) const { return cosh(__t); } 86 }; 87 88 struct __sin 89 { 90 template<typename _Tp> 91 _Tp operator()(const _Tp& __t) const { return sin(__t); } 92 }; 93 94 struct __asin 95 { 96 template<typename _Tp> 97 _Tp operator()(const _Tp& __t) const { return asin(__t); } 98 }; 99 100 struct __sinh 101 { 102 template<typename _Tp> 103 _Tp operator()(const _Tp& __t) const { return sinh(__t); } 104 }; 105 106 struct __tan 107 { 108 template<typename _Tp> 109 _Tp operator()(const _Tp& __t) const { return tan(__t); } 110 }; 111 112 struct __atan 113 { 114 template<typename _Tp> 115 _Tp operator()(const _Tp& __t) const { return atan(__t); } 116 }; 117 118 struct __tanh 119 { 120 template<typename _Tp> 121 _Tp operator()(const _Tp& __t) const { return tanh(__t); } 122 }; 123 124 struct __exp 125 { 126 template<typename _Tp> 127 _Tp operator()(const _Tp& __t) const { return exp(__t); } 128 }; 129 130 struct __log 131 { 132 template<typename _Tp> 133 _Tp operator()(const _Tp& __t) const { return log(__t); } 134 }; 135 136 struct __log10 137 { 138 template<typename _Tp> 139 _Tp operator()(const _Tp& __t) const { return log10(__t); } 140 }; 141 142 struct __sqrt 143 { 144 template<typename _Tp> 145 _Tp operator()(const _Tp& __t) const { return sqrt(__t); } 146 }; 147 148 // In the past, we used to tailor operator applications semantics 149 // to the specialization of standard function objects (i.e. plus<>, etc.) 150 // That is incorrect. Therefore we provide our own surrogates. 151 152 struct __unary_plus 153 { 154 template<typename _Tp> 155 _Tp operator()(const _Tp& __t) const { return +__t; } 156 }; 157 158 struct __negate 159 { 160 template<typename _Tp> 161 _Tp operator()(const _Tp& __t) const { return -__t; } 162 }; 163 164 struct __bitwise_not 165 { 166 template<typename _Tp> 167 _Tp operator()(const _Tp& __t) const { return ~__t; } 168 }; 169 170 struct __plus 171 { 172 template<typename _Tp> 173 _Tp operator()(const _Tp& __x, const _Tp& __y) const 174 { return __x + __y; } 175 }; 176 177 struct __minus 178 { 179 template<typename _Tp> 180 _Tp operator()(const _Tp& __x, const _Tp& __y) const 181 { return __x - __y; } 182 }; 183 184 struct __multiplies 185 { 186 template<typename _Tp> 187 _Tp operator()(const _Tp& __x, const _Tp& __y) const 188 { return __x * __y; } 189 }; 190 191 struct __divides 192 { 193 template<typename _Tp> 194 _Tp operator()(const _Tp& __x, const _Tp& __y) const 195 { return __x / __y; } 196 }; 197 198 struct __modulus 199 { 200 template<typename _Tp> 201 _Tp operator()(const _Tp& __x, const _Tp& __y) const 202 { return __x % __y; } 203 }; 204 205 struct __bitwise_xor 206 { 207 template<typename _Tp> 208 _Tp operator()(const _Tp& __x, const _Tp& __y) const 209 { return __x ^ __y; } 210 }; 211 212 struct __bitwise_and 213 { 214 template<typename _Tp> 215 _Tp operator()(const _Tp& __x, const _Tp& __y) const 216 { return __x & __y; } 217 }; 218 219 struct __bitwise_or 220 { 221 template<typename _Tp> 222 _Tp operator()(const _Tp& __x, const _Tp& __y) const 223 { return __x | __y; } 224 }; 225 226 struct __shift_left 227 { 228 template<typename _Tp> 229 _Tp operator()(const _Tp& __x, const _Tp& __y) const 230 { return __x << __y; } 231 }; 232 233 struct __shift_right 234 { 235 template<typename _Tp> 236 _Tp operator()(const _Tp& __x, const _Tp& __y) const 237 { return __x >> __y; } 238 }; 239 240 struct __logical_and 241 { 242 template<typename _Tp> 243 bool operator()(const _Tp& __x, const _Tp& __y) const 244 { return __x && __y; } 245 }; 246 247 struct __logical_or 248 { 249 template<typename _Tp> 250 bool operator()(const _Tp& __x, const _Tp& __y) const 251 { return __x || __y; } 252 }; 253 254 struct __logical_not 255 { 256 template<typename _Tp> 257 bool operator()(const _Tp& __x) const { return !__x; } 258 }; 259 260 struct __equal_to 261 { 262 template<typename _Tp> 263 bool operator()(const _Tp& __x, const _Tp& __y) const 264 { return __x == __y; } 265 }; 266 267 struct __not_equal_to 268 { 269 template<typename _Tp> 270 bool operator()(const _Tp& __x, const _Tp& __y) const 271 { return __x != __y; } 272 }; 273 274 struct __less 275 { 276 template<typename _Tp> 277 bool operator()(const _Tp& __x, const _Tp& __y) const 278 { return __x < __y; } 279 }; 280 281 struct __greater 282 { 283 template<typename _Tp> 284 bool operator()(const _Tp& __x, const _Tp& __y) const 285 { return __x > __y; } 286 }; 287 288 struct __less_equal 289 { 290 template<typename _Tp> 291 bool operator()(const _Tp& __x, const _Tp& __y) const 292 { return __x <= __y; } 293 }; 294 295 struct __greater_equal 296 { 297 template<typename _Tp> 298 bool operator()(const _Tp& __x, const _Tp& __y) const 299 { return __x >= __y; } 300 }; 301 302 // The few binary functions we miss. 303 struct __atan2 304 { 305 template<typename _Tp> 306 _Tp operator()(const _Tp& __x, const _Tp& __y) const 307 { return atan2(__x, __y); } 308 }; 309 310 struct __pow 311 { 312 template<typename _Tp> 313 _Tp operator()(const _Tp& __x, const _Tp& __y) const 314 { return pow(__x, __y); } 315 }; 316 317 318 // We need these bits in order to recover the return type of 319 // some functions/operators now that we're no longer using 320 // function templates. 321 template<typename, typename _Tp> 322 struct __fun 323 { 324 typedef _Tp result_type; 325 }; 326 327 // several specializations for relational operators. 328 template<typename _Tp> 329 struct __fun<__logical_not, _Tp> 330 { 331 typedef bool result_type; 332 }; 333 334 template<typename _Tp> 335 struct __fun<__logical_and, _Tp> 336 { 337 typedef bool result_type; 338 }; 339 340 template<typename _Tp> 341 struct __fun<__logical_or, _Tp> 342 { 343 typedef bool result_type; 344 }; 345 346 template<typename _Tp> 347 struct __fun<__less, _Tp> 348 { 349 typedef bool result_type; 350 }; 351 352 template<typename _Tp> 353 struct __fun<__greater, _Tp> 354 { 355 typedef bool result_type; 356 }; 357 358 template<typename _Tp> 359 struct __fun<__less_equal, _Tp> 360 { 361 typedef bool result_type; 362 }; 363 364 template<typename _Tp> 365 struct __fun<__greater_equal, _Tp> 366 { 367 typedef bool result_type; 368 }; 369 370 template<typename _Tp> 371 struct __fun<__equal_to, _Tp> 372 { 373 typedef bool result_type; 374 }; 375 376 template<typename _Tp> 377 struct __fun<__not_equal_to, _Tp> 378 { 379 typedef bool result_type; 380 }; 381 382 // 383 // Apply function taking a value/const reference closure 384 // 385 386 template<typename _Dom, typename _Arg> 387 class _FunBase 388 { 389 public: 390 typedef typename _Dom::value_type value_type; 391 392 _FunBase(const _Dom& __e, value_type __f(_Arg)) 393 : _M_expr(__e), _M_func(__f) {} 394 395 value_type operator[](size_t __i) const 396 { return _M_func (_M_expr[__i]); } 397 398 size_t size() const { return _M_expr.size ();} 399 400 private: 401 const _Dom& _M_expr; 402 value_type (*_M_func)(_Arg); 403 }; 404 405 template<class _Dom> 406 struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type> 407 { 408 typedef _FunBase<_Dom, typename _Dom::value_type> _Base; 409 typedef typename _Base::value_type value_type; 410 typedef value_type _Tp; 411 412 _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {} 413 }; 414 415 template<typename _Tp> 416 struct _ValFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, _Tp> 417 { 418 typedef _FunBase<valarray<_Tp>, _Tp> _Base; 419 typedef _Tp value_type; 420 421 _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {} 422 }; 423 424 template<class _Dom> 425 struct _RefFunClos<_Expr,_Dom> : 426 _FunBase<_Dom, const typename _Dom::value_type&> 427 { 428 typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base; 429 typedef typename _Base::value_type value_type; 430 typedef value_type _Tp; 431 432 _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&)) 433 : _Base(__e, __f) {} 434 }; 435 436 template<typename _Tp> 437 struct _RefFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, const _Tp&> 438 { 439 typedef _FunBase<valarray<_Tp>, const _Tp&> _Base; 440 typedef _Tp value_type; 441 442 _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&)) 443 : _Base(__v, __f) {} 444 }; 445 446 // 447 // Unary expression closure. 448 // 449 450 template<class _Oper, class _Arg> 451 class _UnBase 452 { 453 public: 454 typedef typename _Arg::value_type _Vt; 455 typedef typename __fun<_Oper, _Vt>::result_type value_type; 456 457 _UnBase(const _Arg& __e) : _M_expr(__e) {} 458 459 value_type operator[](size_t __i) const 460 { return _Oper()(_M_expr[__i]); } 461 462 size_t size() const { return _M_expr.size(); } 463 464 private: 465 const _Arg& _M_expr; 466 }; 467 468 template<class _Oper, class _Dom> 469 struct _UnClos<_Oper, _Expr, _Dom> : _UnBase<_Oper, _Dom> 470 { 471 typedef _Dom _Arg; 472 typedef _UnBase<_Oper, _Dom> _Base; 473 typedef typename _Base::value_type value_type; 474 475 _UnClos(const _Arg& __e) : _Base(__e) {} 476 }; 477 478 template<class _Oper, typename _Tp> 479 struct _UnClos<_Oper, _ValArray, _Tp> : _UnBase<_Oper, valarray<_Tp> > 480 { 481 typedef valarray<_Tp> _Arg; 482 typedef _UnBase<_Oper, valarray<_Tp> > _Base; 483 typedef typename _Base::value_type value_type; 484 485 _UnClos(const _Arg& __e) : _Base(__e) {} 486 }; 487 488 489 // 490 // Binary expression closure. 491 // 492 493 template<class _Oper, class _FirstArg, class _SecondArg> 494 class _BinBase 495 { 496 public: 497 typedef typename _FirstArg::value_type _Vt; 498 typedef typename __fun<_Oper, _Vt>::result_type value_type; 499 500 _BinBase(const _FirstArg& __e1, const _SecondArg& __e2) 501 : _M_expr1(__e1), _M_expr2(__e2) {} 502 503 value_type operator[](size_t __i) const 504 { return _Oper()(_M_expr1[__i], _M_expr2[__i]); } 505 506 size_t size() const { return _M_expr1.size(); } 507 508 private: 509 const _FirstArg& _M_expr1; 510 const _SecondArg& _M_expr2; 511 }; 512 513 514 template<class _Oper, class _Clos> 515 class _BinBase2 516 { 517 public: 518 typedef typename _Clos::value_type _Vt; 519 typedef typename __fun<_Oper, _Vt>::result_type value_type; 520 521 _BinBase2(const _Clos& __e, const _Vt& __t) 522 : _M_expr1(__e), _M_expr2(__t) {} 523 524 value_type operator[](size_t __i) const 525 { return _Oper()(_M_expr1[__i], _M_expr2); } 526 527 size_t size() const { return _M_expr1.size(); } 528 529 private: 530 const _Clos& _M_expr1; 531 const _Vt& _M_expr2; 532 }; 533 534 template<class _Oper, class _Clos> 535 class _BinBase1 536 { 537 public: 538 typedef typename _Clos::value_type _Vt; 539 typedef typename __fun<_Oper, _Vt>::result_type value_type; 540 541 _BinBase1(const _Vt& __t, const _Clos& __e) 542 : _M_expr1(__t), _M_expr2(__e) {} 543 544 value_type operator[](size_t __i) const 545 { return _Oper()(_M_expr1, _M_expr2[__i]); } 546 547 size_t size() const { return _M_expr2.size(); } 548 549 private: 550 const _Vt& _M_expr1; 551 const _Clos& _M_expr2; 552 }; 553 554 template<class _Oper, class _Dom1, class _Dom2> 555 struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2> 556 : _BinBase<_Oper,_Dom1,_Dom2> 557 { 558 typedef _BinBase<_Oper,_Dom1,_Dom2> _Base; 559 typedef typename _Base::value_type value_type; 560 561 _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {} 562 }; 563 564 template<class _Oper, typename _Tp> 565 struct _BinClos<_Oper,_ValArray,_ValArray,_Tp,_Tp> 566 : _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > 567 { 568 typedef _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > _Base; 569 typedef _Tp value_type; 570 571 _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w) 572 : _Base(__v, __w) {} 573 }; 574 575 template<class _Oper, class _Dom> 576 struct _BinClos<_Oper,_Expr,_ValArray,_Dom,typename _Dom::value_type> 577 : _BinBase<_Oper,_Dom,valarray<typename _Dom::value_type> > 578 { 579 typedef typename _Dom::value_type _Tp; 580 typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base; 581 typedef typename _Base::value_type value_type; 582 583 _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2) 584 : _Base(__e1, __e2) {} 585 }; 586 587 template<class _Oper, class _Dom> 588 struct _BinClos<_Oper,_ValArray,_Expr,typename _Dom::value_type,_Dom> 589 : _BinBase<_Oper,valarray<typename _Dom::value_type>,_Dom> 590 { 591 typedef typename _Dom::value_type _Tp; 592 typedef _BinBase<_Oper,valarray<_Tp>,_Dom> _Base; 593 typedef typename _Base::value_type value_type; 594 595 _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2) 596 : _Base(__e1, __e2) {} 597 }; 598 599 template<class _Oper, class _Dom> 600 struct _BinClos<_Oper,_Expr,_Constant,_Dom,typename _Dom::value_type> 601 : _BinBase2<_Oper,_Dom> 602 { 603 typedef typename _Dom::value_type _Tp; 604 typedef _BinBase2<_Oper,_Dom> _Base; 605 typedef typename _Base::value_type value_type; 606 607 _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {} 608 }; 609 610 template<class _Oper, class _Dom> 611 struct _BinClos<_Oper,_Constant,_Expr,typename _Dom::value_type,_Dom> 612 : _BinBase1<_Oper,_Dom> 613 { 614 typedef typename _Dom::value_type _Tp; 615 typedef _BinBase1<_Oper,_Dom> _Base; 616 typedef typename _Base::value_type value_type; 617 618 _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {} 619 }; 620 621 template<class _Oper, typename _Tp> 622 struct _BinClos<_Oper,_ValArray,_Constant,_Tp,_Tp> 623 : _BinBase2<_Oper,valarray<_Tp> > 624 { 625 typedef _BinBase2<_Oper,valarray<_Tp> > _Base; 626 typedef typename _Base::value_type value_type; 627 628 _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {} 629 }; 630 631 template<class _Oper, typename _Tp> 632 struct _BinClos<_Oper,_Constant,_ValArray,_Tp,_Tp> 633 : _BinBase1<_Oper,valarray<_Tp> > 634 { 635 typedef _BinBase1<_Oper,valarray<_Tp> > _Base; 636 typedef typename _Base::value_type value_type; 637 638 _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {} 639 }; 640 641 642 // 643 // slice_array closure. 644 // 645 template<typename _Dom> class _SBase { 646 public: 647 typedef typename _Dom::value_type value_type; 648 649 _SBase (const _Dom& __e, const slice& __s) 650 : _M_expr (__e), _M_slice (__s) {} 651 value_type operator[] (size_t __i) const 652 { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; } 653 size_t size() const { return _M_slice.size (); } 654 655 private: 656 const _Dom& _M_expr; 657 const slice& _M_slice; 658 }; 659 660 template<typename _Tp> class _SBase<_Array<_Tp> > { 661 public: 662 typedef _Tp value_type; 663 664 _SBase (_Array<_Tp> __a, const slice& __s) 665 : _M_array (__a._M_data+__s.start()), _M_size (__s.size()), 666 _M_stride (__s.stride()) {} 667 value_type operator[] (size_t __i) const 668 { return _M_array._M_data[__i * _M_stride]; } 669 size_t size() const { return _M_size; } 670 671 private: 672 const _Array<_Tp> _M_array; 673 const size_t _M_size; 674 const size_t _M_stride; 675 }; 676 677 template<class _Dom> struct _SClos<_Expr,_Dom> : _SBase<_Dom> { 678 typedef _SBase<_Dom> _Base; 679 typedef typename _Base::value_type value_type; 680 681 _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {} 682 }; 683 684 template<typename _Tp> 685 struct _SClos<_ValArray,_Tp> : _SBase<_Array<_Tp> > { 686 typedef _SBase<_Array<_Tp> > _Base; 687 typedef _Tp value_type; 688 689 _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {} 690 }; 691 692 // 693 // gslice_array closure. 694 // 695 template<class _Dom> class _GBase { 696 public: 697 typedef typename _Dom::value_type value_type; 698 699 _GBase (const _Dom& __e, const valarray<size_t>& __i) 700 : _M_expr (__e), _M_index(__i) {} 701 value_type operator[] (size_t __i) const 702 { return _M_expr[_M_index[__i]]; } 703 size_t size () const { return _M_index.size(); } 704 705 private: 706 const _Dom& _M_expr; 707 const valarray<size_t>& _M_index; 708 }; 709 710 template<typename _Tp> class _GBase<_Array<_Tp> > { 711 public: 712 typedef _Tp value_type; 713 714 _GBase (_Array<_Tp> __a, const valarray<size_t>& __i) 715 : _M_array (__a), _M_index(__i) {} 716 value_type operator[] (size_t __i) const 717 { return _M_array._M_data[_M_index[__i]]; } 718 size_t size () const { return _M_index.size(); } 719 720 private: 721 const _Array<_Tp> _M_array; 722 const valarray<size_t>& _M_index; 723 }; 724 725 template<class _Dom> struct _GClos<_Expr,_Dom> : _GBase<_Dom> { 726 typedef _GBase<_Dom> _Base; 727 typedef typename _Base::value_type value_type; 728 729 _GClos (const _Dom& __e, const valarray<size_t>& __i) 730 : _Base (__e, __i) {} 731 }; 732 733 template<typename _Tp> 734 struct _GClos<_ValArray,_Tp> : _GBase<_Array<_Tp> > { 735 typedef _GBase<_Array<_Tp> > _Base; 736 typedef typename _Base::value_type value_type; 737 738 _GClos (_Array<_Tp> __a, const valarray<size_t>& __i) 739 : _Base (__a, __i) {} 740 }; 741 742 // 743 // indirect_array closure 744 // 745 746 template<class _Dom> class _IBase { 747 public: 748 typedef typename _Dom::value_type value_type; 749 750 _IBase (const _Dom& __e, const valarray<size_t>& __i) 751 : _M_expr (__e), _M_index (__i) {} 752 value_type operator[] (size_t __i) const 753 { return _M_expr[_M_index[__i]]; } 754 size_t size() const { return _M_index.size(); } 755 756 private: 757 const _Dom& _M_expr; 758 const valarray<size_t>& _M_index; 759 }; 760 761 template<class _Dom> struct _IClos<_Expr,_Dom> : _IBase<_Dom> { 762 typedef _IBase<_Dom> _Base; 763 typedef typename _Base::value_type value_type; 764 765 _IClos (const _Dom& __e, const valarray<size_t>& __i) 766 : _Base (__e, __i) {} 767 }; 768 769 template<typename _Tp> 770 struct _IClos<_ValArray,_Tp> : _IBase<valarray<_Tp> > { 771 typedef _IBase<valarray<_Tp> > _Base; 772 typedef _Tp value_type; 773 774 _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i) 775 : _Base (__a, __i) {} 776 }; 777 778 // 779 // class _Expr 780 // 781 template<class _Clos, typename _Tp> 782 class _Expr 783 { 784 public: 785 typedef _Tp value_type; 786 787 _Expr(const _Clos&); 788 789 const _Clos& operator()() const; 790 791 value_type operator[](size_t) const; 792 valarray<value_type> operator[](slice) const; 793 valarray<value_type> operator[](const gslice&) const; 794 valarray<value_type> operator[](const valarray<bool>&) const; 795 valarray<value_type> operator[](const valarray<size_t>&) const; 796 797 _Expr<_UnClos<__unary_plus,std::_Expr,_Clos>, value_type> 798 operator+() const; 799 800 _Expr<_UnClos<__negate,std::_Expr,_Clos>, value_type> 801 operator-() const; 802 803 _Expr<_UnClos<__bitwise_not,std::_Expr,_Clos>, value_type> 804 operator~() const; 805 806 _Expr<_UnClos<__logical_not,std::_Expr,_Clos>, bool> 807 operator!() const; 808 809 size_t size() const; 810 value_type sum() const; 811 812 valarray<value_type> shift(int) const; 813 valarray<value_type> cshift(int) const; 814 815 value_type min() const; 816 value_type max() const; 817 818 valarray<value_type> apply(value_type (*)(const value_type&)) const; 819 valarray<value_type> apply(value_type (*)(value_type)) const; 820 821 private: 822 const _Clos _M_closure; 823 }; 824 825 template<class _Clos, typename _Tp> 826 inline 827 _Expr<_Clos,_Tp>::_Expr(const _Clos& __c) : _M_closure(__c) {} 828 829 template<class _Clos, typename _Tp> 830 inline const _Clos& 831 _Expr<_Clos,_Tp>::operator()() const 832 { return _M_closure; } 833 834 template<class _Clos, typename _Tp> 835 inline _Tp 836 _Expr<_Clos,_Tp>::operator[](size_t __i) const 837 { return _M_closure[__i]; } 838 839 template<class _Clos, typename _Tp> 840 inline valarray<_Tp> 841 _Expr<_Clos,_Tp>::operator[](slice __s) const 842 { return _M_closure[__s]; } 843 844 template<class _Clos, typename _Tp> 845 inline valarray<_Tp> 846 _Expr<_Clos,_Tp>::operator[](const gslice& __gs) const 847 { return _M_closure[__gs]; } 848 849 template<class _Clos, typename _Tp> 850 inline valarray<_Tp> 851 _Expr<_Clos,_Tp>::operator[](const valarray<bool>& __m) const 852 { return _M_closure[__m]; } 853 854 template<class _Clos, typename _Tp> 855 inline valarray<_Tp> 856 _Expr<_Clos,_Tp>::operator[](const valarray<size_t>& __i) const 857 { return _M_closure[__i]; } 858 859 template<class _Clos, typename _Tp> 860 inline size_t 861 _Expr<_Clos,_Tp>::size() const { return _M_closure.size (); } 862 863 template<class _Clos, typename _Tp> 864 inline valarray<_Tp> 865 _Expr<_Clos, _Tp>::shift(int __n) const 866 { return valarray<_Tp>(_M_closure).shift(__n); } 867 868 template<class _Clos, typename _Tp> 869 inline valarray<_Tp> 870 _Expr<_Clos, _Tp>::cshift(int __n) const 871 { return valarray<_Tp>(_M_closure).cshift(__n); } 872 873 template<class _Clos, typename _Tp> 874 inline valarray<_Tp> 875 _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const 876 { return valarray<_Tp>(_M_closure).apply(__f); } 877 878 template<class _Clos, typename _Tp> 879 inline valarray<_Tp> 880 _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const 881 { return valarray<_Tp>(_M_closure).apply(__f); } 882 883 // XXX: replace this with a more robust summation algorithm. 884 template<class _Clos, typename _Tp> 885 inline _Tp 886 _Expr<_Clos,_Tp>::sum() const 887 { 888 size_t __n = _M_closure.size(); 889 if (__n == 0) 890 return _Tp(); 891 else 892 { 893 _Tp __s = _M_closure[--__n]; 894 while (__n != 0) 895 __s += _M_closure[--__n]; 896 return __s; 897 } 898 } 899 900 template<class _Clos, typename _Tp> 901 inline _Tp 902 _Expr<_Clos, _Tp>::min() const 903 { return __valarray_min(_M_closure); } 904 905 template<class _Clos, typename _Tp> 906 inline _Tp 907 _Expr<_Clos, _Tp>::max() const 908 { return __valarray_max(_M_closure); } 909 910 template<class _Dom, typename _Tp> 911 inline _Expr<_UnClos<__logical_not,_Expr,_Dom>, bool> 912 _Expr<_Dom,_Tp>::operator!() const 913 { 914 typedef _UnClos<__logical_not,std::_Expr,_Dom> _Closure; 915 return _Expr<_Closure,_Tp>(_Closure(this->_M_closure)); 916 } 917 918#define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \ 919 template<class _Dom, typename _Tp> \ 920 inline _Expr<_UnClos<_Name,std::_Expr,_Dom>,_Tp> \ 921 _Expr<_Dom,_Tp>::operator _Op() const \ 922 { \ 923 typedef _UnClos<_Name,std::_Expr,_Dom> _Closure; \ 924 return _Expr<_Closure,_Tp>(_Closure(this->_M_closure)); \ 925 } 926 927 _DEFINE_EXPR_UNARY_OPERATOR(+, __unary_plus) 928 _DEFINE_EXPR_UNARY_OPERATOR(-, __negate) 929 _DEFINE_EXPR_UNARY_OPERATOR(~, __bitwise_not) 930 931#undef _DEFINE_EXPR_UNARY_OPERATOR 932 933 934#define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \ 935 template<class _Dom1, class _Dom2> \ 936 inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, \ 937 typename __fun<_Name, typename _Dom1::value_type>::result_type>\ 938 operator _Op(const _Expr<_Dom1,typename _Dom1::value_type>& __v, \ 939 const _Expr<_Dom2,typename _Dom2::value_type>& __w) \ 940 { \ 941 typedef typename _Dom1::value_type _Arg; \ 942 typedef typename __fun<_Name, _Arg>::result_type _Value; \ 943 typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \ 944 return _Expr<_Closure,_Value>(_Closure(__v(), __w())); \ 945 } \ 946 \ 947template<class _Dom> \ 948inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>,\ 949 typename __fun<_Name, typename _Dom::value_type>::result_type>\ 950operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __v, \ 951 const typename _Dom::value_type& __t) \ 952{ \ 953 typedef typename _Dom::value_type _Arg; \ 954 typedef typename __fun<_Name, _Arg>::result_type _Value; \ 955 typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \ 956 return _Expr<_Closure,_Value>(_Closure(__v(), __t)); \ 957} \ 958 \ 959template<class _Dom> \ 960inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>,\ 961 typename __fun<_Name, typename _Dom::value_type>::result_type>\ 962operator _Op(const typename _Dom::value_type& __t, \ 963 const _Expr<_Dom,typename _Dom::value_type>& __v) \ 964{ \ 965 typedef typename _Dom::value_type _Arg; \ 966 typedef typename __fun<_Name, _Arg>::result_type _Value; \ 967 typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \ 968 return _Expr<_Closure,_Value>(_Closure(__t, __v())); \ 969} \ 970 \ 971template<class _Dom> \ 972inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>,\ 973 typename __fun<_Name, typename _Dom::value_type>::result_type>\ 974operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \ 975 const valarray<typename _Dom::value_type>& __v) \ 976{ \ 977 typedef typename _Dom::value_type _Arg; \ 978 typedef typename __fun<_Name, _Arg>::result_type _Value; \ 979 typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Arg> _Closure; \ 980 return _Expr<_Closure,_Value>(_Closure(__e(), __v)); \ 981} \ 982 \ 983template<class _Dom> \ 984inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>,\ 985 typename __fun<_Name, typename _Dom::value_type>::result_type>\ 986operator _Op(const valarray<typename _Dom::value_type>& __v, \ 987 const _Expr<_Dom,typename _Dom::value_type>& __e) \ 988{ \ 989 typedef typename _Dom::value_type _Tp; \ 990 typedef typename __fun<_Name, _Tp>::result_type _Value; \ 991 typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \ 992 return _Expr<_Closure,_Value> (_Closure (__v, __e ())); \ 993} 994 995 _DEFINE_EXPR_BINARY_OPERATOR(+, __plus) 996 _DEFINE_EXPR_BINARY_OPERATOR(-, __minus) 997 _DEFINE_EXPR_BINARY_OPERATOR(*, __multiplies) 998 _DEFINE_EXPR_BINARY_OPERATOR(/, __divides) 999 _DEFINE_EXPR_BINARY_OPERATOR(%, __modulus) 1000 _DEFINE_EXPR_BINARY_OPERATOR(^, __bitwise_xor) 1001 _DEFINE_EXPR_BINARY_OPERATOR(&, __bitwise_and) 1002 _DEFINE_EXPR_BINARY_OPERATOR(|, __bitwise_or) 1003 _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left) 1004 _DEFINE_EXPR_BINARY_OPERATOR(>>, __shift_right) 1005 _DEFINE_EXPR_BINARY_OPERATOR(&&, __logical_and) 1006 _DEFINE_EXPR_BINARY_OPERATOR(||, __logical_or) 1007 _DEFINE_EXPR_BINARY_OPERATOR(==, __equal_to) 1008 _DEFINE_EXPR_BINARY_OPERATOR(!=, __not_equal_to) 1009 _DEFINE_EXPR_BINARY_OPERATOR(<, __less) 1010 _DEFINE_EXPR_BINARY_OPERATOR(>, __greater) 1011 _DEFINE_EXPR_BINARY_OPERATOR(<=, __less_equal) 1012 _DEFINE_EXPR_BINARY_OPERATOR(>=, __greater_equal) 1013 1014#undef _DEFINE_EXPR_BINARY_OPERATOR 1015 1016#define _DEFINE_EXPR_UNARY_FUNCTION(_Name) \ 1017 template<class _Dom> \ 1018 inline _Expr<_UnClos<__##_Name,_Expr,_Dom>,typename _Dom::value_type>\ 1019 _Name(const _Expr<_Dom,typename _Dom::value_type>& __e) \ 1020 { \ 1021 typedef typename _Dom::value_type _Tp; \ 1022 typedef _UnClos<__##_Name,_Expr,_Dom> _Closure; \ 1023 return _Expr<_Closure,_Tp>(_Closure(__e())); \ 1024 } \ 1025 \ 1026 template<typename _Tp> \ 1027 inline _Expr<_UnClos<__##_Name,_ValArray,_Tp>,_Tp> \ 1028 _Name(const valarray<_Tp>& __v) \ 1029 { \ 1030 typedef _UnClos<__##_Name,_ValArray,_Tp> _Closure; \ 1031 return _Expr<_Closure,_Tp>(_Closure(__v)); \ 1032 } 1033 1034 _DEFINE_EXPR_UNARY_FUNCTION(abs) 1035 _DEFINE_EXPR_UNARY_FUNCTION(cos) 1036 _DEFINE_EXPR_UNARY_FUNCTION(acos) 1037 _DEFINE_EXPR_UNARY_FUNCTION(cosh) 1038 _DEFINE_EXPR_UNARY_FUNCTION(sin) 1039 _DEFINE_EXPR_UNARY_FUNCTION(asin) 1040 _DEFINE_EXPR_UNARY_FUNCTION(sinh) 1041 _DEFINE_EXPR_UNARY_FUNCTION(tan) 1042 _DEFINE_EXPR_UNARY_FUNCTION(tanh) 1043 _DEFINE_EXPR_UNARY_FUNCTION(atan) 1044 _DEFINE_EXPR_UNARY_FUNCTION(exp) 1045 _DEFINE_EXPR_UNARY_FUNCTION(log) 1046 _DEFINE_EXPR_UNARY_FUNCTION(log10) 1047 _DEFINE_EXPR_UNARY_FUNCTION(sqrt) 1048 1049#undef _DEFINE_EXPR_UNARY_FUNCTION 1050 1051#define _DEFINE_EXPR_BINARY_FUNCTION(_Fun) \ 1052 template<class _Dom1, class _Dom2> \ 1053 inline _Expr<_BinClos<__##_Fun,_Expr,_Expr,_Dom1,_Dom2>, \ 1054 typename _Dom1::value_type> \ 1055 _Fun(const _Expr<_Dom1,typename _Dom1::value_type>& __e1, \ 1056 const _Expr<_Dom2,typename _Dom2::value_type>& __e2) \ 1057 { \ 1058 typedef typename _Dom1::value_type _Tp; \ 1059 typedef _BinClos<__##_Fun,_Expr,_Expr,_Dom1,_Dom2> _Closure; \ 1060 return _Expr<_Closure,_Tp>(_Closure(__e1(), __e2())); \ 1061 } \ 1062 \ 1063 template<class _Dom> \ 1064 inline _Expr<_BinClos<__##_Fun, _Expr, _ValArray, _Dom, \ 1065 typename _Dom::value_type>, \ 1066 typename _Dom::value_type> \ 1067 _Fun(const _Expr<_Dom,typename _Dom::value_type>& __e, \ 1068 const valarray<typename _Dom::value_type>& __v) \ 1069 { \ 1070 typedef typename _Dom::value_type _Tp; \ 1071 typedef _BinClos<__##_Fun, _Expr, _ValArray, _Dom, _Tp> _Closure;\ 1072 return _Expr<_Closure,_Tp>(_Closure(__e(), __v)); \ 1073 } \ 1074 \ 1075 template<class _Dom> \ 1076 inline _Expr<_BinClos<__##_Fun, _ValArray, _Expr, \ 1077 typename _Dom::value_type,_Dom>, \ 1078 typename _Dom::value_type> \ 1079 _Fun(const valarray<typename _Dom::valarray>& __v, \ 1080 const _Expr<_Dom,typename _Dom::value_type>& __e) \ 1081 { \ 1082 typedef typename _Dom::value_type _Tp; \ 1083 typedef _BinClos<__##_Fun,_ValArray,_Expr,_Tp,_Dom> _Closure; \ 1084 return _Expr<_Closure,_Tp>(_Closure(__v, __e())); \ 1085 } \ 1086 \ 1087 template<class _Dom> \ 1088 inline _Expr<_BinClos<__##_Fun,_Expr,_Constant,_Dom, \ 1089 typename _Dom::value_type>, \ 1090 typename _Dom::value_type> \ 1091 _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \ 1092 const typename _Dom::value_type& __t) \ 1093 { \ 1094 typedef typename _Dom::value_type _Tp; \ 1095 typedef _BinClos<__##_Fun,_Expr,_Constant,_Dom,_Tp> _Closure; \ 1096 return _Expr<_Closure,_Tp>(_Closure(__e(), __t)); \ 1097 } \ 1098 \ 1099 template<class _Dom> \ 1100 inline _Expr<_BinClos<__##_Fun,_Constant,_Expr, \ 1101 typename _Dom::value_type,_Dom>, \ 1102 typename _Dom::value_type> \ 1103 _Fun(const typename _Dom::value_type& __t, \ 1104 const _Expr<_Dom,typename _Dom::value_type>& __e) \ 1105 { \ 1106 typedef typename _Dom::value_type _Tp; \ 1107 typedef _BinClos<__##_Fun, _Constant,_Expr,_Tp,_Dom> _Closure; \ 1108 return _Expr<_Closure,_Tp>(_Closure(__t, __e())); \ 1109 } \ 1110 \ 1111 template<typename _Tp> \ 1112 inline _Expr<_BinClos<__##_Fun,_ValArray,_ValArray,_Tp,_Tp>, _Tp> \ 1113 _Fun(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ 1114 { \ 1115 typedef _BinClos<__##_Fun,_ValArray,_ValArray,_Tp,_Tp> _Closure; \ 1116 return _Expr<_Closure,_Tp>(_Closure(__v, __w)); \ 1117 } \ 1118 \ 1119 template<typename _Tp> \ 1120 inline _Expr<_BinClos<__##_Fun,_ValArray,_Constant,_Tp,_Tp>,_Tp> \ 1121 _Fun(const valarray<_Tp>& __v, const _Tp& __t) \ 1122 { \ 1123 typedef _BinClos<__##_Fun,_ValArray,_Constant,_Tp,_Tp> _Closure; \ 1124 return _Expr<_Closure,_Tp>(_Closure(__v, __t)); \ 1125 } \ 1126 \ 1127 template<typename _Tp> \ 1128 inline _Expr<_BinClos<__##_Fun,_Constant,_ValArray,_Tp,_Tp>,_Tp> \ 1129 _Fun(const _Tp& __t, const valarray<_Tp>& __v) \ 1130 { \ 1131 typedef _BinClos<__##_Fun,_Constant,_ValArray,_Tp,_Tp> _Closure; \ 1132 return _Expr<_Closure,_Tp>(_Closure(__t, __v)); \ 1133 } 1134 1135_DEFINE_EXPR_BINARY_FUNCTION(atan2) 1136_DEFINE_EXPR_BINARY_FUNCTION(pow) 1137 1138#undef _DEFINE_EXPR_BINARY_FUNCTION 1139 1140} // std:: 1141 1142 1143#endif /* _CPP_VALARRAY_META_H */ 1144 1145// Local Variables: 1146// mode:c++ 1147// End: 1148