d5e758f6d9ab2287f454e0e6952558b2fd2d96fe
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
46 // Implementing a loosened valarray return value is tricky.
47 // First we need to meet 26.3.1/3: we should not add more than
48 // two levels of template nesting. Therefore we resort to template
49 // template to "flatten" loosened return value types.
50 // At some point we use partial specialization to remove one level
51 // template nesting due to _Expr<>
55 // This class is NOT defined. It doesn't need to.
56 template<typename _Tp1
, typename _Tp2
> class _Constant
;
59 // Unary function application closure.
61 template<class _Dom
, typename _Op
> class _UnFunBase
64 typedef typename
_Dom::value_type value_type
;
65 typedef value_type _Vt
;
67 explicit _UnFunBase (const _Dom
& __e
) : _M_expr(__e
) {}
69 _Vt
operator[] (size_t __i
) const { return _Op()(_M_expr
[__i
]); }
70 size_t size () const { return _M_expr
.size(); }
76 // Implementations of unary functions applied to valarray<>s.
77 // I use hard-coded object functions here instead of a generic
78 // approach like pointers to function:
79 // 1) correctness: some functions take references, others values.
80 // we can't deduce the correct type afterwards.
81 // 2) efficiency -- object functions can be easily inlined
82 // 3) be Koenig-lookup-friendly
86 template<typename _Tp
>
87 _Tp
operator()(const _Tp
& __t
) const { return abs(__t
); }
92 template<typename _Tp
>
93 _Tp
operator()(const _Tp
& __t
) const { return cos(__t
); }
98 template<typename _Tp
>
99 _Tp
operator()(const _Tp
& __t
) const { return acos(__t
); }
104 template<typename _Tp
>
105 _Tp
operator()(const _Tp
& __t
) const { return cosh(__t
); }
110 template<typename _Tp
>
111 _Tp
operator()(const _Tp
& __t
) const { return sin(__t
); }
116 template<typename _Tp
>
117 _Tp
operator()(const _Tp
& __t
) const { return asin(__t
); }
122 template<typename _Tp
>
123 _Tp
operator()(const _Tp
& __t
) const { return sinh(__t
); }
128 template<typename _Tp
>
129 _Tp
operator()(const _Tp
& __t
) const { return tan(__t
); }
134 template<typename _Tp
>
135 _Tp
operator()(const _Tp
& __t
) const { return atan(__t
); }
140 template<typename _Tp
>
141 _Tp
operator()(const _Tp
& __t
) const { return tanh(__t
); }
146 template<typename _Tp
>
147 _Tp
operator()(const _Tp
& __t
) const { return exp(__t
); }
152 template<typename _Tp
>
153 _Tp
operator()(const _Tp
& __t
) const { return log(__t
); }
158 template<typename _Tp
>
159 _Tp
operator()(const _Tp
& __t
) const { return log10(__t
); }
164 template<typename _Tp
>
165 _Tp
operator()(const _Tp
& __t
) const { return sqrt(__t
); }
168 // In the past, we used to tailor operator applications semantics
169 // to the specialization of standard function objects (i.e. plus<>, etc.)
170 // That is incorrect. Therefore we provide our own surrogates.
174 template<typename _Tp
>
175 _Tp
operator()(const _Tp
& __t
) const { return +__t
; }
180 template<typename _Tp
>
181 _Tp
operator()(const _Tp
& __t
) const { return -__t
; }
186 template<typename _Tp
>
187 _Tp
operator()(const _Tp
& __t
) const { return ~__t
; }
192 template<typename _Tp
>
193 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
194 { return __x
+ __y
; }
199 template<typename _Tp
>
200 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
201 { return __x
- __y
; }
206 template<typename _Tp
>
207 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
208 { return __x
* __y
; }
213 template<typename _Tp
>
214 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
215 { return __x
/ __y
; }
220 template<typename _Tp
>
221 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
222 { return __x
% __y
; }
227 template<typename _Tp
>
228 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
229 { return __x
^ __y
; }
234 template<typename _Tp
>
235 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
236 { return __x
& __y
; }
241 template<typename _Tp
>
242 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
243 { return __x
| __y
; }
248 template<typename _Tp
>
249 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
250 { return __x
<< __y
; }
255 template<typename _Tp
>
256 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
257 { return __x
>> __y
; }
262 template<typename _Tp
>
263 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
264 { return __x
&& __y
; }
269 template<typename _Tp
>
270 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
271 { return __x
|| __y
; }
276 template<typename _Tp
>
277 bool operator()(const _Tp
& __x
) const { return !__x
; }
282 template<typename _Tp
>
283 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
284 { return __x
== __y
; }
287 struct __not_equal_to
289 template<typename _Tp
>
290 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
291 { return __x
== __y
; }
296 template<typename _Tp
>
297 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
298 { return __x
< __y
; }
303 template<typename _Tp
>
304 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
305 { return __x
> __y
; }
310 template<typename _Tp
>
311 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
312 { return __x
<= __y
; }
315 struct __greater_equal
317 template<typename _Tp
>
318 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
319 { return __x
>= __y
; }
322 // The few binary functions we miss.
325 template<typename _Tp
>
326 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
327 { return atan2(__x
, __y
); }
332 template<typename _Tp
>
333 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
334 { return pow(__x
, __y
); }
338 // We need these bits in order to recover the return type of
339 // some functions/operators now that we're no longer using
340 // function templates.
341 template<typename
, typename _Tp
>
344 typedef _Tp result_type
;
347 // several specializations for relational operators.
348 template<typename _Tp
>
349 struct __fun
<__logical_not
, _Tp
>
351 typedef bool result_type
;
354 template<typename _Tp
>
355 struct __fun
<__logical_and
, _Tp
>
357 typedef bool result_type
;
360 template<typename _Tp
>
361 struct __fun
<__logical_or
, _Tp
>
363 typedef bool result_type
;
366 template<typename _Tp
>
367 struct __fun
<__less
, _Tp
>
369 typedef bool result_type
;
372 template<typename _Tp
>
373 struct __fun
<__greater
, _Tp
>
375 typedef bool result_type
;
378 template<typename _Tp
>
379 struct __fun
<__less_equal
, _Tp
>
381 typedef bool result_type
;
384 template<typename _Tp
>
385 struct __fun
<__greater_equal
, _Tp
>
387 typedef bool result_type
;
390 template<typename _Tp
>
391 struct __fun
<__equal_to
, _Tp
>
393 typedef bool result_type
;
396 template<typename _Tp
>
397 struct __fun
<__not_equal_to
, _Tp
>
399 typedef bool result_type
;
402 template<template<class, class> class _Meta
, class _Dom
, typename _Op
>
405 template<class _Dom
, typename _Op
>
406 struct _UnFunClos
<_Expr
,_Dom
, _Op
> : _UnFunBase
<_Dom
, _Op
>
408 typedef _UnFunBase
<_Dom
, _Op
> _Base
;
409 typedef typename
_Base::value_type value_type
;
411 explicit _UnFunClos (const _Dom
& __e
) : _Base (__e
) {}
414 template<typename _Tp
, typename _Op
>
415 struct _UnFunClos
<_ValArray
,_Tp
, _Op
> : _UnFunBase
<valarray
<_Tp
>, _Op
>
417 typedef _UnFunBase
<valarray
<_Tp
>, _Op
> _Base
;
418 typedef typename
_Base::value_type value_type
;
420 explicit _UnFunClos (const valarray
<_Tp
>& __v
) : _Base (__v
) {}
424 // Binary function application closure.
426 template<template<class, class> class _Meta1
,
427 template<class, class> class Meta2
,
428 class _Dom1
, class _Dom2
> class _BinFunClos
;
430 template<class _Dom1
, class _Dom2
> class _BinFunBase
{
432 typedef typename
_Dom1::value_type value_type
;
433 typedef value_type _Vt
;
435 _BinFunBase (const _Dom1
& __e1
, const _Dom2
& __e2
,
437 : _M_expr1 (__e1
), _M_expr2 (__e2
), _M_func (__f
) {}
439 value_type
operator[] (size_t __i
) const
440 { return _M_func (_M_expr1
[__i
], _M_expr2
[__i
]); }
441 size_t size () const { return _M_expr1
.size (); }
444 const _Dom1
& _M_expr1
;
445 const _Dom2
& _M_expr2
;
446 _Vt (*_M_func
)(_Vt
, _Vt
);
449 template<class _Dom
> class _BinFunBase1
{
451 typedef typename
_Dom::value_type value_type
;
452 typedef value_type _Vt
;
454 _BinFunBase1 (const _Vt
& __c
, const _Dom
& __e
, _Vt
__f(_Vt
, _Vt
))
455 : _M_expr1 (__c
), _M_expr2 (__e
), _M_func (__f
) {}
457 value_type
operator[] (size_t __i
) const
458 { return _M_func (_M_expr1
, _M_expr2
[__i
]); }
459 size_t size () const { return _M_expr2
.size (); }
463 const _Dom
& _M_expr2
;
464 _Vt (*_M_func
)(_Vt
, _Vt
);
467 template<class _Dom
> class _BinFunBase2
{
469 typedef typename
_Dom::value_type value_type
;
470 typedef value_type _Vt
;
472 _BinFunBase2 (const _Dom
& __e
, const _Vt
& __c
, _Vt
__f(_Vt
, _Vt
))
473 : _M_expr1 (__e
), _M_expr2 (__c
), _M_func (__f
) {}
475 value_type
operator[] (size_t __i
) const
476 { return _M_func (_M_expr1
[__i
], _M_expr2
); }
477 size_t size () const { return _M_expr1
.size (); }
480 const _Dom
& _M_expr1
;
482 _Vt (*_M_func
)(_Vt
, _Vt
);
485 template<class _Dom1
, class _Dom2
>
486 struct _BinFunClos
<_Expr
,_Expr
,_Dom1
,_Dom2
> : _BinFunBase
<_Dom1
,_Dom2
> {
487 typedef _BinFunBase
<_Dom1
,_Dom2
> _Base
;
488 typedef typename
_Base::value_type value_type
;
489 typedef value_type _Tp
;
491 _BinFunClos (const _Dom1
& __e1
, const _Dom2
& __e2
,
493 : _Base (__e1
, __e2
, __f
) {}
496 template<typename _Tp
>
497 struct _BinFunClos
<_ValArray
,_ValArray
,_Tp
,_Tp
>
498 : _BinFunBase
<valarray
<_Tp
>, valarray
<_Tp
> > {
499 typedef _BinFunBase
<valarray
<_Tp
>, valarray
<_Tp
> > _Base
;
500 typedef _Tp value_type
;
502 _BinFunClos (const valarray
<_Tp
>& __v
, const valarray
<_Tp
>& __w
,
504 : _Base (__v
, __w
, __f
) {}
508 struct _BinFunClos
<_Expr
,_ValArray
,_Dom
,typename
_Dom::value_type
>
509 : _BinFunBase
<_Dom
,valarray
<typename
_Dom::value_type
> > {
510 typedef typename
_Dom::value_type _Tp
;
511 typedef _BinFunBase
<_Dom
,valarray
<_Tp
> > _Base
;
512 typedef _Tp value_type
;
514 _BinFunClos (const _Dom
& __e
, const valarray
<_Tp
>& __v
,
516 : _Base (__e
, __v
, __f
) {}
520 struct _BinFunClos
<_ValArray
,_Expr
,typename
_Dom::value_type
,_Dom
>
521 : _BinFunBase
<valarray
<typename
_Dom::value_type
>,_Dom
> {
522 typedef typename
_Dom::value_type _Tp
;
523 typedef _BinFunBase
<_Dom
,valarray
<_Tp
> > _Base
;
524 typedef _Tp value_type
;
526 _BinFunClos (const valarray
<_Tp
>& __v
, const _Dom
& __e
,
528 : _Base (__v
, __e
, __f
) {}
532 struct _BinFunClos
<_Expr
,_Constant
,_Dom
,typename
_Dom::value_type
>
533 : _BinFunBase2
<_Dom
> {
534 typedef typename
_Dom::value_type _Tp
;
535 typedef _Tp value_type
;
536 typedef _BinFunBase2
<_Dom
> _Base
;
538 _BinFunClos (const _Dom
& __e
, const _Tp
& __t
, _Tp
__f (_Tp
, _Tp
))
539 : _Base (__e
, __t
, __f
) {}
543 struct _BinFunClos
<_Constant
,_Expr
,_Dom
,typename
_Dom::value_type
>
544 : _BinFunBase1
<_Dom
> {
545 typedef typename
_Dom::value_type _Tp
;
546 typedef _Tp value_type
;
547 typedef _BinFunBase1
<_Dom
> _Base
;
549 _BinFunClos (const _Tp
& __t
, const _Dom
& __e
, _Tp
__f (_Tp
, _Tp
))
550 : _Base (__t
, __e
, __f
) {}
553 template<typename _Tp
>
554 struct _BinFunClos
<_ValArray
,_Constant
,_Tp
,_Tp
>
555 : _BinFunBase2
<valarray
<_Tp
> > {
556 typedef _BinFunBase2
<valarray
<_Tp
> > _Base
;
557 typedef _Tp value_type
;
559 _BinFunClos (const valarray
<_Tp
>& __v
, const _Tp
& __t
,
561 : _Base (__v
, __t
, __f
) {}
564 template<typename _Tp
>
565 struct _BinFunClos
<_Constant
,_ValArray
,_Tp
,_Tp
>
566 : _BinFunBase1
<valarray
<_Tp
> > {
567 typedef _BinFunBase1
<valarray
<_Tp
> > _Base
;
568 typedef _Tp value_type
;
570 _BinFunClos (const _Tp
& __t
, const valarray
<_Tp
>& __v
,
572 : _Base (__t
, __v
, __f
) {}
576 // Apply function taking a value/const reference closure
579 template<typename _Dom
, typename _Arg
> class _FunBase
{
581 typedef typename
_Dom::value_type value_type
;
583 _FunBase (const _Dom
& __e
, value_type
__f(_Arg
))
584 : _M_expr (__e
), _M_func (__f
) {}
586 value_type
operator[] (size_t __i
) const
587 { return _M_func (_M_expr
[__i
]); }
588 size_t size() const { return _M_expr
.size ();}
592 value_type (*_M_func
)(_Arg
);
596 struct _ValFunClos
<_Expr
,_Dom
>
597 : _FunBase
<_Dom
, typename
_Dom::value_type
> {
598 typedef _FunBase
<_Dom
, typename
_Dom::value_type
> _Base
;
599 typedef typename
_Base::value_type value_type
;
600 typedef value_type _Tp
;
602 _ValFunClos (const _Dom
& __e
, _Tp
__f (_Tp
)) : _Base (__e
, __f
) {}
605 template<typename _Tp
>
606 struct _ValFunClos
<_ValArray
,_Tp
>
607 : _FunBase
<valarray
<_Tp
>, _Tp
> {
608 typedef _FunBase
<valarray
<_Tp
>, _Tp
> _Base
;
609 typedef _Tp value_type
;
611 _ValFunClos (const valarray
<_Tp
>& __v
, _Tp
__f(_Tp
))
612 : _Base (__v
, __f
) {}
616 struct _RefFunClos
<_Expr
,_Dom
> :
617 _FunBase
<_Dom
, const typename
_Dom::value_type
&> {
618 typedef _FunBase
<_Dom
, const typename
_Dom::value_type
&> _Base
;
619 typedef typename
_Base::value_type value_type
;
620 typedef value_type _Tp
;
622 _RefFunClos (const _Dom
& __e
, _Tp
__f (const _Tp
&))
623 : _Base (__e
, __f
) {}
626 template<typename _Tp
>
627 struct _RefFunClos
<_ValArray
,_Tp
>
628 : _FunBase
<valarray
<_Tp
>, const _Tp
&> {
629 typedef _FunBase
<valarray
<_Tp
>, const _Tp
&> _Base
;
630 typedef _Tp value_type
;
632 _RefFunClos (const valarray
<_Tp
>& __v
, _Tp
__f(const _Tp
&))
633 : _Base (__v
, __f
) {}
637 // Unary expression closure.
640 template<template<class> class _Oper
, typename _Arg
>
643 typedef _Oper
<typename
_Arg::value_type
> _Op
;
644 typedef typename
_Op::result_type value_type
;
646 _UnBase (const _Arg
& __e
) : _M_expr(__e
) {}
647 value_type
operator[] (size_t) const;
648 size_t size () const { return _M_expr
.size (); }
654 template<template<class> class _Oper
, typename _Arg
>
655 inline typename _UnBase
<_Oper
, _Arg
>::value_type
656 _UnBase
<_Oper
, _Arg
>::operator[] (size_t __i
) const
657 { return _Op() (_M_expr
[__i
]); }
659 template<template<class> class _Oper
, class _Dom
>
660 struct _UnClos
<_Oper
, _Expr
, _Dom
> : _UnBase
<_Oper
, _Dom
> {
662 typedef _UnBase
<_Oper
, _Dom
> _Base
;
663 typedef typename
_Base::value_type value_type
;
665 _UnClos (const _Arg
& __e
) : _Base(__e
) {}
668 template<template<class> class _Oper
, typename _Tp
>
669 struct _UnClos
<_Oper
, _ValArray
, _Tp
> : _UnBase
<_Oper
, valarray
<_Tp
> > {
670 typedef valarray
<_Tp
> _Arg
;
671 typedef _UnBase
<_Oper
, valarray
<_Tp
> > _Base
;
672 typedef typename
_Base::value_type value_type
;
674 _UnClos (const _Arg
& __e
) : _Base(__e
) {}
679 // Binary expression closure.
682 template<template<class> class _Oper
,
683 typename _FirstArg
, typename _SecondArg
>
686 typedef _Oper
<typename
_FirstArg::value_type
> _Op
;
687 typedef typename
_Op::result_type value_type
;
689 _BinBase (const _FirstArg
& __e1
, const _SecondArg
& __e2
)
690 : _M_expr1 (__e1
), _M_expr2 (__e2
) {}
691 value_type
operator[] (size_t) const;
692 size_t size () const { return _M_expr1
.size (); }
695 const _FirstArg
& _M_expr1
;
696 const _SecondArg
& _M_expr2
;
699 template<template<class> class _Oper
,
700 typename _FirstArg
, typename _SecondArg
>
701 inline typename _BinBase
<_Oper
,_FirstArg
,_SecondArg
>::value_type
702 _BinBase
<_Oper
,_FirstArg
,_SecondArg
>::operator[] (size_t __i
) const
703 { return _Op() (_M_expr1
[__i
], _M_expr2
[__i
]); }
706 template<template<class> class _Oper
, class _Clos
>
709 typedef typename
_Clos::value_type _Vt
;
710 typedef _Oper
<_Vt
> _Op
;
711 typedef typename
_Op::result_type value_type
;
713 _BinBase2 (const _Clos
& __e
, const _Vt
& __t
)
714 : _M_expr1 (__e
), _M_expr2 (__t
) {}
715 value_type
operator[] (size_t) const;
716 size_t size () const { return _M_expr1
.size (); }
719 const _Clos
& _M_expr1
;
723 template<template<class> class _Oper
, class _Clos
>
724 inline typename _BinBase2
<_Oper
,_Clos
>::value_type
725 _BinBase2
<_Oper
,_Clos
>::operator[] (size_t __i
) const
726 { return _Op() (_M_expr1
[__i
], _M_expr2
); }
729 template<template<class> class _Oper
, class _Clos
>
732 typedef typename
_Clos::value_type _Vt
;
733 typedef _Oper
<_Vt
> _Op
;
734 typedef typename
_Op::result_type value_type
;
736 _BinBase1 (const _Vt
& __t
, const _Clos
& __e
)
737 : _M_expr1 (__t
), _M_expr2 (__e
) {}
738 value_type
operator[] (size_t) const;
739 size_t size () const { return _M_expr2
.size (); }
743 const _Clos
& _M_expr2
;
746 template<template<class> class _Oper
, class _Clos
>
748 _BinBase1
<_Oper
,_Clos
>::value_type
749 _BinBase1
<_Oper
,_Clos
>:: operator[] (size_t __i
) const
750 { return _Op() (_M_expr1
, _M_expr2
[__i
]); }
753 template<template<class> class _Oper
, class _Dom1
, class _Dom2
>
754 struct _BinClos
<_Oper
, _Expr
, _Expr
, _Dom1
, _Dom2
>
755 : _BinBase
<_Oper
,_Dom1
,_Dom2
> {
756 typedef _BinBase
<_Oper
,_Dom1
,_Dom2
> _Base
;
757 typedef typename
_Base::value_type value_type
;
759 _BinClos(const _Dom1
& __e1
, const _Dom2
& __e2
) : _Base(__e1
, __e2
) {}
762 template<template<class> class _Oper
, typename _Tp
>
763 struct _BinClos
<_Oper
,_ValArray
,_ValArray
,_Tp
,_Tp
>
764 : _BinBase
<_Oper
,valarray
<_Tp
>,valarray
<_Tp
> > {
765 typedef _BinBase
<_Oper
,valarray
<_Tp
>,valarray
<_Tp
> > _Base
;
766 typedef _Tp value_type
;
768 _BinClos (const valarray
<_Tp
>& __v
, const valarray
<_Tp
>& __w
)
769 : _Base (__v
, __w
) {}
772 template<template<class> class _Oper
, class _Dom
>
773 struct _BinClos
<_Oper
,_Expr
,_ValArray
,_Dom
,typename
_Dom::value_type
>
774 : _BinBase
<_Oper
,_Dom
,valarray
<typename
_Dom::value_type
> > {
775 typedef typename
_Dom::value_type _Tp
;
776 typedef _BinBase
<_Oper
,_Dom
,valarray
<_Tp
> > _Base
;
777 typedef typename
_Base::value_type value_type
;
779 _BinClos(const _Dom
& __e1
, const valarray
<_Tp
>& __e2
)
780 : _Base (__e1
, __e2
) {}
783 template<template<class> class _Oper
, class _Dom
>
784 struct _BinClos
<_Oper
,_ValArray
,_Expr
,typename
_Dom::value_type
,_Dom
>
785 : _BinBase
<_Oper
,valarray
<typename
_Dom::value_type
>,_Dom
> {
786 typedef typename
_Dom::value_type _Tp
;
787 typedef _BinBase
<_Oper
,valarray
<_Tp
>,_Dom
> _Base
;
788 typedef typename
_Base::value_type value_type
;
790 _BinClos (const valarray
<_Tp
>& __e1
, const _Dom
& __e2
)
791 : _Base (__e1
, __e2
) {}
794 template<template<class> class _Oper
, class _Dom
>
795 struct _BinClos
<_Oper
,_Expr
,_Constant
,_Dom
,typename
_Dom::value_type
>
796 : _BinBase2
<_Oper
,_Dom
> {
797 typedef typename
_Dom::value_type _Tp
;
798 typedef _BinBase2
<_Oper
,_Dom
> _Base
;
799 typedef typename
_Base::value_type value_type
;
801 _BinClos (const _Dom
& __e1
, const _Tp
& __e2
) : _Base (__e1
, __e2
) {}
804 template<template<class> class _Oper
, class _Dom
>
805 struct _BinClos
<_Oper
,_Constant
,_Expr
,typename
_Dom::value_type
,_Dom
>
806 : _BinBase1
<_Oper
,_Dom
> {
807 typedef typename
_Dom::value_type _Tp
;
808 typedef _BinBase1
<_Oper
,_Dom
> _Base
;
809 typedef typename
_Base::value_type value_type
;
811 _BinClos (const _Tp
& __e1
, const _Dom
& __e2
) : _Base (__e1
, __e2
) {}
814 template<template<class> class _Oper
, typename _Tp
>
815 struct _BinClos
<_Oper
,_ValArray
,_Constant
,_Tp
,_Tp
>
816 : _BinBase2
<_Oper
,valarray
<_Tp
> > {
817 typedef _BinBase2
<_Oper
,valarray
<_Tp
> > _Base
;
818 typedef typename
_Base::value_type value_type
;
820 _BinClos (const valarray
<_Tp
>& __v
, const _Tp
& __t
)
821 : _Base (__v
, __t
) {}
824 template<template<class> class _Oper
, typename _Tp
>
825 struct _BinClos
<_Oper
,_Constant
,_ValArray
,_Tp
,_Tp
>
826 : _BinBase1
<_Oper
,valarray
<_Tp
> > {
827 typedef _BinBase1
<_Oper
,valarray
<_Tp
> > _Base
;
828 typedef typename
_Base::value_type value_type
;
830 _BinClos (const _Tp
& __t
, const valarray
<_Tp
>& __v
)
831 : _Base (__t
, __v
) {}
836 // slice_array closure.
838 template<typename _Dom
> class _SBase
{
840 typedef typename
_Dom::value_type value_type
;
842 _SBase (const _Dom
& __e
, const slice
& __s
)
843 : _M_expr (__e
), _M_slice (__s
) {}
844 value_type
operator[] (size_t __i
) const
845 { return _M_expr
[_M_slice
.start () + __i
* _M_slice
.stride ()]; }
846 size_t size() const { return _M_slice
.size (); }
850 const slice
& _M_slice
;
853 template<typename _Tp
> class _SBase
<_Array
<_Tp
> > {
855 typedef _Tp value_type
;
857 _SBase (_Array
<_Tp
> __a
, const slice
& __s
)
858 : _M_array (__a
._M_data
+__s
.start()), _M_size (__s
.size()),
859 _M_stride (__s
.stride()) {}
860 value_type
operator[] (size_t __i
) const
861 { return _M_array
._M_data
[__i
* _M_stride
]; }
862 size_t size() const { return _M_size
; }
865 const _Array
<_Tp
> _M_array
;
866 const size_t _M_size
;
867 const size_t _M_stride
;
870 template<class _Dom
> struct _SClos
<_Expr
,_Dom
> : _SBase
<_Dom
> {
871 typedef _SBase
<_Dom
> _Base
;
872 typedef typename
_Base::value_type value_type
;
874 _SClos (const _Dom
& __e
, const slice
& __s
) : _Base (__e
, __s
) {}
877 template<typename _Tp
>
878 struct _SClos
<_ValArray
,_Tp
> : _SBase
<_Array
<_Tp
> > {
879 typedef _SBase
<_Array
<_Tp
> > _Base
;
880 typedef _Tp value_type
;
882 _SClos (_Array
<_Tp
> __a
, const slice
& __s
) : _Base (__a
, __s
) {}
886 // gslice_array closure.
888 template<class _Dom
> class _GBase
{
890 typedef typename
_Dom::value_type value_type
;
892 _GBase (const _Dom
& __e
, const valarray
<size_t>& __i
)
893 : _M_expr (__e
), _M_index(__i
) {}
894 value_type
operator[] (size_t __i
) const
895 { return _M_expr
[_M_index
[__i
]]; }
896 size_t size () const { return _M_index
.size(); }
900 const valarray
<size_t>& _M_index
;
903 template<typename _Tp
> class _GBase
<_Array
<_Tp
> > {
905 typedef _Tp value_type
;
907 _GBase (_Array
<_Tp
> __a
, const valarray
<size_t>& __i
)
908 : _M_array (__a
), _M_index(__i
) {}
909 value_type
operator[] (size_t __i
) const
910 { return _M_array
._M_data
[_M_index
[__i
]]; }
911 size_t size () const { return _M_index
.size(); }
914 const _Array
<_Tp
> _M_array
;
915 const valarray
<size_t>& _M_index
;
918 template<class _Dom
> struct _GClos
<_Expr
,_Dom
> : _GBase
<_Dom
> {
919 typedef _GBase
<_Dom
> _Base
;
920 typedef typename
_Base::value_type value_type
;
922 _GClos (const _Dom
& __e
, const valarray
<size_t>& __i
)
923 : _Base (__e
, __i
) {}
926 template<typename _Tp
>
927 struct _GClos
<_ValArray
,_Tp
> : _GBase
<_Array
<_Tp
> > {
928 typedef _GBase
<_Array
<_Tp
> > _Base
;
929 typedef typename
_Base::value_type value_type
;
931 _GClos (_Array
<_Tp
> __a
, const valarray
<size_t>& __i
)
932 : _Base (__a
, __i
) {}
936 // indirect_array closure
939 template<class _Dom
> class _IBase
{
941 typedef typename
_Dom::value_type value_type
;
943 _IBase (const _Dom
& __e
, const valarray
<size_t>& __i
)
944 : _M_expr (__e
), _M_index (__i
) {}
945 value_type
operator[] (size_t __i
) const
946 { return _M_expr
[_M_index
[__i
]]; }
947 size_t size() const { return _M_index
.size(); }
951 const valarray
<size_t>& _M_index
;
954 template<class _Dom
> struct _IClos
<_Expr
,_Dom
> : _IBase
<_Dom
> {
955 typedef _IBase
<_Dom
> _Base
;
956 typedef typename
_Base::value_type value_type
;
958 _IClos (const _Dom
& __e
, const valarray
<size_t>& __i
)
959 : _Base (__e
, __i
) {}
962 template<typename _Tp
>
963 struct _IClos
<_ValArray
,_Tp
> : _IBase
<valarray
<_Tp
> > {
964 typedef _IBase
<valarray
<_Tp
> > _Base
;
965 typedef _Tp value_type
;
967 _IClos (const valarray
<_Tp
>& __a
, const valarray
<size_t>& __i
)
968 : _Base (__a
, __i
) {}
974 template<class _Clos
, typename _Tp
> class _Expr
{
976 typedef _Tp value_type
;
978 _Expr (const _Clos
&);
980 const _Clos
& operator() () const;
982 value_type
operator[] (size_t) const;
983 valarray
<value_type
> operator[] (slice
) const;
984 valarray
<value_type
> operator[] (const gslice
&) const;
985 valarray
<value_type
> operator[] (const valarray
<bool>&) const;
986 valarray
<value_type
> operator[] (const valarray
<size_t>&) const;
988 _Expr
<_UnClos
<_Unary_plus
,std::_Expr
,_Clos
>, value_type
>
991 _Expr
<_UnClos
<negate
,std::_Expr
,_Clos
>, value_type
>
994 _Expr
<_UnClos
<_Bitwise_not
,std::_Expr
,_Clos
>, value_type
>
997 _Expr
<_UnClos
<logical_not
,std::_Expr
,_Clos
>, bool>
1000 size_t size () const;
1001 value_type
sum () const;
1003 valarray
<value_type
> shift (int) const;
1004 valarray
<value_type
> cshift (int) const;
1006 value_type
min() const;
1007 value_type
max() const;
1009 valarray
<value_type
> apply(value_type (*) (const value_type
&)) const;
1010 valarray
<value_type
> apply(value_type (*) (value_type
)) const;
1013 const _Clos _M_closure
;
1016 template<class _Clos
, typename _Tp
>
1018 _Expr
<_Clos
,_Tp
>::_Expr (const _Clos
& __c
) : _M_closure(__c
) {}
1020 template<class _Clos
, typename _Tp
>
1022 _Expr
<_Clos
,_Tp
>::operator() () const
1023 { return _M_closure
; }
1025 template<class _Clos
, typename _Tp
>
1027 _Expr
<_Clos
,_Tp
>::operator[] (size_t __i
) const
1028 { return _M_closure
[__i
]; }
1030 template<class _Clos
, typename _Tp
>
1031 inline valarray
<_Tp
>
1032 _Expr
<_Clos
,_Tp
>::operator[] (slice __s
) const
1033 { return _M_closure
[__s
]; }
1035 template<class _Clos
, typename _Tp
>
1036 inline valarray
<_Tp
>
1037 _Expr
<_Clos
,_Tp
>::operator[] (const gslice
& __gs
) const
1038 { return _M_closure
[__gs
]; }
1040 template<class _Clos
, typename _Tp
>
1041 inline valarray
<_Tp
>
1042 _Expr
<_Clos
,_Tp
>::operator[] (const valarray
<bool>& __m
) const
1043 { return _M_closure
[__m
]; }
1045 template<class _Clos
, typename _Tp
>
1046 inline valarray
<_Tp
>
1047 _Expr
<_Clos
,_Tp
>::operator[] (const valarray
<size_t>& __i
) const
1048 { return _M_closure
[__i
]; }
1050 template<class _Clos
, typename _Tp
>
1052 _Expr
<_Clos
,_Tp
>::size () const { return _M_closure
.size (); }
1054 template<class _Clos
, typename _Tp
>
1055 inline valarray
<_Tp
>
1056 _Expr
<_Clos
, _Tp
>::shift(int __n
) const
1057 { return valarray
<_Tp
>(_M_closure
).shift(__n
); }
1059 template<class _Clos
, typename _Tp
>
1060 inline valarray
<_Tp
>
1061 _Expr
<_Clos
, _Tp
>::cshift(int __n
) const
1062 { return valarray
<_Tp
>(_M_closure
).cshift(__n
); }
1064 template<class _Clos
, typename _Tp
>
1065 inline valarray
<_Tp
>
1066 _Expr
<_Clos
, _Tp
>::apply(_Tp
__f(const _Tp
&)) const
1067 { return valarray
<_Tp
>(_M_closure
).apply(__f
); }
1069 template<class _Clos
, typename _Tp
>
1070 inline valarray
<_Tp
>
1071 _Expr
<_Clos
, _Tp
>::apply(_Tp
__f(_Tp
)) const
1072 { return valarray
<_Tp
>(_M_closure
).apply(__f
); }
1074 // XXX: replace this with a more robust summation algorithm.
1075 template<class _Clos
, typename _Tp
>
1077 _Expr
<_Clos
,_Tp
>::sum () const
1079 size_t __n
= _M_closure
.size();
1080 if (__n
== 0) return _Tp();
1082 _Tp __s
= _M_closure
[--__n
];
1083 while (__n
!= 0) __s
+= _M_closure
[--__n
];
1088 template<class _Clos
, typename _Tp
>
1090 _Expr
<_Clos
, _Tp
>::min() const
1091 { return __valarray_min(_M_closure
); }
1093 template<class _Clos
, typename _Tp
>
1095 _Expr
<_Clos
, _Tp
>::max() const
1096 { return __valarray_max(_M_closure
); }
1098 template<class _Dom
, typename _Tp
>
1099 inline _Expr
<_UnClos
<logical_not
,_Expr
,_Dom
>, bool>
1100 _Expr
<_Dom
,_Tp
>::operator! () const
1102 typedef _UnClos
<logical_not
,std::_Expr
,_Dom
> _Closure
;
1103 return _Expr
<_Closure
,_Tp
> (_Closure(this->_M_closure
));
1106 #define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \
1107 template<class _Dom, typename _Tp> \
1108 inline _Expr<_UnClos<_Name,std::_Expr,_Dom>,_Tp> \
1109 _Expr<_Dom,_Tp>::operator _Op () const \
1111 typedef _UnClos<_Name,std::_Expr,_Dom> _Closure; \
1112 return _Expr<_Closure,_Tp> (_Closure (this->_M_closure)); \
1115 _DEFINE_EXPR_UNARY_OPERATOR(+, _Unary_plus
)
1116 _DEFINE_EXPR_UNARY_OPERATOR(-, negate
)
1117 _DEFINE_EXPR_UNARY_OPERATOR(~, _Bitwise_not
)
1119 #undef _DEFINE_EXPR_UNARY_OPERATOR
1122 #define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \
1123 template<class _Dom1, class _Dom2> \
1124 inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, \
1125 typename _Name<typename _Dom1::value_type>::result_type> \
1126 operator _Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v, \
1127 const _Expr<_Dom2,typename _Dom2::value_type>& __w) \
1129 typedef typename _Dom1::value_type _Arg; \
1130 typedef typename _Name<_Arg>::result_type _Value; \
1131 typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \
1132 return _Expr<_Closure,_Value> (_Closure (__v (), __w ())); \
1135 template<class _Dom> \
1136 inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \
1137 typename _Name<typename _Dom::value_type>::result_type> \
1138 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __v, \
1139 const typename _Dom::value_type& __t) \
1141 typedef typename _Dom::value_type _Arg; \
1142 typedef typename _Name<_Arg>::result_type _Value; \
1143 typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \
1144 return _Expr<_Closure,_Value> (_Closure (__v (), __t)); \
1147 template<class _Dom> \
1148 inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \
1149 typename _Name<typename _Dom::value_type>::result_type> \
1150 operator _Op (const typename _Dom::value_type& __t, \
1151 const _Expr<_Dom,typename _Dom::value_type>& __v) \
1153 typedef typename _Dom::value_type _Arg; \
1154 typedef typename _Name<_Arg>::result_type _Value; \
1155 typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \
1156 return _Expr<_Closure,_Value> (_Closure (__t, __v ())); \
1159 template<class _Dom> \
1160 inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
1161 typename _Name<typename _Dom::value_type>::result_type> \
1162 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __e, \
1163 const valarray<typename _Dom::value_type>& __v) \
1165 typedef typename _Dom::value_type _Arg; \
1166 typedef typename _Name<_Arg>::result_type _Value; \
1167 typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Arg> _Closure; \
1168 return _Expr<_Closure,_Value> (_Closure (__e (), __v)); \
1171 template<class _Dom> \
1172 inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
1173 typename _Name<typename _Dom::value_type>::result_type> \
1174 operator _Op (const valarray<typename _Dom::value_type>& __v, \
1175 const _Expr<_Dom,typename _Dom::value_type>& __e) \
1177 typedef typename _Dom::value_type _Tp; \
1178 typedef typename _Name<_Tp>::result_type _Value; \
1179 typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \
1180 return _Expr<_Closure,_Value> (_Closure (__v, __e ())); \
1183 _DEFINE_EXPR_BINARY_OPERATOR(+, plus
)
1184 _DEFINE_EXPR_BINARY_OPERATOR(-, minus
)
1185 _DEFINE_EXPR_BINARY_OPERATOR(*, multiplies
)
1186 _DEFINE_EXPR_BINARY_OPERATOR(/, divides
)
1187 _DEFINE_EXPR_BINARY_OPERATOR(%, modulus
)
1188 _DEFINE_EXPR_BINARY_OPERATOR(^, _Bitwise_xor
)
1189 _DEFINE_EXPR_BINARY_OPERATOR(&, _Bitwise_and
)
1190 _DEFINE_EXPR_BINARY_OPERATOR(|, _Bitwise_or
)
1191 _DEFINE_EXPR_BINARY_OPERATOR(<<, _Shift_left
)
1192 _DEFINE_EXPR_BINARY_OPERATOR(>>, _Shift_right
)
1194 #undef _DEFINE_EXPR_BINARY_OPERATOR
1196 #define _DEFINE_EXPR_RELATIONAL_OPERATOR(_Op, _Name) \
1197 template<class _Dom1, class _Dom2> \
1198 inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, bool> \
1199 operator _Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v, \
1200 const _Expr<_Dom2,typename _Dom2::value_type>& __w) \
1202 typedef typename _Dom1::value_type _Arg; \
1203 typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \
1204 return _Expr<_Closure,bool> (_Closure (__v (), __w ())); \
1207 template<class _Dom> \
1208 inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \
1210 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __v, \
1211 const typename _Dom::value_type& __t) \
1213 typedef typename _Dom::value_type _Arg; \
1214 typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \
1215 return _Expr<_Closure,bool> (_Closure (__v (), __t)); \
1218 template<class _Dom> \
1219 inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \
1221 operator _Op (const typename _Dom::value_type& __t, \
1222 const _Expr<_Dom,typename _Dom::value_type>& __v) \
1224 typedef typename _Dom::value_type _Arg; \
1225 typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \
1226 return _Expr<_Closure,bool> (_Closure (__t, __v ())); \
1229 template<class _Dom> \
1230 inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
1232 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __e, \
1233 const valarray<typename _Dom::value_type>& __v) \
1235 typedef typename _Dom::value_type _Tp; \
1236 typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Tp> _Closure; \
1237 return _Expr<_Closure,bool> (_Closure (__e (), __v)); \
1240 template<class _Dom> \
1241 inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
1243 operator _Op (const valarray<typename _Dom::value_type>& __v, \
1244 const _Expr<_Dom,typename _Dom::value_type>& __e) \
1246 typedef typename _Dom::value_type _Tp; \
1247 typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \
1248 return _Expr<_Closure,bool> (_Closure (__v, __e ())); \
1251 _DEFINE_EXPR_RELATIONAL_OPERATOR(&&, logical_and
)
1252 _DEFINE_EXPR_RELATIONAL_OPERATOR(||, logical_or
)
1253 _DEFINE_EXPR_RELATIONAL_OPERATOR(==, equal_to
)
1254 _DEFINE_EXPR_RELATIONAL_OPERATOR(!=, not_equal_to
)
1255 _DEFINE_EXPR_RELATIONAL_OPERATOR(<, less
)
1256 _DEFINE_EXPR_RELATIONAL_OPERATOR(>, greater
)
1257 _DEFINE_EXPR_RELATIONAL_OPERATOR(<=, less_equal
)
1258 _DEFINE_EXPR_RELATIONAL_OPERATOR(>=, greater_equal
)
1260 #undef _DEFINE_EXPR_RELATIONAL_OPERATOR
1264 #define _DEFINE_EXPR_UNARY_FUNCTION(_Name) \
1265 template<class _Dom> \
1266 inline _Expr<_UnFunClos<_Expr,_Dom,__##_Name>,typename _Dom::value_type>\
1267 _Name(const _Expr<_Dom,typename _Dom::value_type>& __e) \
1269 typedef typename _Dom::value_type _Tp; \
1270 typedef _UnFunClos<_Expr,_Dom,__##_Name> _Closure; \
1271 return _Expr<_Closure,_Tp>(_Closure(__e())); \
1274 template<typename _Tp> \
1275 inline _Expr<_UnFunClos<_ValArray,_Tp,__##_Name>,_Tp> \
1276 _Name(const valarray<_Tp>& __v) \
1278 typedef _UnFunClos<_ValArray,_Tp,__##_Name> _Closure; \
1279 return _Expr<_Closure,_Tp>(_Closure (__v)); \
1283 _DEFINE_EXPR_UNARY_FUNCTION(abs
)
1284 _DEFINE_EXPR_UNARY_FUNCTION(cos
)
1285 _DEFINE_EXPR_UNARY_FUNCTION(acos
)
1286 _DEFINE_EXPR_UNARY_FUNCTION(cosh
)
1287 _DEFINE_EXPR_UNARY_FUNCTION(sin
)
1288 _DEFINE_EXPR_UNARY_FUNCTION(asin
)
1289 _DEFINE_EXPR_UNARY_FUNCTION(sinh
)
1290 _DEFINE_EXPR_UNARY_FUNCTION(tan
)
1291 _DEFINE_EXPR_UNARY_FUNCTION(tanh
)
1292 _DEFINE_EXPR_UNARY_FUNCTION(atan
)
1293 _DEFINE_EXPR_UNARY_FUNCTION(exp
)
1294 _DEFINE_EXPR_UNARY_FUNCTION(log
)
1295 _DEFINE_EXPR_UNARY_FUNCTION(log10
)
1296 _DEFINE_EXPR_UNARY_FUNCTION(sqrt
)
1298 #undef _DEFINE_EXPR_UNARY_FUNCTION
1301 #define _DEFINE_EXPR_BINARY_FUNCTION(_Name) \
1302 template<class _Dom1, class _Dom2> \
1303 inline _Expr<_BinFunClos<_Expr,_Expr,_Dom1,_Dom2>,typename _Dom1::value_type>\
1304 _Name (const _Expr<_Dom1,typename _Dom1::value_type>& __e1, \
1305 const _Expr<_Dom2,typename _Dom2::value_type>& __e2) \
1307 typedef typename _Dom1::value_type _Tp; \
1308 typedef _BinFunClos<_Expr,_Expr,_Dom1,_Dom2> _Closure; \
1309 return _Expr<_Closure,_Tp> \
1310 (_Closure (__e1 (), __e2 (), (_Tp(*)(_Tp, _Tp))(&_Name))); \
1313 template<class _Dom> \
1314 inline _Expr<_BinFunClos<_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
1315 typename _Dom::value_type> \
1316 _Name (const _Expr<_Dom,typename _Dom::value_type>& __e, \
1317 const valarray<typename _Dom::value_type>& __v) \
1319 typedef typename _Dom::value_type _Tp; \
1320 typedef _BinFunClos<_Expr,_ValArray,_Dom,_Tp> _Closure; \
1321 return _Expr<_Closure,_Tp> \
1322 (_Closure (__e (), __v, (_Tp(*)(_Tp, _Tp))(&_Name))); \
1325 template<class _Dom> \
1326 inline _Expr<_BinFunClos<_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
1327 typename _Dom::value_type> \
1328 _Name (const valarray<typename _Dom::valarray>& __v, \
1329 const _Expr<_Dom,typename _Dom::value_type>& __e) \
1331 typedef typename _Dom::value_type _Tp; \
1332 typedef _BinFunClos<_ValArray,_Expr,_Tp,_Dom> _Closure; \
1333 return _Expr<_Closure,_Tp> \
1334 (_Closure (__v, __e (), (_Tp(*)(_Tp, _Tp))(&_Name))); \
1337 template<class _Dom> \
1338 inline _Expr<_BinFunClos<_Expr,_Constant,_Dom,typename _Dom::value_type>, \
1339 typename _Dom::value_type> \
1340 _Name (const _Expr<_Dom, typename _Dom::value_type>& __e, \
1341 const typename _Dom::value_type& __t) \
1343 typedef typename _Dom::value_type _Tp; \
1344 typedef _BinFunClos<_Expr,_Constant,_Dom,_Tp> _Closure; \
1345 return _Expr<_Closure,_Tp> \
1346 (_Closure (__e (), __t, (_Tp(*)(_Tp, _Tp))(&_Name))); \
1349 template<class _Dom> \
1350 inline _Expr<_BinFunClos<_Constant,_Expr,typename _Dom::value_type,_Dom>, \
1351 typename _Dom::value_type> \
1352 _Name (const typename _Dom::value_type& __t, \
1353 const _Expr<_Dom,typename _Dom::value_type>& __e) \
1355 typedef typename _Dom::value_type _Tp; \
1356 typedef _BinFunClos<_Constant,_Expr,_Tp,_Dom> _Closure; \
1357 return _Expr<_Closure,_Tp> \
1358 (_Closure (__t, __e (), (_Tp(*)(_Tp, _Tp))(&_Name))); \
1361 template<typename _Tp> \
1362 inline _Expr<_BinFunClos<_ValArray,_ValArray,_Tp,_Tp>, _Tp> \
1363 _Name (const valarray<_Tp>& __v, const valarray<_Tp>& __w) \
1365 typedef _BinFunClos<_ValArray,_ValArray,_Tp,_Tp> _Closure; \
1366 return _Expr<_Closure,_Tp> \
1367 (_Closure (__v, __w, (_Tp(*)(_Tp,_Tp))(&_Name))); \
1370 template<typename _Tp> \
1371 inline _Expr<_BinFunClos<_ValArray,_Constant,_Tp,_Tp>,_Tp> \
1372 _Name (const valarray<_Tp>& __v, const _Tp& __t) \
1374 typedef _BinFunClos<_ValArray,_Constant,_Tp,_Tp> _Closure; \
1375 return _Expr<_Closure,_Tp> \
1376 (_Closure (__v, __t, (_Tp(*)(_Tp,_Tp))(&_Name))); \
1379 template<typename _Tp> \
1380 inline _Expr<_BinFunClos<_Constant,_ValArray,_Tp,_Tp>,_Tp> \
1381 _Name (const _Tp& __t, const valarray<_Tp>& __v) \
1383 typedef _BinFunClos<_Constant,_ValArray,_Tp,_Tp> _Closure; \
1384 return _Expr<_Closure,_Tp> \
1385 (_Closure (__t, __v, (_Tp(*)(_Tp,_Tp))(&_Name))); \
1388 _DEFINE_EXPR_BINARY_FUNCTION(atan2
)
1389 _DEFINE_EXPR_BINARY_FUNCTION(pow
)
1391 #undef _DEFINE_EXPR_BINARY_FUNCTION
1396 #endif /* _CPP_VALARRAY_META_H */