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 65extern "C" { 66 void* alloca(size_t); 67} 68 69 70extern "C++" { 71 72template<class _Clos, typename _Tp> class _Expr; 73 74template<typename _Tp1, typename _Tp2> class _ValArray; 75 76template<template<class> class _Oper, 77 template<class, class> class _Meta, class _Dom> struct _UnClos; 78 79template<template<class> class _Oper, 80 template<class, class> class _Meta1, 81 template<class, class> class _Meta2, 82 class _Dom1, class _Dom2> class _BinClos; 83 84template<template<class, class> class _Meta, class _Dom> class _SClos; 85 86template<template<class, class> class _Meta, class _Dom> class _GClos; 87 88template<template<class, class> class _Meta, class _Dom> class _IClos; 89 90template<template<class, class> class _Meta, class _Dom> class _ValFunClos; 91 92template<template<class, class> class _Meta, class _Dom> class _RefFunClos; 93 94template<class _Tp> struct _Unary_plus; 95template<class _Tp> struct _Bitwise_and; 96template<class _Tp> struct _Bitwise_or; 97template<class _Tp> struct _Bitwise_xor; 98template<class _Tp> struct _Bitwise_not; 99template<class _Tp> struct _Shift_left; 100template<class _Tp> struct _Shift_right; 101 102template<class _Tp> class valarray; // An array of type _Tp 103class slice; // BLAS-like slice out of an array 104template<class _Tp> class slice_array; 105class gslice; // generalized slice out of an array 106template<class _Tp> class gslice_array; 107template<class _Tp> class mask_array; // masked array 108template<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 115extern "C++" { 116 117template<class _Tp> class valarray 118{ 119public: 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 226private: 227 size_t _M_size; 228 _Tp* __restrict__ _M_data; 229 230 friend class _Array<_Tp>; 231}; 232 233 234template<typename _Tp> struct _Unary_plus : unary_function<_Tp,_Tp> { 235 _Tp operator() (const _Tp& __t) const { return __t; } 236}; 237 238template<typename _Tp> struct _Bitwise_and : binary_function<_Tp,_Tp,_Tp> { 239 _Tp operator() (_Tp __x, _Tp __y) const { return __x & __y; } 240}; 241 242template<typename _Tp> struct _Bitwise_or : binary_function<_Tp,_Tp,_Tp> { 243 _Tp operator() (_Tp __x, _Tp __y) const { return __x | __y; } 244}; 245 246template<typename _Tp> struct _Bitwise_xor : binary_function<_Tp,_Tp,_Tp> { 247 _Tp operator() (_Tp __x, _Tp __y) const { return __x ^ __y; } 248}; 249 250template<typename _Tp> struct _Bitwise_not : unary_function<_Tp,_Tp> { 251 _Tp operator() (_Tp __t) const { return ~__t; } 252}; 253 254template<typename _Tp> struct _Shift_left : unary_function<_Tp,_Tp> { 255 _Tp operator() (_Tp __x, _Tp __y) const { return __x << __y; } 256}; 257 258template<typename _Tp> struct _Shift_right : unary_function<_Tp,_Tp> { 259 _Tp operator() (_Tp __x, _Tp __y) const { return __x >> __y; } 260}; 261 262 263template<typename _Tp> 264inline _Tp 265valarray<_Tp>::operator[] (size_t __i) const 266{ return _M_data[__i]; } 267 268template<typename _Tp> 269inline _Tp& 270valarray<_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 282extern "C++" { 283 284template<typename _Tp> 285inline valarray<_Tp>::valarray () : _M_size (0), _M_data (0) {} 286 287template<typename _Tp> 288inline valarray<_Tp>::valarray (size_t __n) 289 : _M_size (__n), _M_data (new _Tp[__n]) {} 290 291template<typename _Tp> 292inline 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 296template<typename _Tp> 297inline 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 301template<typename _Tp> 302inline 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 306template<typename _Tp> 307inline 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 312template<typename _Tp> 313inline 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 318template<typename _Tp> 319inline 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 324template<typename _Tp> 325inline 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 330template<typename _Tp> template<class _Dom> 331inline 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 335template<typename _Tp> 336inline valarray<_Tp>::~valarray () { delete[] _M_data; } 337 338template<typename _Tp> 339inline valarray<_Tp>& 340valarray<_Tp>::operator= (const valarray<_Tp>& __v) 341{ 342 __valarray_copy(__v._M_data, _M_size, _M_data); 343 return *this; 344} 345 346template<typename _Tp> 347inline valarray<_Tp>& 348valarray<_Tp>::operator= (const _Tp& __t) 349{ 350 __valarray_fill (_M_data, _M_size, __t); 351 return *this; 352} 353 354template<typename _Tp> 355inline valarray<_Tp>& 356valarray<_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 363template<typename _Tp> 364inline valarray<_Tp>& 365valarray<_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 372template<typename _Tp> 373inline valarray<_Tp>& 374valarray<_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 381template<typename _Tp> 382inline valarray<_Tp>& 383valarray<_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 390template<typename _Tp> template<class _Dom> 391inline valarray<_Tp>& 392valarray<_Tp>::operator= (const _Expr<_Dom, _Tp>& __e) 393{ 394 __valarray_copy (__e, _M_size, _Array<_Tp>(_M_data)); 395 return *this; 396} 397 398template<typename _Tp> 399inline _Expr<_SClos<_ValArray,_Tp>, _Tp> 400valarray<_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 406template<typename _Tp> 407inline slice_array<_Tp> 408valarray<_Tp>::operator[] (slice __s) 409{ 410 return slice_array<_Tp> (_Array<_Tp>(_M_data), __s); 411} 412 413template<typename _Tp> 414inline _Expr<_GClos<_ValArray,_Tp>, _Tp> 415valarray<_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 422template<typename _Tp> 423inline gslice_array<_Tp> 424valarray<_Tp>::operator[] (const gslice& __gs) 425{ 426 return gslice_array<_Tp> 427 (_Array<_Tp>(_M_data), __gs._M_index->_M_index); 428} 429 430template<typename _Tp> 431inline valarray<_Tp> 432valarray<_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 442template<typename _Tp> 443inline mask_array<_Tp> 444valarray<_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 453template<typename _Tp> 454inline _Expr<_IClos<_ValArray,_Tp>, _Tp> 455valarray<_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 461template<typename _Tp> 462inline indirect_array<_Tp> 463valarray<_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 469template<class _Tp> 470inline size_t valarray<_Tp>::size () const { return _M_size; } 471 472template<class _Tp> 473inline _Tp 474valarray<_Tp>::sum () const 475{ 476 return accumulate (_M_data, _M_data + _M_size, _Tp ()); 477} 478 479template<typename _Tp> 480inline _Tp 481valarray<_Tp>::product () const 482{ 483 return accumulate (_M_data, _M_data+_M_size, _Tp(1), multiplies<_Tp> ()); 484} 485 486template <class _Tp> 487inline valarray<_Tp> 488valarray<_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 508template <class _Tp> 509inline valarray<_Tp> 510valarray<_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 526template <class _Tp> 527inline void 528valarray<_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 538template<typename _Tp> 539inline _Tp 540valarray<_Tp>::min() const 541{ 542 return *min_element (_M_data, _M_data+_M_size); 543} 544 545template<typename _Tp> 546inline _Tp 547valarray<_Tp>::max() const 548{ 549 return *max_element (_M_data, _M_data+_M_size); 550} 551 552template<class _Tp> 553inline _Expr<_ValFunClos<_ValArray,_Tp>,_Tp> 554valarray<_Tp>::apply (_Tp func (_Tp)) const 555{ 556 typedef _ValFunClos<_ValArray,_Tp> _Closure; 557 return _Expr<_Closure,_Tp> (_Closure (*this, func)); 558} 559 560template<class _Tp> 561inline _Expr<_RefFunClos<_ValArray,_Tp>,_Tp> 562valarray<_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