xref: /openbsd-src/gnu/lib/libstdc++/libstdc++/include/std/std_valarray.h (revision 03a78d155d6fff5698289342b62759a75b20d130)
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 <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
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 <algorithm>
49 
50 namespace std
51 {
52   template<class _Clos, typename _Tp>
53     class _Expr;
54 
55   template<typename _Tp1, typename _Tp2>
56     class _ValArray;
57 
58   template<class _Oper, template<class, class> class _Meta, class _Dom>
59     struct _UnClos;
60 
61   template<class _Oper,
62         template<class, class> class _Meta1,
63         template<class, class> class _Meta2,
64         class _Dom1, class _Dom2>
65     class _BinClos;
66 
67   template<template<class, class> class _Meta, class _Dom>
68     class _SClos;
69 
70   template<template<class, class> class _Meta, class _Dom>
71     class _GClos;
72 
73   template<template<class, class> class _Meta, class _Dom>
74     class _IClos;
75 
76   template<template<class, class> class _Meta, class _Dom>
77     class _ValFunClos;
78 
79   template<template<class, class> class _Meta, class _Dom>
80     class _RefFunClos;
81 
82   template<class _Tp> class valarray;   // An array of type _Tp
83   class slice;                          // BLAS-like slice out of an array
84   template<class _Tp> class slice_array;
85   class gslice;                         // generalized slice out of an array
86   template<class _Tp> class gslice_array;
87   template<class _Tp> class mask_array;     // masked array
88   template<class _Tp> class indirect_array; // indirected array
89 
90 } // namespace std
91 
92 #include <bits/valarray_array.h>
93 #include <bits/valarray_meta.h>
94 
95 namespace std
96 {
97   template<class _Tp>
98     class valarray
99     {
100       template<class _Op>
101 	struct _UnaryOp
102 	{
103 	  typedef typename __fun<_Op, _Tp>::result_type __rt;
104 	  typedef _Expr<_UnClos<_Op, _ValArray, _Tp>, __rt> _Rt;
105 	};
106     public:
107       typedef _Tp value_type;
108 
109 	// _lib.valarray.cons_ construct/destroy:
110       valarray();
111       explicit valarray(size_t);
112       valarray(const _Tp&, size_t);
113       valarray(const _Tp* __restrict__, size_t);
114       valarray(const valarray&);
115       valarray(const slice_array<_Tp>&);
116       valarray(const gslice_array<_Tp>&);
117       valarray(const mask_array<_Tp>&);
118       valarray(const indirect_array<_Tp>&);
119       template<class _Dom>
120 	valarray(const _Expr<_Dom,_Tp>& __e);
121       ~valarray();
122 
123       // _lib.valarray.assign_ assignment:
124       valarray<_Tp>& operator=(const valarray<_Tp>&);
125       valarray<_Tp>& operator=(const _Tp&);
126       valarray<_Tp>& operator=(const slice_array<_Tp>&);
127       valarray<_Tp>& operator=(const gslice_array<_Tp>&);
128       valarray<_Tp>& operator=(const mask_array<_Tp>&);
129       valarray<_Tp>& operator=(const indirect_array<_Tp>&);
130 
131       template<class _Dom> valarray<_Tp>&
132 	operator= (const _Expr<_Dom,_Tp>&);
133 
134       // _lib.valarray.access_ element access:
135       // XXX: LWG to be resolved.
136       const _Tp&                 operator[](size_t) const;
137       _Tp&                operator[](size_t);
138       // _lib.valarray.sub_ subset operations:
139       _Expr<_SClos<_ValArray,_Tp>, _Tp> operator[](slice) const;
140       slice_array<_Tp>    operator[](slice);
141       _Expr<_GClos<_ValArray,_Tp>, _Tp> operator[](const gslice&) const;
142       gslice_array<_Tp>   operator[](const gslice&);
143       valarray<_Tp>     	 operator[](const valarray<bool>&) const;
144       mask_array<_Tp>     operator[](const valarray<bool>&);
145       _Expr<_IClos<_ValArray, _Tp>, _Tp>
146         operator[](const valarray<size_t>&) const;
147       indirect_array<_Tp> operator[](const valarray<size_t>&);
148 
149       // _lib.valarray.unary_ unary operators:
150       typename _UnaryOp<__unary_plus>::_Rt  operator+() const;
151       typename _UnaryOp<__negate>::_Rt      operator-() const;
152       typename _UnaryOp<__bitwise_not>::_Rt operator~() const;
153       typename _UnaryOp<__logical_not>::_Rt operator!() const;
154 
155       // _lib.valarray.cassign_ computed assignment:
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 _Tp&);
161       valarray<_Tp>& operator^=(const _Tp&);
162       valarray<_Tp>& operator&=(const _Tp&);
163       valarray<_Tp>& operator|=(const _Tp&);
164       valarray<_Tp>& operator<<=(const _Tp&);
165       valarray<_Tp>& operator>>=(const _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       valarray<_Tp>& operator-=(const valarray<_Tp>&);
171       valarray<_Tp>& operator^=(const valarray<_Tp>&);
172       valarray<_Tp>& operator|=(const valarray<_Tp>&);
173       valarray<_Tp>& operator&=(const valarray<_Tp>&);
174       valarray<_Tp>& operator<<=(const valarray<_Tp>&);
175       valarray<_Tp>& operator>>=(const valarray<_Tp>&);
176 
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       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 
198 
199       // _lib.valarray.members_ member functions:
200       size_t size() const;
201       _Tp    sum() const;
202       _Tp    min() const;
203       _Tp    max() const;
204 
205   //           // FIXME: Extension
206   //       _Tp    product () const;
207 
208       valarray<_Tp> shift (int) const;
209       valarray<_Tp> cshift(int) const;
210       _Expr<_ValFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(_Tp)) const;
211       _Expr<_RefFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(const _Tp&)) const;
212       void resize(size_t __size, _Tp __c = _Tp());
213 
214     private:
215       size_t _M_size;
216       _Tp* __restrict__ _M_data;
217 
218       friend class _Array<_Tp>;
219     };
220 
221   template<typename _Tp>
222     inline const _Tp&
223     valarray<_Tp>::operator[](size_t __i) const
224     { return _M_data[__i]; }
225 
226   template<typename _Tp>
227     inline _Tp&
228     valarray<_Tp>::operator[](size_t __i)
229     { return _M_data[__i]; }
230 
231 } // std::
232 
233 #include <bits/slice_array.h>
234 #include <bits/gslice.h>
235 #include <bits/gslice_array.h>
236 #include <bits/mask_array.h>
237 #include <bits/indirect_array.h>
238 
239 namespace std
240 {
241   template<typename _Tp>
242     inline
valarray()243     valarray<_Tp>::valarray() : _M_size(0), _M_data(0) {}
244 
245   template<typename _Tp>
246     inline
valarray(size_t __n)247     valarray<_Tp>::valarray(size_t __n)
248 	: _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
249     { __valarray_default_construct(_M_data, _M_data + __n); }
250 
251   template<typename _Tp>
252     inline
valarray(const _Tp & __t,size_t __n)253     valarray<_Tp>::valarray(const _Tp& __t, size_t __n)
254       : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
255     { __valarray_fill_construct(_M_data, _M_data + __n, __t); }
256 
257   template<typename _Tp>
258     inline
valarray(const _Tp * __restrict__ __p,size_t __n)259     valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n)
260       : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
261     { __valarray_copy_construct(__p, __p + __n, _M_data); }
262 
263   template<typename _Tp>
264     inline
valarray(const valarray<_Tp> & __v)265     valarray<_Tp>::valarray(const valarray<_Tp>& __v)
266       : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size))
267     { __valarray_copy_construct(__v._M_data, __v._M_data + _M_size, _M_data); }
268 
269   template<typename _Tp>
270     inline
valarray(const slice_array<_Tp> & __sa)271     valarray<_Tp>::valarray(const slice_array<_Tp>& __sa)
272       : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz))
273     {
274       __valarray_copy
275 	(__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data));
276     }
277 
278   template<typename _Tp>
279     inline
valarray(const gslice_array<_Tp> & __ga)280     valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga)
281       : _M_size(__ga._M_index.size()),
282 	_M_data(__valarray_get_storage<_Tp>(_M_size))
283     {
284       __valarray_copy
285 	(__ga._M_array, _Array<size_t>(__ga._M_index),
286 	 _Array<_Tp>(_M_data), _M_size);
287     }
288 
289   template<typename _Tp>
290     inline
valarray(const mask_array<_Tp> & __ma)291     valarray<_Tp>::valarray(const mask_array<_Tp>& __ma)
292       : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz))
293     {
294       __valarray_copy
295 	(__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size);
296     }
297 
298   template<typename _Tp>
299     inline
valarray(const indirect_array<_Tp> & __ia)300     valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia)
301       : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz))
302     {
303       __valarray_copy
304 	(__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size);
305     }
306 
307   template<typename _Tp> template<class _Dom>
308     inline
valarray(const _Expr<_Dom,_Tp> & __e)309     valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e)
310       : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size))
311     { __valarray_copy(__e, _M_size, _Array<_Tp>(_M_data)); }
312 
313   template<typename _Tp>
314     inline
~valarray()315     valarray<_Tp>::~valarray()
316     {
317       __valarray_destroy_elements(_M_data, _M_data + _M_size);
318       __valarray_release_memory(_M_data);
319     }
320 
321   template<typename _Tp>
322     inline valarray<_Tp>&
323     valarray<_Tp>::operator=(const valarray<_Tp>& __v)
324     {
325       __valarray_copy(__v._M_data, _M_size, _M_data);
326       return *this;
327     }
328 
329   template<typename _Tp>
330     inline valarray<_Tp>&
331     valarray<_Tp>::operator=(const _Tp& __t)
332     {
333       __valarray_fill(_M_data, _M_size, __t);
334       return *this;
335     }
336 
337   template<typename _Tp>
338     inline valarray<_Tp>&
339     valarray<_Tp>::operator=(const slice_array<_Tp>& __sa)
340     {
341       __valarray_copy(__sa._M_array, __sa._M_sz,
342 		      __sa._M_stride, _Array<_Tp>(_M_data));
343       return *this;
344     }
345 
346   template<typename _Tp>
347     inline valarray<_Tp>&
348     valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga)
349     {
350       __valarray_copy(__ga._M_array, _Array<size_t>(__ga._M_index),
351 		      _Array<_Tp>(_M_data), _M_size);
352       return *this;
353     }
354 
355   template<typename _Tp>
356     inline valarray<_Tp>&
357     valarray<_Tp>::operator=(const mask_array<_Tp>& __ma)
358     {
359       __valarray_copy(__ma._M_array, __ma._M_mask,
360 		      _Array<_Tp>(_M_data), _M_size);
361       return *this;
362     }
363 
364   template<typename _Tp>
365     inline valarray<_Tp>&
366     valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia)
367     {
368       __valarray_copy(__ia._M_array, __ia._M_index,
369 		       _Array<_Tp>(_M_data), _M_size);
370       return *this;
371     }
372 
373   template<typename _Tp> template<class _Dom>
374     inline valarray<_Tp>&
375     valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e)
376     {
377       __valarray_copy(__e, _M_size, _Array<_Tp>(_M_data));
378 	return *this;
379     }
380 
381   template<typename _Tp>
382     inline _Expr<_SClos<_ValArray,_Tp>, _Tp>
383     valarray<_Tp>::operator[](slice __s) const
384     {
385       typedef _SClos<_ValArray,_Tp> _Closure;
386       return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s));
387     }
388 
389   template<typename _Tp>
390     inline slice_array<_Tp>
391     valarray<_Tp>::operator[](slice __s)
392     {
393       return slice_array<_Tp>(_Array<_Tp>(_M_data), __s);
394     }
395 
396   template<typename _Tp>
397     inline _Expr<_GClos<_ValArray,_Tp>, _Tp>
398     valarray<_Tp>::operator[](const gslice& __gs) const
399     {
400       typedef _GClos<_ValArray,_Tp> _Closure;
401       return _Expr<_Closure, _Tp>
402 	(_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index));
403     }
404 
405   template<typename _Tp>
406     inline gslice_array<_Tp>
407     valarray<_Tp>::operator[](const gslice& __gs)
408     {
409       return gslice_array<_Tp>
410 	(_Array<_Tp>(_M_data), __gs._M_index->_M_index);
411     }
412 
413   template<typename _Tp>
414     inline valarray<_Tp>
415     valarray<_Tp>::operator[](const valarray<bool>& __m) const
416     {
417       size_t __s = 0;
418       size_t __e = __m.size();
419       for (size_t __i=0; __i<__e; ++__i)
420 	if (__m[__i]) ++__s;
421       return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s,
422 					   _Array<bool> (__m)));
423     }
424 
425   template<typename _Tp>
426     inline mask_array<_Tp>
427     valarray<_Tp>::operator[](const valarray<bool>& __m)
428     {
429       size_t __s = 0;
430       size_t __e = __m.size();
431       for (size_t __i=0; __i<__e; ++__i)
432 	if (__m[__i]) ++__s;
433       return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array<bool>(__m));
434     }
435 
436   template<typename _Tp>
437     inline _Expr<_IClos<_ValArray,_Tp>, _Tp>
438     valarray<_Tp>::operator[](const valarray<size_t>& __i) const
439     {
440       typedef _IClos<_ValArray,_Tp> _Closure;
441       return _Expr<_Closure, _Tp>(_Closure(*this, __i));
442     }
443 
444   template<typename _Tp>
445     inline indirect_array<_Tp>
446     valarray<_Tp>::operator[](const valarray<size_t>& __i)
447     {
448       return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(),
449 				 _Array<size_t>(__i));
450     }
451 
452   template<class _Tp>
453     inline size_t
size()454     valarray<_Tp>::size() const
455     { return _M_size; }
456 
457   template<class _Tp>
458     inline _Tp
sum()459     valarray<_Tp>::sum() const
460     {
461       return __valarray_sum(_M_data, _M_data + _M_size);
462     }
463 
464 //   template<typename _Tp>
465 //   inline _Tp
466 //   valarray<_Tp>::product () const
467 //   {
468 //       return __valarray_product(_M_data, _M_data + _M_size);
469 //   }
470 
471   template <class _Tp>
472      inline valarray<_Tp>
shift(int __n)473      valarray<_Tp>::shift(int __n) const
474      {
475        _Tp* const __a = static_cast<_Tp*>
476          (__builtin_alloca(sizeof(_Tp) * _M_size));
477        if (__n == 0)                          // no shift
478          __valarray_copy_construct(_M_data, _M_data + _M_size, __a);
479        else if (__n > 0)         // __n > 0: shift left
480          {
481            if (size_t(__n) > _M_size)
482              __valarray_default_construct(__a, __a + __n);
483            else
484              {
485                __valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a);
486                __valarray_default_construct(__a+_M_size-__n, __a + _M_size);
487              }
488          }
489        else                        // __n < 0: shift right
490          {
491            __valarray_copy_construct (_M_data, _M_data+_M_size+__n, __a-__n);
492            __valarray_default_construct(__a, __a - __n);
493          }
494        return valarray<_Tp> (__a, _M_size);
495      }
496 
497   template <class _Tp>
498      inline valarray<_Tp>
cshift(int __n)499      valarray<_Tp>::cshift (int __n) const
500      {
501        _Tp* const __a = static_cast<_Tp*>
502          (__builtin_alloca (sizeof(_Tp) * _M_size));
503        if (__n == 0)               // no cshift
504          __valarray_copy_construct(_M_data, _M_data + _M_size, __a);
505        else if (__n > 0)           // cshift left
506          {
507            __valarray_copy_construct(_M_data, _M_data+__n, __a+_M_size-__n);
508            __valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a);
509          }
510        else                        // cshift right
511          {
512            __valarray_copy_construct
513              (_M_data + _M_size+__n, _M_data + _M_size, __a);
514            __valarray_copy_construct
515              (_M_data, _M_data + _M_size+__n, __a - __n);
516          }
517        return valarray<_Tp>(__a, _M_size);
518      }
519 
520   template <class _Tp>
521     inline void
resize(size_t __n,_Tp __c)522     valarray<_Tp>::resize (size_t __n, _Tp __c)
523     {
524       // This complication is so to make valarray<valarray<T> > work
525       // even though it is not required by the standard.  Nobody should
526       // be saying valarray<valarray<T> > anyway.  See the specs.
527       __valarray_destroy_elements(_M_data, _M_data + _M_size);
528       if (_M_size != __n)
529 	{
530 	  __valarray_release_memory(_M_data);
531 	  _M_size = __n;
532 	  _M_data = __valarray_get_storage<_Tp>(__n);
533 	}
534       __valarray_fill_construct(_M_data, _M_data + __n, __c);
535     }
536 
537   template<typename _Tp>
538     inline _Tp
min()539     valarray<_Tp>::min() const
540     {
541       return *min_element (_M_data, _M_data+_M_size);
542     }
543 
544   template<typename _Tp>
545     inline _Tp
max()546     valarray<_Tp>::max() const
547     {
548       return *max_element (_M_data, _M_data+_M_size);
549     }
550 
551   template<class _Tp>
552     inline _Expr<_ValFunClos<_ValArray,_Tp>,_Tp>
apply(_Tp func (_Tp))553     valarray<_Tp>::apply(_Tp func(_Tp)) const
554     {
555       typedef _ValFunClos<_ValArray,_Tp> _Closure;
556       return _Expr<_Closure,_Tp>(_Closure(*this, func));
557     }
558 
559   template<class _Tp>
560     inline _Expr<_RefFunClos<_ValArray,_Tp>,_Tp>
apply(_Tp func (const _Tp &))561     valarray<_Tp>::apply(_Tp func(const _Tp &)) const
562     {
563       typedef _RefFunClos<_ValArray,_Tp> _Closure;
564       return _Expr<_Closure,_Tp>(_Closure(*this, func));
565     }
566 
567 #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name)                     \
568   template<typename _Tp>						\
569   inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt         	\
570   valarray<_Tp>::operator _Op() const					\
571   {									\
572     typedef _UnClos<_Name,_ValArray,_Tp> _Closure;	                \
573     typedef typename __fun<_Name, _Tp>::result_type _Rt;                \
574     return _Expr<_Closure, _Rt>(_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     _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not)
581 
582 #undef _DEFINE_VALARRAY_UNARY_OPERATOR
583 
584 #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name)               \
585   template<class _Tp>							\
586     inline valarray<_Tp>&						\
587     valarray<_Tp>::operator _Op##=(const _Tp &__t)			\
588     {									\
589       _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t);	\
590       return *this;							\
591     }									\
592 									\
593   template<class _Tp>							\
594     inline valarray<_Tp>&						\
595     valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v)		\
596     {									\
597       _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, 		\
598 			       _Array<_Tp>(__v._M_data));		\
599       return *this;							\
600     }
601 
602 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus)
603 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus)
604 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies)
605 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides)
606 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus)
607 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
608 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
609 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
610 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left)
611 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right)
612 
613 #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT
614 
615 #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name)          \
616   template<class _Tp> template<class _Dom>				\
617     inline valarray<_Tp>&						\
618     valarray<_Tp>::operator _Op##=(const _Expr<_Dom,_Tp>& __e)		\
619     {									\
620       _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size);	\
621       return *this;							\
622     }
623 
624 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus)
625 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus)
626 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies)
627 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides)
628 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus)
629 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
630 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
631 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
632 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left)
633 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right)
634 
635 #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT
636 
637 
638 #define _DEFINE_BINARY_OPERATOR(_Op, _Name)				\
639   template<typename _Tp>						\
640     inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>,           \
641                  typename __fun<_Name, _Tp>::result_type>               \
642     operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w)	\
643     {									\
644       typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure;     \
645       typedef typename __fun<_Name, _Tp>::result_type _Rt;              \
646       return _Expr<_Closure, _Rt>(_Closure(__v, __w));                  \
647     }									\
648 									\
649   template<typename _Tp>						\
650   inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>,             \
651                typename __fun<_Name, _Tp>::result_type>                 \
652   operator _Op(const valarray<_Tp>& __v, const _Tp& __t)		\
653   {									\
654     typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure;	\
655     typedef typename __fun<_Name, _Tp>::result_type _Rt;                \
656     return _Expr<_Closure, _Rt>(_Closure(__v, __t));	                \
657   }									\
658 									\
659   template<typename _Tp>						\
660   inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>,             \
661                typename __fun<_Name, _Tp>::result_type>                 \
662   operator _Op(const _Tp& __t, const valarray<_Tp>& __v)		\
663   {									\
664     typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure;       \
665     typedef typename __fun<_Name, _Tp>::result_type _Rt;                \
666     return _Expr<_Closure, _Tp>(_Closure(__t, __v));        	        \
667   }
668 
669 _DEFINE_BINARY_OPERATOR(+, __plus)
670 _DEFINE_BINARY_OPERATOR(-, __minus)
671 _DEFINE_BINARY_OPERATOR(*, __multiplies)
672 _DEFINE_BINARY_OPERATOR(/, __divides)
673 _DEFINE_BINARY_OPERATOR(%, __modulus)
674 _DEFINE_BINARY_OPERATOR(^, __bitwise_xor)
675 _DEFINE_BINARY_OPERATOR(&, __bitwise_and)
676 _DEFINE_BINARY_OPERATOR(|, __bitwise_or)
677 _DEFINE_BINARY_OPERATOR(<<, __shift_left)
678 _DEFINE_BINARY_OPERATOR(>>, __shift_right)
679 _DEFINE_BINARY_OPERATOR(&&, __logical_and)
680 _DEFINE_BINARY_OPERATOR(||, __logical_or)
681 _DEFINE_BINARY_OPERATOR(==, __equal_to)
682 _DEFINE_BINARY_OPERATOR(!=, __not_equal_to)
683 _DEFINE_BINARY_OPERATOR(<, __less)
684 _DEFINE_BINARY_OPERATOR(>, __greater)
685 _DEFINE_BINARY_OPERATOR(<=, __less_equal)
686 _DEFINE_BINARY_OPERATOR(>=, __greater_equal)
687 
688 } // namespace std
689 
690 #endif // _CPP_VALARRAY
691 
692 // Local Variables:
693 // mode:c++
694 // End:
695