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