1 // The template and inlines for the -*- C++ -*- internal _Meta class.
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
30 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr>
32 /** @file valarray_meta.h
33 * This is an internal header file, included by other library headers.
34 * You should not attempt to use it directly.
37 #ifndef _CPP_VALARRAY_META_H
38 #define _CPP_VALARRAY_META_H 1
40 #pragma GCC system_header
45 // Implementing a loosened valarray return value is tricky.
46 // First we need to meet 26.3.1/3: we should not add more than
47 // two levels of template nesting. Therefore we resort to template
48 // template to "flatten" loosened return value types.
49 // At some point we use partial specialization to remove one level
50 // template nesting due to _Expr<>
53 // This class is NOT defined. It doesn't need to.
54 template<typename _Tp1, typename _Tp2> class _Constant;
56 // Implementations of unary functions applied to valarray<>s.
57 // I use hard-coded object functions here instead of a generic
58 // approach like pointers to function:
59 // 1) correctness: some functions take references, others values.
60 // we can't deduce the correct type afterwards.
61 // 2) efficiency -- object functions can be easily inlined
62 // 3) be Koenig-lookup-friendly
66 template<typename _Tp>
67 _Tp operator()(const _Tp& __t) const { return abs(__t); }
72 template<typename _Tp>
73 _Tp operator()(const _Tp& __t) const { return cos(__t); }
78 template<typename _Tp>
79 _Tp operator()(const _Tp& __t) const { return acos(__t); }
84 template<typename _Tp>
85 _Tp operator()(const _Tp& __t) const { return cosh(__t); }
90 template<typename _Tp>
91 _Tp operator()(const _Tp& __t) const { return sin(__t); }
96 template<typename _Tp>
97 _Tp operator()(const _Tp& __t) const { return asin(__t); }
102 template<typename _Tp>
103 _Tp operator()(const _Tp& __t) const { return sinh(__t); }
108 template<typename _Tp>
109 _Tp operator()(const _Tp& __t) const { return tan(__t); }
114 template<typename _Tp>
115 _Tp operator()(const _Tp& __t) const { return atan(__t); }
120 template<typename _Tp>
121 _Tp operator()(const _Tp& __t) const { return tanh(__t); }
126 template<typename _Tp>
127 _Tp operator()(const _Tp& __t) const { return exp(__t); }
132 template<typename _Tp>
133 _Tp operator()(const _Tp& __t) const { return log(__t); }
138 template<typename _Tp>
139 _Tp operator()(const _Tp& __t) const { return log10(__t); }
144 template<typename _Tp>
145 _Tp operator()(const _Tp& __t) const { return sqrt(__t); }
148 // In the past, we used to tailor operator applications semantics
149 // to the specialization of standard function objects (i.e. plus<>, etc.)
150 // That is incorrect. Therefore we provide our own surrogates.
154 template<typename _Tp>
155 _Tp operator()(const _Tp& __t) const { return +__t; }
160 template<typename _Tp>
161 _Tp operator()(const _Tp& __t) const { return -__t; }
166 template<typename _Tp>
167 _Tp operator()(const _Tp& __t) const { return ~__t; }
172 template<typename _Tp>
173 _Tp operator()(const _Tp& __x, const _Tp& __y) const
174 { return __x + __y; }
179 template<typename _Tp>
180 _Tp operator()(const _Tp& __x, const _Tp& __y) const
181 { return __x - __y; }
186 template<typename _Tp>
187 _Tp operator()(const _Tp& __x, const _Tp& __y) const
188 { return __x * __y; }
193 template<typename _Tp>
194 _Tp operator()(const _Tp& __x, const _Tp& __y) const
195 { return __x / __y; }
200 template<typename _Tp>
201 _Tp operator()(const _Tp& __x, const _Tp& __y) const
202 { return __x % __y; }
207 template<typename _Tp>
208 _Tp operator()(const _Tp& __x, const _Tp& __y) const
209 { return __x ^ __y; }
214 template<typename _Tp>
215 _Tp operator()(const _Tp& __x, const _Tp& __y) const
216 { return __x & __y; }
221 template<typename _Tp>
222 _Tp operator()(const _Tp& __x, const _Tp& __y) const
223 { return __x | __y; }
228 template<typename _Tp>
229 _Tp operator()(const _Tp& __x, const _Tp& __y) const
230 { return __x << __y; }
235 template<typename _Tp>
236 _Tp operator()(const _Tp& __x, const _Tp& __y) const
237 { return __x >> __y; }
242 template<typename _Tp>
243 bool operator()(const _Tp& __x, const _Tp& __y) const
244 { return __x && __y; }
249 template<typename _Tp>
250 bool operator()(const _Tp& __x, const _Tp& __y) const
251 { return __x || __y; }
256 template<typename _Tp>
257 bool operator()(const _Tp& __x) const { return !__x; }
262 template<typename _Tp>
263 bool operator()(const _Tp& __x, const _Tp& __y) const
264 { return __x == __y; }
267 struct __not_equal_to
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 _Tp& __y) const
278 { return __x < __y; }
283 template<typename _Tp>
284 bool operator()(const _Tp& __x, const _Tp& __y) const
285 { return __x > __y; }
290 template<typename _Tp>
291 bool operator()(const _Tp& __x, const _Tp& __y) const
292 { return __x <= __y; }
295 struct __greater_equal
297 template<typename _Tp>
298 bool operator()(const _Tp& __x, const _Tp& __y) const
299 { return __x >= __y; }
302 // The few binary functions we miss.
305 template<typename _Tp>
306 _Tp operator()(const _Tp& __x, const _Tp& __y) const
307 { return atan2(__x, __y); }
312 template<typename _Tp>
313 _Tp operator()(const _Tp& __x, const _Tp& __y) const
314 { return pow(__x, __y); }
318 // We need these bits in order to recover the return type of
319 // some functions/operators now that we're no longer using
320 // function templates.
321 template<typename, typename _Tp>
324 typedef _Tp result_type;
327 // several specializations for relational operators.
328 template<typename _Tp>
329 struct __fun<__logical_not, _Tp>
331 typedef bool result_type;
334 template<typename _Tp>
335 struct __fun<__logical_and, _Tp>
337 typedef bool result_type;
340 template<typename _Tp>
341 struct __fun<__logical_or, _Tp>
343 typedef bool result_type;
346 template<typename _Tp>
347 struct __fun<__less, _Tp>
349 typedef bool result_type;
352 template<typename _Tp>
353 struct __fun<__greater, _Tp>
355 typedef bool result_type;
358 template<typename _Tp>
359 struct __fun<__less_equal, _Tp>
361 typedef bool result_type;
364 template<typename _Tp>
365 struct __fun<__greater_equal, _Tp>
367 typedef bool result_type;
370 template<typename _Tp>
371 struct __fun<__equal_to, _Tp>
373 typedef bool result_type;
376 template<typename _Tp>
377 struct __fun<__not_equal_to, _Tp>
379 typedef bool result_type;
383 // Apply function taking a value/const reference closure
386 template<typename _Dom, typename _Arg>
390 typedef typename _Dom::value_type value_type;
392 _FunBase(const _Dom& __e, value_type __f(_Arg))
393 : _M_expr(__e), _M_func(__f) {}
395 value_type operator[](size_t __i) const
396 { return _M_func (_M_expr[__i]); }
398 size_t size() const { return _M_expr.size ();}
402 value_type (*_M_func)(_Arg);
406 struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type>
408 typedef _FunBase<_Dom, typename _Dom::value_type> _Base;
409 typedef typename _Base::value_type value_type;
410 typedef value_type _Tp;
412 _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {}
415 template<typename _Tp>
416 struct _ValFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, _Tp>
418 typedef _FunBase<valarray<_Tp>, _Tp> _Base;
419 typedef _Tp value_type;
421 _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {}
425 struct _RefFunClos<_Expr,_Dom> :
426 _FunBase<_Dom, const typename _Dom::value_type&>
428 typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base;
429 typedef typename _Base::value_type value_type;
430 typedef value_type _Tp;
432 _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&))
436 template<typename _Tp>
437 struct _RefFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, const _Tp&>
439 typedef _FunBase<valarray<_Tp>, const _Tp&> _Base;
440 typedef _Tp value_type;
442 _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&))
447 // Unary expression closure.
450 template<class _Oper, class _Arg>
454 typedef typename _Arg::value_type _Vt;
455 typedef typename __fun<_Oper, _Vt>::result_type value_type;
457 _UnBase(const _Arg& __e) : _M_expr(__e) {}
459 value_type operator[](size_t __i) const
460 { return _Oper()(_M_expr[__i]); }
462 size_t size() const { return _M_expr.size(); }
468 template<class _Oper, class _Dom>
469 struct _UnClos<_Oper, _Expr, _Dom> : _UnBase<_Oper, _Dom>
472 typedef _UnBase<_Oper, _Dom> _Base;
473 typedef typename _Base::value_type value_type;
475 _UnClos(const _Arg& __e) : _Base(__e) {}
478 template<class _Oper, typename _Tp>
479 struct _UnClos<_Oper, _ValArray, _Tp> : _UnBase<_Oper, valarray<_Tp> >
481 typedef valarray<_Tp> _Arg;
482 typedef _UnBase<_Oper, valarray<_Tp> > _Base;
483 typedef typename _Base::value_type value_type;
485 _UnClos(const _Arg& __e) : _Base(__e) {}
490 // Binary expression closure.
493 template<class _Oper, class _FirstArg, class _SecondArg>
497 typedef typename _FirstArg::value_type _Vt;
498 typedef typename __fun<_Oper, _Vt>::result_type value_type;
500 _BinBase(const _FirstArg& __e1, const _SecondArg& __e2)
501 : _M_expr1(__e1), _M_expr2(__e2) {}
503 value_type operator[](size_t __i) const
504 { return _Oper()(_M_expr1[__i], _M_expr2[__i]); }
506 size_t size() const { return _M_expr1.size(); }
509 const _FirstArg& _M_expr1;
510 const _SecondArg& _M_expr2;
514 template<class _Oper, class _Clos>
518 typedef typename _Clos::value_type _Vt;
519 typedef typename __fun<_Oper, _Vt>::result_type value_type;
521 _BinBase2(const _Clos& __e, const _Vt& __t)
522 : _M_expr1(__e), _M_expr2(__t) {}
524 value_type operator[](size_t __i) const
525 { return _Oper()(_M_expr1[__i], _M_expr2); }
527 size_t size() const { return _M_expr1.size(); }
530 const _Clos& _M_expr1;
534 template<class _Oper, class _Clos>
538 typedef typename _Clos::value_type _Vt;
539 typedef typename __fun<_Oper, _Vt>::result_type value_type;
541 _BinBase1(const _Vt& __t, const _Clos& __e)
542 : _M_expr1(__t), _M_expr2(__e) {}
544 value_type operator[](size_t __i) const
545 { return _Oper()(_M_expr1, _M_expr2[__i]); }
547 size_t size() const { return _M_expr2.size(); }
551 const _Clos& _M_expr2;
554 template<class _Oper, class _Dom1, class _Dom2>
555 struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2>
556 : _BinBase<_Oper,_Dom1,_Dom2>
558 typedef _BinBase<_Oper,_Dom1,_Dom2> _Base;
559 typedef typename _Base::value_type value_type;
561 _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {}
564 template<class _Oper, typename _Tp>
565 struct _BinClos<_Oper,_ValArray,_ValArray,_Tp,_Tp>
566 : _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> >
568 typedef _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > _Base;
569 typedef _Tp value_type;
571 _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w)
575 template<class _Oper, class _Dom>
576 struct _BinClos<_Oper,_Expr,_ValArray,_Dom,typename _Dom::value_type>
577 : _BinBase<_Oper,_Dom,valarray<typename _Dom::value_type> >
579 typedef typename _Dom::value_type _Tp;
580 typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base;
581 typedef typename _Base::value_type value_type;
583 _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2)
584 : _Base(__e1, __e2) {}
587 template<class _Oper, class _Dom>
588 struct _BinClos<_Oper,_ValArray,_Expr,typename _Dom::value_type,_Dom>
589 : _BinBase<_Oper,valarray<typename _Dom::value_type>,_Dom>
591 typedef typename _Dom::value_type _Tp;
592 typedef _BinBase<_Oper,valarray<_Tp>,_Dom> _Base;
593 typedef typename _Base::value_type value_type;
595 _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2)
596 : _Base(__e1, __e2) {}
599 template<class _Oper, class _Dom>
600 struct _BinClos<_Oper,_Expr,_Constant,_Dom,typename _Dom::value_type>
601 : _BinBase2<_Oper,_Dom>
603 typedef typename _Dom::value_type _Tp;
604 typedef _BinBase2<_Oper,_Dom> _Base;
605 typedef typename _Base::value_type value_type;
607 _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {}
610 template<class _Oper, class _Dom>
611 struct _BinClos<_Oper,_Constant,_Expr,typename _Dom::value_type,_Dom>
612 : _BinBase1<_Oper,_Dom>
614 typedef typename _Dom::value_type _Tp;
615 typedef _BinBase1<_Oper,_Dom> _Base;
616 typedef typename _Base::value_type value_type;
618 _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {}
621 template<class _Oper, typename _Tp>
622 struct _BinClos<_Oper,_ValArray,_Constant,_Tp,_Tp>
623 : _BinBase2<_Oper,valarray<_Tp> >
625 typedef _BinBase2<_Oper,valarray<_Tp> > _Base;
626 typedef typename _Base::value_type value_type;
628 _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {}
631 template<class _Oper, typename _Tp>
632 struct _BinClos<_Oper,_Constant,_ValArray,_Tp,_Tp>
633 : _BinBase1<_Oper,valarray<_Tp> >
635 typedef _BinBase1<_Oper,valarray<_Tp> > _Base;
636 typedef typename _Base::value_type value_type;
638 _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {}
643 // slice_array closure.
645 template<typename _Dom> class _SBase {
647 typedef typename _Dom::value_type value_type;
649 _SBase (const _Dom& __e, const slice& __s)
650 : _M_expr (__e), _M_slice (__s) {}
651 value_type operator[] (size_t __i) const
652 { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; }
653 size_t size() const { return _M_slice.size (); }
657 const slice& _M_slice;
660 template<typename _Tp> class _SBase<_Array<_Tp> > {
662 typedef _Tp value_type;
664 _SBase (_Array<_Tp> __a, const slice& __s)
665 : _M_array (__a._M_data+__s.start()), _M_size (__s.size()),
666 _M_stride (__s.stride()) {}
667 value_type operator[] (size_t __i) const
668 { return _M_array._M_data[__i * _M_stride]; }
669 size_t size() const { return _M_size; }
672 const _Array<_Tp> _M_array;
673 const size_t _M_size;
674 const size_t _M_stride;
677 template<class _Dom> struct _SClos<_Expr,_Dom> : _SBase<_Dom> {
678 typedef _SBase<_Dom> _Base;
679 typedef typename _Base::value_type value_type;
681 _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {}
684 template<typename _Tp>
685 struct _SClos<_ValArray,_Tp> : _SBase<_Array<_Tp> > {
686 typedef _SBase<_Array<_Tp> > _Base;
687 typedef _Tp value_type;
689 _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {}
693 // gslice_array closure.
695 template<class _Dom> class _GBase {
697 typedef typename _Dom::value_type value_type;
699 _GBase (const _Dom& __e, const valarray<size_t>& __i)
700 : _M_expr (__e), _M_index(__i) {}
701 value_type operator[] (size_t __i) const
702 { return _M_expr[_M_index[__i]]; }
703 size_t size () const { return _M_index.size(); }
707 const valarray<size_t>& _M_index;
710 template<typename _Tp> class _GBase<_Array<_Tp> > {
712 typedef _Tp value_type;
714 _GBase (_Array<_Tp> __a, const valarray<size_t>& __i)
715 : _M_array (__a), _M_index(__i) {}
716 value_type operator[] (size_t __i) const
717 { return _M_array._M_data[_M_index[__i]]; }
718 size_t size () const { return _M_index.size(); }
721 const _Array<_Tp> _M_array;
722 const valarray<size_t>& _M_index;
725 template<class _Dom> struct _GClos<_Expr,_Dom> : _GBase<_Dom> {
726 typedef _GBase<_Dom> _Base;
727 typedef typename _Base::value_type value_type;
729 _GClos (const _Dom& __e, const valarray<size_t>& __i)
730 : _Base (__e, __i) {}
733 template<typename _Tp>
734 struct _GClos<_ValArray,_Tp> : _GBase<_Array<_Tp> > {
735 typedef _GBase<_Array<_Tp> > _Base;
736 typedef typename _Base::value_type value_type;
738 _GClos (_Array<_Tp> __a, const valarray<size_t>& __i)
739 : _Base (__a, __i) {}
743 // indirect_array closure
746 template<class _Dom> class _IBase {
748 typedef typename _Dom::value_type value_type;
750 _IBase (const _Dom& __e, const valarray<size_t>& __i)
751 : _M_expr (__e), _M_index (__i) {}
752 value_type operator[] (size_t __i) const
753 { return _M_expr[_M_index[__i]]; }
754 size_t size() const { return _M_index.size(); }
758 const valarray<size_t>& _M_index;
761 template<class _Dom> struct _IClos<_Expr,_Dom> : _IBase<_Dom> {
762 typedef _IBase<_Dom> _Base;
763 typedef typename _Base::value_type value_type;
765 _IClos (const _Dom& __e, const valarray<size_t>& __i)
766 : _Base (__e, __i) {}
769 template<typename _Tp>
770 struct _IClos<_ValArray,_Tp> : _IBase<valarray<_Tp> > {
771 typedef _IBase<valarray<_Tp> > _Base;
772 typedef _Tp value_type;
774 _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i)
775 : _Base (__a, __i) {}
781 template<class _Clos, typename _Tp>
785 typedef _Tp value_type;
789 const _Clos& operator()() const;
791 value_type operator[](size_t) const;
792 valarray<value_type> operator[](slice) const;
793 valarray<value_type> operator[](const gslice&) const;
794 valarray<value_type> operator[](const valarray<bool>&) const;
795 valarray<value_type> operator[](const valarray<size_t>&) const;
797 _Expr<_UnClos<__unary_plus,std::_Expr,_Clos>, value_type>
800 _Expr<_UnClos<__negate,std::_Expr,_Clos>, value_type>
803 _Expr<_UnClos<__bitwise_not,std::_Expr,_Clos>, value_type>
806 _Expr<_UnClos<__logical_not,std::_Expr,_Clos>, bool>
810 value_type sum() const;
812 valarray<value_type> shift(int) const;
813 valarray<value_type> cshift(int) const;
815 value_type min() const;
816 value_type max() const;
818 valarray<value_type> apply(value_type (*)(const value_type&)) const;
819 valarray<value_type> apply(value_type (*)(value_type)) const;
822 const _Clos _M_closure;
825 template<class _Clos, typename _Tp>
827 _Expr<_Clos,_Tp>::_Expr(const _Clos& __c) : _M_closure(__c) {}
829 template<class _Clos, typename _Tp>
831 _Expr<_Clos,_Tp>::operator()() const
832 { return _M_closure; }
834 template<class _Clos, typename _Tp>
836 _Expr<_Clos,_Tp>::operator[](size_t __i) const
837 { return _M_closure[__i]; }
839 template<class _Clos, typename _Tp>
841 _Expr<_Clos,_Tp>::operator[](slice __s) const
842 { return _M_closure[__s]; }
844 template<class _Clos, typename _Tp>
846 _Expr<_Clos,_Tp>::operator[](const gslice& __gs) const
847 { return _M_closure[__gs]; }
849 template<class _Clos, typename _Tp>
851 _Expr<_Clos,_Tp>::operator[](const valarray<bool>& __m) const
852 { return _M_closure[__m]; }
854 template<class _Clos, typename _Tp>
856 _Expr<_Clos,_Tp>::operator[](const valarray<size_t>& __i) const
857 { return _M_closure[__i]; }
859 template<class _Clos, typename _Tp>
861 _Expr<_Clos,_Tp>::size() const { return _M_closure.size (); }
863 template<class _Clos, typename _Tp>
865 _Expr<_Clos, _Tp>::shift(int __n) const
866 { return valarray<_Tp>(_M_closure).shift(__n); }
868 template<class _Clos, typename _Tp>
870 _Expr<_Clos, _Tp>::cshift(int __n) const
871 { return valarray<_Tp>(_M_closure).cshift(__n); }
873 template<class _Clos, typename _Tp>
875 _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const
876 { return valarray<_Tp>(_M_closure).apply(__f); }
878 template<class _Clos, typename _Tp>
880 _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const
881 { return valarray<_Tp>(_M_closure).apply(__f); }
883 // XXX: replace this with a more robust summation algorithm.
884 template<class _Clos, typename _Tp>
886 _Expr<_Clos,_Tp>::sum() const
888 size_t __n = _M_closure.size();
893 _Tp __s = _M_closure[--__n];
895 __s += _M_closure[--__n];
900 template<class _Clos, typename _Tp>
902 _Expr<_Clos, _Tp>::min() const
903 { return __valarray_min(_M_closure); }
905 template<class _Clos, typename _Tp>
907 _Expr<_Clos, _Tp>::max() const
908 { return __valarray_max(_M_closure); }
910 template<class _Dom, typename _Tp>
911 inline _Expr<_UnClos<__logical_not,_Expr,_Dom>, bool>
912 _Expr<_Dom,_Tp>::operator!() const
914 typedef _UnClos<__logical_not,std::_Expr,_Dom> _Closure;
915 return _Expr<_Closure,_Tp>(_Closure(this->_M_closure));
918 #define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \
919 template<class _Dom, typename _Tp> \
920 inline _Expr<_UnClos<_Name,std::_Expr,_Dom>,_Tp> \
921 _Expr<_Dom,_Tp>::operator _Op() const \
923 typedef _UnClos<_Name,std::_Expr,_Dom> _Closure; \
924 return _Expr<_Closure,_Tp>(_Closure(this->_M_closure)); \
927 _DEFINE_EXPR_UNARY_OPERATOR(+, __unary_plus)
928 _DEFINE_EXPR_UNARY_OPERATOR(-, __negate)
929 _DEFINE_EXPR_UNARY_OPERATOR(~, __bitwise_not)
931 #undef _DEFINE_EXPR_UNARY_OPERATOR
934 #define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \
935 template<class _Dom1, class _Dom2> \
936 inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, \
937 typename __fun<_Name, typename _Dom1::value_type>::result_type>\
938 operator _Op(const _Expr<_Dom1,typename _Dom1::value_type>& __v, \
939 const _Expr<_Dom2,typename _Dom2::value_type>& __w) \
941 typedef typename _Dom1::value_type _Arg; \
942 typedef typename __fun<_Name, _Arg>::result_type _Value; \
943 typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \
944 return _Expr<_Closure,_Value>(_Closure(__v(), __w())); \
947 template<class _Dom> \
948 inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>,\
949 typename __fun<_Name, typename _Dom::value_type>::result_type>\
950 operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __v, \
951 const typename _Dom::value_type& __t) \
953 typedef typename _Dom::value_type _Arg; \
954 typedef typename __fun<_Name, _Arg>::result_type _Value; \
955 typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \
956 return _Expr<_Closure,_Value>(_Closure(__v(), __t)); \
959 template<class _Dom> \
960 inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>,\
961 typename __fun<_Name, typename _Dom::value_type>::result_type>\
962 operator _Op(const typename _Dom::value_type& __t, \
963 const _Expr<_Dom,typename _Dom::value_type>& __v) \
965 typedef typename _Dom::value_type _Arg; \
966 typedef typename __fun<_Name, _Arg>::result_type _Value; \
967 typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \
968 return _Expr<_Closure,_Value>(_Closure(__t, __v())); \
971 template<class _Dom> \
972 inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>,\
973 typename __fun<_Name, typename _Dom::value_type>::result_type>\
974 operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \
975 const valarray<typename _Dom::value_type>& __v) \
977 typedef typename _Dom::value_type _Arg; \
978 typedef typename __fun<_Name, _Arg>::result_type _Value; \
979 typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Arg> _Closure; \
980 return _Expr<_Closure,_Value>(_Closure(__e(), __v)); \
983 template<class _Dom> \
984 inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>,\
985 typename __fun<_Name, typename _Dom::value_type>::result_type>\
986 operator _Op(const valarray<typename _Dom::value_type>& __v, \
987 const _Expr<_Dom,typename _Dom::value_type>& __e) \
989 typedef typename _Dom::value_type _Tp; \
990 typedef typename __fun<_Name, _Tp>::result_type _Value; \
991 typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \
992 return _Expr<_Closure,_Value> (_Closure (__v, __e ())); \
995 _DEFINE_EXPR_BINARY_OPERATOR(+, __plus)
996 _DEFINE_EXPR_BINARY_OPERATOR(-, __minus)
997 _DEFINE_EXPR_BINARY_OPERATOR(*, __multiplies)
998 _DEFINE_EXPR_BINARY_OPERATOR(/, __divides)
999 _DEFINE_EXPR_BINARY_OPERATOR(%, __modulus)
1000 _DEFINE_EXPR_BINARY_OPERATOR(^, __bitwise_xor)
1001 _DEFINE_EXPR_BINARY_OPERATOR(&, __bitwise_and)
1002 _DEFINE_EXPR_BINARY_OPERATOR(|, __bitwise_or)
1003 _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)
1004 _DEFINE_EXPR_BINARY_OPERATOR(>>, __shift_right)
1005 _DEFINE_EXPR_BINARY_OPERATOR(&&, __logical_and)
1006 _DEFINE_EXPR_BINARY_OPERATOR(||, __logical_or)
1007 _DEFINE_EXPR_BINARY_OPERATOR(==, __equal_to)
1008 _DEFINE_EXPR_BINARY_OPERATOR(!=, __not_equal_to)
1009 _DEFINE_EXPR_BINARY_OPERATOR(<, __less)
1010 _DEFINE_EXPR_BINARY_OPERATOR(>, __greater)
1011 _DEFINE_EXPR_BINARY_OPERATOR(<=, __less_equal)
1012 _DEFINE_EXPR_BINARY_OPERATOR(>=, __greater_equal)
1014 #undef _DEFINE_EXPR_BINARY_OPERATOR
1016 #define _DEFINE_EXPR_UNARY_FUNCTION(_Name) \
1017 template<class _Dom> \
1018 inline _Expr<_UnClos<__##_Name,_Expr,_Dom>,typename _Dom::value_type>\
1019 _Name(const _Expr<_Dom,typename _Dom::value_type>& __e) \
1021 typedef typename _Dom::value_type _Tp; \
1022 typedef _UnClos<__##_Name,_Expr,_Dom> _Closure; \
1023 return _Expr<_Closure,_Tp>(_Closure(__e())); \
1026 template<typename _Tp> \
1027 inline _Expr<_UnClos<__##_Name,_ValArray,_Tp>,_Tp> \
1028 _Name(const valarray<_Tp>& __v) \
1030 typedef _UnClos<__##_Name,_ValArray,_Tp> _Closure; \
1031 return _Expr<_Closure,_Tp>(_Closure(__v)); \
1034 _DEFINE_EXPR_UNARY_FUNCTION(abs)
1035 _DEFINE_EXPR_UNARY_FUNCTION(cos)
1036 _DEFINE_EXPR_UNARY_FUNCTION(acos)
1037 _DEFINE_EXPR_UNARY_FUNCTION(cosh)
1038 _DEFINE_EXPR_UNARY_FUNCTION(sin)
1039 _DEFINE_EXPR_UNARY_FUNCTION(asin)
1040 _DEFINE_EXPR_UNARY_FUNCTION(sinh)
1041 _DEFINE_EXPR_UNARY_FUNCTION(tan)
1042 _DEFINE_EXPR_UNARY_FUNCTION(tanh)
1043 _DEFINE_EXPR_UNARY_FUNCTION(atan)
1044 _DEFINE_EXPR_UNARY_FUNCTION(exp)
1045 _DEFINE_EXPR_UNARY_FUNCTION(log)
1046 _DEFINE_EXPR_UNARY_FUNCTION(log10)
1047 _DEFINE_EXPR_UNARY_FUNCTION(sqrt)
1049 #undef _DEFINE_EXPR_UNARY_FUNCTION
1051 #define _DEFINE_EXPR_BINARY_FUNCTION(_Fun) \
1052 template<class _Dom1, class _Dom2> \
1053 inline _Expr<_BinClos<__##_Fun,_Expr,_Expr,_Dom1,_Dom2>, \
1054 typename _Dom1::value_type> \
1055 _Fun(const _Expr<_Dom1,typename _Dom1::value_type>& __e1, \
1056 const _Expr<_Dom2,typename _Dom2::value_type>& __e2) \
1058 typedef typename _Dom1::value_type _Tp; \
1059 typedef _BinClos<__##_Fun,_Expr,_Expr,_Dom1,_Dom2> _Closure; \
1060 return _Expr<_Closure,_Tp>(_Closure(__e1(), __e2())); \
1063 template<class _Dom> \
1064 inline _Expr<_BinClos<__##_Fun, _Expr, _ValArray, _Dom, \
1065 typename _Dom::value_type>, \
1066 typename _Dom::value_type> \
1067 _Fun(const _Expr<_Dom,typename _Dom::value_type>& __e, \
1068 const valarray<typename _Dom::value_type>& __v) \
1070 typedef typename _Dom::value_type _Tp; \
1071 typedef _BinClos<__##_Fun, _Expr, _ValArray, _Dom, _Tp> _Closure;\
1072 return _Expr<_Closure,_Tp>(_Closure(__e(), __v)); \
1075 template<class _Dom> \
1076 inline _Expr<_BinClos<__##_Fun, _ValArray, _Expr, \
1077 typename _Dom::value_type,_Dom>, \
1078 typename _Dom::value_type> \
1079 _Fun(const valarray<typename _Dom::valarray>& __v, \
1080 const _Expr<_Dom,typename _Dom::value_type>& __e) \
1082 typedef typename _Dom::value_type _Tp; \
1083 typedef _BinClos<__##_Fun,_ValArray,_Expr,_Tp,_Dom> _Closure; \
1084 return _Expr<_Closure,_Tp>(_Closure(__v, __e())); \
1087 template<class _Dom> \
1088 inline _Expr<_BinClos<__##_Fun,_Expr,_Constant,_Dom, \
1089 typename _Dom::value_type>, \
1090 typename _Dom::value_type> \
1091 _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \
1092 const typename _Dom::value_type& __t) \
1094 typedef typename _Dom::value_type _Tp; \
1095 typedef _BinClos<__##_Fun,_Expr,_Constant,_Dom,_Tp> _Closure; \
1096 return _Expr<_Closure,_Tp>(_Closure(__e(), __t)); \
1099 template<class _Dom> \
1100 inline _Expr<_BinClos<__##_Fun,_Constant,_Expr, \
1101 typename _Dom::value_type,_Dom>, \
1102 typename _Dom::value_type> \
1103 _Fun(const typename _Dom::value_type& __t, \
1104 const _Expr<_Dom,typename _Dom::value_type>& __e) \
1106 typedef typename _Dom::value_type _Tp; \
1107 typedef _BinClos<__##_Fun, _Constant,_Expr,_Tp,_Dom> _Closure; \
1108 return _Expr<_Closure,_Tp>(_Closure(__t, __e())); \
1111 template<typename _Tp> \
1112 inline _Expr<_BinClos<__##_Fun,_ValArray,_ValArray,_Tp,_Tp>, _Tp> \
1113 _Fun(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \
1115 typedef _BinClos<__##_Fun,_ValArray,_ValArray,_Tp,_Tp> _Closure; \
1116 return _Expr<_Closure,_Tp>(_Closure(__v, __w)); \
1119 template<typename _Tp> \
1120 inline _Expr<_BinClos<__##_Fun,_ValArray,_Constant,_Tp,_Tp>,_Tp> \
1121 _Fun(const valarray<_Tp>& __v, const _Tp& __t) \
1123 typedef _BinClos<__##_Fun,_ValArray,_Constant,_Tp,_Tp> _Closure; \
1124 return _Expr<_Closure,_Tp>(_Closure(__v, __t)); \
1127 template<typename _Tp> \
1128 inline _Expr<_BinClos<__##_Fun,_Constant,_ValArray,_Tp,_Tp>,_Tp> \
1129 _Fun(const _Tp& __t, const valarray<_Tp>& __v) \
1131 typedef _BinClos<__##_Fun,_Constant,_ValArray,_Tp,_Tp> _Closure; \
1132 return _Expr<_Closure,_Tp>(_Closure(__t, __v)); \
1135 _DEFINE_EXPR_BINARY_FUNCTION(atan2)
1136 _DEFINE_EXPR_BINARY_FUNCTION(pow)
1138 #undef _DEFINE_EXPR_BINARY_FUNCTION
1143 #endif /* _CPP_VALARRAY_META_H */