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 // 2009 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 valarray_after.h 27 * This is an internal header file, included by other library headers. 28 * You should not attempt to use it directly. 29 */ 30 31 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis (at) cmla.ens-cachan.fr> 32 33 #ifndef _VALARRAY_AFTER_H 34 #define _VALARRAY_AFTER_H 1 35 36 #pragma GCC system_header 37 38 _GLIBCXX_BEGIN_NAMESPACE(std) 39 40 // 41 // gslice_array closure. 42 // 43 template<class _Dom> 44 class _GBase 45 { 46 public: 47 typedef typename _Dom::value_type value_type; 48 49 _GBase (const _Dom& __e, const valarray<size_t>& __i) 50 : _M_expr (__e), _M_index(__i) {} 51 52 value_type 53 operator[] (size_t __i) const 54 { return _M_expr[_M_index[__i]]; } 55 56 size_t 57 size () const 58 { return _M_index.size(); } 59 60 private: 61 const _Dom& _M_expr; 62 const valarray<size_t>& _M_index; 63 }; 64 65 template<typename _Tp> 66 class _GBase<_Array<_Tp> > 67 { 68 public: 69 typedef _Tp value_type; 70 71 _GBase (_Array<_Tp> __a, const valarray<size_t>& __i) 72 : _M_array (__a), _M_index(__i) {} 73 74 value_type 75 operator[] (size_t __i) const 76 { return _M_array._M_data[_M_index[__i]]; } 77 78 size_t 79 size () const 80 { return _M_index.size(); } 81 82 private: 83 const _Array<_Tp> _M_array; 84 const valarray<size_t>& _M_index; 85 }; 86 87 template<class _Dom> 88 struct _GClos<_Expr, _Dom> 89 : _GBase<_Dom> 90 { 91 typedef _GBase<_Dom> _Base; 92 typedef typename _Base::value_type value_type; 93 94 _GClos (const _Dom& __e, const valarray<size_t>& __i) 95 : _Base (__e, __i) {} 96 }; 97 98 template<typename _Tp> 99 struct _GClos<_ValArray, _Tp> 100 : _GBase<_Array<_Tp> > 101 { 102 typedef _GBase<_Array<_Tp> > _Base; 103 typedef typename _Base::value_type value_type; 104 105 _GClos (_Array<_Tp> __a, const valarray<size_t>& __i) 106 : _Base (__a, __i) {} 107 }; 108 109 // 110 // indirect_array closure 111 // 112 template<class _Dom> 113 class _IBase 114 { 115 public: 116 typedef typename _Dom::value_type value_type; 117 118 _IBase (const _Dom& __e, const valarray<size_t>& __i) 119 : _M_expr (__e), _M_index (__i) {} 120 121 value_type 122 operator[] (size_t __i) const 123 { return _M_expr[_M_index[__i]]; } 124 125 size_t 126 size() const 127 { return _M_index.size(); } 128 129 private: 130 const _Dom& _M_expr; 131 const valarray<size_t>& _M_index; 132 }; 133 134 template<class _Dom> 135 struct _IClos<_Expr, _Dom> 136 : _IBase<_Dom> 137 { 138 typedef _IBase<_Dom> _Base; 139 typedef typename _Base::value_type value_type; 140 141 _IClos (const _Dom& __e, const valarray<size_t>& __i) 142 : _Base (__e, __i) {} 143 }; 144 145 template<typename _Tp> 146 struct _IClos<_ValArray, _Tp> 147 : _IBase<valarray<_Tp> > 148 { 149 typedef _IBase<valarray<_Tp> > _Base; 150 typedef _Tp value_type; 151 152 _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i) 153 : _Base (__a, __i) {} 154 }; 155 156 // 157 // class _Expr 158 // 159 template<class _Clos, typename _Tp> 160 class _Expr 161 { 162 public: 163 typedef _Tp value_type; 164 165 _Expr(const _Clos&); 166 167 const _Clos& operator()() const; 168 169 value_type operator[](size_t) const; 170 valarray<value_type> operator[](slice) const; 171 valarray<value_type> operator[](const gslice&) const; 172 valarray<value_type> operator[](const valarray<bool>&) const; 173 valarray<value_type> operator[](const valarray<size_t>&) const; 174 175 _Expr<_UnClos<__unary_plus, std::_Expr, _Clos>, value_type> 176 operator+() const; 177 178 _Expr<_UnClos<__negate, std::_Expr, _Clos>, value_type> 179 operator-() const; 180 181 _Expr<_UnClos<__bitwise_not, std::_Expr, _Clos>, value_type> 182 operator~() const; 183 184 _Expr<_UnClos<__logical_not, std::_Expr, _Clos>, bool> 185 operator!() const; 186 187 size_t size() const; 188 value_type sum() const; 189 190 valarray<value_type> shift(int) const; 191 valarray<value_type> cshift(int) const; 192 193 value_type min() const; 194 value_type max() const; 195 196 valarray<value_type> apply(value_type (*)(const value_type&)) const; 197 valarray<value_type> apply(value_type (*)(value_type)) const; 198 199 private: 200 const _Clos _M_closure; 201 }; 202 203 template<class _Clos, typename _Tp> 204 inline 205 _Expr<_Clos, _Tp>::_Expr(const _Clos& __c) : _M_closure(__c) {} 206 207 template<class _Clos, typename _Tp> 208 inline const _Clos& 209 _Expr<_Clos, _Tp>::operator()() const 210 { return _M_closure; } 211 212 template<class _Clos, typename _Tp> 213 inline _Tp 214 _Expr<_Clos, _Tp>::operator[](size_t __i) const 215 { return _M_closure[__i]; } 216 217 template<class _Clos, typename _Tp> 218 inline valarray<_Tp> 219 _Expr<_Clos, _Tp>::operator[](slice __s) const 220 { 221 valarray<_Tp> __v = valarray<_Tp>(*this)[__s]; 222 return __v; 223 } 224 225 template<class _Clos, typename _Tp> 226 inline valarray<_Tp> 227 _Expr<_Clos, _Tp>::operator[](const gslice& __gs) const 228 { 229 valarray<_Tp> __v = valarray<_Tp>(*this)[__gs]; 230 return __v; 231 } 232 233 template<class _Clos, typename _Tp> 234 inline valarray<_Tp> 235 _Expr<_Clos, _Tp>::operator[](const valarray<bool>& __m) const 236 { 237 valarray<_Tp> __v = valarray<_Tp>(*this)[__m]; 238 return __v; 239 } 240 241 template<class _Clos, typename _Tp> 242 inline valarray<_Tp> 243 _Expr<_Clos, _Tp>::operator[](const valarray<size_t>& __i) const 244 { 245 valarray<_Tp> __v = valarray<_Tp>(*this)[__i]; 246 return __v; 247 } 248 249 template<class _Clos, typename _Tp> 250 inline size_t 251 _Expr<_Clos, _Tp>::size() const 252 { return _M_closure.size(); } 253 254 template<class _Clos, typename _Tp> 255 inline valarray<_Tp> 256 _Expr<_Clos, _Tp>::shift(int __n) const 257 { 258 valarray<_Tp> __v = valarray<_Tp>(*this).shift(__n); 259 return __v; 260 } 261 262 template<class _Clos, typename _Tp> 263 inline valarray<_Tp> 264 _Expr<_Clos, _Tp>::cshift(int __n) const 265 { 266 valarray<_Tp> __v = valarray<_Tp>(*this).cshift(__n); 267 return __v; 268 } 269 270 template<class _Clos, typename _Tp> 271 inline valarray<_Tp> 272 _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const 273 { 274 valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f); 275 return __v; 276 } 277 278 template<class _Clos, typename _Tp> 279 inline valarray<_Tp> 280 _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const 281 { 282 valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f); 283 return __v; 284 } 285 286 // XXX: replace this with a more robust summation algorithm. 287 template<class _Clos, typename _Tp> 288 inline _Tp 289 _Expr<_Clos, _Tp>::sum() const 290 { 291 size_t __n = _M_closure.size(); 292 if (__n == 0) 293 return _Tp(); 294 else 295 { 296 _Tp __s = _M_closure[--__n]; 297 while (__n != 0) 298 __s += _M_closure[--__n]; 299 return __s; 300 } 301 } 302 303 template<class _Clos, typename _Tp> 304 inline _Tp 305 _Expr<_Clos, _Tp>::min() const 306 { return __valarray_min(_M_closure); } 307 308 template<class _Clos, typename _Tp> 309 inline _Tp 310 _Expr<_Clos, _Tp>::max() const 311 { return __valarray_max(_M_closure); } 312 313 template<class _Dom, typename _Tp> 314 inline _Expr<_UnClos<__logical_not, _Expr, _Dom>, bool> 315 _Expr<_Dom, _Tp>::operator!() const 316 { 317 typedef _UnClos<__logical_not, std::_Expr, _Dom> _Closure; 318 return _Expr<_Closure, bool>(_Closure(this->_M_closure)); 319 } 320 321 #define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \ 322 template<class _Dom, typename _Tp> \ 323 inline _Expr<_UnClos<_Name, std::_Expr, _Dom>, _Tp> \ 324 _Expr<_Dom, _Tp>::operator _Op() const \ 325 { \ 326 typedef _UnClos<_Name, std::_Expr, _Dom> _Closure; \ 327 return _Expr<_Closure, _Tp>(_Closure(this->_M_closure)); \ 328 } 329 330 _DEFINE_EXPR_UNARY_OPERATOR(+, __unary_plus) 331 _DEFINE_EXPR_UNARY_OPERATOR(-, __negate) 332 _DEFINE_EXPR_UNARY_OPERATOR(~, __bitwise_not) 333 334 #undef _DEFINE_EXPR_UNARY_OPERATOR 335 336 #define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \ 337 template<class _Dom1, class _Dom2> \ 338 inline _Expr<_BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2>, \ 339 typename __fun<_Name, typename _Dom1::value_type>::result_type> \ 340 operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \ 341 const _Expr<_Dom2, typename _Dom2::value_type>& __w) \ 342 { \ 343 typedef typename _Dom1::value_type _Arg; \ 344 typedef typename __fun<_Name, _Arg>::result_type _Value; \ 345 typedef _BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2> _Closure; \ 346 return _Expr<_Closure, _Value>(_Closure(__v(), __w())); \ 347 } \ 348 \ 349 template<class _Dom> \ 350 inline _Expr<_BinClos<_Name, _Expr, _Constant, _Dom, \ 351 typename _Dom::value_type>, \ 352 typename __fun<_Name, typename _Dom::value_type>::result_type> \ 353 operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \ 354 const typename _Dom::value_type& __t) \ 355 { \ 356 typedef typename _Dom::value_type _Arg; \ 357 typedef typename __fun<_Name, _Arg>::result_type _Value; \ 358 typedef _BinClos<_Name, _Expr, _Constant, _Dom, _Arg> _Closure; \ 359 return _Expr<_Closure, _Value>(_Closure(__v(), __t)); \ 360 } \ 361 \ 362 template<class _Dom> \ 363 inline _Expr<_BinClos<_Name, _Constant, _Expr, \ 364 typename _Dom::value_type, _Dom>, \ 365 typename __fun<_Name, typename _Dom::value_type>::result_type> \ 366 operator _Op(const typename _Dom::value_type& __t, \ 367 const _Expr<_Dom, typename _Dom::value_type>& __v) \ 368 { \ 369 typedef typename _Dom::value_type _Arg; \ 370 typedef typename __fun<_Name, _Arg>::result_type _Value; \ 371 typedef _BinClos<_Name, _Constant, _Expr, _Arg, _Dom> _Closure; \ 372 return _Expr<_Closure, _Value>(_Closure(__t, __v())); \ 373 } \ 374 \ 375 template<class _Dom> \ 376 inline _Expr<_BinClos<_Name, _Expr, _ValArray, \ 377 _Dom, typename _Dom::value_type>, \ 378 typename __fun<_Name, typename _Dom::value_type>::result_type> \ 379 operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \ 380 const valarray<typename _Dom::value_type>& __v) \ 381 { \ 382 typedef typename _Dom::value_type _Arg; \ 383 typedef typename __fun<_Name, _Arg>::result_type _Value; \ 384 typedef _BinClos<_Name, _Expr, _ValArray, _Dom, _Arg> _Closure; \ 385 return _Expr<_Closure, _Value>(_Closure(__e(), __v)); \ 386 } \ 387 \ 388 template<class _Dom> \ 389 inline _Expr<_BinClos<_Name, _ValArray, _Expr, \ 390 typename _Dom::value_type, _Dom>, \ 391 typename __fun<_Name, typename _Dom::value_type>::result_type> \ 392 operator _Op(const valarray<typename _Dom::value_type>& __v, \ 393 const _Expr<_Dom, typename _Dom::value_type>& __e) \ 394 { \ 395 typedef typename _Dom::value_type _Tp; \ 396 typedef typename __fun<_Name, _Tp>::result_type _Value; \ 397 typedef _BinClos<_Name, _ValArray, _Expr, _Tp, _Dom> _Closure; \ 398 return _Expr<_Closure, _Value>(_Closure(__v, __e ())); \ 399 } 400 401 _DEFINE_EXPR_BINARY_OPERATOR(+, __plus) 402 _DEFINE_EXPR_BINARY_OPERATOR(-, __minus) 403 _DEFINE_EXPR_BINARY_OPERATOR(*, __multiplies) 404 _DEFINE_EXPR_BINARY_OPERATOR(/, __divides) 405 _DEFINE_EXPR_BINARY_OPERATOR(%, __modulus) 406 _DEFINE_EXPR_BINARY_OPERATOR(^, __bitwise_xor) 407 _DEFINE_EXPR_BINARY_OPERATOR(&, __bitwise_and) 408 _DEFINE_EXPR_BINARY_OPERATOR(|, __bitwise_or) 409 _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left) 410 _DEFINE_EXPR_BINARY_OPERATOR(>>, __shift_right) 411 _DEFINE_EXPR_BINARY_OPERATOR(&&, __logical_and) 412 _DEFINE_EXPR_BINARY_OPERATOR(||, __logical_or) 413 _DEFINE_EXPR_BINARY_OPERATOR(==, __equal_to) 414 _DEFINE_EXPR_BINARY_OPERATOR(!=, __not_equal_to) 415 _DEFINE_EXPR_BINARY_OPERATOR(<, __less) 416 _DEFINE_EXPR_BINARY_OPERATOR(>, __greater) 417 _DEFINE_EXPR_BINARY_OPERATOR(<=, __less_equal) 418 _DEFINE_EXPR_BINARY_OPERATOR(>=, __greater_equal) 419 420 #undef _DEFINE_EXPR_BINARY_OPERATOR 421 422 #define _DEFINE_EXPR_UNARY_FUNCTION(_Name) \ 423 template<class _Dom> \ 424 inline _Expr<_UnClos<__##_Name, _Expr, _Dom>, \ 425 typename _Dom::value_type> \ 426 _Name(const _Expr<_Dom, typename _Dom::value_type>& __e) \ 427 { \ 428 typedef typename _Dom::value_type _Tp; \ 429 typedef _UnClos<__##_Name, _Expr, _Dom> _Closure; \ 430 return _Expr<_Closure, _Tp>(_Closure(__e())); \ 431 } \ 432 \ 433 template<typename _Tp> \ 434 inline _Expr<_UnClos<__##_Name, _ValArray, _Tp>, _Tp> \ 435 _Name(const valarray<_Tp>& __v) \ 436 { \ 437 typedef _UnClos<__##_Name, _ValArray, _Tp> _Closure; \ 438 return _Expr<_Closure, _Tp>(_Closure(__v)); \ 439 } 440 441 _DEFINE_EXPR_UNARY_FUNCTION(abs) 442 _DEFINE_EXPR_UNARY_FUNCTION(cos) 443 _DEFINE_EXPR_UNARY_FUNCTION(acos) 444 _DEFINE_EXPR_UNARY_FUNCTION(cosh) 445 _DEFINE_EXPR_UNARY_FUNCTION(sin) 446 _DEFINE_EXPR_UNARY_FUNCTION(asin) 447 _DEFINE_EXPR_UNARY_FUNCTION(sinh) 448 _DEFINE_EXPR_UNARY_FUNCTION(tan) 449 _DEFINE_EXPR_UNARY_FUNCTION(tanh) 450 _DEFINE_EXPR_UNARY_FUNCTION(atan) 451 _DEFINE_EXPR_UNARY_FUNCTION(exp) 452 _DEFINE_EXPR_UNARY_FUNCTION(log) 453 _DEFINE_EXPR_UNARY_FUNCTION(log10) 454 _DEFINE_EXPR_UNARY_FUNCTION(sqrt) 455 456 #undef _DEFINE_EXPR_UNARY_FUNCTION 457 458 #define _DEFINE_EXPR_BINARY_FUNCTION(_Fun) \ 459 template<class _Dom1, class _Dom2> \ 460 inline _Expr<_BinClos<__##_Fun, _Expr, _Expr, _Dom1, _Dom2>, \ 461 typename _Dom1::value_type> \ 462 _Fun(const _Expr<_Dom1, typename _Dom1::value_type>& __e1, \ 463 const _Expr<_Dom2, typename _Dom2::value_type>& __e2) \ 464 { \ 465 typedef typename _Dom1::value_type _Tp; \ 466 typedef _BinClos<__##_Fun, _Expr, _Expr, _Dom1, _Dom2> _Closure; \ 467 return _Expr<_Closure, _Tp>(_Closure(__e1(), __e2())); \ 468 } \ 469 \ 470 template<class _Dom> \ 471 inline _Expr<_BinClos<__##_Fun, _Expr, _ValArray, _Dom, \ 472 typename _Dom::value_type>, \ 473 typename _Dom::value_type> \ 474 _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \ 475 const valarray<typename _Dom::value_type>& __v) \ 476 { \ 477 typedef typename _Dom::value_type _Tp; \ 478 typedef _BinClos<__##_Fun, _Expr, _ValArray, _Dom, _Tp> _Closure; \ 479 return _Expr<_Closure, _Tp>(_Closure(__e(), __v)); \ 480 } \ 481 \ 482 template<class _Dom> \ 483 inline _Expr<_BinClos<__##_Fun, _ValArray, _Expr, \ 484 typename _Dom::value_type, _Dom>, \ 485 typename _Dom::value_type> \ 486 _Fun(const valarray<typename _Dom::valarray>& __v, \ 487 const _Expr<_Dom, typename _Dom::value_type>& __e) \ 488 { \ 489 typedef typename _Dom::value_type _Tp; \ 490 typedef _BinClos<__##_Fun, _ValArray, _Expr, _Tp, _Dom> _Closure; \ 491 return _Expr<_Closure, _Tp>(_Closure(__v, __e())); \ 492 } \ 493 \ 494 template<class _Dom> \ 495 inline _Expr<_BinClos<__##_Fun, _Expr, _Constant, _Dom, \ 496 typename _Dom::value_type>, \ 497 typename _Dom::value_type> \ 498 _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \ 499 const typename _Dom::value_type& __t) \ 500 { \ 501 typedef typename _Dom::value_type _Tp; \ 502 typedef _BinClos<__##_Fun, _Expr, _Constant, _Dom, _Tp> _Closure;\ 503 return _Expr<_Closure, _Tp>(_Closure(__e(), __t)); \ 504 } \ 505 \ 506 template<class _Dom> \ 507 inline _Expr<_BinClos<__##_Fun, _Constant, _Expr, \ 508 typename _Dom::value_type, _Dom>, \ 509 typename _Dom::value_type> \ 510 _Fun(const typename _Dom::value_type& __t, \ 511 const _Expr<_Dom, typename _Dom::value_type>& __e) \ 512 { \ 513 typedef typename _Dom::value_type _Tp; \ 514 typedef _BinClos<__##_Fun, _Constant, _Expr, _Tp, _Dom> _Closure; \ 515 return _Expr<_Closure, _Tp>(_Closure(__t, __e())); \ 516 } \ 517 \ 518 template<typename _Tp> \ 519 inline _Expr<_BinClos<__##_Fun, _ValArray, _ValArray, _Tp, _Tp>, _Tp> \ 520 _Fun(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ 521 { \ 522 typedef _BinClos<__##_Fun, _ValArray, _ValArray, _Tp, _Tp> _Closure; \ 523 return _Expr<_Closure, _Tp>(_Closure(__v, __w)); \ 524 } \ 525 \ 526 template<typename _Tp> \ 527 inline _Expr<_BinClos<__##_Fun, _ValArray, _Constant, _Tp, _Tp>, _Tp> \ 528 _Fun(const valarray<_Tp>& __v, const _Tp& __t) \ 529 { \ 530 typedef _BinClos<__##_Fun, _ValArray, _Constant, _Tp, _Tp> _Closure; \ 531 return _Expr<_Closure, _Tp>(_Closure(__v, __t)); \ 532 } \ 533 \ 534 template<typename _Tp> \ 535 inline _Expr<_BinClos<__##_Fun, _Constant, _ValArray, _Tp, _Tp>, _Tp> \ 536 _Fun(const _Tp& __t, const valarray<_Tp>& __v) \ 537 { \ 538 typedef _BinClos<__##_Fun, _Constant, _ValArray, _Tp, _Tp> _Closure; \ 539 return _Expr<_Closure, _Tp>(_Closure(__t, __v)); \ 540 } 541 542 _DEFINE_EXPR_BINARY_FUNCTION(atan2) 543 _DEFINE_EXPR_BINARY_FUNCTION(pow) 544 545 #undef _DEFINE_EXPR_BINARY_FUNCTION 546 547 _GLIBCXX_END_NAMESPACE 548 549 #endif /* _CPP_VALARRAY_AFTER_H */ 550