1 // The template and inlines for the -*- C++ -*- valarray class.
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
4 // Free Software Foundation, Inc.
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)
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.
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,
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.
31 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
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.
41 #pragma GCC system_header
43 #include <bits/c++config.h>
52 template<class _Clos, typename _Tp>
55 template<typename _Tp1, typename _Tp2>
58 template<class _Oper, template<class, class> class _Meta, class _Dom>
62 template<class, class> class _Meta1,
63 template<class, class> class _Meta2,
64 class _Dom1, class _Dom2>
67 template<template<class, class> class _Meta, class _Dom>
70 template<template<class, class> class _Meta, class _Dom>
73 template<template<class, class> class _Meta, class _Dom>
76 template<template<class, class> class _Meta, class _Dom>
79 template<template<class, class> class _Meta, class _Dom>
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
92 #include <bits/valarray_array.h>
93 #include <bits/valarray_before.h>
103 typedef typename __fun<_Op, _Tp>::result_type __rt;
104 typedef _Expr<_UnClos<_Op, _ValArray, _Tp>, __rt> _Rt;
107 typedef _Tp value_type;
109 // _lib.valarray.cons_ construct/destroy:
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>&);
120 valarray(const _Expr<_Dom,_Tp>& __e);
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>&);
131 template<class _Dom> valarray<_Tp>&
132 operator= (const _Expr<_Dom,_Tp>&);
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>&);
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;
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>&);
178 valarray<_Tp>& operator*=(const _Expr<_Dom,_Tp>&);
180 valarray<_Tp>& operator/=(const _Expr<_Dom,_Tp>&);
182 valarray<_Tp>& operator%=(const _Expr<_Dom,_Tp>&);
184 valarray<_Tp>& operator+=(const _Expr<_Dom,_Tp>&);
186 valarray<_Tp>& operator-=(const _Expr<_Dom,_Tp>&);
188 valarray<_Tp>& operator^=(const _Expr<_Dom,_Tp>&);
190 valarray<_Tp>& operator|=(const _Expr<_Dom,_Tp>&);
192 valarray<_Tp>& operator&=(const _Expr<_Dom,_Tp>&);
194 valarray<_Tp>& operator<<=(const _Expr<_Dom,_Tp>&);
196 valarray<_Tp>& operator>>=(const _Expr<_Dom,_Tp>&);
199 // _lib.valarray.members_ member functions:
205 // // FIXME: Extension
206 // _Tp product () const;
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());
216 _Tp* __restrict__ _M_data;
218 friend class _Array<_Tp>;
221 template<typename _Tp>
223 valarray<_Tp>::operator[](size_t __i) const
224 { return _M_data[__i]; }
226 template<typename _Tp>
228 valarray<_Tp>::operator[](size_t __i)
229 { return _M_data[__i]; }
233 #include <bits/valarray_after.h>
235 #include <bits/slice_array.h>
236 #include <bits/gslice.h>
237 #include <bits/gslice_array.h>
238 #include <bits/mask_array.h>
239 #include <bits/indirect_array.h>
243 template<typename _Tp>
245 valarray<_Tp>::valarray() : _M_size(0), _M_data(0) {}
247 template<typename _Tp>
249 valarray<_Tp>::valarray(size_t __n)
250 : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
251 { std::__valarray_default_construct(_M_data, _M_data + __n); }
253 template<typename _Tp>
255 valarray<_Tp>::valarray(const _Tp& __t, size_t __n)
256 : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
257 { std::__valarray_fill_construct(_M_data, _M_data + __n, __t); }
259 template<typename _Tp>
261 valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n)
262 : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
263 { std::__valarray_copy_construct(__p, __p + __n, _M_data); }
265 template<typename _Tp>
267 valarray<_Tp>::valarray(const valarray<_Tp>& __v)
268 : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size))
269 { std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size, _M_data); }
271 template<typename _Tp>
273 valarray<_Tp>::valarray(const slice_array<_Tp>& __sa)
274 : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz))
277 (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data));
280 template<typename _Tp>
282 valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga)
283 : _M_size(__ga._M_index.size()),
284 _M_data(__valarray_get_storage<_Tp>(_M_size))
287 (__ga._M_array, _Array<size_t>(__ga._M_index),
288 _Array<_Tp>(_M_data), _M_size);
291 template<typename _Tp>
293 valarray<_Tp>::valarray(const mask_array<_Tp>& __ma)
294 : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz))
297 (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size);
300 template<typename _Tp>
302 valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia)
303 : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz))
306 (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size);
309 template<typename _Tp> template<class _Dom>
311 valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e)
312 : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size))
313 { std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data)); }
315 template<typename _Tp>
317 valarray<_Tp>::~valarray()
319 std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
320 std::__valarray_release_memory(_M_data);
323 template<typename _Tp>
324 inline valarray<_Tp>&
325 valarray<_Tp>::operator=(const valarray<_Tp>& __v)
327 std::__valarray_copy(__v._M_data, _M_size, _M_data);
331 template<typename _Tp>
332 inline valarray<_Tp>&
333 valarray<_Tp>::operator=(const _Tp& __t)
335 std::__valarray_fill(_M_data, _M_size, __t);
339 template<typename _Tp>
340 inline valarray<_Tp>&
341 valarray<_Tp>::operator=(const slice_array<_Tp>& __sa)
343 std::__valarray_copy(__sa._M_array, __sa._M_sz,
344 __sa._M_stride, _Array<_Tp>(_M_data));
348 template<typename _Tp>
349 inline valarray<_Tp>&
350 valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga)
352 std::__valarray_copy(__ga._M_array, _Array<size_t>(__ga._M_index),
353 _Array<_Tp>(_M_data), _M_size);
357 template<typename _Tp>
358 inline valarray<_Tp>&
359 valarray<_Tp>::operator=(const mask_array<_Tp>& __ma)
361 std::__valarray_copy(__ma._M_array, __ma._M_mask,
362 _Array<_Tp>(_M_data), _M_size);
366 template<typename _Tp>
367 inline valarray<_Tp>&
368 valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia)
370 std::__valarray_copy(__ia._M_array, __ia._M_index,
371 _Array<_Tp>(_M_data), _M_size);
375 template<typename _Tp> template<class _Dom>
376 inline valarray<_Tp>&
377 valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e)
379 std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data));
383 template<typename _Tp>
384 inline _Expr<_SClos<_ValArray,_Tp>, _Tp>
385 valarray<_Tp>::operator[](slice __s) const
387 typedef _SClos<_ValArray,_Tp> _Closure;
388 return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s));
391 template<typename _Tp>
392 inline slice_array<_Tp>
393 valarray<_Tp>::operator[](slice __s)
395 return slice_array<_Tp>(_Array<_Tp>(_M_data), __s);
398 template<typename _Tp>
399 inline _Expr<_GClos<_ValArray,_Tp>, _Tp>
400 valarray<_Tp>::operator[](const gslice& __gs) const
402 typedef _GClos<_ValArray,_Tp> _Closure;
403 return _Expr<_Closure, _Tp>
404 (_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index));
407 template<typename _Tp>
408 inline gslice_array<_Tp>
409 valarray<_Tp>::operator[](const gslice& __gs)
411 return gslice_array<_Tp>
412 (_Array<_Tp>(_M_data), __gs._M_index->_M_index);
415 template<typename _Tp>
417 valarray<_Tp>::operator[](const valarray<bool>& __m) const
420 size_t __e = __m.size();
421 for (size_t __i=0; __i<__e; ++__i)
423 return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s,
424 _Array<bool> (__m)));
427 template<typename _Tp>
428 inline mask_array<_Tp>
429 valarray<_Tp>::operator[](const valarray<bool>& __m)
432 size_t __e = __m.size();
433 for (size_t __i=0; __i<__e; ++__i)
435 return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array<bool>(__m));
438 template<typename _Tp>
439 inline _Expr<_IClos<_ValArray,_Tp>, _Tp>
440 valarray<_Tp>::operator[](const valarray<size_t>& __i) const
442 typedef _IClos<_ValArray,_Tp> _Closure;
443 return _Expr<_Closure, _Tp>(_Closure(*this, __i));
446 template<typename _Tp>
447 inline indirect_array<_Tp>
448 valarray<_Tp>::operator[](const valarray<size_t>& __i)
450 return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(),
451 _Array<size_t>(__i));
456 valarray<_Tp>::size() const
461 valarray<_Tp>::sum() const
463 return std::__valarray_sum(_M_data, _M_data + _M_size);
466 // template<typename _Tp>
468 // valarray<_Tp>::product () const
470 // return __valarray_product(_M_data, _M_data + _M_size);
475 valarray<_Tp>::shift(int __n) const
477 _Tp* const __a = static_cast<_Tp*>
478 (__builtin_alloca(sizeof(_Tp) * _M_size));
479 if (__n == 0) // no shift
480 std::__valarray_copy_construct(_M_data, _M_data + _M_size, __a);
481 else if (__n > 0) // __n > 0: shift left
483 if (size_t(__n) > _M_size)
484 std::__valarray_default_construct(__a, __a + __n);
487 std::__valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a);
488 std::__valarray_default_construct(__a+_M_size-__n, __a + _M_size);
491 else // __n < 0: shift right
493 std::__valarray_copy_construct (_M_data, _M_data+_M_size+__n, __a-__n);
494 std::__valarray_default_construct(__a, __a - __n);
496 return valarray<_Tp> (__a, _M_size);
501 valarray<_Tp>::cshift (int __n) const
503 _Tp* const __a = static_cast<_Tp*>
504 (__builtin_alloca (sizeof(_Tp) * _M_size));
505 if (__n == 0) // no cshift
506 std::__valarray_copy_construct(_M_data, _M_data + _M_size, __a);
507 else if (__n > 0) // cshift left
509 std::__valarray_copy_construct(_M_data, _M_data+__n, __a+_M_size-__n);
510 std::__valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a);
514 std::__valarray_copy_construct
515 (_M_data + _M_size+__n, _M_data + _M_size, __a);
516 std::__valarray_copy_construct
517 (_M_data, _M_data + _M_size+__n, __a - __n);
519 return valarray<_Tp>(__a, _M_size);
524 valarray<_Tp>::resize (size_t __n, _Tp __c)
526 // This complication is so to make valarray<valarray<T> > work
527 // even though it is not required by the standard. Nobody should
528 // be saying valarray<valarray<T> > anyway. See the specs.
529 std::__valarray_destroy_elements(_M_data, _M_data + _M_size);
532 std::__valarray_release_memory(_M_data);
534 _M_data = __valarray_get_storage<_Tp>(__n);
536 std::__valarray_fill_construct(_M_data, _M_data + __n, __c);
539 template<typename _Tp>
541 valarray<_Tp>::min() const
543 return *std::min_element (_M_data, _M_data+_M_size);
546 template<typename _Tp>
548 valarray<_Tp>::max() const
550 return *std::max_element (_M_data, _M_data+_M_size);
554 inline _Expr<_ValFunClos<_ValArray,_Tp>,_Tp>
555 valarray<_Tp>::apply(_Tp func(_Tp)) const
557 typedef _ValFunClos<_ValArray,_Tp> _Closure;
558 return _Expr<_Closure,_Tp>(_Closure(*this, func));
562 inline _Expr<_RefFunClos<_ValArray,_Tp>,_Tp>
563 valarray<_Tp>::apply(_Tp func(const _Tp &)) const
565 typedef _RefFunClos<_ValArray,_Tp> _Closure;
566 return _Expr<_Closure,_Tp>(_Closure(*this, func));
569 #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name) \
570 template<typename _Tp> \
571 inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt \
572 valarray<_Tp>::operator _Op() const \
574 typedef _UnClos<_Name,_ValArray,_Tp> _Closure; \
575 typedef typename __fun<_Name, _Tp>::result_type _Rt; \
576 return _Expr<_Closure, _Rt>(_Closure(*this)); \
579 _DEFINE_VALARRAY_UNARY_OPERATOR(+, __unary_plus)
580 _DEFINE_VALARRAY_UNARY_OPERATOR(-, __negate)
581 _DEFINE_VALARRAY_UNARY_OPERATOR(~, __bitwise_not)
582 _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not)
584 #undef _DEFINE_VALARRAY_UNARY_OPERATOR
586 #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name) \
587 template<class _Tp> \
588 inline valarray<_Tp>& \
589 valarray<_Tp>::operator _Op##=(const _Tp &__t) \
591 _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t); \
595 template<class _Tp> \
596 inline valarray<_Tp>& \
597 valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v) \
599 _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, \
600 _Array<_Tp>(__v._M_data)); \
604 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus)
605 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus)
606 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies)
607 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides)
608 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus)
609 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
610 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
611 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
612 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left)
613 _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right)
615 #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT
617 #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name) \
618 template<class _Tp> template<class _Dom> \
619 inline valarray<_Tp>& \
620 valarray<_Tp>::operator _Op##=(const _Expr<_Dom,_Tp>& __e) \
622 _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size); \
626 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus)
627 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus)
628 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies)
629 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides)
630 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus)
631 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor)
632 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and)
633 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or)
634 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left)
635 _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right)
637 #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT
640 #define _DEFINE_BINARY_OPERATOR(_Op, _Name) \
641 template<typename _Tp> \
642 inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>, \
643 typename __fun<_Name, _Tp>::result_type> \
644 operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \
646 typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure; \
647 typedef typename __fun<_Name, _Tp>::result_type _Rt; \
648 return _Expr<_Closure, _Rt>(_Closure(__v, __w)); \
651 template<typename _Tp> \
652 inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>, \
653 typename __fun<_Name, _Tp>::result_type> \
654 operator _Op(const valarray<_Tp>& __v, const _Tp& __t) \
656 typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure; \
657 typedef typename __fun<_Name, _Tp>::result_type _Rt; \
658 return _Expr<_Closure, _Rt>(_Closure(__v, __t)); \
661 template<typename _Tp> \
662 inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>, \
663 typename __fun<_Name, _Tp>::result_type> \
664 operator _Op(const _Tp& __t, const valarray<_Tp>& __v) \
666 typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure; \
667 typedef typename __fun<_Name, _Tp>::result_type _Rt; \
668 return _Expr<_Closure, _Tp>(_Closure(__t, __v)); \
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 _DEFINE_BINARY_OPERATOR(&&, __logical_and)
682 _DEFINE_BINARY_OPERATOR(||, __logical_or)
683 _DEFINE_BINARY_OPERATOR(==, __equal_to)
684 _DEFINE_BINARY_OPERATOR(!=, __not_equal_to)
685 _DEFINE_BINARY_OPERATOR(<, __less)
686 _DEFINE_BINARY_OPERATOR(>, __greater)
687 _DEFINE_BINARY_OPERATOR(<=, __less_equal)
688 _DEFINE_BINARY_OPERATOR(>=, __greater_equal)