1 // The template and inlines for the -*- C++ -*- internal _Meta class.
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
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)
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.
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,
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.
30 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr>
32 /** @file valarray_meta.h
33 * This is an internal header file, included by other library headers.
34 * You should not attempt to use it directly.
37 #ifndef _CPP_VALARRAY_META_H
38 #define _CPP_VALARRAY_META_H 1
40 #pragma GCC system_header
45 // Implementing a loosened valarray return value is tricky.
46 // First we need to meet 26.3.1/3: we should not add more than
47 // two levels of template nesting. Therefore we resort to template
48 // template to "flatten" loosened return value types.
49 // At some point we use partial specialization to remove one level
50 // template nesting due to _Expr<>
54 // This class is NOT defined. It doesn't need to.
55 template<typename _Tp1
, typename _Tp2
> class _Constant
;
57 // Implementations of unary functions applied to valarray<>s.
58 // I use hard-coded object functions here instead of a generic
59 // approach like pointers to function:
60 // 1) correctness: some functions take references, others values.
61 // we can't deduce the correct type afterwards.
62 // 2) efficiency -- object functions can be easily inlined
63 // 3) be Koenig-lookup-friendly
67 template<typename _Tp
>
68 _Tp
operator()(const _Tp
& __t
) const { return abs(__t
); }
73 template<typename _Tp
>
74 _Tp
operator()(const _Tp
& __t
) const { return cos(__t
); }
79 template<typename _Tp
>
80 _Tp
operator()(const _Tp
& __t
) const { return acos(__t
); }
85 template<typename _Tp
>
86 _Tp
operator()(const _Tp
& __t
) const { return cosh(__t
); }
91 template<typename _Tp
>
92 _Tp
operator()(const _Tp
& __t
) const { return sin(__t
); }
97 template<typename _Tp
>
98 _Tp
operator()(const _Tp
& __t
) const { return asin(__t
); }
103 template<typename _Tp
>
104 _Tp
operator()(const _Tp
& __t
) const { return sinh(__t
); }
109 template<typename _Tp
>
110 _Tp
operator()(const _Tp
& __t
) const { return tan(__t
); }
115 template<typename _Tp
>
116 _Tp
operator()(const _Tp
& __t
) const { return atan(__t
); }
121 template<typename _Tp
>
122 _Tp
operator()(const _Tp
& __t
) const { return tanh(__t
); }
127 template<typename _Tp
>
128 _Tp
operator()(const _Tp
& __t
) const { return exp(__t
); }
133 template<typename _Tp
>
134 _Tp
operator()(const _Tp
& __t
) const { return log(__t
); }
139 template<typename _Tp
>
140 _Tp
operator()(const _Tp
& __t
) const { return log10(__t
); }
145 template<typename _Tp
>
146 _Tp
operator()(const _Tp
& __t
) const { return sqrt(__t
); }
149 // In the past, we used to tailor operator applications semantics
150 // to the specialization of standard function objects (i.e. plus<>, etc.)
151 // That is incorrect. Therefore we provide our own surrogates.
155 template<typename _Tp
>
156 _Tp
operator()(const _Tp
& __t
) const { return +__t
; }
161 template<typename _Tp
>
162 _Tp
operator()(const _Tp
& __t
) const { return -__t
; }
167 template<typename _Tp
>
168 _Tp
operator()(const _Tp
& __t
) const { return ~__t
; }
173 template<typename _Tp
>
174 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
175 { return __x
+ __y
; }
180 template<typename _Tp
>
181 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
182 { return __x
- __y
; }
187 template<typename _Tp
>
188 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
189 { return __x
* __y
; }
194 template<typename _Tp
>
195 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
196 { return __x
/ __y
; }
201 template<typename _Tp
>
202 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
203 { return __x
% __y
; }
208 template<typename _Tp
>
209 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
210 { return __x
^ __y
; }
215 template<typename _Tp
>
216 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
217 { return __x
& __y
; }
222 template<typename _Tp
>
223 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
224 { return __x
| __y
; }
229 template<typename _Tp
>
230 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
231 { return __x
<< __y
; }
236 template<typename _Tp
>
237 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
238 { return __x
>> __y
; }
243 template<typename _Tp
>
244 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
245 { return __x
&& __y
; }
250 template<typename _Tp
>
251 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
252 { return __x
|| __y
; }
257 template<typename _Tp
>
258 bool operator()(const _Tp
& __x
) const { return !__x
; }
263 template<typename _Tp
>
264 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
265 { return __x
== __y
; }
268 struct __not_equal_to
270 template<typename _Tp
>
271 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
272 { return __x
== __y
; }
277 template<typename _Tp
>
278 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
279 { return __x
< __y
; }
284 template<typename _Tp
>
285 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
286 { return __x
> __y
; }
291 template<typename _Tp
>
292 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
293 { return __x
<= __y
; }
296 struct __greater_equal
298 template<typename _Tp
>
299 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
300 { return __x
>= __y
; }
303 // The few binary functions we miss.
306 template<typename _Tp
>
307 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
308 { return atan2(__x
, __y
); }
313 template<typename _Tp
>
314 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
315 { return pow(__x
, __y
); }
319 // We need these bits in order to recover the return type of
320 // some functions/operators now that we're no longer using
321 // function templates.
322 template<typename
, typename _Tp
>
325 typedef _Tp result_type
;
328 // several specializations for relational operators.
329 template<typename _Tp
>
330 struct __fun
<__logical_not
, _Tp
>
332 typedef bool result_type
;
335 template<typename _Tp
>
336 struct __fun
<__logical_and
, _Tp
>
338 typedef bool result_type
;
341 template<typename _Tp
>
342 struct __fun
<__logical_or
, _Tp
>
344 typedef bool result_type
;
347 template<typename _Tp
>
348 struct __fun
<__less
, _Tp
>
350 typedef bool result_type
;
353 template<typename _Tp
>
354 struct __fun
<__greater
, _Tp
>
356 typedef bool result_type
;
359 template<typename _Tp
>
360 struct __fun
<__less_equal
, _Tp
>
362 typedef bool result_type
;
365 template<typename _Tp
>
366 struct __fun
<__greater_equal
, _Tp
>
368 typedef bool result_type
;
371 template<typename _Tp
>
372 struct __fun
<__equal_to
, _Tp
>
374 typedef bool result_type
;
377 template<typename _Tp
>
378 struct __fun
<__not_equal_to
, _Tp
>
380 typedef bool result_type
;
384 // Binary function application closure.
386 template<template<class, class> class _Meta1
,
387 template<class, class> class Meta2
,
388 class _Dom1
, class _Dom2
> class _BinFunClos
;
390 template<class _Dom1
, class _Dom2
> class _BinFunBase
{
392 typedef typename
_Dom1::value_type value_type
;
393 typedef value_type _Vt
;
395 _BinFunBase (const _Dom1
& __e1
, const _Dom2
& __e2
,
397 : _M_expr1 (__e1
), _M_expr2 (__e2
), _M_func (__f
) {}
399 value_type
operator[] (size_t __i
) const
400 { return _M_func (_M_expr1
[__i
], _M_expr2
[__i
]); }
401 size_t size () const { return _M_expr1
.size (); }
404 const _Dom1
& _M_expr1
;
405 const _Dom2
& _M_expr2
;
406 _Vt (*_M_func
)(_Vt
, _Vt
);
409 template<class _Dom
> class _BinFunBase1
{
411 typedef typename
_Dom::value_type value_type
;
412 typedef value_type _Vt
;
414 _BinFunBase1 (const _Vt
& __c
, const _Dom
& __e
, _Vt
__f(_Vt
, _Vt
))
415 : _M_expr1 (__c
), _M_expr2 (__e
), _M_func (__f
) {}
417 value_type
operator[] (size_t __i
) const
418 { return _M_func (_M_expr1
, _M_expr2
[__i
]); }
419 size_t size () const { return _M_expr2
.size (); }
423 const _Dom
& _M_expr2
;
424 _Vt (*_M_func
)(_Vt
, _Vt
);
427 template<class _Dom
> class _BinFunBase2
{
429 typedef typename
_Dom::value_type value_type
;
430 typedef value_type _Vt
;
432 _BinFunBase2 (const _Dom
& __e
, const _Vt
& __c
, _Vt
__f(_Vt
, _Vt
))
433 : _M_expr1 (__e
), _M_expr2 (__c
), _M_func (__f
) {}
435 value_type
operator[] (size_t __i
) const
436 { return _M_func (_M_expr1
[__i
], _M_expr2
); }
437 size_t size () const { return _M_expr1
.size (); }
440 const _Dom
& _M_expr1
;
442 _Vt (*_M_func
)(_Vt
, _Vt
);
445 template<class _Dom1
, class _Dom2
>
446 struct _BinFunClos
<_Expr
,_Expr
,_Dom1
,_Dom2
> : _BinFunBase
<_Dom1
,_Dom2
> {
447 typedef _BinFunBase
<_Dom1
,_Dom2
> _Base
;
448 typedef typename
_Base::value_type value_type
;
449 typedef value_type _Tp
;
451 _BinFunClos (const _Dom1
& __e1
, const _Dom2
& __e2
,
453 : _Base (__e1
, __e2
, __f
) {}
456 template<typename _Tp
>
457 struct _BinFunClos
<_ValArray
,_ValArray
,_Tp
,_Tp
>
458 : _BinFunBase
<valarray
<_Tp
>, valarray
<_Tp
> > {
459 typedef _BinFunBase
<valarray
<_Tp
>, valarray
<_Tp
> > _Base
;
460 typedef _Tp value_type
;
462 _BinFunClos (const valarray
<_Tp
>& __v
, const valarray
<_Tp
>& __w
,
464 : _Base (__v
, __w
, __f
) {}
468 struct _BinFunClos
<_Expr
,_ValArray
,_Dom
,typename
_Dom::value_type
>
469 : _BinFunBase
<_Dom
,valarray
<typename
_Dom::value_type
> > {
470 typedef typename
_Dom::value_type _Tp
;
471 typedef _BinFunBase
<_Dom
,valarray
<_Tp
> > _Base
;
472 typedef _Tp value_type
;
474 _BinFunClos (const _Dom
& __e
, const valarray
<_Tp
>& __v
,
476 : _Base (__e
, __v
, __f
) {}
480 struct _BinFunClos
<_ValArray
,_Expr
,typename
_Dom::value_type
,_Dom
>
481 : _BinFunBase
<valarray
<typename
_Dom::value_type
>,_Dom
> {
482 typedef typename
_Dom::value_type _Tp
;
483 typedef _BinFunBase
<_Dom
,valarray
<_Tp
> > _Base
;
484 typedef _Tp value_type
;
486 _BinFunClos (const valarray
<_Tp
>& __v
, const _Dom
& __e
,
488 : _Base (__v
, __e
, __f
) {}
492 struct _BinFunClos
<_Expr
,_Constant
,_Dom
,typename
_Dom::value_type
>
493 : _BinFunBase2
<_Dom
> {
494 typedef typename
_Dom::value_type _Tp
;
495 typedef _Tp value_type
;
496 typedef _BinFunBase2
<_Dom
> _Base
;
498 _BinFunClos (const _Dom
& __e
, const _Tp
& __t
, _Tp
__f (_Tp
, _Tp
))
499 : _Base (__e
, __t
, __f
) {}
503 struct _BinFunClos
<_Constant
,_Expr
,_Dom
,typename
_Dom::value_type
>
504 : _BinFunBase1
<_Dom
> {
505 typedef typename
_Dom::value_type _Tp
;
506 typedef _Tp value_type
;
507 typedef _BinFunBase1
<_Dom
> _Base
;
509 _BinFunClos (const _Tp
& __t
, const _Dom
& __e
, _Tp
__f (_Tp
, _Tp
))
510 : _Base (__t
, __e
, __f
) {}
513 template<typename _Tp
>
514 struct _BinFunClos
<_ValArray
,_Constant
,_Tp
,_Tp
>
515 : _BinFunBase2
<valarray
<_Tp
> > {
516 typedef _BinFunBase2
<valarray
<_Tp
> > _Base
;
517 typedef _Tp value_type
;
519 _BinFunClos (const valarray
<_Tp
>& __v
, const _Tp
& __t
,
521 : _Base (__v
, __t
, __f
) {}
524 template<typename _Tp
>
525 struct _BinFunClos
<_Constant
,_ValArray
,_Tp
,_Tp
>
526 : _BinFunBase1
<valarray
<_Tp
> > {
527 typedef _BinFunBase1
<valarray
<_Tp
> > _Base
;
528 typedef _Tp value_type
;
530 _BinFunClos (const _Tp
& __t
, const valarray
<_Tp
>& __v
,
532 : _Base (__t
, __v
, __f
) {}
536 // Apply function taking a value/const reference closure
539 template<typename _Dom
, typename _Arg
> class _FunBase
{
541 typedef typename
_Dom::value_type value_type
;
543 _FunBase (const _Dom
& __e
, value_type
__f(_Arg
))
544 : _M_expr (__e
), _M_func (__f
) {}
546 value_type
operator[] (size_t __i
) const
547 { return _M_func (_M_expr
[__i
]); }
548 size_t size() const { return _M_expr
.size ();}
552 value_type (*_M_func
)(_Arg
);
556 struct _ValFunClos
<_Expr
,_Dom
>
557 : _FunBase
<_Dom
, typename
_Dom::value_type
> {
558 typedef _FunBase
<_Dom
, typename
_Dom::value_type
> _Base
;
559 typedef typename
_Base::value_type value_type
;
560 typedef value_type _Tp
;
562 _ValFunClos (const _Dom
& __e
, _Tp
__f (_Tp
)) : _Base (__e
, __f
) {}
565 template<typename _Tp
>
566 struct _ValFunClos
<_ValArray
,_Tp
>
567 : _FunBase
<valarray
<_Tp
>, _Tp
> {
568 typedef _FunBase
<valarray
<_Tp
>, _Tp
> _Base
;
569 typedef _Tp value_type
;
571 _ValFunClos (const valarray
<_Tp
>& __v
, _Tp
__f(_Tp
))
572 : _Base (__v
, __f
) {}
576 struct _RefFunClos
<_Expr
,_Dom
> :
577 _FunBase
<_Dom
, const typename
_Dom::value_type
&> {
578 typedef _FunBase
<_Dom
, const typename
_Dom::value_type
&> _Base
;
579 typedef typename
_Base::value_type value_type
;
580 typedef value_type _Tp
;
582 _RefFunClos (const _Dom
& __e
, _Tp
__f (const _Tp
&))
583 : _Base (__e
, __f
) {}
586 template<typename _Tp
>
587 struct _RefFunClos
<_ValArray
,_Tp
>
588 : _FunBase
<valarray
<_Tp
>, const _Tp
&> {
589 typedef _FunBase
<valarray
<_Tp
>, const _Tp
&> _Base
;
590 typedef _Tp value_type
;
592 _RefFunClos (const valarray
<_Tp
>& __v
, _Tp
__f(const _Tp
&))
593 : _Base (__v
, __f
) {}
597 // Unary expression closure.
600 template<class _Oper
, class _Arg
>
604 typedef typename
_Arg::value_type _Vt
;
605 typedef typename __fun
<_Oper
, _Vt
>::result_type value_type
;
607 _UnBase(const _Arg
& __e
) : _M_expr(__e
) {}
609 value_type
operator[](size_t __i
) const
610 { return _M_expr
[__i
]; }
612 size_t size() const { return _M_expr
.size(); }
618 template<class _Oper
, class _Dom
>
619 struct _UnClos
<_Oper
, _Expr
, _Dom
> : _UnBase
<_Oper
, _Dom
>
622 typedef _UnBase
<_Oper
, _Dom
> _Base
;
623 typedef typename
_Base::value_type value_type
;
625 _UnClos(const _Arg
& __e
) : _Base(__e
) {}
628 template<class _Oper
, typename _Tp
>
629 struct _UnClos
<_Oper
, _ValArray
, _Tp
> : _UnBase
<_Oper
, valarray
<_Tp
> >
631 typedef valarray
<_Tp
> _Arg
;
632 typedef _UnBase
<_Oper
, valarray
<_Tp
> > _Base
;
633 typedef typename
_Base::value_type value_type
;
635 _UnClos(const _Arg
& __e
) : _Base(__e
) {}
640 // Binary expression closure.
643 template<template<class> class _Oper
,
644 typename _FirstArg
, typename _SecondArg
>
647 typedef _Oper
<typename
_FirstArg::value_type
> _Op
;
648 typedef typename
_Op::result_type value_type
;
650 _BinBase (const _FirstArg
& __e1
, const _SecondArg
& __e2
)
651 : _M_expr1 (__e1
), _M_expr2 (__e2
) {}
652 value_type
operator[] (size_t) const;
653 size_t size () const { return _M_expr1
.size (); }
656 const _FirstArg
& _M_expr1
;
657 const _SecondArg
& _M_expr2
;
660 template<template<class> class _Oper
,
661 typename _FirstArg
, typename _SecondArg
>
662 inline typename _BinBase
<_Oper
,_FirstArg
,_SecondArg
>::value_type
663 _BinBase
<_Oper
,_FirstArg
,_SecondArg
>::operator[] (size_t __i
) const
664 { return _Op() (_M_expr1
[__i
], _M_expr2
[__i
]); }
667 template<template<class> class _Oper
, class _Clos
>
670 typedef typename
_Clos::value_type _Vt
;
671 typedef _Oper
<_Vt
> _Op
;
672 typedef typename
_Op::result_type value_type
;
674 _BinBase2 (const _Clos
& __e
, const _Vt
& __t
)
675 : _M_expr1 (__e
), _M_expr2 (__t
) {}
676 value_type
operator[] (size_t) const;
677 size_t size () const { return _M_expr1
.size (); }
680 const _Clos
& _M_expr1
;
684 template<template<class> class _Oper
, class _Clos
>
685 inline typename _BinBase2
<_Oper
,_Clos
>::value_type
686 _BinBase2
<_Oper
,_Clos
>::operator[] (size_t __i
) const
687 { return _Op() (_M_expr1
[__i
], _M_expr2
); }
690 template<template<class> class _Oper
, class _Clos
>
693 typedef typename
_Clos::value_type _Vt
;
694 typedef _Oper
<_Vt
> _Op
;
695 typedef typename
_Op::result_type value_type
;
697 _BinBase1 (const _Vt
& __t
, const _Clos
& __e
)
698 : _M_expr1 (__t
), _M_expr2 (__e
) {}
699 value_type
operator[] (size_t) const;
700 size_t size () const { return _M_expr2
.size (); }
704 const _Clos
& _M_expr2
;
707 template<template<class> class _Oper
, class _Clos
>
709 _BinBase1
<_Oper
,_Clos
>::value_type
710 _BinBase1
<_Oper
,_Clos
>:: operator[] (size_t __i
) const
711 { return _Op() (_M_expr1
, _M_expr2
[__i
]); }
714 template<template<class> class _Oper
, class _Dom1
, class _Dom2
>
715 struct _BinClos
<_Oper
, _Expr
, _Expr
, _Dom1
, _Dom2
>
716 : _BinBase
<_Oper
,_Dom1
,_Dom2
> {
717 typedef _BinBase
<_Oper
,_Dom1
,_Dom2
> _Base
;
718 typedef typename
_Base::value_type value_type
;
720 _BinClos(const _Dom1
& __e1
, const _Dom2
& __e2
) : _Base(__e1
, __e2
) {}
723 template<template<class> class _Oper
, typename _Tp
>
724 struct _BinClos
<_Oper
,_ValArray
,_ValArray
,_Tp
,_Tp
>
725 : _BinBase
<_Oper
,valarray
<_Tp
>,valarray
<_Tp
> > {
726 typedef _BinBase
<_Oper
,valarray
<_Tp
>,valarray
<_Tp
> > _Base
;
727 typedef _Tp value_type
;
729 _BinClos (const valarray
<_Tp
>& __v
, const valarray
<_Tp
>& __w
)
730 : _Base (__v
, __w
) {}
733 template<template<class> class _Oper
, class _Dom
>
734 struct _BinClos
<_Oper
,_Expr
,_ValArray
,_Dom
,typename
_Dom::value_type
>
735 : _BinBase
<_Oper
,_Dom
,valarray
<typename
_Dom::value_type
> > {
736 typedef typename
_Dom::value_type _Tp
;
737 typedef _BinBase
<_Oper
,_Dom
,valarray
<_Tp
> > _Base
;
738 typedef typename
_Base::value_type value_type
;
740 _BinClos(const _Dom
& __e1
, const valarray
<_Tp
>& __e2
)
741 : _Base (__e1
, __e2
) {}
744 template<template<class> class _Oper
, class _Dom
>
745 struct _BinClos
<_Oper
,_ValArray
,_Expr
,typename
_Dom::value_type
,_Dom
>
746 : _BinBase
<_Oper
,valarray
<typename
_Dom::value_type
>,_Dom
> {
747 typedef typename
_Dom::value_type _Tp
;
748 typedef _BinBase
<_Oper
,valarray
<_Tp
>,_Dom
> _Base
;
749 typedef typename
_Base::value_type value_type
;
751 _BinClos (const valarray
<_Tp
>& __e1
, const _Dom
& __e2
)
752 : _Base (__e1
, __e2
) {}
755 template<template<class> class _Oper
, class _Dom
>
756 struct _BinClos
<_Oper
,_Expr
,_Constant
,_Dom
,typename
_Dom::value_type
>
757 : _BinBase2
<_Oper
,_Dom
> {
758 typedef typename
_Dom::value_type _Tp
;
759 typedef _BinBase2
<_Oper
,_Dom
> _Base
;
760 typedef typename
_Base::value_type value_type
;
762 _BinClos (const _Dom
& __e1
, const _Tp
& __e2
) : _Base (__e1
, __e2
) {}
765 template<template<class> class _Oper
, class _Dom
>
766 struct _BinClos
<_Oper
,_Constant
,_Expr
,typename
_Dom::value_type
,_Dom
>
767 : _BinBase1
<_Oper
,_Dom
> {
768 typedef typename
_Dom::value_type _Tp
;
769 typedef _BinBase1
<_Oper
,_Dom
> _Base
;
770 typedef typename
_Base::value_type value_type
;
772 _BinClos (const _Tp
& __e1
, const _Dom
& __e2
) : _Base (__e1
, __e2
) {}
775 template<template<class> class _Oper
, typename _Tp
>
776 struct _BinClos
<_Oper
,_ValArray
,_Constant
,_Tp
,_Tp
>
777 : _BinBase2
<_Oper
,valarray
<_Tp
> > {
778 typedef _BinBase2
<_Oper
,valarray
<_Tp
> > _Base
;
779 typedef typename
_Base::value_type value_type
;
781 _BinClos (const valarray
<_Tp
>& __v
, const _Tp
& __t
)
782 : _Base (__v
, __t
) {}
785 template<template<class> class _Oper
, typename _Tp
>
786 struct _BinClos
<_Oper
,_Constant
,_ValArray
,_Tp
,_Tp
>
787 : _BinBase1
<_Oper
,valarray
<_Tp
> > {
788 typedef _BinBase1
<_Oper
,valarray
<_Tp
> > _Base
;
789 typedef typename
_Base::value_type value_type
;
791 _BinClos (const _Tp
& __t
, const valarray
<_Tp
>& __v
)
792 : _Base (__t
, __v
) {}
797 // slice_array closure.
799 template<typename _Dom
> class _SBase
{
801 typedef typename
_Dom::value_type value_type
;
803 _SBase (const _Dom
& __e
, const slice
& __s
)
804 : _M_expr (__e
), _M_slice (__s
) {}
805 value_type
operator[] (size_t __i
) const
806 { return _M_expr
[_M_slice
.start () + __i
* _M_slice
.stride ()]; }
807 size_t size() const { return _M_slice
.size (); }
811 const slice
& _M_slice
;
814 template<typename _Tp
> class _SBase
<_Array
<_Tp
> > {
816 typedef _Tp value_type
;
818 _SBase (_Array
<_Tp
> __a
, const slice
& __s
)
819 : _M_array (__a
._M_data
+__s
.start()), _M_size (__s
.size()),
820 _M_stride (__s
.stride()) {}
821 value_type
operator[] (size_t __i
) const
822 { return _M_array
._M_data
[__i
* _M_stride
]; }
823 size_t size() const { return _M_size
; }
826 const _Array
<_Tp
> _M_array
;
827 const size_t _M_size
;
828 const size_t _M_stride
;
831 template<class _Dom
> struct _SClos
<_Expr
,_Dom
> : _SBase
<_Dom
> {
832 typedef _SBase
<_Dom
> _Base
;
833 typedef typename
_Base::value_type value_type
;
835 _SClos (const _Dom
& __e
, const slice
& __s
) : _Base (__e
, __s
) {}
838 template<typename _Tp
>
839 struct _SClos
<_ValArray
,_Tp
> : _SBase
<_Array
<_Tp
> > {
840 typedef _SBase
<_Array
<_Tp
> > _Base
;
841 typedef _Tp value_type
;
843 _SClos (_Array
<_Tp
> __a
, const slice
& __s
) : _Base (__a
, __s
) {}
847 // gslice_array closure.
849 template<class _Dom
> class _GBase
{
851 typedef typename
_Dom::value_type value_type
;
853 _GBase (const _Dom
& __e
, const valarray
<size_t>& __i
)
854 : _M_expr (__e
), _M_index(__i
) {}
855 value_type
operator[] (size_t __i
) const
856 { return _M_expr
[_M_index
[__i
]]; }
857 size_t size () const { return _M_index
.size(); }
861 const valarray
<size_t>& _M_index
;
864 template<typename _Tp
> class _GBase
<_Array
<_Tp
> > {
866 typedef _Tp value_type
;
868 _GBase (_Array
<_Tp
> __a
, const valarray
<size_t>& __i
)
869 : _M_array (__a
), _M_index(__i
) {}
870 value_type
operator[] (size_t __i
) const
871 { return _M_array
._M_data
[_M_index
[__i
]]; }
872 size_t size () const { return _M_index
.size(); }
875 const _Array
<_Tp
> _M_array
;
876 const valarray
<size_t>& _M_index
;
879 template<class _Dom
> struct _GClos
<_Expr
,_Dom
> : _GBase
<_Dom
> {
880 typedef _GBase
<_Dom
> _Base
;
881 typedef typename
_Base::value_type value_type
;
883 _GClos (const _Dom
& __e
, const valarray
<size_t>& __i
)
884 : _Base (__e
, __i
) {}
887 template<typename _Tp
>
888 struct _GClos
<_ValArray
,_Tp
> : _GBase
<_Array
<_Tp
> > {
889 typedef _GBase
<_Array
<_Tp
> > _Base
;
890 typedef typename
_Base::value_type value_type
;
892 _GClos (_Array
<_Tp
> __a
, const valarray
<size_t>& __i
)
893 : _Base (__a
, __i
) {}
897 // indirect_array closure
900 template<class _Dom
> class _IBase
{
902 typedef typename
_Dom::value_type value_type
;
904 _IBase (const _Dom
& __e
, const valarray
<size_t>& __i
)
905 : _M_expr (__e
), _M_index (__i
) {}
906 value_type
operator[] (size_t __i
) const
907 { return _M_expr
[_M_index
[__i
]]; }
908 size_t size() const { return _M_index
.size(); }
912 const valarray
<size_t>& _M_index
;
915 template<class _Dom
> struct _IClos
<_Expr
,_Dom
> : _IBase
<_Dom
> {
916 typedef _IBase
<_Dom
> _Base
;
917 typedef typename
_Base::value_type value_type
;
919 _IClos (const _Dom
& __e
, const valarray
<size_t>& __i
)
920 : _Base (__e
, __i
) {}
923 template<typename _Tp
>
924 struct _IClos
<_ValArray
,_Tp
> : _IBase
<valarray
<_Tp
> > {
925 typedef _IBase
<valarray
<_Tp
> > _Base
;
926 typedef _Tp value_type
;
928 _IClos (const valarray
<_Tp
>& __a
, const valarray
<size_t>& __i
)
929 : _Base (__a
, __i
) {}
935 template<class _Clos
, typename _Tp
>
939 typedef _Tp value_type
;
943 const _Clos
& operator()() const;
945 value_type
operator[](size_t) const;
946 valarray
<value_type
> operator[](slice
) const;
947 valarray
<value_type
> operator[](const gslice
&) const;
948 valarray
<value_type
> operator[](const valarray
<bool>&) const;
949 valarray
<value_type
> operator[](const valarray
<size_t>&) const;
951 _Expr
<_UnClos
<__unary_plus
,std::_Expr
,_Clos
>, value_type
>
954 _Expr
<_UnClos
<__negate
,std::_Expr
,_Clos
>, value_type
>
957 _Expr
<_UnClos
<__bitwise_not
,std::_Expr
,_Clos
>, value_type
>
960 _Expr
<_UnClos
<__logical_not
,std::_Expr
,_Clos
>, bool>
964 value_type
sum() const;
966 valarray
<value_type
> shift(int) const;
967 valarray
<value_type
> cshift(int) const;
969 value_type
min() const;
970 value_type
max() const;
972 valarray
<value_type
> apply(value_type (*)(const value_type
&)) const;
973 valarray
<value_type
> apply(value_type (*)(value_type
)) const;
976 const _Clos _M_closure
;
979 template<class _Clos
, typename _Tp
>
981 _Expr
<_Clos
,_Tp
>::_Expr(const _Clos
& __c
) : _M_closure(__c
) {}
983 template<class _Clos
, typename _Tp
>
985 _Expr
<_Clos
,_Tp
>::operator()() const
986 { return _M_closure
; }
988 template<class _Clos
, typename _Tp
>
990 _Expr
<_Clos
,_Tp
>::operator[](size_t __i
) const
991 { return _M_closure
[__i
]; }
993 template<class _Clos
, typename _Tp
>
995 _Expr
<_Clos
,_Tp
>::operator[](slice __s
) const
996 { return _M_closure
[__s
]; }
998 template<class _Clos
, typename _Tp
>
1000 _Expr
<_Clos
,_Tp
>::operator[](const gslice
& __gs
) const
1001 { return _M_closure
[__gs
]; }
1003 template<class _Clos
, typename _Tp
>
1004 inline valarray
<_Tp
>
1005 _Expr
<_Clos
,_Tp
>::operator[](const valarray
<bool>& __m
) const
1006 { return _M_closure
[__m
]; }
1008 template<class _Clos
, typename _Tp
>
1009 inline valarray
<_Tp
>
1010 _Expr
<_Clos
,_Tp
>::operator[](const valarray
<size_t>& __i
) const
1011 { return _M_closure
[__i
]; }
1013 template<class _Clos
, typename _Tp
>
1015 _Expr
<_Clos
,_Tp
>::size() const { return _M_closure
.size (); }
1017 template<class _Clos
, typename _Tp
>
1018 inline valarray
<_Tp
>
1019 _Expr
<_Clos
, _Tp
>::shift(int __n
) const
1020 { return valarray
<_Tp
>(_M_closure
).shift(__n
); }
1022 template<class _Clos
, typename _Tp
>
1023 inline valarray
<_Tp
>
1024 _Expr
<_Clos
, _Tp
>::cshift(int __n
) const
1025 { return valarray
<_Tp
>(_M_closure
).cshift(__n
); }
1027 template<class _Clos
, typename _Tp
>
1028 inline valarray
<_Tp
>
1029 _Expr
<_Clos
, _Tp
>::apply(_Tp
__f(const _Tp
&)) const
1030 { return valarray
<_Tp
>(_M_closure
).apply(__f
); }
1032 template<class _Clos
, typename _Tp
>
1033 inline valarray
<_Tp
>
1034 _Expr
<_Clos
, _Tp
>::apply(_Tp
__f(_Tp
)) const
1035 { return valarray
<_Tp
>(_M_closure
).apply(__f
); }
1037 // XXX: replace this with a more robust summation algorithm.
1038 template<class _Clos
, typename _Tp
>
1040 _Expr
<_Clos
,_Tp
>::sum() const
1042 size_t __n
= _M_closure
.size();
1047 _Tp __s
= _M_closure
[--__n
];
1049 __s
+= _M_closure
[--__n
];
1054 template<class _Clos
, typename _Tp
>
1056 _Expr
<_Clos
, _Tp
>::min() const
1057 { return __valarray_min(_M_closure
); }
1059 template<class _Clos
, typename _Tp
>
1061 _Expr
<_Clos
, _Tp
>::max() const
1062 { return __valarray_max(_M_closure
); }
1064 template<class _Dom
, typename _Tp
>
1065 inline _Expr
<_UnClos
<__logical_not
,_Expr
,_Dom
>, bool>
1066 _Expr
<_Dom
,_Tp
>::operator!() const
1068 typedef _UnClos
<__logical_not
,std::_Expr
,_Dom
> _Closure
;
1069 return _Expr
<_Closure
,_Tp
>(_Closure(this->_M_closure
));
1072 #define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \
1073 template<class _Dom, typename _Tp> \
1074 inline _Expr<_UnClos<_Name,std::_Expr,_Dom>,_Tp> \
1075 _Expr<_Dom,_Tp>::operator _Op() const \
1077 typedef _UnClos<_Name,std::_Expr,_Dom> _Closure; \
1078 return _Expr<_Closure,_Tp>(_Closure(this->_M_closure)); \
1081 _DEFINE_EXPR_UNARY_OPERATOR(+, __unary_plus
)
1082 _DEFINE_EXPR_UNARY_OPERATOR(-, __negate
)
1083 _DEFINE_EXPR_UNARY_OPERATOR(~, __bitwise_not
)
1085 #undef _DEFINE_EXPR_UNARY_OPERATOR
1088 #define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \
1089 template<class _Dom1, class _Dom2> \
1090 inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, \
1091 typename _Name<typename _Dom1::value_type>::result_type> \
1092 operator _Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v, \
1093 const _Expr<_Dom2,typename _Dom2::value_type>& __w) \
1095 typedef typename _Dom1::value_type _Arg; \
1096 typedef typename _Name<_Arg>::result_type _Value; \
1097 typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \
1098 return _Expr<_Closure,_Value> (_Closure (__v (), __w ())); \
1101 template<class _Dom> \
1102 inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \
1103 typename _Name<typename _Dom::value_type>::result_type> \
1104 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __v, \
1105 const typename _Dom::value_type& __t) \
1107 typedef typename _Dom::value_type _Arg; \
1108 typedef typename _Name<_Arg>::result_type _Value; \
1109 typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \
1110 return _Expr<_Closure,_Value> (_Closure (__v (), __t)); \
1113 template<class _Dom> \
1114 inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \
1115 typename _Name<typename _Dom::value_type>::result_type> \
1116 operator _Op (const typename _Dom::value_type& __t, \
1117 const _Expr<_Dom,typename _Dom::value_type>& __v) \
1119 typedef typename _Dom::value_type _Arg; \
1120 typedef typename _Name<_Arg>::result_type _Value; \
1121 typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \
1122 return _Expr<_Closure,_Value> (_Closure (__t, __v ())); \
1125 template<class _Dom> \
1126 inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
1127 typename _Name<typename _Dom::value_type>::result_type> \
1128 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __e, \
1129 const valarray<typename _Dom::value_type>& __v) \
1131 typedef typename _Dom::value_type _Arg; \
1132 typedef typename _Name<_Arg>::result_type _Value; \
1133 typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Arg> _Closure; \
1134 return _Expr<_Closure,_Value> (_Closure (__e (), __v)); \
1137 template<class _Dom> \
1138 inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
1139 typename _Name<typename _Dom::value_type>::result_type> \
1140 operator _Op (const valarray<typename _Dom::value_type>& __v, \
1141 const _Expr<_Dom,typename _Dom::value_type>& __e) \
1143 typedef typename _Dom::value_type _Tp; \
1144 typedef typename _Name<_Tp>::result_type _Value; \
1145 typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \
1146 return _Expr<_Closure,_Value> (_Closure (__v, __e ())); \
1149 _DEFINE_EXPR_BINARY_OPERATOR(+, plus
)
1150 _DEFINE_EXPR_BINARY_OPERATOR(-, minus
)
1151 _DEFINE_EXPR_BINARY_OPERATOR(*, multiplies
)
1152 _DEFINE_EXPR_BINARY_OPERATOR(/, divides
)
1153 _DEFINE_EXPR_BINARY_OPERATOR(%, modulus
)
1154 _DEFINE_EXPR_BINARY_OPERATOR(^, _Bitwise_xor
)
1155 _DEFINE_EXPR_BINARY_OPERATOR(&, _Bitwise_and
)
1156 _DEFINE_EXPR_BINARY_OPERATOR(|, _Bitwise_or
)
1157 _DEFINE_EXPR_BINARY_OPERATOR(<<, _Shift_left
)
1158 _DEFINE_EXPR_BINARY_OPERATOR(>>, _Shift_right
)
1160 #undef _DEFINE_EXPR_BINARY_OPERATOR
1162 #define _DEFINE_EXPR_RELATIONAL_OPERATOR(_Op, _Name) \
1163 template<class _Dom1, class _Dom2> \
1164 inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, bool> \
1165 operator _Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v, \
1166 const _Expr<_Dom2,typename _Dom2::value_type>& __w) \
1168 typedef typename _Dom1::value_type _Arg; \
1169 typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \
1170 return _Expr<_Closure,bool> (_Closure (__v (), __w ())); \
1173 template<class _Dom> \
1174 inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \
1176 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __v, \
1177 const typename _Dom::value_type& __t) \
1179 typedef typename _Dom::value_type _Arg; \
1180 typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \
1181 return _Expr<_Closure,bool> (_Closure (__v (), __t)); \
1184 template<class _Dom> \
1185 inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \
1187 operator _Op (const typename _Dom::value_type& __t, \
1188 const _Expr<_Dom,typename _Dom::value_type>& __v) \
1190 typedef typename _Dom::value_type _Arg; \
1191 typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \
1192 return _Expr<_Closure,bool> (_Closure (__t, __v ())); \
1195 template<class _Dom> \
1196 inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
1198 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __e, \
1199 const valarray<typename _Dom::value_type>& __v) \
1201 typedef typename _Dom::value_type _Tp; \
1202 typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Tp> _Closure; \
1203 return _Expr<_Closure,bool> (_Closure (__e (), __v)); \
1206 template<class _Dom> \
1207 inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
1209 operator _Op (const valarray<typename _Dom::value_type>& __v, \
1210 const _Expr<_Dom,typename _Dom::value_type>& __e) \
1212 typedef typename _Dom::value_type _Tp; \
1213 typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \
1214 return _Expr<_Closure,bool> (_Closure (__v, __e ())); \
1217 _DEFINE_EXPR_RELATIONAL_OPERATOR(&&, logical_and
)
1218 _DEFINE_EXPR_RELATIONAL_OPERATOR(||, logical_or
)
1219 _DEFINE_EXPR_RELATIONAL_OPERATOR(==, equal_to
)
1220 _DEFINE_EXPR_RELATIONAL_OPERATOR(!=, not_equal_to
)
1221 _DEFINE_EXPR_RELATIONAL_OPERATOR(<, less
)
1222 _DEFINE_EXPR_RELATIONAL_OPERATOR(>, greater
)
1223 _DEFINE_EXPR_RELATIONAL_OPERATOR(<=, less_equal
)
1224 _DEFINE_EXPR_RELATIONAL_OPERATOR(>=, greater_equal
)
1226 #undef _DEFINE_EXPR_RELATIONAL_OPERATOR
1230 #define _DEFINE_EXPR_UNARY_FUNCTION(_Name) \
1231 template<class _Dom> \
1232 inline _Expr<_UnClos<__##_Name,_Expr,_Dom>,typename _Dom::value_type> \
1233 _Name(const _Expr<_Dom,typename _Dom::value_type>& __e) \
1235 typedef typename _Dom::value_type _Tp; \
1236 typedef _UnClos<__##_Name,_Expr,_Dom> _Closure; \
1237 return _Expr<_Closure,_Tp>(_Closure(__e())); \
1240 template<typename _Tp> \
1241 inline _Expr<_UnClos<__##_Name,_ValArray,_Tp>,_Tp> \
1242 _Name(const valarray<_Tp>& __v) \
1244 typedef _UnClos<__##_Name,_ValArray,_Tp> _Closure; \
1245 return _Expr<_Closure,_Tp>(_Closure (__v)); \
1249 _DEFINE_EXPR_UNARY_FUNCTION(abs
)
1250 _DEFINE_EXPR_UNARY_FUNCTION(cos
)
1251 _DEFINE_EXPR_UNARY_FUNCTION(acos
)
1252 _DEFINE_EXPR_UNARY_FUNCTION(cosh
)
1253 _DEFINE_EXPR_UNARY_FUNCTION(sin
)
1254 _DEFINE_EXPR_UNARY_FUNCTION(asin
)
1255 _DEFINE_EXPR_UNARY_FUNCTION(sinh
)
1256 _DEFINE_EXPR_UNARY_FUNCTION(tan
)
1257 _DEFINE_EXPR_UNARY_FUNCTION(tanh
)
1258 _DEFINE_EXPR_UNARY_FUNCTION(atan
)
1259 _DEFINE_EXPR_UNARY_FUNCTION(exp
)
1260 _DEFINE_EXPR_UNARY_FUNCTION(log
)
1261 _DEFINE_EXPR_UNARY_FUNCTION(log10
)
1262 _DEFINE_EXPR_UNARY_FUNCTION(sqrt
)
1264 #undef _DEFINE_EXPR_UNARY_FUNCTION
1267 #define _DEFINE_EXPR_BINARY_FUNCTION(_Name) \
1268 template<class _Dom1, class _Dom2> \
1269 inline _Expr<_BinFunClos<_Expr,_Expr,_Dom1,_Dom2>,typename _Dom1::value_type>\
1270 _Name (const _Expr<_Dom1,typename _Dom1::value_type>& __e1, \
1271 const _Expr<_Dom2,typename _Dom2::value_type>& __e2) \
1273 typedef typename _Dom1::value_type _Tp; \
1274 typedef _BinFunClos<_Expr,_Expr,_Dom1,_Dom2> _Closure; \
1275 return _Expr<_Closure,_Tp> \
1276 (_Closure (__e1 (), __e2 (), (_Tp(*)(_Tp, _Tp))(&_Name))); \
1279 template<class _Dom> \
1280 inline _Expr<_BinFunClos<_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
1281 typename _Dom::value_type> \
1282 _Name (const _Expr<_Dom,typename _Dom::value_type>& __e, \
1283 const valarray<typename _Dom::value_type>& __v) \
1285 typedef typename _Dom::value_type _Tp; \
1286 typedef _BinFunClos<_Expr,_ValArray,_Dom,_Tp> _Closure; \
1287 return _Expr<_Closure,_Tp> \
1288 (_Closure (__e (), __v, (_Tp(*)(_Tp, _Tp))(&_Name))); \
1291 template<class _Dom> \
1292 inline _Expr<_BinFunClos<_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
1293 typename _Dom::value_type> \
1294 _Name (const valarray<typename _Dom::valarray>& __v, \
1295 const _Expr<_Dom,typename _Dom::value_type>& __e) \
1297 typedef typename _Dom::value_type _Tp; \
1298 typedef _BinFunClos<_ValArray,_Expr,_Tp,_Dom> _Closure; \
1299 return _Expr<_Closure,_Tp> \
1300 (_Closure (__v, __e (), (_Tp(*)(_Tp, _Tp))(&_Name))); \
1303 template<class _Dom> \
1304 inline _Expr<_BinFunClos<_Expr,_Constant,_Dom,typename _Dom::value_type>, \
1305 typename _Dom::value_type> \
1306 _Name (const _Expr<_Dom, typename _Dom::value_type>& __e, \
1307 const typename _Dom::value_type& __t) \
1309 typedef typename _Dom::value_type _Tp; \
1310 typedef _BinFunClos<_Expr,_Constant,_Dom,_Tp> _Closure; \
1311 return _Expr<_Closure,_Tp> \
1312 (_Closure (__e (), __t, (_Tp(*)(_Tp, _Tp))(&_Name))); \
1315 template<class _Dom> \
1316 inline _Expr<_BinFunClos<_Constant,_Expr,typename _Dom::value_type,_Dom>, \
1317 typename _Dom::value_type> \
1318 _Name (const typename _Dom::value_type& __t, \
1319 const _Expr<_Dom,typename _Dom::value_type>& __e) \
1321 typedef typename _Dom::value_type _Tp; \
1322 typedef _BinFunClos<_Constant,_Expr,_Tp,_Dom> _Closure; \
1323 return _Expr<_Closure,_Tp> \
1324 (_Closure (__t, __e (), (_Tp(*)(_Tp, _Tp))(&_Name))); \
1327 template<typename _Tp> \
1328 inline _Expr<_BinFunClos<_ValArray,_ValArray,_Tp,_Tp>, _Tp> \
1329 _Name (const valarray<_Tp>& __v, const valarray<_Tp>& __w) \
1331 typedef _BinFunClos<_ValArray,_ValArray,_Tp,_Tp> _Closure; \
1332 return _Expr<_Closure,_Tp> \
1333 (_Closure (__v, __w, (_Tp(*)(_Tp,_Tp))(&_Name))); \
1336 template<typename _Tp> \
1337 inline _Expr<_BinFunClos<_ValArray,_Constant,_Tp,_Tp>,_Tp> \
1338 _Name (const valarray<_Tp>& __v, const _Tp& __t) \
1340 typedef _BinFunClos<_ValArray,_Constant,_Tp,_Tp> _Closure; \
1341 return _Expr<_Closure,_Tp> \
1342 (_Closure (__v, __t, (_Tp(*)(_Tp,_Tp))(&_Name))); \
1345 template<typename _Tp> \
1346 inline _Expr<_BinFunClos<_Constant,_ValArray,_Tp,_Tp>,_Tp> \
1347 _Name (const _Tp& __t, const valarray<_Tp>& __v) \
1349 typedef _BinFunClos<_Constant,_ValArray,_Tp,_Tp> _Closure; \
1350 return _Expr<_Closure,_Tp> \
1351 (_Closure (__t, __v, (_Tp(*)(_Tp,_Tp))(&_Name))); \
1354 _DEFINE_EXPR_BINARY_FUNCTION(atan2
)
1355 _DEFINE_EXPR_BINARY_FUNCTION(pow
)
1357 #undef _DEFINE_EXPR_BINARY_FUNCTION
1362 #endif /* _CPP_VALARRAY_META_H */