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