d5e758f6d9ab2287f454e0e6952558b2fd2d96fe
[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 //
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<>
52 //
53
54
55 // This class is NOT defined. It doesn't need to.
56 template<typename _Tp1, typename _Tp2> class _Constant;
57
58 //
59 // Unary function application closure.
60 //
61 template<class _Dom, typename _Op> class _UnFunBase
62 {
63 public:
64 typedef typename _Dom::value_type value_type;
65 typedef value_type _Vt;
66
67 explicit _UnFunBase (const _Dom& __e) : _M_expr(__e) {}
68
69 _Vt operator[] (size_t __i) const { return _Op()(_M_expr[__i]); }
70 size_t size () const { return _M_expr.size(); }
71
72 private:
73 const _Dom& _M_expr;
74 };
75
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
83
84 struct __abs
85 {
86 template<typename _Tp>
87 _Tp operator()(const _Tp& __t) const { return abs(__t); }
88 };
89
90 struct __cos
91 {
92 template<typename _Tp>
93 _Tp operator()(const _Tp& __t) const { return cos(__t); }
94 };
95
96 struct __acos
97 {
98 template<typename _Tp>
99 _Tp operator()(const _Tp& __t) const { return acos(__t); }
100 };
101
102 struct __cosh
103 {
104 template<typename _Tp>
105 _Tp operator()(const _Tp& __t) const { return cosh(__t); }
106 };
107
108 struct __sin
109 {
110 template<typename _Tp>
111 _Tp operator()(const _Tp& __t) const { return sin(__t); }
112 };
113
114 struct __asin
115 {
116 template<typename _Tp>
117 _Tp operator()(const _Tp& __t) const { return asin(__t); }
118 };
119
120 struct __sinh
121 {
122 template<typename _Tp>
123 _Tp operator()(const _Tp& __t) const { return sinh(__t); }
124 };
125
126 struct __tan
127 {
128 template<typename _Tp>
129 _Tp operator()(const _Tp& __t) const { return tan(__t); }
130 };
131
132 struct __atan
133 {
134 template<typename _Tp>
135 _Tp operator()(const _Tp& __t) const { return atan(__t); }
136 };
137
138 struct __tanh
139 {
140 template<typename _Tp>
141 _Tp operator()(const _Tp& __t) const { return tanh(__t); }
142 };
143
144 struct __exp
145 {
146 template<typename _Tp>
147 _Tp operator()(const _Tp& __t) const { return exp(__t); }
148 };
149
150 struct __log
151 {
152 template<typename _Tp>
153 _Tp operator()(const _Tp& __t) const { return log(__t); }
154 };
155
156 struct __log10
157 {
158 template<typename _Tp>
159 _Tp operator()(const _Tp& __t) const { return log10(__t); }
160 };
161
162 struct __sqrt
163 {
164 template<typename _Tp>
165 _Tp operator()(const _Tp& __t) const { return sqrt(__t); }
166 };
167
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.
171
172 struct __unary_plus
173 {
174 template<typename _Tp>
175 _Tp operator()(const _Tp& __t) const { return +__t; }
176 };
177
178 struct __negate
179 {
180 template<typename _Tp>
181 _Tp operator()(const _Tp& __t) const { return -__t; }
182 };
183
184 struct __bitwise_not
185 {
186 template<typename _Tp>
187 _Tp operator()(const _Tp& __t) const { return ~__t; }
188 };
189
190 struct __plus
191 {
192 template<typename _Tp>
193 _Tp operator()(const _Tp& __x, const _Tp& __y) const
194 { return __x + __y; }
195 };
196
197 struct __minus
198 {
199 template<typename _Tp>
200 _Tp operator()(const _Tp& __x, const _Tp& __y) const
201 { return __x - __y; }
202 };
203
204 struct __multiplies
205 {
206 template<typename _Tp>
207 _Tp operator()(const _Tp& __x, const _Tp& __y) const
208 { return __x * __y; }
209 };
210
211 struct __divides
212 {
213 template<typename _Tp>
214 _Tp operator()(const _Tp& __x, const _Tp& __y) const
215 { return __x / __y; }
216 };
217
218 struct __modulus
219 {
220 template<typename _Tp>
221 _Tp operator()(const _Tp& __x, const _Tp& __y) const
222 { return __x % __y; }
223 };
224
225 struct __bitwise_xor
226 {
227 template<typename _Tp>
228 _Tp operator()(const _Tp& __x, const _Tp& __y) const
229 { return __x ^ __y; }
230 };
231
232 struct __bitwise_and
233 {
234 template<typename _Tp>
235 _Tp operator()(const _Tp& __x, const _Tp& __y) const
236 { return __x & __y; }
237 };
238
239 struct __bitwise_or
240 {
241 template<typename _Tp>
242 _Tp operator()(const _Tp& __x, const _Tp& __y) const
243 { return __x | __y; }
244 };
245
246 struct __shift__left
247 {
248 template<typename _Tp>
249 _Tp operator()(const _Tp& __x, const _Tp& __y) const
250 { return __x << __y; }
251 };
252
253 struct __shift_right
254 {
255 template<typename _Tp>
256 _Tp operator()(const _Tp& __x, const _Tp& __y) const
257 { return __x >> __y; }
258 };
259
260 struct __logical_and
261 {
262 template<typename _Tp>
263 bool operator()(const _Tp& __x, const _Tp& __y) const
264 { return __x && __y; }
265 };
266
267 struct __logical_or
268 {
269 template<typename _Tp>
270 bool operator()(const _Tp& __x, const _Tp& __y) const
271 { return __x || __y; }
272 };
273
274 struct __logical_not
275 {
276 template<typename _Tp>
277 bool operator()(const _Tp& __x) const { return !__x; }
278 };
279
280 struct __equal_to
281 {
282 template<typename _Tp>
283 bool operator()(const _Tp& __x, const _Tp& __y) const
284 { return __x == __y; }
285 };
286
287 struct __not_equal_to
288 {
289 template<typename _Tp>
290 bool operator()(const _Tp& __x, const _Tp& __y) const
291 { return __x == __y; }
292 };
293
294 struct __less
295 {
296 template<typename _Tp>
297 bool operator()(const _Tp& __x, const _Tp& __y) const
298 { return __x < __y; }
299 };
300
301 struct __greater
302 {
303 template<typename _Tp>
304 bool operator()(const _Tp& __x, const _Tp& __y) const
305 { return __x > __y; }
306 };
307
308 struct __less_equal
309 {
310 template<typename _Tp>
311 bool operator()(const _Tp& __x, const _Tp& __y) const
312 { return __x <= __y; }
313 };
314
315 struct __greater_equal
316 {
317 template<typename _Tp>
318 bool operator()(const _Tp& __x, const _Tp& __y) const
319 { return __x >= __y; }
320 };
321
322 // The few binary functions we miss.
323 struct __atan2
324 {
325 template<typename _Tp>
326 _Tp operator()(const _Tp& __x, const _Tp& __y) const
327 { return atan2(__x, __y); }
328 };
329
330 struct __pow
331 {
332 template<typename _Tp>
333 _Tp operator()(const _Tp& __x, const _Tp& __y) const
334 { return pow(__x, __y); }
335 };
336
337
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>
342 struct __fun
343 {
344 typedef _Tp result_type;
345 };
346
347 // several specializations for relational operators.
348 template<typename _Tp>
349 struct __fun<__logical_not, _Tp>
350 {
351 typedef bool result_type;
352 };
353
354 template<typename _Tp>
355 struct __fun<__logical_and, _Tp>
356 {
357 typedef bool result_type;
358 };
359
360 template<typename _Tp>
361 struct __fun<__logical_or, _Tp>
362 {
363 typedef bool result_type;
364 };
365
366 template<typename _Tp>
367 struct __fun<__less, _Tp>
368 {
369 typedef bool result_type;
370 };
371
372 template<typename _Tp>
373 struct __fun<__greater, _Tp>
374 {
375 typedef bool result_type;
376 };
377
378 template<typename _Tp>
379 struct __fun<__less_equal, _Tp>
380 {
381 typedef bool result_type;
382 };
383
384 template<typename _Tp>
385 struct __fun<__greater_equal, _Tp>
386 {
387 typedef bool result_type;
388 };
389
390 template<typename _Tp>
391 struct __fun<__equal_to, _Tp>
392 {
393 typedef bool result_type;
394 };
395
396 template<typename _Tp>
397 struct __fun<__not_equal_to, _Tp>
398 {
399 typedef bool result_type;
400 };
401
402 template<template<class, class> class _Meta, class _Dom, typename _Op>
403 class _UnFunClos;
404
405 template<class _Dom, typename _Op>
406 struct _UnFunClos<_Expr,_Dom, _Op> : _UnFunBase<_Dom, _Op>
407 {
408 typedef _UnFunBase<_Dom, _Op> _Base;
409 typedef typename _Base::value_type value_type;
410
411 explicit _UnFunClos (const _Dom& __e) : _Base (__e) {}
412 };
413
414 template<typename _Tp, typename _Op>
415 struct _UnFunClos<_ValArray,_Tp, _Op> : _UnFunBase<valarray<_Tp>, _Op>
416 {
417 typedef _UnFunBase<valarray<_Tp>, _Op> _Base;
418 typedef typename _Base::value_type value_type;
419
420 explicit _UnFunClos (const valarray<_Tp>& __v) : _Base (__v) {}
421 };
422
423 //
424 // Binary function application closure.
425 //
426 template<template<class, class> class _Meta1,
427 template<class, class> class Meta2,
428 class _Dom1, class _Dom2> class _BinFunClos;
429
430 template<class _Dom1, class _Dom2> class _BinFunBase {
431 public:
432 typedef typename _Dom1::value_type value_type;
433 typedef value_type _Vt;
434
435 _BinFunBase (const _Dom1& __e1, const _Dom2& __e2,
436 _Vt __f (_Vt, _Vt))
437 : _M_expr1 (__e1), _M_expr2 (__e2), _M_func (__f) {}
438
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 (); }
442
443 private:
444 const _Dom1& _M_expr1;
445 const _Dom2& _M_expr2;
446 _Vt (*_M_func)(_Vt, _Vt);
447 };
448
449 template<class _Dom> class _BinFunBase1 {
450 public:
451 typedef typename _Dom::value_type value_type ;
452 typedef value_type _Vt;
453
454 _BinFunBase1 (const _Vt& __c, const _Dom& __e, _Vt __f(_Vt, _Vt))
455 : _M_expr1 (__c), _M_expr2 (__e), _M_func (__f) {}
456
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 (); }
460
461 private:
462 const _Vt& _M_expr1;
463 const _Dom& _M_expr2;
464 _Vt (*_M_func)(_Vt, _Vt);
465 };
466
467 template<class _Dom> class _BinFunBase2 {
468 public:
469 typedef typename _Dom::value_type value_type;
470 typedef value_type _Vt;
471
472 _BinFunBase2 (const _Dom& __e, const _Vt& __c, _Vt __f(_Vt, _Vt))
473 : _M_expr1 (__e), _M_expr2 (__c), _M_func (__f) {}
474
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 (); }
478
479 private:
480 const _Dom& _M_expr1;
481 const _Vt& _M_expr2;
482 _Vt (*_M_func)(_Vt, _Vt);
483 };
484
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;
490
491 _BinFunClos (const _Dom1& __e1, const _Dom2& __e2,
492 _Tp __f(_Tp, _Tp))
493 : _Base (__e1, __e2, __f) {}
494 };
495
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;
501
502 _BinFunClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w,
503 _Tp __f(_Tp, _Tp))
504 : _Base (__v, __w, __f) {}
505 };
506
507 template<class _Dom>
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;
513
514 _BinFunClos (const _Dom& __e, const valarray<_Tp>& __v,
515 _Tp __f(_Tp, _Tp))
516 : _Base (__e, __v, __f) {}
517 };
518
519 template<class _Dom>
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;
525
526 _BinFunClos (const valarray<_Tp>& __v, const _Dom& __e,
527 _Tp __f(_Tp, _Tp))
528 : _Base (__v, __e, __f) {}
529 };
530
531 template<class _Dom>
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;
537
538 _BinFunClos (const _Dom& __e, const _Tp& __t, _Tp __f (_Tp, _Tp))
539 : _Base (__e, __t, __f) {}
540 };
541
542 template<class _Dom>
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;
548
549 _BinFunClos (const _Tp& __t, const _Dom& __e, _Tp __f (_Tp, _Tp))
550 : _Base (__t, __e, __f) {}
551 };
552
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;
558
559 _BinFunClos (const valarray<_Tp>& __v, const _Tp& __t,
560 _Tp __f(_Tp, _Tp))
561 : _Base (__v, __t, __f) {}
562 };
563
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;
569
570 _BinFunClos (const _Tp& __t, const valarray<_Tp>& __v,
571 _Tp __f (_Tp, _Tp))
572 : _Base (__t, __v, __f) {}
573 };
574
575 //
576 // Apply function taking a value/const reference closure
577 //
578
579 template<typename _Dom, typename _Arg> class _FunBase {
580 public:
581 typedef typename _Dom::value_type value_type;
582
583 _FunBase (const _Dom& __e, value_type __f(_Arg))
584 : _M_expr (__e), _M_func (__f) {}
585
586 value_type operator[] (size_t __i) const
587 { return _M_func (_M_expr[__i]); }
588 size_t size() const { return _M_expr.size ();}
589
590 private:
591 const _Dom& _M_expr;
592 value_type (*_M_func)(_Arg);
593 };
594
595 template<class _Dom>
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;
601
602 _ValFunClos (const _Dom& __e, _Tp __f (_Tp)) : _Base (__e, __f) {}
603 };
604
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;
610
611 _ValFunClos (const valarray<_Tp>& __v, _Tp __f(_Tp))
612 : _Base (__v, __f) {}
613 };
614
615 template<class _Dom>
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;
621
622 _RefFunClos (const _Dom& __e, _Tp __f (const _Tp&))
623 : _Base (__e, __f) {}
624 };
625
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;
631
632 _RefFunClos (const valarray<_Tp>& __v, _Tp __f(const _Tp&))
633 : _Base (__v, __f) {}
634 };
635
636 //
637 // Unary expression closure.
638 //
639
640 template<template<class> class _Oper, typename _Arg>
641 class _UnBase {
642 public:
643 typedef _Oper<typename _Arg::value_type> _Op;
644 typedef typename _Op::result_type value_type;
645
646 _UnBase (const _Arg& __e) : _M_expr(__e) {}
647 value_type operator[] (size_t) const;
648 size_t size () const { return _M_expr.size (); }
649
650 private:
651 const _Arg& _M_expr;
652 };
653
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]); }
658
659 template<template<class> class _Oper, class _Dom>
660 struct _UnClos<_Oper, _Expr, _Dom> : _UnBase<_Oper, _Dom> {
661 typedef _Dom _Arg;
662 typedef _UnBase<_Oper, _Dom> _Base;
663 typedef typename _Base::value_type value_type;
664
665 _UnClos (const _Arg& __e) : _Base(__e) {}
666 };
667
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;
673
674 _UnClos (const _Arg& __e) : _Base(__e) {}
675 };
676
677
678 //
679 // Binary expression closure.
680 //
681
682 template<template<class> class _Oper,
683 typename _FirstArg, typename _SecondArg>
684 class _BinBase {
685 public:
686 typedef _Oper<typename _FirstArg::value_type> _Op;
687 typedef typename _Op::result_type value_type;
688
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 (); }
693
694 private:
695 const _FirstArg& _M_expr1;
696 const _SecondArg& _M_expr2;
697 };
698
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]); }
704
705
706 template<template<class> class _Oper, class _Clos>
707 class _BinBase2 {
708 public:
709 typedef typename _Clos::value_type _Vt;
710 typedef _Oper<_Vt> _Op;
711 typedef typename _Op::result_type value_type;
712
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 (); }
717
718 private:
719 const _Clos& _M_expr1;
720 const _Vt& _M_expr2;
721 };
722
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); }
727
728
729 template<template<class> class _Oper, class _Clos>
730 class _BinBase1 {
731 public:
732 typedef typename _Clos::value_type _Vt;
733 typedef _Oper<_Vt> _Op;
734 typedef typename _Op::result_type value_type;
735
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 (); }
740
741 private:
742 const _Vt& _M_expr1;
743 const _Clos& _M_expr2;
744 };
745
746 template<template<class> class _Oper, class _Clos>
747 inline typename
748 _BinBase1<_Oper,_Clos>::value_type
749 _BinBase1<_Oper,_Clos>:: operator[] (size_t __i) const
750 { return _Op() (_M_expr1, _M_expr2[__i]); }
751
752
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;
758
759 _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {}
760 };
761
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;
767
768 _BinClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w)
769 : _Base (__v, __w) {}
770 };
771
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;
778
779 _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2)
780 : _Base (__e1, __e2) {}
781 };
782
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;
789
790 _BinClos (const valarray<_Tp>& __e1, const _Dom& __e2)
791 : _Base (__e1, __e2) {}
792 };
793
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;
800
801 _BinClos (const _Dom& __e1, const _Tp& __e2) : _Base (__e1, __e2) {}
802 };
803
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;
810
811 _BinClos (const _Tp& __e1, const _Dom& __e2) : _Base (__e1, __e2) {}
812 };
813
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;
819
820 _BinClos (const valarray<_Tp>& __v, const _Tp& __t)
821 : _Base (__v, __t) {}
822 };
823
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;
829
830 _BinClos (const _Tp& __t, const valarray<_Tp>& __v)
831 : _Base (__t, __v) {}
832 };
833
834
835 //
836 // slice_array closure.
837 //
838 template<typename _Dom> class _SBase {
839 public:
840 typedef typename _Dom::value_type value_type;
841
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 (); }
847
848 private:
849 const _Dom& _M_expr;
850 const slice& _M_slice;
851 };
852
853 template<typename _Tp> class _SBase<_Array<_Tp> > {
854 public:
855 typedef _Tp value_type;
856
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; }
863
864 private:
865 const _Array<_Tp> _M_array;
866 const size_t _M_size;
867 const size_t _M_stride;
868 };
869
870 template<class _Dom> struct _SClos<_Expr,_Dom> : _SBase<_Dom> {
871 typedef _SBase<_Dom> _Base;
872 typedef typename _Base::value_type value_type;
873
874 _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {}
875 };
876
877 template<typename _Tp>
878 struct _SClos<_ValArray,_Tp> : _SBase<_Array<_Tp> > {
879 typedef _SBase<_Array<_Tp> > _Base;
880 typedef _Tp value_type;
881
882 _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {}
883 };
884
885 //
886 // gslice_array closure.
887 //
888 template<class _Dom> class _GBase {
889 public:
890 typedef typename _Dom::value_type value_type;
891
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(); }
897
898 private:
899 const _Dom& _M_expr;
900 const valarray<size_t>& _M_index;
901 };
902
903 template<typename _Tp> class _GBase<_Array<_Tp> > {
904 public:
905 typedef _Tp value_type;
906
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(); }
912
913 private:
914 const _Array<_Tp> _M_array;
915 const valarray<size_t>& _M_index;
916 };
917
918 template<class _Dom> struct _GClos<_Expr,_Dom> : _GBase<_Dom> {
919 typedef _GBase<_Dom> _Base;
920 typedef typename _Base::value_type value_type;
921
922 _GClos (const _Dom& __e, const valarray<size_t>& __i)
923 : _Base (__e, __i) {}
924 };
925
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;
930
931 _GClos (_Array<_Tp> __a, const valarray<size_t>& __i)
932 : _Base (__a, __i) {}
933 };
934
935 //
936 // indirect_array closure
937 //
938
939 template<class _Dom> class _IBase {
940 public:
941 typedef typename _Dom::value_type value_type;
942
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(); }
948
949 private:
950 const _Dom& _M_expr;
951 const valarray<size_t>& _M_index;
952 };
953
954 template<class _Dom> struct _IClos<_Expr,_Dom> : _IBase<_Dom> {
955 typedef _IBase<_Dom> _Base;
956 typedef typename _Base::value_type value_type;
957
958 _IClos (const _Dom& __e, const valarray<size_t>& __i)
959 : _Base (__e, __i) {}
960 };
961
962 template<typename _Tp>
963 struct _IClos<_ValArray,_Tp> : _IBase<valarray<_Tp> > {
964 typedef _IBase<valarray<_Tp> > _Base;
965 typedef _Tp value_type;
966
967 _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i)
968 : _Base (__a, __i) {}
969 };
970
971 //
972 // class _Expr
973 //
974 template<class _Clos, typename _Tp> class _Expr {
975 public:
976 typedef _Tp value_type;
977
978 _Expr (const _Clos&);
979
980 const _Clos& operator() () const;
981
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;
987
988 _Expr<_UnClos<_Unary_plus,std::_Expr,_Clos>, value_type>
989 operator+ () const;
990
991 _Expr<_UnClos<negate,std::_Expr,_Clos>, value_type>
992 operator- () const;
993
994 _Expr<_UnClos<_Bitwise_not,std::_Expr,_Clos>, value_type>
995 operator~ () const;
996
997 _Expr<_UnClos<logical_not,std::_Expr,_Clos>, bool>
998 operator! () const;
999
1000 size_t size () const;
1001 value_type sum () const;
1002
1003 valarray<value_type> shift (int) const;
1004 valarray<value_type> cshift (int) const;
1005
1006 value_type min() const;
1007 value_type max() const;
1008
1009 valarray<value_type> apply(value_type (*) (const value_type&)) const;
1010 valarray<value_type> apply(value_type (*) (value_type)) const;
1011
1012 private:
1013 const _Clos _M_closure;
1014 };
1015
1016 template<class _Clos, typename _Tp>
1017 inline
1018 _Expr<_Clos,_Tp>::_Expr (const _Clos& __c) : _M_closure(__c) {}
1019
1020 template<class _Clos, typename _Tp>
1021 inline const _Clos&
1022 _Expr<_Clos,_Tp>::operator() () const
1023 { return _M_closure; }
1024
1025 template<class _Clos, typename _Tp>
1026 inline _Tp
1027 _Expr<_Clos,_Tp>::operator[] (size_t __i) const
1028 { return _M_closure[__i]; }
1029
1030 template<class _Clos, typename _Tp>
1031 inline valarray<_Tp>
1032 _Expr<_Clos,_Tp>::operator[] (slice __s) const
1033 { return _M_closure[__s]; }
1034
1035 template<class _Clos, typename _Tp>
1036 inline valarray<_Tp>
1037 _Expr<_Clos,_Tp>::operator[] (const gslice& __gs) const
1038 { return _M_closure[__gs]; }
1039
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]; }
1044
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]; }
1049
1050 template<class _Clos, typename _Tp>
1051 inline size_t
1052 _Expr<_Clos,_Tp>::size () const { return _M_closure.size (); }
1053
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); }
1058
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); }
1063
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); }
1068
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); }
1073
1074 // XXX: replace this with a more robust summation algorithm.
1075 template<class _Clos, typename _Tp>
1076 inline _Tp
1077 _Expr<_Clos,_Tp>::sum () const
1078 {
1079 size_t __n = _M_closure.size();
1080 if (__n == 0) return _Tp();
1081 else {
1082 _Tp __s = _M_closure[--__n];
1083 while (__n != 0) __s += _M_closure[--__n];
1084 return __s;
1085 }
1086 }
1087
1088 template<class _Clos, typename _Tp>
1089 inline _Tp
1090 _Expr<_Clos, _Tp>::min() const
1091 { return __valarray_min(_M_closure); }
1092
1093 template<class _Clos, typename _Tp>
1094 inline _Tp
1095 _Expr<_Clos, _Tp>::max() const
1096 { return __valarray_max(_M_closure); }
1097
1098 template<class _Dom, typename _Tp>
1099 inline _Expr<_UnClos<logical_not,_Expr,_Dom>, bool>
1100 _Expr<_Dom,_Tp>::operator! () const
1101 {
1102 typedef _UnClos<logical_not,std::_Expr,_Dom> _Closure;
1103 return _Expr<_Closure,_Tp> (_Closure(this->_M_closure));
1104 }
1105
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 \
1110 { \
1111 typedef _UnClos<_Name,std::_Expr,_Dom> _Closure; \
1112 return _Expr<_Closure,_Tp> (_Closure (this->_M_closure)); \
1113 }
1114
1115 _DEFINE_EXPR_UNARY_OPERATOR(+, _Unary_plus)
1116 _DEFINE_EXPR_UNARY_OPERATOR(-, negate)
1117 _DEFINE_EXPR_UNARY_OPERATOR(~, _Bitwise_not)
1118
1119 #undef _DEFINE_EXPR_UNARY_OPERATOR
1120
1121
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) \
1128 { \
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 ())); \
1133 } \
1134 \
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) \
1140 { \
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)); \
1145 } \
1146 \
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) \
1152 { \
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 ())); \
1157 } \
1158 \
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) \
1164 { \
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)); \
1169 } \
1170 \
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) \
1176 { \
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 ())); \
1181 }
1182
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)
1193
1194 #undef _DEFINE_EXPR_BINARY_OPERATOR
1195
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) \
1201 { \
1202 typedef typename _Dom1::value_type _Arg; \
1203 typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \
1204 return _Expr<_Closure,bool> (_Closure (__v (), __w ())); \
1205 } \
1206 \
1207 template<class _Dom> \
1208 inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \
1209 bool> \
1210 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __v, \
1211 const typename _Dom::value_type& __t) \
1212 { \
1213 typedef typename _Dom::value_type _Arg; \
1214 typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \
1215 return _Expr<_Closure,bool> (_Closure (__v (), __t)); \
1216 } \
1217 \
1218 template<class _Dom> \
1219 inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \
1220 bool> \
1221 operator _Op (const typename _Dom::value_type& __t, \
1222 const _Expr<_Dom,typename _Dom::value_type>& __v) \
1223 { \
1224 typedef typename _Dom::value_type _Arg; \
1225 typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \
1226 return _Expr<_Closure,bool> (_Closure (__t, __v ())); \
1227 } \
1228 \
1229 template<class _Dom> \
1230 inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \
1231 bool> \
1232 operator _Op (const _Expr<_Dom,typename _Dom::value_type>& __e, \
1233 const valarray<typename _Dom::value_type>& __v) \
1234 { \
1235 typedef typename _Dom::value_type _Tp; \
1236 typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Tp> _Closure; \
1237 return _Expr<_Closure,bool> (_Closure (__e (), __v)); \
1238 } \
1239 \
1240 template<class _Dom> \
1241 inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \
1242 bool> \
1243 operator _Op (const valarray<typename _Dom::value_type>& __v, \
1244 const _Expr<_Dom,typename _Dom::value_type>& __e) \
1245 { \
1246 typedef typename _Dom::value_type _Tp; \
1247 typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \
1248 return _Expr<_Closure,bool> (_Closure (__v, __e ())); \
1249 }
1250
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)
1259
1260 #undef _DEFINE_EXPR_RELATIONAL_OPERATOR
1261
1262
1263
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) \
1268 { \
1269 typedef typename _Dom::value_type _Tp; \
1270 typedef _UnFunClos<_Expr,_Dom,__##_Name> _Closure; \
1271 return _Expr<_Closure,_Tp>(_Closure(__e())); \
1272 } \
1273 \
1274 template<typename _Tp> \
1275 inline _Expr<_UnFunClos<_ValArray,_Tp,__##_Name>,_Tp> \
1276 _Name(const valarray<_Tp>& __v) \
1277 { \
1278 typedef _UnFunClos<_ValArray,_Tp,__##_Name> _Closure; \
1279 return _Expr<_Closure,_Tp>(_Closure (__v)); \
1280 }
1281
1282
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)
1297
1298 #undef _DEFINE_EXPR_UNARY_FUNCTION
1299
1300
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) \
1306 { \
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))); \
1311 } \
1312 \
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) \
1318 { \
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))); \
1323 } \
1324 \
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) \
1330 { \
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))); \
1335 } \
1336 \
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) \
1342 { \
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))); \
1347 } \
1348 \
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) \
1354 { \
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))); \
1359 } \
1360 \
1361 template<typename _Tp> \
1362 inline _Expr<_BinFunClos<_ValArray,_ValArray,_Tp,_Tp>, _Tp> \
1363 _Name (const valarray<_Tp>& __v, const valarray<_Tp>& __w) \
1364 { \
1365 typedef _BinFunClos<_ValArray,_ValArray,_Tp,_Tp> _Closure; \
1366 return _Expr<_Closure,_Tp> \
1367 (_Closure (__v, __w, (_Tp(*)(_Tp,_Tp))(&_Name))); \
1368 } \
1369 \
1370 template<typename _Tp> \
1371 inline _Expr<_BinFunClos<_ValArray,_Constant,_Tp,_Tp>,_Tp> \
1372 _Name (const valarray<_Tp>& __v, const _Tp& __t) \
1373 { \
1374 typedef _BinFunClos<_ValArray,_Constant,_Tp,_Tp> _Closure; \
1375 return _Expr<_Closure,_Tp> \
1376 (_Closure (__v, __t, (_Tp(*)(_Tp,_Tp))(&_Name))); \
1377 } \
1378 \
1379 template<typename _Tp> \
1380 inline _Expr<_BinFunClos<_Constant,_ValArray,_Tp,_Tp>,_Tp> \
1381 _Name (const _Tp& __t, const valarray<_Tp>& __v) \
1382 { \
1383 typedef _BinFunClos<_Constant,_ValArray,_Tp,_Tp> _Closure; \
1384 return _Expr<_Closure,_Tp> \
1385 (_Closure (__t, __v, (_Tp(*)(_Tp,_Tp))(&_Name))); \
1386 }
1387
1388 _DEFINE_EXPR_BINARY_FUNCTION(atan2)
1389 _DEFINE_EXPR_BINARY_FUNCTION(pow)
1390
1391 #undef _DEFINE_EXPR_BINARY_FUNCTION
1392
1393 } // std::
1394
1395
1396 #endif /* _CPP_VALARRAY_META_H */
1397
1398 // Local Variables:
1399 // mode:c++
1400 // End: