valarray_meta.h (_UnFunBase<>): Remove.
[gcc.git] / libstdc++-v3 / include / bits / valarray_meta.h
1 // The template and inlines for the -*- C++ -*- internal _Meta class.
2
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 // USA.
20
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
29
30 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr>
31
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.
35 */
36
37 #ifndef _CPP_VALARRAY_META_H
38 #define _CPP_VALARRAY_META_H 1
39
40 #pragma GCC system_header
41
42 namespace std
43 {
44 //
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<>
51 //
52
53
54 // This class is NOT defined. It doesn't need to.
55 template<typename _Tp1, typename _Tp2> class _Constant;
56
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
64
65 struct __abs
66 {
67 template<typename _Tp>
68 _Tp operator()(const _Tp& __t) const { return abs(__t); }
69 };
70
71 struct __cos
72 {
73 template<typename _Tp>
74 _Tp operator()(const _Tp& __t) const { return cos(__t); }
75 };
76
77 struct __acos
78 {
79 template<typename _Tp>
80 _Tp operator()(const _Tp& __t) const { return acos(__t); }
81 };
82
83 struct __cosh
84 {
85 template<typename _Tp>
86 _Tp operator()(const _Tp& __t) const { return cosh(__t); }
87 };
88
89 struct __sin
90 {
91 template<typename _Tp>
92 _Tp operator()(const _Tp& __t) const { return sin(__t); }
93 };
94
95 struct __asin
96 {
97 template<typename _Tp>
98 _Tp operator()(const _Tp& __t) const { return asin(__t); }
99 };
100
101 struct __sinh
102 {
103 template<typename _Tp>
104 _Tp operator()(const _Tp& __t) const { return sinh(__t); }
105 };
106
107 struct __tan
108 {
109 template<typename _Tp>
110 _Tp operator()(const _Tp& __t) const { return tan(__t); }
111 };
112
113 struct __atan
114 {
115 template<typename _Tp>
116 _Tp operator()(const _Tp& __t) const { return atan(__t); }
117 };
118
119 struct __tanh
120 {
121 template<typename _Tp>
122 _Tp operator()(const _Tp& __t) const { return tanh(__t); }
123 };
124
125 struct __exp
126 {
127 template<typename _Tp>
128 _Tp operator()(const _Tp& __t) const { return exp(__t); }
129 };
130
131 struct __log
132 {
133 template<typename _Tp>
134 _Tp operator()(const _Tp& __t) const { return log(__t); }
135 };
136
137 struct __log10
138 {
139 template<typename _Tp>
140 _Tp operator()(const _Tp& __t) const { return log10(__t); }
141 };
142
143 struct __sqrt
144 {
145 template<typename _Tp>
146 _Tp operator()(const _Tp& __t) const { return sqrt(__t); }
147 };
148
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.
152
153 struct __unary_plus
154 {
155 template<typename _Tp>
156 _Tp operator()(const _Tp& __t) const { return +__t; }
157 };
158
159 struct __negate
160 {
161 template<typename _Tp>
162 _Tp operator()(const _Tp& __t) const { return -__t; }
163 };
164
165 struct __bitwise_not
166 {
167 template<typename _Tp>
168 _Tp operator()(const _Tp& __t) const { return ~__t; }
169 };
170
171 struct __plus
172 {
173 template<typename _Tp>
174 _Tp operator()(const _Tp& __x, const _Tp& __y) const
175 { return __x + __y; }
176 };
177
178 struct __minus
179 {
180 template<typename _Tp>
181 _Tp operator()(const _Tp& __x, const _Tp& __y) const
182 { return __x - __y; }
183 };
184
185 struct __multiplies
186 {
187 template<typename _Tp>
188 _Tp operator()(const _Tp& __x, const _Tp& __y) const
189 { return __x * __y; }
190 };
191
192 struct __divides
193 {
194 template<typename _Tp>
195 _Tp operator()(const _Tp& __x, const _Tp& __y) const
196 { return __x / __y; }
197 };
198
199 struct __modulus
200 {
201 template<typename _Tp>
202 _Tp operator()(const _Tp& __x, const _Tp& __y) const
203 { return __x % __y; }
204 };
205
206 struct __bitwise_xor
207 {
208 template<typename _Tp>
209 _Tp operator()(const _Tp& __x, const _Tp& __y) const
210 { return __x ^ __y; }
211 };
212
213 struct __bitwise_and
214 {
215 template<typename _Tp>
216 _Tp operator()(const _Tp& __x, const _Tp& __y) const
217 { return __x & __y; }
218 };
219
220 struct __bitwise_or
221 {
222 template<typename _Tp>
223 _Tp operator()(const _Tp& __x, const _Tp& __y) const
224 { return __x | __y; }
225 };
226
227 struct __shift__left
228 {
229 template<typename _Tp>
230 _Tp operator()(const _Tp& __x, const _Tp& __y) const
231 { return __x << __y; }
232 };
233
234 struct __shift_right
235 {
236 template<typename _Tp>
237 _Tp operator()(const _Tp& __x, const _Tp& __y) const
238 { return __x >> __y; }
239 };
240
241 struct __logical_and
242 {
243 template<typename _Tp>
244 bool operator()(const _Tp& __x, const _Tp& __y) const
245 { return __x && __y; }
246 };
247
248 struct __logical_or
249 {
250 template<typename _Tp>
251 bool operator()(const _Tp& __x, const _Tp& __y) const
252 { return __x || __y; }
253 };
254
255 struct __logical_not
256 {
257 template<typename _Tp>
258 bool operator()(const _Tp& __x) const { return !__x; }
259 };
260
261 struct __equal_to
262 {
263 template<typename _Tp>
264 bool operator()(const _Tp& __x, const _Tp& __y) const
265 { return __x == __y; }
266 };
267
268 struct __not_equal_to
269 {
270 template<typename _Tp>
271 bool operator()(const _Tp& __x, const _Tp& __y) const
272 { return __x == __y; }
273 };
274
275 struct __less
276 {
277 template<typename _Tp>
278 bool operator()(const _Tp& __x, const _Tp& __y) const
279 { return __x < __y; }
280 };
281
282 struct __greater
283 {
284 template<typename _Tp>
285 bool operator()(const _Tp& __x, const _Tp& __y) const
286 { return __x > __y; }
287 };
288
289 struct __less_equal
290 {
291 template<typename _Tp>
292 bool operator()(const _Tp& __x, const _Tp& __y) const
293 { return __x <= __y; }
294 };
295
296 struct __greater_equal
297 {
298 template<typename _Tp>
299 bool operator()(const _Tp& __x, const _Tp& __y) const
300 { return __x >= __y; }
301 };
302
303 // The few binary functions we miss.
304 struct __atan2
305 {
306 template<typename _Tp>
307 _Tp operator()(const _Tp& __x, const _Tp& __y) const
308 { return atan2(__x, __y); }
309 };
310
311 struct __pow
312 {
313 template<typename _Tp>
314 _Tp operator()(const _Tp& __x, const _Tp& __y) const
315 { return pow(__x, __y); }
316 };
317
318
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>
323 struct __fun
324 {
325 typedef _Tp result_type;
326 };
327
328 // several specializations for relational operators.
329 template<typename _Tp>
330 struct __fun<__logical_not, _Tp>
331 {
332 typedef bool result_type;
333 };
334
335 template<typename _Tp>
336 struct __fun<__logical_and, _Tp>
337 {
338 typedef bool result_type;
339 };
340
341 template<typename _Tp>
342 struct __fun<__logical_or, _Tp>
343 {
344 typedef bool result_type;
345 };
346
347 template<typename _Tp>
348 struct __fun<__less, _Tp>
349 {
350 typedef bool result_type;
351 };
352
353 template<typename _Tp>
354 struct __fun<__greater, _Tp>
355 {
356 typedef bool result_type;
357 };
358
359 template<typename _Tp>
360 struct __fun<__less_equal, _Tp>
361 {
362 typedef bool result_type;
363 };
364
365 template<typename _Tp>
366 struct __fun<__greater_equal, _Tp>
367 {
368 typedef bool result_type;
369 };
370
371 template<typename _Tp>
372 struct __fun<__equal_to, _Tp>
373 {
374 typedef bool result_type;
375 };
376
377 template<typename _Tp>
378 struct __fun<__not_equal_to, _Tp>
379 {
380 typedef bool result_type;
381 };
382
383 //
384 // Binary function application closure.
385 //
386 template<template<class, class> class _Meta1,
387 template<class, class> class Meta2,
388 class _Dom1, class _Dom2> class _BinFunClos;
389
390 template<class _Dom1, class _Dom2> class _BinFunBase {
391 public:
392 typedef typename _Dom1::value_type value_type;
393 typedef value_type _Vt;
394
395 _BinFunBase (const _Dom1& __e1, const _Dom2& __e2,
396 _Vt __f (_Vt, _Vt))
397 : _M_expr1 (__e1), _M_expr2 (__e2), _M_func (__f) {}
398
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 (); }
402
403 private:
404 const _Dom1& _M_expr1;
405 const _Dom2& _M_expr2;
406 _Vt (*_M_func)(_Vt, _Vt);
407 };
408
409 template<class _Dom> class _BinFunBase1 {
410 public:
411 typedef typename _Dom::value_type value_type ;
412 typedef value_type _Vt;
413
414 _BinFunBase1 (const _Vt& __c, const _Dom& __e, _Vt __f(_Vt, _Vt))
415 : _M_expr1 (__c), _M_expr2 (__e), _M_func (__f) {}
416
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 (); }
420
421 private:
422 const _Vt& _M_expr1;
423 const _Dom& _M_expr2;
424 _Vt (*_M_func)(_Vt, _Vt);
425 };
426
427 template<class _Dom> class _BinFunBase2 {
428 public:
429 typedef typename _Dom::value_type value_type;
430 typedef value_type _Vt;
431
432 _BinFunBase2 (const _Dom& __e, const _Vt& __c, _Vt __f(_Vt, _Vt))
433 : _M_expr1 (__e), _M_expr2 (__c), _M_func (__f) {}
434
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 (); }
438
439 private:
440 const _Dom& _M_expr1;
441 const _Vt& _M_expr2;
442 _Vt (*_M_func)(_Vt, _Vt);
443 };
444
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;
450
451 _BinFunClos (const _Dom1& __e1, const _Dom2& __e2,
452 _Tp __f(_Tp, _Tp))
453 : _Base (__e1, __e2, __f) {}
454 };
455
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;
461
462 _BinFunClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w,
463 _Tp __f(_Tp, _Tp))
464 : _Base (__v, __w, __f) {}
465 };
466
467 template<class _Dom>
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;
473
474 _BinFunClos (const _Dom& __e, const valarray<_Tp>& __v,
475 _Tp __f(_Tp, _Tp))
476 : _Base (__e, __v, __f) {}
477 };
478
479 template<class _Dom>
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;
485
486 _BinFunClos (const valarray<_Tp>& __v, const _Dom& __e,
487 _Tp __f(_Tp, _Tp))
488 : _Base (__v, __e, __f) {}
489 };
490
491 template<class _Dom>
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;
497
498 _BinFunClos (const _Dom& __e, const _Tp& __t, _Tp __f (_Tp, _Tp))
499 : _Base (__e, __t, __f) {}
500 };
501
502 template<class _Dom>
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;
508
509 _BinFunClos (const _Tp& __t, const _Dom& __e, _Tp __f (_Tp, _Tp))
510 : _Base (__t, __e, __f) {}
511 };
512
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;
518
519 _BinFunClos (const valarray<_Tp>& __v, const _Tp& __t,
520 _Tp __f(_Tp, _Tp))
521 : _Base (__v, __t, __f) {}
522 };
523
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;
529
530 _BinFunClos (const _Tp& __t, const valarray<_Tp>& __v,
531 _Tp __f (_Tp, _Tp))
532 : _Base (__t, __v, __f) {}
533 };
534
535 //
536 // Apply function taking a value/const reference closure
537 //
538
539 template<typename _Dom, typename _Arg> class _FunBase {
540 public:
541 typedef typename _Dom::value_type value_type;
542
543 _FunBase (const _Dom& __e, value_type __f(_Arg))
544 : _M_expr (__e), _M_func (__f) {}
545
546 value_type operator[] (size_t __i) const
547 { return _M_func (_M_expr[__i]); }
548 size_t size() const { return _M_expr.size ();}
549
550 private:
551 const _Dom& _M_expr;
552 value_type (*_M_func)(_Arg);
553 };
554
555 template<class _Dom>
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;
561
562 _ValFunClos (const _Dom& __e, _Tp __f (_Tp)) : _Base (__e, __f) {}
563 };
564
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;
570
571 _ValFunClos (const valarray<_Tp>& __v, _Tp __f(_Tp))
572 : _Base (__v, __f) {}
573 };
574
575 template<class _Dom>
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;
581
582 _RefFunClos (const _Dom& __e, _Tp __f (const _Tp&))
583 : _Base (__e, __f) {}
584 };
585
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;
591
592 _RefFunClos (const valarray<_Tp>& __v, _Tp __f(const _Tp&))
593 : _Base (__v, __f) {}
594 };
595
596 //
597 // Unary expression closure.
598 //
599
600 template<class _Oper, class _Arg>
601 class _UnBase
602 {
603 public:
604 typedef typename _Arg::value_type _Vt;
605 typedef typename __fun<_Oper, _Vt>::result_type value_type;
606
607 _UnBase(const _Arg& __e) : _M_expr(__e) {}
608
609 value_type operator[](size_t __i) const
610 { return _M_expr[__i]; }
611
612 size_t size() const { return _M_expr.size(); }
613
614 private:
615 const _Arg& _M_expr;
616 };
617
618 template<class _Oper, class _Dom>
619 struct _UnClos<_Oper, _Expr, _Dom> : _UnBase<_Oper, _Dom>
620 {
621 typedef _Dom _Arg;
622 typedef _UnBase<_Oper, _Dom> _Base;
623 typedef typename _Base::value_type value_type;
624
625 _UnClos(const _Arg& __e) : _Base(__e) {}
626 };
627
628 template<class _Oper, typename _Tp>
629 struct _UnClos<_Oper, _ValArray, _Tp> : _UnBase<_Oper, valarray<_Tp> >
630 {
631 typedef valarray<_Tp> _Arg;
632 typedef _UnBase<_Oper, valarray<_Tp> > _Base;
633 typedef typename _Base::value_type value_type;
634
635 _UnClos(const _Arg& __e) : _Base(__e) {}
636 };
637
638
639 //
640 // Binary expression closure.
641 //
642
643 template<template<class> class _Oper,
644 typename _FirstArg, typename _SecondArg>
645 class _BinBase {
646 public:
647 typedef _Oper<typename _FirstArg::value_type> _Op;
648 typedef typename _Op::result_type value_type;
649
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 (); }
654
655 private:
656 const _FirstArg& _M_expr1;
657 const _SecondArg& _M_expr2;
658 };
659
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]); }
665
666
667 template<template<class> class _Oper, class _Clos>
668 class _BinBase2 {
669 public:
670 typedef typename _Clos::value_type _Vt;
671 typedef _Oper<_Vt> _Op;
672 typedef typename _Op::result_type value_type;
673
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 (); }
678
679 private:
680 const _Clos& _M_expr1;
681 const _Vt& _M_expr2;
682 };
683
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); }
688
689
690 template<template<class> class _Oper, class _Clos>
691 class _BinBase1 {
692 public:
693 typedef typename _Clos::value_type _Vt;
694 typedef _Oper<_Vt> _Op;
695 typedef typename _Op::result_type value_type;
696
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 (); }
701
702 private:
703 const _Vt& _M_expr1;
704 const _Clos& _M_expr2;
705 };
706
707 template<template<class> class _Oper, class _Clos>
708 inline typename
709 _BinBase1<_Oper,_Clos>::value_type
710 _BinBase1<_Oper,_Clos>:: operator[] (size_t __i) const
711 { return _Op() (_M_expr1, _M_expr2[__i]); }
712
713
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;
719
720 _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {}
721 };
722
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;
728
729 _BinClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w)
730 : _Base (__v, __w) {}
731 };
732
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;
739
740 _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2)
741 : _Base (__e1, __e2) {}
742 };
743
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;
750
751 _BinClos (const valarray<_Tp>& __e1, const _Dom& __e2)
752 : _Base (__e1, __e2) {}
753 };
754
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;
761
762 _BinClos (const _Dom& __e1, const _Tp& __e2) : _Base (__e1, __e2) {}
763 };
764
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;
771
772 _BinClos (const _Tp& __e1, const _Dom& __e2) : _Base (__e1, __e2) {}
773 };
774
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;
780
781 _BinClos (const valarray<_Tp>& __v, const _Tp& __t)
782 : _Base (__v, __t) {}
783 };
784
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;
790
791 _BinClos (const _Tp& __t, const valarray<_Tp>& __v)
792 : _Base (__t, __v) {}
793 };
794
795
796 //
797 // slice_array closure.
798 //
799 template<typename _Dom> class _SBase {
800 public:
801 typedef typename _Dom::value_type value_type;
802
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 (); }
808
809 private:
810 const _Dom& _M_expr;
811 const slice& _M_slice;
812 };
813
814 template<typename _Tp> class _SBase<_Array<_Tp> > {
815 public:
816 typedef _Tp value_type;
817
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; }
824
825 private:
826 const _Array<_Tp> _M_array;
827 const size_t _M_size;
828 const size_t _M_stride;
829 };
830
831 template<class _Dom> struct _SClos<_Expr,_Dom> : _SBase<_Dom> {
832 typedef _SBase<_Dom> _Base;
833 typedef typename _Base::value_type value_type;
834
835 _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {}
836 };
837
838 template<typename _Tp>
839 struct _SClos<_ValArray,_Tp> : _SBase<_Array<_Tp> > {
840 typedef _SBase<_Array<_Tp> > _Base;
841 typedef _Tp value_type;
842
843 _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {}
844 };
845
846 //
847 // gslice_array closure.
848 //
849 template<class _Dom> class _GBase {
850 public:
851 typedef typename _Dom::value_type value_type;
852
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(); }
858
859 private:
860 const _Dom& _M_expr;
861 const valarray<size_t>& _M_index;
862 };
863
864 template<typename _Tp> class _GBase<_Array<_Tp> > {
865 public:
866 typedef _Tp value_type;
867
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(); }
873
874 private:
875 const _Array<_Tp> _M_array;
876 const valarray<size_t>& _M_index;
877 };
878
879 template<class _Dom> struct _GClos<_Expr,_Dom> : _GBase<_Dom> {
880 typedef _GBase<_Dom> _Base;
881 typedef typename _Base::value_type value_type;
882
883 _GClos (const _Dom& __e, const valarray<size_t>& __i)
884 : _Base (__e, __i) {}
885 };
886
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;
891
892 _GClos (_Array<_Tp> __a, const valarray<size_t>& __i)
893 : _Base (__a, __i) {}
894 };
895
896 //
897 // indirect_array closure
898 //
899
900 template<class _Dom> class _IBase {
901 public:
902 typedef typename _Dom::value_type value_type;
903
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(); }
909
910 private:
911 const _Dom& _M_expr;
912 const valarray<size_t>& _M_index;
913 };
914
915 template<class _Dom> struct _IClos<_Expr,_Dom> : _IBase<_Dom> {
916 typedef _IBase<_Dom> _Base;
917 typedef typename _Base::value_type value_type;
918
919 _IClos (const _Dom& __e, const valarray<size_t>& __i)
920 : _Base (__e, __i) {}
921 };
922
923 template<typename _Tp>
924 struct _IClos<_ValArray,_Tp> : _IBase<valarray<_Tp> > {
925 typedef _IBase<valarray<_Tp> > _Base;
926 typedef _Tp value_type;
927
928 _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i)
929 : _Base (__a, __i) {}
930 };
931
932 //
933 // class _Expr
934 //
935 template<class _Clos, typename _Tp>
936 class _Expr
937 {
938 public:
939 typedef _Tp value_type;
940
941 _Expr(const _Clos&);
942
943 const _Clos& operator()() const;
944
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;
950
951 _Expr<_UnClos<__unary_plus,std::_Expr,_Clos>, value_type>
952 operator+() const;
953
954 _Expr<_UnClos<__negate,std::_Expr,_Clos>, value_type>
955 operator-() const;
956
957 _Expr<_UnClos<__bitwise_not,std::_Expr,_Clos>, value_type>
958 operator~() const;
959
960 _Expr<_UnClos<__logical_not,std::_Expr,_Clos>, bool>
961 operator!() const;
962
963 size_t size() const;
964 value_type sum() const;
965
966 valarray<value_type> shift(int) const;
967 valarray<value_type> cshift(int) const;
968
969 value_type min() const;
970 value_type max() const;
971
972 valarray<value_type> apply(value_type (*)(const value_type&)) const;
973 valarray<value_type> apply(value_type (*)(value_type)) const;
974
975 private:
976 const _Clos _M_closure;
977 };
978
979 template<class _Clos, typename _Tp>
980 inline
981 _Expr<_Clos,_Tp>::_Expr(const _Clos& __c) : _M_closure(__c) {}
982
983 template<class _Clos, typename _Tp>
984 inline const _Clos&
985 _Expr<_Clos,_Tp>::operator()() const
986 { return _M_closure; }
987
988 template<class _Clos, typename _Tp>
989 inline _Tp
990 _Expr<_Clos,_Tp>::operator[](size_t __i) const
991 { return _M_closure[__i]; }
992
993 template<class _Clos, typename _Tp>
994 inline valarray<_Tp>
995 _Expr<_Clos,_Tp>::operator[](slice __s) const
996 { return _M_closure[__s]; }
997
998 template<class _Clos, typename _Tp>
999 inline valarray<_Tp>
1000 _Expr<_Clos,_Tp>::operator[](const gslice& __gs) const
1001 { return _M_closure[__gs]; }
1002
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]; }
1007
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]; }
1012
1013 template<class _Clos, typename _Tp>
1014 inline size_t
1015 _Expr<_Clos,_Tp>::size() const { return _M_closure.size (); }
1016
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); }
1021
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); }
1026
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); }
1031
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); }
1036
1037 // XXX: replace this with a more robust summation algorithm.
1038 template<class _Clos, typename _Tp>
1039 inline _Tp
1040 _Expr<_Clos,_Tp>::sum() const
1041 {
1042 size_t __n = _M_closure.size();
1043 if (__n == 0)
1044 return _Tp();
1045 else
1046 {
1047 _Tp __s = _M_closure[--__n];
1048 while (__n != 0)
1049 __s += _M_closure[--__n];
1050 return __s;
1051 }
1052 }
1053
1054 template<class _Clos, typename _Tp>
1055 inline _Tp
1056 _Expr<_Clos, _Tp>::min() const
1057 { return __valarray_min(_M_closure); }
1058
1059 template<class _Clos, typename _Tp>
1060 inline _Tp
1061 _Expr<_Clos, _Tp>::max() const
1062 { return __valarray_max(_M_closure); }
1063
1064 template<class _Dom, typename _Tp>
1065 inline _Expr<_UnClos<__logical_not,_Expr,_Dom>, bool>
1066 _Expr<_Dom,_Tp>::operator!() const
1067 {
1068 typedef _UnClos<__logical_not,std::_Expr,_Dom> _Closure;
1069 return _Expr<_Closure,_Tp>(_Closure(this->_M_closure));
1070 }
1071
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 \
1076 { \
1077 typedef _UnClos<_Name,std::_Expr,_Dom> _Closure; \
1078 return _Expr<_Closure,_Tp>(_Closure(this->_M_closure)); \
1079 }
1080
1081 _DEFINE_EXPR_UNARY_OPERATOR(+, __unary_plus)
1082 _DEFINE_EXPR_UNARY_OPERATOR(-, __negate)
1083 _DEFINE_EXPR_UNARY_OPERATOR(~, __bitwise_not)
1084
1085 #undef _DEFINE_EXPR_UNARY_OPERATOR
1086
1087
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) \
1094 { \
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 ())); \
1099 } \
1100 \
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) \
1106 { \
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)); \
1111 } \
1112 \
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) \
1118 { \
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 ())); \
1123 } \
1124 \
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) \
1130 { \
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)); \
1135 } \
1136 \
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) \
1142 { \
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 ())); \
1147 }
1148
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)
1159
1160 #undef _DEFINE_EXPR_BINARY_OPERATOR
1161
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) \
1167 { \
1168 typedef typename _Dom1::value_type _Arg; \
1169 typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \
1170 return _Expr<_Closure,bool> (_Closure (__v (), __w ())); \
1171 } \
1172 \
1173 template<class _Dom> \
1174 inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \
1175 bool> \
1176 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __v, \
1177 const typename _Dom::value_type& __t) \
1178 { \
1179 typedef typename _Dom::value_type _Arg; \
1180 typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \
1181 return _Expr<_Closure,bool> (_Closure (__v (), __t)); \
1182 } \
1183 \
1184 template<class _Dom> \
1185 inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \
1186 bool> \
1187 operator _Op (const typename _Dom::value_type& __t, \
1188 const _Expr<_Dom,typename _Dom::value_type>& __v) \
1189 { \
1190 typedef typename _Dom::value_type _Arg; \
1191 typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \
1192 return _Expr<_Closure,bool> (_Closure (__t, __v ())); \
1193 } \
1194 \
1195 template<class _Dom> \
1196 inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
1197 bool> \
1198 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __e, \
1199 const valarray<typename _Dom::value_type>& __v) \
1200 { \
1201 typedef typename _Dom::value_type _Tp; \
1202 typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Tp> _Closure; \
1203 return _Expr<_Closure,bool> (_Closure (__e (), __v)); \
1204 } \
1205 \
1206 template<class _Dom> \
1207 inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
1208 bool> \
1209 operator _Op (const valarray<typename _Dom::value_type>& __v, \
1210 const _Expr<_Dom,typename _Dom::value_type>& __e) \
1211 { \
1212 typedef typename _Dom::value_type _Tp; \
1213 typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \
1214 return _Expr<_Closure,bool> (_Closure (__v, __e ())); \
1215 }
1216
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)
1225
1226 #undef _DEFINE_EXPR_RELATIONAL_OPERATOR
1227
1228
1229
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) \
1234 { \
1235 typedef typename _Dom::value_type _Tp; \
1236 typedef _UnClos<__##_Name,_Expr,_Dom> _Closure; \
1237 return _Expr<_Closure,_Tp>(_Closure(__e())); \
1238 } \
1239 \
1240 template<typename _Tp> \
1241 inline _Expr<_UnClos<__##_Name,_ValArray,_Tp>,_Tp> \
1242 _Name(const valarray<_Tp>& __v) \
1243 { \
1244 typedef _UnClos<__##_Name,_ValArray,_Tp> _Closure; \
1245 return _Expr<_Closure,_Tp>(_Closure (__v)); \
1246 }
1247
1248
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)
1263
1264 #undef _DEFINE_EXPR_UNARY_FUNCTION
1265
1266
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) \
1272 { \
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))); \
1277 } \
1278 \
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) \
1284 { \
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))); \
1289 } \
1290 \
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) \
1296 { \
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))); \
1301 } \
1302 \
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) \
1308 { \
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))); \
1313 } \
1314 \
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) \
1320 { \
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))); \
1325 } \
1326 \
1327 template<typename _Tp> \
1328 inline _Expr<_BinFunClos<_ValArray,_ValArray,_Tp,_Tp>, _Tp> \
1329 _Name (const valarray<_Tp>& __v, const valarray<_Tp>& __w) \
1330 { \
1331 typedef _BinFunClos<_ValArray,_ValArray,_Tp,_Tp> _Closure; \
1332 return _Expr<_Closure,_Tp> \
1333 (_Closure (__v, __w, (_Tp(*)(_Tp,_Tp))(&_Name))); \
1334 } \
1335 \
1336 template<typename _Tp> \
1337 inline _Expr<_BinFunClos<_ValArray,_Constant,_Tp,_Tp>,_Tp> \
1338 _Name (const valarray<_Tp>& __v, const _Tp& __t) \
1339 { \
1340 typedef _BinFunClos<_ValArray,_Constant,_Tp,_Tp> _Closure; \
1341 return _Expr<_Closure,_Tp> \
1342 (_Closure (__v, __t, (_Tp(*)(_Tp,_Tp))(&_Name))); \
1343 } \
1344 \
1345 template<typename _Tp> \
1346 inline _Expr<_BinFunClos<_Constant,_ValArray,_Tp,_Tp>,_Tp> \
1347 _Name (const _Tp& __t, const valarray<_Tp>& __v) \
1348 { \
1349 typedef _BinFunClos<_Constant,_ValArray,_Tp,_Tp> _Closure; \
1350 return _Expr<_Closure,_Tp> \
1351 (_Closure (__t, __v, (_Tp(*)(_Tp,_Tp))(&_Name))); \
1352 }
1353
1354 _DEFINE_EXPR_BINARY_FUNCTION(atan2)
1355 _DEFINE_EXPR_BINARY_FUNCTION(pow)
1356
1357 #undef _DEFINE_EXPR_BINARY_FUNCTION
1358
1359 } // std::
1360
1361
1362 #endif /* _CPP_VALARRAY_META_H */
1363
1364 // Local Variables:
1365 // mode:c++
1366 // End: