1 // The template and inlines for the -*- C++ -*- valarray class. 2 3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 // Written by Gabriel Dos Reis <[email protected]> 32 33 /** @file valarray 34 * This is a Standard C++ Library header. You should @c #include this header 35 * in your programs, rather than any of the "st[dl]_*.h" implementation files. 36 */ 37 38 #ifndef _CPP_VALARRAY 39 #define _CPP_VALARRAY 1 40 41 #pragma GCC system_header 42 43 #include <bits/c++config.h> 44 #include <cstddef> 45 #include <cmath> 46 #include <cstdlib> 47 #include <numeric> 48 #include <functional> 49 #include <algorithm> 50 51 namespace std 52 { 53 template<class _Clos, typename _Tp> class _Expr; 54 55 template<typename _Tp1, typename _Tp2> class _ValArray; 56 57 template<template<class> class _Oper, 58 template<class, class> class _Meta, class _Dom> struct _UnClos; 59 60 template<template<class> class _Oper, 61 template<class, class> class _Meta1, 62 template<class, class> class _Meta2, 63 class _Dom1, class _Dom2> class _BinClos; 64 65 template<template<class, class> class _Meta, class _Dom> class _SClos; 66 67 template<template<class, class> class _Meta, class _Dom> class _GClos; 68 69 template<template<class, class> class _Meta, class _Dom> class _IClos; 70 71 template<template<class, class> class _Meta, class _Dom> class _ValFunClos; 72 73 template<template<class, class> class _Meta, class _Dom> class _RefFunClos; 74 75 template<class _Tp> struct _Unary_plus; 76 template<class _Tp> struct _Bitwise_and; 77 template<class _Tp> struct _Bitwise_or; 78 template<class _Tp> struct _Bitwise_xor; 79 template<class _Tp> struct _Bitwise_not; 80 template<class _Tp> struct _Shift_left; 81 template<class _Tp> struct _Shift_right; 82 83 template<class _Tp> class valarray; // An array of type _Tp 84 class slice; // BLAS-like slice out of an array 85 template<class _Tp> class slice_array; 86 class gslice; // generalized slice out of an array 87 template<class _Tp> class gslice_array; 88 template<class _Tp> class mask_array; // masked array 89 template<class _Tp> class indirect_array; // indirected array 90 91 } // namespace std 92 93 #include <bits/valarray_array.h> 94 #include <bits/valarray_meta.h> 95 96 namespace std 97 { 98 template<class _Tp> class valarray 99 { 100 public: 101 typedef _Tp value_type; 102 103 // _lib.valarray.cons_ construct/destroy: 104 valarray(); 105 explicit valarray(size_t); 106 valarray(const _Tp&, size_t); 107 valarray(const _Tp* __restrict__, size_t); 108 valarray(const valarray&); 109 valarray(const slice_array<_Tp>&); 110 valarray(const gslice_array<_Tp>&); 111 valarray(const mask_array<_Tp>&); 112 valarray(const indirect_array<_Tp>&); 113 template<class _Dom> 114 valarray(const _Expr<_Dom,_Tp>& __e); 115 ~valarray(); 116 117 // _lib.valarray.assign_ assignment: 118 valarray<_Tp>& operator=(const valarray<_Tp>&); 119 valarray<_Tp>& operator=(const _Tp&); 120 valarray<_Tp>& operator=(const slice_array<_Tp>&); 121 valarray<_Tp>& operator=(const gslice_array<_Tp>&); 122 valarray<_Tp>& operator=(const mask_array<_Tp>&); 123 valarray<_Tp>& operator=(const indirect_array<_Tp>&); 124 125 template<class _Dom> valarray<_Tp>& 126 operator= (const _Expr<_Dom,_Tp>&); 127 128 // _lib.valarray.access_ element access: 129 // XXX: LWG to be resolved. 130 const _Tp& operator[](size_t) const; 131 _Tp& operator[](size_t); 132 // _lib.valarray.sub_ subset operations: 133 _Expr<_SClos<_ValArray,_Tp>, _Tp> operator[](slice) const; 134 slice_array<_Tp> operator[](slice); 135 _Expr<_GClos<_ValArray,_Tp>, _Tp> operator[](const gslice&) const; 136 gslice_array<_Tp> operator[](const gslice&); 137 valarray<_Tp> operator[](const valarray<bool>&) const; 138 mask_array<_Tp> operator[](const valarray<bool>&); 139 _Expr<_IClos<_ValArray, _Tp>, _Tp> 140 operator[](const valarray<size_t>&) const; 141 indirect_array<_Tp> operator[](const valarray<size_t>&); 142 143 // _lib.valarray.unary_ unary operators: 144 _Expr<_UnClos<_Unary_plus,_ValArray,_Tp>,_Tp> operator+ () const; 145 _Expr<_UnClos<negate,_ValArray,_Tp>,_Tp> operator- () const; 146 _Expr<_UnClos<_Bitwise_not,_ValArray,_Tp>,_Tp> operator~ () const; 147 _Expr<_UnClos<logical_not,_ValArray,_Tp>,bool> operator! () const; 148 149 // _lib.valarray.cassign_ computed assignment: 150 valarray<_Tp>& operator*= (const _Tp&); 151 valarray<_Tp>& operator/= (const _Tp&); 152 valarray<_Tp>& operator%= (const _Tp&); 153 valarray<_Tp>& operator+= (const _Tp&); 154 valarray<_Tp>& operator-= (const _Tp&); 155 valarray<_Tp>& operator^= (const _Tp&); 156 valarray<_Tp>& operator&= (const _Tp&); 157 valarray<_Tp>& operator|= (const _Tp&); 158 valarray<_Tp>& operator<<=(const _Tp&); 159 valarray<_Tp>& operator>>=(const _Tp&); 160 valarray<_Tp>& operator*= (const valarray<_Tp>&); 161 valarray<_Tp>& operator/= (const valarray<_Tp>&); 162 valarray<_Tp>& operator%= (const valarray<_Tp>&); 163 valarray<_Tp>& operator+= (const valarray<_Tp>&); 164 valarray<_Tp>& operator-= (const valarray<_Tp>&); 165 valarray<_Tp>& operator^= (const valarray<_Tp>&); 166 valarray<_Tp>& operator|= (const valarray<_Tp>&); 167 valarray<_Tp>& operator&= (const valarray<_Tp>&); 168 valarray<_Tp>& operator<<=(const valarray<_Tp>&); 169 valarray<_Tp>& operator>>=(const valarray<_Tp>&); 170 171 template<class _Dom> 172 valarray<_Tp>& operator*= (const _Expr<_Dom,_Tp>&); 173 template<class _Dom> 174 valarray<_Tp>& operator/= (const _Expr<_Dom,_Tp>&); 175 template<class _Dom> 176 valarray<_Tp>& operator%= (const _Expr<_Dom,_Tp>&); 177 template<class _Dom> 178 valarray<_Tp>& operator+= (const _Expr<_Dom,_Tp>&); 179 template<class _Dom> 180 valarray<_Tp>& operator-= (const _Expr<_Dom,_Tp>&); 181 template<class _Dom> 182 valarray<_Tp>& operator^= (const _Expr<_Dom,_Tp>&); 183 template<class _Dom> 184 valarray<_Tp>& operator|= (const _Expr<_Dom,_Tp>&); 185 template<class _Dom> 186 valarray<_Tp>& operator&= (const _Expr<_Dom,_Tp>&); 187 template<class _Dom> 188 valarray<_Tp>& operator<<=(const _Expr<_Dom,_Tp>&); 189 template<class _Dom> 190 valarray<_Tp>& operator>>=(const _Expr<_Dom,_Tp>&); 191 192 193 // _lib.valarray.members_ member functions: 194 size_t size() const; 195 _Tp sum() const; 196 _Tp min() const; 197 _Tp max() const; 198 199 // // FIXME: Extension 200 // _Tp product () const; 201 202 valarray<_Tp> shift (int) const; 203 valarray<_Tp> cshift(int) const; 204 _Expr<_ValFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(_Tp)) const; 205 _Expr<_RefFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(const _Tp&)) const; 206 void resize(size_t __size, _Tp __c = _Tp()); 207 208 private: 209 size_t _M_size; 210 _Tp* __restrict__ _M_data; 211 212 friend class _Array<_Tp>; 213 }; 214 215 216 template<typename _Tp> struct _Unary_plus : unary_function<_Tp,_Tp> { 217 _Tp operator() (const _Tp& __t) const { return __t; } 218 }; 219 220 template<typename _Tp> struct _Bitwise_and : binary_function<_Tp,_Tp,_Tp> { 221 _Tp operator() (_Tp __x, _Tp __y) const { return __x & __y; } 222 }; 223 224 template<typename _Tp> struct _Bitwise_or : binary_function<_Tp,_Tp,_Tp> { 225 _Tp operator() (_Tp __x, _Tp __y) const { return __x | __y; } 226 }; 227 228 template<typename _Tp> struct _Bitwise_xor : binary_function<_Tp,_Tp,_Tp> { 229 _Tp operator() (_Tp __x, _Tp __y) const { return __x ^ __y; } 230 }; 231 232 template<typename _Tp> struct _Bitwise_not : unary_function<_Tp,_Tp> { 233 _Tp operator() (_Tp __t) const { return ~__t; } 234 }; 235 236 template<typename _Tp> struct _Shift_left : unary_function<_Tp,_Tp> { 237 _Tp operator() (_Tp __x, _Tp __y) const { return __x << __y; } 238 }; 239 240 template<typename _Tp> struct _Shift_right : unary_function<_Tp,_Tp> { 241 _Tp operator() (_Tp __x, _Tp __y) const { return __x >> __y; } 242 }; 243 244 245 template<typename _Tp> 246 inline const _Tp& 247 valarray<_Tp>::operator[] (size_t __i) const 248 { return _M_data[__i]; } 249 250 template<typename _Tp> 251 inline _Tp& 252 valarray<_Tp>::operator[] (size_t __i) 253 { return _M_data[__i]; } 254 255 } // std:: 256 257 #include <bits/slice.h> 258 #include <bits/slice_array.h> 259 #include <bits/gslice.h> 260 #include <bits/gslice_array.h> 261 #include <bits/mask_array.h> 262 #include <bits/indirect_array.h> 263 264 namespace std 265 { 266 template<typename _Tp> 267 inline valarray<_Tp>::valarray () : _M_size (0), _M_data (0) {} 268 269 template<typename _Tp> 270 inline valarray<_Tp>::valarray (size_t __n) 271 : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) 272 { __valarray_default_construct(_M_data, _M_data + __n); } 273 274 template<typename _Tp> 275 inline valarray<_Tp>::valarray (const _Tp& __t, size_t __n) 276 : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) 277 { __valarray_fill_construct (_M_data, _M_data + __n, __t); } 278 279 template<typename _Tp> 280 inline valarray<_Tp>::valarray (const _Tp* __restrict__ __p, size_t __n) 281 : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) 282 { __valarray_copy_construct (__p, __p + __n, _M_data); } 283 284 template<typename _Tp> 285 inline valarray<_Tp>::valarray (const valarray<_Tp>& __v) 286 : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size)) 287 { __valarray_copy_construct (__v._M_data, __v._M_data + _M_size, _M_data); } 288 289 template<typename _Tp> 290 inline valarray<_Tp>::valarray (const slice_array<_Tp>& __sa) 291 : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz)) 292 { 293 __valarray_copy 294 (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data)); 295 } 296 297 template<typename _Tp> 298 inline valarray<_Tp>::valarray (const gslice_array<_Tp>& __ga) 299 : _M_size(__ga._M_index.size()), 300 _M_data(__valarray_get_storage<_Tp>(_M_size)) 301 { 302 __valarray_copy 303 (__ga._M_array, _Array<size_t>(__ga._M_index), 304 _Array<_Tp>(_M_data), _M_size); 305 } 306 307 template<typename _Tp> 308 inline valarray<_Tp>::valarray (const mask_array<_Tp>& __ma) 309 : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz)) 310 { 311 __valarray_copy 312 (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size); 313 } 314 315 template<typename _Tp> 316 inline valarray<_Tp>::valarray (const indirect_array<_Tp>& __ia) 317 : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz)) 318 { 319 __valarray_copy 320 (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size); 321 } 322 323 template<typename _Tp> template<class _Dom> 324 inline valarray<_Tp>::valarray (const _Expr<_Dom, _Tp>& __e) 325 : _M_size(__e.size ()), _M_data(__valarray_get_storage<_Tp>(_M_size)) 326 { __valarray_copy (__e, _M_size, _Array<_Tp>(_M_data)); } 327 328 template<typename _Tp> 329 inline valarray<_Tp>::~valarray () 330 { 331 __valarray_destroy_elements(_M_data, _M_data + _M_size); 332 __valarray_release_memory(_M_data); 333 } 334 335 template<typename _Tp> 336 inline valarray<_Tp>& 337 valarray<_Tp>::operator= (const valarray<_Tp>& __v) 338 { 339 __valarray_copy(__v._M_data, _M_size, _M_data); 340 return *this; 341 } 342 343 template<typename _Tp> 344 inline valarray<_Tp>& 345 valarray<_Tp>::operator= (const _Tp& __t) 346 { 347 __valarray_fill (_M_data, _M_size, __t); 348 return *this; 349 } 350 351 template<typename _Tp> 352 inline valarray<_Tp>& 353 valarray<_Tp>::operator= (const slice_array<_Tp>& __sa) 354 { 355 __valarray_copy (__sa._M_array, __sa._M_sz, 356 __sa._M_stride, _Array<_Tp>(_M_data)); 357 return *this; 358 } 359 360 template<typename _Tp> 361 inline valarray<_Tp>& 362 valarray<_Tp>::operator= (const gslice_array<_Tp>& __ga) 363 { 364 __valarray_copy (__ga._M_array, _Array<size_t>(__ga._M_index), 365 _Array<_Tp>(_M_data), _M_size); 366 return *this; 367 } 368 369 template<typename _Tp> 370 inline valarray<_Tp>& 371 valarray<_Tp>::operator= (const mask_array<_Tp>& __ma) 372 { 373 __valarray_copy (__ma._M_array, __ma._M_mask, 374 _Array<_Tp>(_M_data), _M_size); 375 return *this; 376 } 377 378 template<typename _Tp> 379 inline valarray<_Tp>& 380 valarray<_Tp>::operator= (const indirect_array<_Tp>& __ia) 381 { 382 __valarray_copy (__ia._M_array, __ia._M_index, 383 _Array<_Tp>(_M_data), _M_size); 384 return *this; 385 } 386 387 template<typename _Tp> template<class _Dom> 388 inline valarray<_Tp>& 389 valarray<_Tp>::operator= (const _Expr<_Dom, _Tp>& __e) 390 { 391 __valarray_copy (__e, _M_size, _Array<_Tp>(_M_data)); 392 return *this; 393 } 394 395 template<typename _Tp> 396 inline _Expr<_SClos<_ValArray,_Tp>, _Tp> 397 valarray<_Tp>::operator[] (slice __s) const 398 { 399 typedef _SClos<_ValArray,_Tp> _Closure; 400 return _Expr<_Closure, _Tp> (_Closure (_Array<_Tp>(_M_data), __s)); 401 } 402 403 template<typename _Tp> 404 inline slice_array<_Tp> 405 valarray<_Tp>::operator[] (slice __s) 406 { 407 return slice_array<_Tp> (_Array<_Tp>(_M_data), __s); 408 } 409 410 template<typename _Tp> 411 inline _Expr<_GClos<_ValArray,_Tp>, _Tp> 412 valarray<_Tp>::operator[] (const gslice& __gs) const 413 { 414 typedef _GClos<_ValArray,_Tp> _Closure; 415 return _Expr<_Closure, _Tp> 416 (_Closure (_Array<_Tp>(_M_data), __gs._M_index->_M_index)); 417 } 418 419 template<typename _Tp> 420 inline gslice_array<_Tp> 421 valarray<_Tp>::operator[] (const gslice& __gs) 422 { 423 return gslice_array<_Tp> 424 (_Array<_Tp>(_M_data), __gs._M_index->_M_index); 425 } 426 427 template<typename _Tp> 428 inline valarray<_Tp> 429 valarray<_Tp>::operator[] (const valarray<bool>& __m) const 430 { 431 size_t __s (0); 432 size_t __e (__m.size ()); 433 for (size_t __i=0; __i<__e; ++__i) 434 if (__m[__i]) ++__s; 435 return valarray<_Tp> (mask_array<_Tp> (_Array<_Tp>(_M_data), __s, 436 _Array<bool> (__m))); 437 } 438 439 template<typename _Tp> 440 inline mask_array<_Tp> 441 valarray<_Tp>::operator[] (const valarray<bool>& __m) 442 { 443 size_t __s (0); 444 size_t __e (__m.size ()); 445 for (size_t __i=0; __i<__e; ++__i) 446 if (__m[__i]) ++__s; 447 return mask_array<_Tp> (_Array<_Tp>(_M_data), __s, _Array<bool> (__m)); 448 } 449 450 template<typename _Tp> 451 inline _Expr<_IClos<_ValArray,_Tp>, _Tp> 452 valarray<_Tp>::operator[] (const valarray<size_t>& __i) const 453 { 454 typedef _IClos<_ValArray,_Tp> _Closure; 455 return _Expr<_Closure, _Tp> (_Closure (*this, __i)); 456 } 457 458 template<typename _Tp> 459 inline indirect_array<_Tp> 460 valarray<_Tp>::operator[] (const valarray<size_t>& __i) 461 { 462 return indirect_array<_Tp> (_Array<_Tp>(_M_data), __i.size(), 463 _Array<size_t> (__i)); 464 } 465 466 template<class _Tp> 467 inline size_t valarray<_Tp>::size () const { return _M_size; } 468 469 template<class _Tp> 470 inline _Tp 471 valarray<_Tp>::sum () const 472 { 473 return __valarray_sum(_M_data, _M_data + _M_size); 474 } 475 476 // template<typename _Tp> 477 // inline _Tp 478 // valarray<_Tp>::product () const 479 // { 480 // return __valarray_product(_M_data, _M_data + _M_size); 481 // } 482 483 template <class _Tp> 484 inline valarray<_Tp> 485 valarray<_Tp>::shift(int __n) const 486 { 487 _Tp* const __a = static_cast<_Tp*> 488 (__builtin_alloca(sizeof(_Tp) * _M_size)); 489 if (__n == 0) // no shift 490 __valarray_copy_construct(_M_data, _M_data + _M_size, __a); 491 else if (__n > 0) // __n > 0: shift left 492 { 493 if (size_t(__n) > _M_size) 494 __valarray_default_construct(__a, __a + __n); 495 else 496 { 497 __valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a); 498 __valarray_default_construct(__a+_M_size-__n, __a + _M_size); 499 } 500 } 501 else // __n < 0: shift right 502 { 503 __valarray_copy_construct (_M_data, _M_data+_M_size+__n, __a-__n); 504 __valarray_default_construct(__a, __a - __n); 505 } 506 return valarray<_Tp> (__a, _M_size); 507 } 508 509 template <class _Tp> 510 inline valarray<_Tp> 511 valarray<_Tp>::cshift (int __n) const 512 { 513 _Tp* const __a = static_cast<_Tp*> 514 (__builtin_alloca (sizeof(_Tp) * _M_size)); 515 if (__n == 0) // no cshift 516 __valarray_copy_construct(_M_data, _M_data + _M_size, __a); 517 else if (__n > 0) // cshift left 518 { 519 __valarray_copy_construct(_M_data, _M_data+__n, __a+_M_size-__n); 520 __valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a); 521 } 522 else // cshift right 523 { 524 __valarray_copy_construct 525 (_M_data + _M_size+__n, _M_data + _M_size, __a); 526 __valarray_copy_construct 527 (_M_data, _M_data + _M_size+__n, __a - __n); 528 } 529 return valarray<_Tp>(__a, _M_size); 530 } 531 532 template <class _Tp> 533 inline void 534 valarray<_Tp>::resize (size_t __n, _Tp __c) 535 { 536 // This complication is so to make valarray<valarray<T> > work 537 // even though it is not required by the standard. Nobody should 538 // be saying valarray<valarray<T> > anyway. See the specs. 539 __valarray_destroy_elements(_M_data, _M_data + _M_size); 540 if (_M_size != __n) 541 { 542 __valarray_release_memory(_M_data); 543 _M_size = __n; 544 _M_data = __valarray_get_storage<_Tp>(__n); 545 } 546 __valarray_fill_construct(_M_data, _M_data + __n, __c); 547 } 548 549 template<typename _Tp> 550 inline _Tp 551 valarray<_Tp>::min() const 552 { 553 return *min_element (_M_data, _M_data+_M_size); 554 } 555 556 template<typename _Tp> 557 inline _Tp 558 valarray<_Tp>::max() const 559 { 560 return *max_element (_M_data, _M_data+_M_size); 561 } 562 563 template<class _Tp> 564 inline _Expr<_ValFunClos<_ValArray,_Tp>,_Tp> 565 valarray<_Tp>::apply (_Tp func (_Tp)) const 566 { 567 typedef _ValFunClos<_ValArray,_Tp> _Closure; 568 return _Expr<_Closure,_Tp> (_Closure (*this, func)); 569 } 570 571 template<class _Tp> 572 inline _Expr<_RefFunClos<_ValArray,_Tp>,_Tp> 573 valarray<_Tp>::apply (_Tp func (const _Tp &)) const 574 { 575 typedef _RefFunClos<_ValArray,_Tp> _Closure; 576 return _Expr<_Closure,_Tp> (_Closure (*this, func)); 577 } 578 579 #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name) \ 580 template<typename _Tp> \ 581 inline _Expr<_UnClos<_Name,_ValArray,_Tp>, _Tp> \ 582 valarray<_Tp>::operator _Op() const \ 583 { \ 584 typedef _UnClos<_Name,_ValArray,_Tp> _Closure; \ 585 return _Expr<_Closure, _Tp> (_Closure (*this)); \ 586 } 587 588 _DEFINE_VALARRAY_UNARY_OPERATOR(+, _Unary_plus) 589 _DEFINE_VALARRAY_UNARY_OPERATOR(-, negate) 590 _DEFINE_VALARRAY_UNARY_OPERATOR(~, _Bitwise_not) 591 592 #undef _DEFINE_VALARRAY_UNARY_OPERATOR 593 594 template<typename _Tp> 595 inline _Expr<_UnClos<logical_not,_ValArray,_Tp>, bool> 596 valarray<_Tp>::operator!() const 597 { 598 typedef _UnClos<logical_not,_ValArray,_Tp> _Closure; 599 return _Expr<_Closure, bool> (_Closure (*this)); 600 } 601 602 #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name) \ 603 template<class _Tp> \ 604 inline valarray<_Tp> & \ 605 valarray<_Tp>::operator _Op##= (const _Tp &__t) \ 606 { \ 607 _Array_augmented_##_Name (_Array<_Tp>(_M_data), _M_size, __t); \ 608 return *this; \ 609 } \ 610 \ 611 template<class _Tp> \ 612 inline valarray<_Tp> & \ 613 valarray<_Tp>::operator _Op##= (const valarray<_Tp> &__v) \ 614 { \ 615 _Array_augmented_##_Name (_Array<_Tp>(_M_data), _M_size, \ 616 _Array<_Tp>(__v._M_data)); \ 617 return *this; \ 618 } 619 620 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, plus) 621 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, minus) 622 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, multiplies) 623 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, divides) 624 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, modulus) 625 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, xor) 626 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, and) 627 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, or) 628 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, shift_left) 629 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, shift_right) 630 631 #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT 632 633 634 } // std:: 635 636 637 namespace std 638 { 639 640 #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name) \ 641 template<class _Tp> template<class _Dom> \ 642 inline valarray<_Tp> & \ 643 valarray<_Tp>::operator _Op##= (const _Expr<_Dom,_Tp> &__e) \ 644 { \ 645 _Array_augmented_##_Name (_Array<_Tp>(_M_data), __e, _M_size); \ 646 return *this; \ 647 } 648 649 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, plus) 650 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, minus) 651 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, multiplies) 652 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, divides) 653 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, modulus) 654 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, xor) 655 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, and) 656 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, or) 657 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, shift_left) 658 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, shift_right) 659 660 #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT 661 662 663 #define _DEFINE_BINARY_OPERATOR(_Op, _Name) \ 664 template<typename _Tp> \ 665 inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>, _Tp> \ 666 operator _Op (const valarray<_Tp> &__v, const valarray<_Tp> &__w) \ 667 { \ 668 typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure; \ 669 return _Expr<_Closure, _Tp> (_Closure (__v, __w)); \ 670 } \ 671 \ 672 template<typename _Tp> \ 673 inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>,_Tp> \ 674 operator _Op (const valarray<_Tp> &__v, const _Tp &__t) \ 675 { \ 676 typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure; \ 677 return _Expr<_Closure, _Tp> (_Closure (__v, __t)); \ 678 } \ 679 \ 680 template<typename _Tp> \ 681 inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>,_Tp> \ 682 operator _Op (const _Tp &__t, const valarray<_Tp> &__v) \ 683 { \ 684 typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure; \ 685 return _Expr<_Closure, _Tp> (_Closure (__t, __v)); \ 686 } 687 688 _DEFINE_BINARY_OPERATOR(+, plus) 689 _DEFINE_BINARY_OPERATOR(-, minus) 690 _DEFINE_BINARY_OPERATOR(*, multiplies) 691 _DEFINE_BINARY_OPERATOR(/, divides) 692 _DEFINE_BINARY_OPERATOR(%, modulus) 693 _DEFINE_BINARY_OPERATOR(^, _Bitwise_xor) 694 _DEFINE_BINARY_OPERATOR(&, _Bitwise_and) 695 _DEFINE_BINARY_OPERATOR(|, _Bitwise_or) 696 _DEFINE_BINARY_OPERATOR(<<, _Shift_left) 697 _DEFINE_BINARY_OPERATOR(>>, _Shift_right) 698 699 #undef _DEFINE_BINARY_OPERATOR 700 701 #define _DEFINE_LOGICAL_OPERATOR(_Op, _Name) \ 702 template<typename _Tp> \ 703 inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>,bool> \ 704 operator _Op (const valarray<_Tp> &__v, const valarray<_Tp> &__w) \ 705 { \ 706 typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure; \ 707 return _Expr<_Closure, bool> (_Closure (__v, __w)); \ 708 } \ 709 \ 710 template<class _Tp> \ 711 inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>,bool> \ 712 operator _Op (const valarray<_Tp> &__v, const _Tp &__t) \ 713 { \ 714 typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure; \ 715 return _Expr<_Closure, bool> (_Closure (__v, __t)); \ 716 } \ 717 \ 718 template<class _Tp> \ 719 inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>,bool> \ 720 operator _Op (const _Tp &__t, const valarray<_Tp> &__v) \ 721 { \ 722 typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure; \ 723 return _Expr<_Closure, bool> (_Closure (__t, __v)); \ 724 } 725 726 _DEFINE_LOGICAL_OPERATOR(&&, logical_and) 727 _DEFINE_LOGICAL_OPERATOR(||, logical_or) 728 _DEFINE_LOGICAL_OPERATOR(==, equal_to) 729 _DEFINE_LOGICAL_OPERATOR(!=, not_equal_to) 730 _DEFINE_LOGICAL_OPERATOR(<, less) 731 _DEFINE_LOGICAL_OPERATOR(>, greater) 732 _DEFINE_LOGICAL_OPERATOR(<=, less_equal) 733 _DEFINE_LOGICAL_OPERATOR(>=, greater_equal) 734 735 #undef _DEFINE_LOGICAL_OPERATOR 736 737 } // namespace std 738 739 #endif // _CPP_VALARRAY 740 741 // Local Variables: 742 // mode:c++ 743 // End: 744