1ffeaf689SAlexander Kabaev // The template and inlines for the -*- C++ -*- internal _Meta class.
2ffeaf689SAlexander Kabaev 
3*f8a1b7d9SAlexander Kabaev // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
4*f8a1b7d9SAlexander Kabaev // Free Software Foundation, Inc.
5ffeaf689SAlexander Kabaev //
6ffeaf689SAlexander Kabaev // This file is part of the GNU ISO C++ Library.  This library is free
7ffeaf689SAlexander Kabaev // software; you can redistribute it and/or modify it under the
8ffeaf689SAlexander Kabaev // terms of the GNU General Public License as published by the
9ffeaf689SAlexander Kabaev // Free Software Foundation; either version 2, or (at your option)
10ffeaf689SAlexander Kabaev // any later version.
11ffeaf689SAlexander Kabaev 
12ffeaf689SAlexander Kabaev // This library is distributed in the hope that it will be useful,
13ffeaf689SAlexander Kabaev // but WITHOUT ANY WARRANTY; without even the implied warranty of
14ffeaf689SAlexander Kabaev // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15ffeaf689SAlexander Kabaev // GNU General Public License for more details.
16ffeaf689SAlexander Kabaev 
17ffeaf689SAlexander Kabaev // You should have received a copy of the GNU General Public License along
18ffeaf689SAlexander Kabaev // with this library; see the file COPYING.  If not, write to the Free
19*f8a1b7d9SAlexander Kabaev // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20ffeaf689SAlexander Kabaev // USA.
21ffeaf689SAlexander Kabaev 
22ffeaf689SAlexander Kabaev // As a special exception, you may use this file as part of a free software
23ffeaf689SAlexander Kabaev // library without restriction.  Specifically, if other files instantiate
24ffeaf689SAlexander Kabaev // templates or use macros or inline functions from this file, or you compile
25ffeaf689SAlexander Kabaev // this file and link it with other files to produce an executable, this
26ffeaf689SAlexander Kabaev // file does not by itself cause the resulting executable to be covered by
27ffeaf689SAlexander Kabaev // the GNU General Public License.  This exception does not however
28ffeaf689SAlexander Kabaev // invalidate any other reasons why the executable file might be covered by
29ffeaf689SAlexander Kabaev // the GNU General Public License.
30ffeaf689SAlexander Kabaev 
31*f8a1b7d9SAlexander Kabaev /** @file valarray_after.h
32ffeaf689SAlexander Kabaev  *  This is an internal header file, included by other library headers.
33ffeaf689SAlexander Kabaev  *  You should not attempt to use it directly.
34ffeaf689SAlexander Kabaev  */
35ffeaf689SAlexander Kabaev 
36*f8a1b7d9SAlexander Kabaev // Written by Gabriel Dos Reis <[email protected]>
37*f8a1b7d9SAlexander Kabaev 
38ffeaf689SAlexander Kabaev #ifndef _VALARRAY_AFTER_H
39ffeaf689SAlexander Kabaev #define _VALARRAY_AFTER_H 1
40ffeaf689SAlexander Kabaev 
41ffeaf689SAlexander Kabaev #pragma GCC system_header
42ffeaf689SAlexander Kabaev 
_GLIBCXX_BEGIN_NAMESPACE(std)43*f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NAMESPACE(std)
44ffeaf689SAlexander Kabaev 
45ffeaf689SAlexander Kabaev   //
46ffeaf689SAlexander Kabaev   // gslice_array closure.
47ffeaf689SAlexander Kabaev   //
48*f8a1b7d9SAlexander Kabaev   template<class _Dom>
49*f8a1b7d9SAlexander Kabaev     class _GBase
50*f8a1b7d9SAlexander Kabaev     {
51ffeaf689SAlexander Kabaev     public:
52ffeaf689SAlexander Kabaev       typedef typename _Dom::value_type value_type;
53ffeaf689SAlexander Kabaev 
54ffeaf689SAlexander Kabaev       _GBase (const _Dom& __e, const valarray<size_t>& __i)
55ffeaf689SAlexander Kabaev       : _M_expr (__e), _M_index(__i) {}
56*f8a1b7d9SAlexander Kabaev 
57*f8a1b7d9SAlexander Kabaev       value_type
58*f8a1b7d9SAlexander Kabaev       operator[] (size_t __i) const
59ffeaf689SAlexander Kabaev       { return _M_expr[_M_index[__i]]; }
60*f8a1b7d9SAlexander Kabaev 
61*f8a1b7d9SAlexander Kabaev       size_t
62*f8a1b7d9SAlexander Kabaev       size () const
63*f8a1b7d9SAlexander Kabaev       { return _M_index.size(); }
64ffeaf689SAlexander Kabaev 
65ffeaf689SAlexander Kabaev     private:
66ffeaf689SAlexander Kabaev       const _Dom&	      _M_expr;
67ffeaf689SAlexander Kabaev       const valarray<size_t>& _M_index;
68ffeaf689SAlexander Kabaev     };
69ffeaf689SAlexander Kabaev 
70*f8a1b7d9SAlexander Kabaev   template<typename _Tp>
71*f8a1b7d9SAlexander Kabaev     class _GBase<_Array<_Tp> >
72*f8a1b7d9SAlexander Kabaev     {
73ffeaf689SAlexander Kabaev     public:
74ffeaf689SAlexander Kabaev       typedef _Tp value_type;
75ffeaf689SAlexander Kabaev 
_GBase(_Array<_Tp> __a,const valarray<size_t> & __i)76ffeaf689SAlexander Kabaev       _GBase (_Array<_Tp> __a, const valarray<size_t>& __i)
77ffeaf689SAlexander Kabaev       : _M_array (__a), _M_index(__i) {}
78*f8a1b7d9SAlexander Kabaev 
79*f8a1b7d9SAlexander Kabaev       value_type
80*f8a1b7d9SAlexander Kabaev       operator[] (size_t __i) const
81ffeaf689SAlexander Kabaev       { return _M_array._M_data[_M_index[__i]]; }
82*f8a1b7d9SAlexander Kabaev 
83*f8a1b7d9SAlexander Kabaev       size_t
size()84*f8a1b7d9SAlexander Kabaev       size () const
85*f8a1b7d9SAlexander Kabaev       { return _M_index.size(); }
86ffeaf689SAlexander Kabaev 
87ffeaf689SAlexander Kabaev     private:
88ffeaf689SAlexander Kabaev       const _Array<_Tp>       _M_array;
89ffeaf689SAlexander Kabaev       const valarray<size_t>& _M_index;
90ffeaf689SAlexander Kabaev     };
91ffeaf689SAlexander Kabaev 
92*f8a1b7d9SAlexander Kabaev   template<class _Dom>
93*f8a1b7d9SAlexander Kabaev     struct _GClos<_Expr, _Dom>
94*f8a1b7d9SAlexander Kabaev     : _GBase<_Dom>
95*f8a1b7d9SAlexander Kabaev     {
96ffeaf689SAlexander Kabaev       typedef _GBase<_Dom> _Base;
97ffeaf689SAlexander Kabaev       typedef typename _Base::value_type value_type;
98ffeaf689SAlexander Kabaev 
99ffeaf689SAlexander Kabaev       _GClos (const _Dom& __e, const valarray<size_t>& __i)
100ffeaf689SAlexander Kabaev       : _Base (__e, __i) {}
101ffeaf689SAlexander Kabaev     };
102ffeaf689SAlexander Kabaev 
103ffeaf689SAlexander Kabaev   template<typename _Tp>
104*f8a1b7d9SAlexander Kabaev     struct _GClos<_ValArray, _Tp>
105*f8a1b7d9SAlexander Kabaev     : _GBase<_Array<_Tp> >
106*f8a1b7d9SAlexander Kabaev     {
107ffeaf689SAlexander Kabaev       typedef _GBase<_Array<_Tp> > _Base;
108ffeaf689SAlexander Kabaev       typedef typename _Base::value_type value_type;
109ffeaf689SAlexander Kabaev 
110ffeaf689SAlexander Kabaev       _GClos (_Array<_Tp> __a, const valarray<size_t>& __i)
111ffeaf689SAlexander Kabaev       : _Base (__a, __i) {}
112ffeaf689SAlexander Kabaev     };
113ffeaf689SAlexander Kabaev 
114ffeaf689SAlexander Kabaev   //
115ffeaf689SAlexander Kabaev   // indirect_array closure
116ffeaf689SAlexander Kabaev   //
117*f8a1b7d9SAlexander Kabaev   template<class _Dom>
118*f8a1b7d9SAlexander Kabaev     class _IBase
119*f8a1b7d9SAlexander Kabaev     {
120ffeaf689SAlexander Kabaev     public:
121ffeaf689SAlexander Kabaev       typedef typename _Dom::value_type value_type;
122ffeaf689SAlexander Kabaev 
123ffeaf689SAlexander Kabaev       _IBase (const _Dom& __e, const valarray<size_t>& __i)
124ffeaf689SAlexander Kabaev       : _M_expr (__e), _M_index (__i) {}
125*f8a1b7d9SAlexander Kabaev 
126*f8a1b7d9SAlexander Kabaev       value_type
127*f8a1b7d9SAlexander Kabaev       operator[] (size_t __i) const
128ffeaf689SAlexander Kabaev       { return _M_expr[_M_index[__i]]; }
129*f8a1b7d9SAlexander Kabaev 
130*f8a1b7d9SAlexander Kabaev       size_t
131*f8a1b7d9SAlexander Kabaev       size() const
132*f8a1b7d9SAlexander Kabaev       { return _M_index.size(); }
133ffeaf689SAlexander Kabaev 
134ffeaf689SAlexander Kabaev     private:
135ffeaf689SAlexander Kabaev       const _Dom&	      _M_expr;
136ffeaf689SAlexander Kabaev       const valarray<size_t>& _M_index;
137ffeaf689SAlexander Kabaev     };
138ffeaf689SAlexander Kabaev 
139*f8a1b7d9SAlexander Kabaev   template<class _Dom>
140*f8a1b7d9SAlexander Kabaev     struct _IClos<_Expr, _Dom>
141*f8a1b7d9SAlexander Kabaev     : _IBase<_Dom>
142*f8a1b7d9SAlexander Kabaev     {
143ffeaf689SAlexander Kabaev       typedef _IBase<_Dom> _Base;
144ffeaf689SAlexander Kabaev       typedef typename _Base::value_type value_type;
145ffeaf689SAlexander Kabaev 
146ffeaf689SAlexander Kabaev       _IClos (const _Dom& __e, const valarray<size_t>& __i)
147ffeaf689SAlexander Kabaev       : _Base (__e, __i) {}
148ffeaf689SAlexander Kabaev     };
149ffeaf689SAlexander Kabaev 
150ffeaf689SAlexander Kabaev   template<typename _Tp>
151*f8a1b7d9SAlexander Kabaev     struct _IClos<_ValArray, _Tp>
152*f8a1b7d9SAlexander Kabaev     : _IBase<valarray<_Tp> >
153*f8a1b7d9SAlexander Kabaev     {
154ffeaf689SAlexander Kabaev       typedef _IBase<valarray<_Tp> > _Base;
155ffeaf689SAlexander Kabaev       typedef _Tp value_type;
156ffeaf689SAlexander Kabaev 
157ffeaf689SAlexander Kabaev       _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i)
158ffeaf689SAlexander Kabaev       : _Base (__a, __i) {}
159ffeaf689SAlexander Kabaev     };
160ffeaf689SAlexander Kabaev 
161ffeaf689SAlexander Kabaev   //
162ffeaf689SAlexander Kabaev   // class _Expr
163ffeaf689SAlexander Kabaev   //
164ffeaf689SAlexander Kabaev   template<class _Clos, typename _Tp>
165ffeaf689SAlexander Kabaev     class _Expr
166ffeaf689SAlexander Kabaev     {
167ffeaf689SAlexander Kabaev     public:
168ffeaf689SAlexander Kabaev       typedef _Tp value_type;
169ffeaf689SAlexander Kabaev 
170ffeaf689SAlexander Kabaev       _Expr(const _Clos&);
171ffeaf689SAlexander Kabaev 
172ffeaf689SAlexander Kabaev       const _Clos& operator()() const;
173ffeaf689SAlexander Kabaev 
174ffeaf689SAlexander Kabaev       value_type operator[](size_t) const;
175ffeaf689SAlexander Kabaev       valarray<value_type> operator[](slice) const;
176ffeaf689SAlexander Kabaev       valarray<value_type> operator[](const gslice&) const;
177ffeaf689SAlexander Kabaev       valarray<value_type> operator[](const valarray<bool>&) const;
178ffeaf689SAlexander Kabaev       valarray<value_type> operator[](const valarray<size_t>&) const;
179ffeaf689SAlexander Kabaev 
180ffeaf689SAlexander Kabaev       _Expr<_UnClos<__unary_plus, std::_Expr, _Clos>, value_type>
181ffeaf689SAlexander Kabaev       operator+() const;
182ffeaf689SAlexander Kabaev 
183ffeaf689SAlexander Kabaev       _Expr<_UnClos<__negate, std::_Expr, _Clos>, value_type>
184ffeaf689SAlexander Kabaev       operator-() const;
185ffeaf689SAlexander Kabaev 
186ffeaf689SAlexander Kabaev       _Expr<_UnClos<__bitwise_not, std::_Expr, _Clos>, value_type>
187ffeaf689SAlexander Kabaev       operator~() const;
188ffeaf689SAlexander Kabaev 
189ffeaf689SAlexander Kabaev       _Expr<_UnClos<__logical_not, std::_Expr, _Clos>, bool>
190ffeaf689SAlexander Kabaev       operator!() const;
191ffeaf689SAlexander Kabaev 
192ffeaf689SAlexander Kabaev       size_t size() const;
193ffeaf689SAlexander Kabaev       value_type sum() const;
194ffeaf689SAlexander Kabaev 
195ffeaf689SAlexander Kabaev       valarray<value_type> shift(int) const;
196ffeaf689SAlexander Kabaev       valarray<value_type> cshift(int) const;
197ffeaf689SAlexander Kabaev 
198ffeaf689SAlexander Kabaev       value_type min() const;
199ffeaf689SAlexander Kabaev       value_type max() const;
200ffeaf689SAlexander Kabaev 
201ffeaf689SAlexander Kabaev       valarray<value_type> apply(value_type (*)(const value_type&)) const;
202ffeaf689SAlexander Kabaev       valarray<value_type> apply(value_type (*)(value_type)) const;
203ffeaf689SAlexander Kabaev 
204ffeaf689SAlexander Kabaev     private:
205ffeaf689SAlexander Kabaev       const _Clos _M_closure;
206ffeaf689SAlexander Kabaev     };
207ffeaf689SAlexander Kabaev 
208ffeaf689SAlexander Kabaev   template<class _Clos, typename _Tp>
209ffeaf689SAlexander Kabaev     inline
210ffeaf689SAlexander Kabaev     _Expr<_Clos, _Tp>::_Expr(const _Clos& __c) : _M_closure(__c) {}
211ffeaf689SAlexander Kabaev 
212ffeaf689SAlexander Kabaev   template<class _Clos, typename _Tp>
213ffeaf689SAlexander Kabaev     inline const _Clos&
214ffeaf689SAlexander Kabaev     _Expr<_Clos, _Tp>::operator()() const
215ffeaf689SAlexander Kabaev     { return _M_closure; }
216ffeaf689SAlexander Kabaev 
217ffeaf689SAlexander Kabaev   template<class _Clos, typename _Tp>
218ffeaf689SAlexander Kabaev     inline _Tp
219ffeaf689SAlexander Kabaev     _Expr<_Clos, _Tp>::operator[](size_t __i) const
220ffeaf689SAlexander Kabaev     { return _M_closure[__i]; }
221ffeaf689SAlexander Kabaev 
222ffeaf689SAlexander Kabaev   template<class _Clos, typename _Tp>
223ffeaf689SAlexander Kabaev     inline valarray<_Tp>
224ffeaf689SAlexander Kabaev     _Expr<_Clos, _Tp>::operator[](slice __s) const
225*f8a1b7d9SAlexander Kabaev     {
226*f8a1b7d9SAlexander Kabaev       valarray<_Tp> __v = valarray<_Tp>(*this)[__s];
227*f8a1b7d9SAlexander Kabaev       return __v;
228*f8a1b7d9SAlexander Kabaev     }
229ffeaf689SAlexander Kabaev 
230ffeaf689SAlexander Kabaev   template<class _Clos, typename _Tp>
231ffeaf689SAlexander Kabaev     inline valarray<_Tp>
232ffeaf689SAlexander Kabaev     _Expr<_Clos, _Tp>::operator[](const gslice& __gs) const
233*f8a1b7d9SAlexander Kabaev     {
234*f8a1b7d9SAlexander Kabaev       valarray<_Tp> __v = valarray<_Tp>(*this)[__gs];
235*f8a1b7d9SAlexander Kabaev       return __v;
236*f8a1b7d9SAlexander Kabaev     }
237ffeaf689SAlexander Kabaev 
238ffeaf689SAlexander Kabaev   template<class _Clos, typename _Tp>
239ffeaf689SAlexander Kabaev     inline valarray<_Tp>
240ffeaf689SAlexander Kabaev     _Expr<_Clos, _Tp>::operator[](const valarray<bool>& __m) const
241*f8a1b7d9SAlexander Kabaev     {
242*f8a1b7d9SAlexander Kabaev       valarray<_Tp> __v = valarray<_Tp>(*this)[__m];
243*f8a1b7d9SAlexander Kabaev       return __v;
244*f8a1b7d9SAlexander Kabaev     }
245ffeaf689SAlexander Kabaev 
246ffeaf689SAlexander Kabaev   template<class _Clos, typename _Tp>
247ffeaf689SAlexander Kabaev     inline valarray<_Tp>
248ffeaf689SAlexander Kabaev     _Expr<_Clos, _Tp>::operator[](const valarray<size_t>& __i) const
249*f8a1b7d9SAlexander Kabaev     {
250*f8a1b7d9SAlexander Kabaev       valarray<_Tp> __v = valarray<_Tp>(*this)[__i];
251*f8a1b7d9SAlexander Kabaev       return __v;
252*f8a1b7d9SAlexander Kabaev     }
253ffeaf689SAlexander Kabaev 
254ffeaf689SAlexander Kabaev   template<class _Clos, typename _Tp>
255ffeaf689SAlexander Kabaev     inline size_t
256*f8a1b7d9SAlexander Kabaev     _Expr<_Clos, _Tp>::size() const
257*f8a1b7d9SAlexander Kabaev     { return _M_closure.size(); }
258ffeaf689SAlexander Kabaev 
259ffeaf689SAlexander Kabaev   template<class _Clos, typename _Tp>
260ffeaf689SAlexander Kabaev     inline valarray<_Tp>
261ffeaf689SAlexander Kabaev     _Expr<_Clos, _Tp>::shift(int __n) const
262*f8a1b7d9SAlexander Kabaev     {
263*f8a1b7d9SAlexander Kabaev       valarray<_Tp> __v = valarray<_Tp>(*this).shift(__n);
264*f8a1b7d9SAlexander Kabaev       return __v;
265*f8a1b7d9SAlexander Kabaev     }
266ffeaf689SAlexander Kabaev 
267ffeaf689SAlexander Kabaev   template<class _Clos, typename _Tp>
268ffeaf689SAlexander Kabaev     inline valarray<_Tp>
269ffeaf689SAlexander Kabaev     _Expr<_Clos, _Tp>::cshift(int __n) const
270*f8a1b7d9SAlexander Kabaev     {
271*f8a1b7d9SAlexander Kabaev       valarray<_Tp> __v = valarray<_Tp>(*this).cshift(__n);
272*f8a1b7d9SAlexander Kabaev       return __v;
273*f8a1b7d9SAlexander Kabaev     }
274ffeaf689SAlexander Kabaev 
275ffeaf689SAlexander Kabaev   template<class _Clos, typename _Tp>
276ffeaf689SAlexander Kabaev     inline valarray<_Tp>
277ffeaf689SAlexander Kabaev     _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const
278*f8a1b7d9SAlexander Kabaev     {
279*f8a1b7d9SAlexander Kabaev       valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f);
280*f8a1b7d9SAlexander Kabaev       return __v;
281*f8a1b7d9SAlexander Kabaev     }
282ffeaf689SAlexander Kabaev 
283ffeaf689SAlexander Kabaev   template<class _Clos, typename _Tp>
284ffeaf689SAlexander Kabaev     inline valarray<_Tp>
285ffeaf689SAlexander Kabaev     _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const
286*f8a1b7d9SAlexander Kabaev     {
287*f8a1b7d9SAlexander Kabaev       valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f);
288*f8a1b7d9SAlexander Kabaev       return __v;
289*f8a1b7d9SAlexander Kabaev     }
290ffeaf689SAlexander Kabaev 
291ffeaf689SAlexander Kabaev   // XXX: replace this with a more robust summation algorithm.
292ffeaf689SAlexander Kabaev   template<class _Clos, typename _Tp>
293ffeaf689SAlexander Kabaev     inline _Tp
294ffeaf689SAlexander Kabaev     _Expr<_Clos, _Tp>::sum() const
295ffeaf689SAlexander Kabaev     {
296ffeaf689SAlexander Kabaev       size_t __n = _M_closure.size();
297ffeaf689SAlexander Kabaev       if (__n == 0)
298ffeaf689SAlexander Kabaev 	return _Tp();
299ffeaf689SAlexander Kabaev       else
300ffeaf689SAlexander Kabaev 	{
301ffeaf689SAlexander Kabaev 	  _Tp __s = _M_closure[--__n];
302ffeaf689SAlexander Kabaev 	  while (__n != 0)
303ffeaf689SAlexander Kabaev 	    __s += _M_closure[--__n];
304ffeaf689SAlexander Kabaev 	  return __s;
305ffeaf689SAlexander Kabaev         }
306ffeaf689SAlexander Kabaev     }
307ffeaf689SAlexander Kabaev 
308ffeaf689SAlexander Kabaev   template<class _Clos, typename _Tp>
309ffeaf689SAlexander Kabaev     inline _Tp
310ffeaf689SAlexander Kabaev     _Expr<_Clos, _Tp>::min() const
311ffeaf689SAlexander Kabaev     { return __valarray_min(_M_closure); }
312ffeaf689SAlexander Kabaev 
313ffeaf689SAlexander Kabaev   template<class _Clos, typename _Tp>
314ffeaf689SAlexander Kabaev     inline _Tp
315ffeaf689SAlexander Kabaev     _Expr<_Clos, _Tp>::max() const
316ffeaf689SAlexander Kabaev     { return __valarray_max(_M_closure); }
317ffeaf689SAlexander Kabaev 
318ffeaf689SAlexander Kabaev   template<class _Dom, typename _Tp>
319ffeaf689SAlexander Kabaev     inline _Expr<_UnClos<__logical_not, _Expr, _Dom>, bool>
320ffeaf689SAlexander Kabaev     _Expr<_Dom, _Tp>::operator!() const
321ffeaf689SAlexander Kabaev     {
322ffeaf689SAlexander Kabaev       typedef _UnClos<__logical_not, std::_Expr, _Dom> _Closure;
323ffeaf689SAlexander Kabaev       return _Expr<_Closure, _Tp>(_Closure(this->_M_closure));
324ffeaf689SAlexander Kabaev     }
325ffeaf689SAlexander Kabaev 
326ffeaf689SAlexander Kabaev #define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name)                           \
327ffeaf689SAlexander Kabaev   template<class _Dom, typename _Tp>                                      \
328ffeaf689SAlexander Kabaev     inline _Expr<_UnClos<_Name, std::_Expr, _Dom>, _Tp>                   \
329ffeaf689SAlexander Kabaev     _Expr<_Dom, _Tp>::operator _Op() const                                \
330ffeaf689SAlexander Kabaev     {                                                                     \
331ffeaf689SAlexander Kabaev       typedef _UnClos<_Name, std::_Expr, _Dom> _Closure;                  \
332ffeaf689SAlexander Kabaev       return _Expr<_Closure, _Tp>(_Closure(this->_M_closure));            \
333ffeaf689SAlexander Kabaev     }
334ffeaf689SAlexander Kabaev 
335ffeaf689SAlexander Kabaev     _DEFINE_EXPR_UNARY_OPERATOR(+, __unary_plus)
336ffeaf689SAlexander Kabaev     _DEFINE_EXPR_UNARY_OPERATOR(-, __negate)
337ffeaf689SAlexander Kabaev     _DEFINE_EXPR_UNARY_OPERATOR(~, __bitwise_not)
338ffeaf689SAlexander Kabaev 
339ffeaf689SAlexander Kabaev #undef _DEFINE_EXPR_UNARY_OPERATOR
340ffeaf689SAlexander Kabaev 
341ffeaf689SAlexander Kabaev #define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name)                        \
342ffeaf689SAlexander Kabaev   template<class _Dom1, class _Dom2>					\
343ffeaf689SAlexander Kabaev     inline _Expr<_BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2>,           \
344ffeaf689SAlexander Kabaev            typename __fun<_Name, typename _Dom1::value_type>::result_type> \
345ffeaf689SAlexander Kabaev     operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v,   \
346ffeaf689SAlexander Kabaev 	         const _Expr<_Dom2, typename _Dom2::value_type>& __w)   \
347ffeaf689SAlexander Kabaev     {                                                                   \
348ffeaf689SAlexander Kabaev       typedef typename _Dom1::value_type _Arg;                          \
349ffeaf689SAlexander Kabaev       typedef typename __fun<_Name, _Arg>::result_type _Value;          \
350ffeaf689SAlexander Kabaev       typedef _BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2> _Closure;     \
351ffeaf689SAlexander Kabaev       return _Expr<_Closure, _Value>(_Closure(__v(), __w()));           \
352ffeaf689SAlexander Kabaev     }                                                                   \
353ffeaf689SAlexander Kabaev                                                                         \
354ffeaf689SAlexander Kabaev   template<class _Dom>                                                  \
355*f8a1b7d9SAlexander Kabaev     inline _Expr<_BinClos<_Name, _Expr, _Constant, _Dom,                \
356*f8a1b7d9SAlexander Kabaev                           typename _Dom::value_type>,                   \
357ffeaf689SAlexander Kabaev              typename __fun<_Name, typename _Dom::value_type>::result_type> \
358ffeaf689SAlexander Kabaev     operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v,     \
359ffeaf689SAlexander Kabaev                  const typename _Dom::value_type& __t)                  \
360ffeaf689SAlexander Kabaev     {                                                                   \
361ffeaf689SAlexander Kabaev       typedef typename _Dom::value_type _Arg;                           \
362ffeaf689SAlexander Kabaev       typedef typename __fun<_Name, _Arg>::result_type _Value;          \
363ffeaf689SAlexander Kabaev       typedef _BinClos<_Name, _Expr, _Constant, _Dom, _Arg> _Closure;   \
364ffeaf689SAlexander Kabaev       return _Expr<_Closure, _Value>(_Closure(__v(), __t));             \
365ffeaf689SAlexander Kabaev     }                                                                   \
366ffeaf689SAlexander Kabaev                                                                         \
367ffeaf689SAlexander Kabaev   template<class _Dom>                                                  \
368*f8a1b7d9SAlexander Kabaev     inline _Expr<_BinClos<_Name, _Constant, _Expr,                      \
369*f8a1b7d9SAlexander Kabaev                           typename _Dom::value_type, _Dom>,             \
370ffeaf689SAlexander Kabaev              typename __fun<_Name, typename _Dom::value_type>::result_type> \
371ffeaf689SAlexander Kabaev     operator _Op(const typename _Dom::value_type& __t,                  \
372ffeaf689SAlexander Kabaev                  const _Expr<_Dom, typename _Dom::value_type>& __v)     \
373ffeaf689SAlexander Kabaev     {                                                                   \
374ffeaf689SAlexander Kabaev       typedef typename _Dom::value_type _Arg;                           \
375ffeaf689SAlexander Kabaev       typedef typename __fun<_Name, _Arg>::result_type _Value;          \
376ffeaf689SAlexander Kabaev       typedef _BinClos<_Name, _Constant, _Expr, _Arg, _Dom> _Closure;   \
377ffeaf689SAlexander Kabaev       return _Expr<_Closure, _Value>(_Closure(__t, __v()));             \
378ffeaf689SAlexander Kabaev     }                                                                   \
379ffeaf689SAlexander Kabaev                                                                         \
380ffeaf689SAlexander Kabaev   template<class _Dom>                                                  \
381*f8a1b7d9SAlexander Kabaev     inline _Expr<_BinClos<_Name, _Expr, _ValArray,                      \
382*f8a1b7d9SAlexander Kabaev                           _Dom, typename _Dom::value_type>,             \
383ffeaf689SAlexander Kabaev              typename __fun<_Name, typename _Dom::value_type>::result_type> \
384ffeaf689SAlexander Kabaev     operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e,      \
385ffeaf689SAlexander Kabaev                  const valarray<typename _Dom::value_type>& __v)        \
386ffeaf689SAlexander Kabaev     {                                                                   \
387ffeaf689SAlexander Kabaev       typedef typename _Dom::value_type _Arg;                           \
388ffeaf689SAlexander Kabaev       typedef typename __fun<_Name, _Arg>::result_type _Value;          \
389ffeaf689SAlexander Kabaev       typedef _BinClos<_Name, _Expr, _ValArray, _Dom, _Arg> _Closure;   \
390ffeaf689SAlexander Kabaev       return _Expr<_Closure, _Value>(_Closure(__e(), __v));             \
391ffeaf689SAlexander Kabaev     }                                                                   \
392ffeaf689SAlexander Kabaev                                                                         \
393ffeaf689SAlexander Kabaev   template<class _Dom>                                                  \
394*f8a1b7d9SAlexander Kabaev     inline _Expr<_BinClos<_Name, _ValArray, _Expr,                      \
395*f8a1b7d9SAlexander Kabaev                  typename _Dom::value_type, _Dom>,                      \
396ffeaf689SAlexander Kabaev              typename __fun<_Name, typename _Dom::value_type>::result_type> \
397ffeaf689SAlexander Kabaev     operator _Op(const valarray<typename _Dom::value_type>& __v,        \
398ffeaf689SAlexander Kabaev                  const _Expr<_Dom, typename _Dom::value_type>& __e)     \
399ffeaf689SAlexander Kabaev     {                                                                   \
400ffeaf689SAlexander Kabaev       typedef typename _Dom::value_type _Tp;                            \
401ffeaf689SAlexander Kabaev       typedef typename __fun<_Name, _Tp>::result_type _Value;           \
402ffeaf689SAlexander Kabaev       typedef _BinClos<_Name, _ValArray, _Expr, _Tp, _Dom> _Closure;    \
403ffeaf689SAlexander Kabaev       return _Expr<_Closure, _Value>(_Closure(__v, __e ()));            \
404ffeaf689SAlexander Kabaev     }
405ffeaf689SAlexander Kabaev 
406ffeaf689SAlexander Kabaev     _DEFINE_EXPR_BINARY_OPERATOR(+, __plus)
407ffeaf689SAlexander Kabaev     _DEFINE_EXPR_BINARY_OPERATOR(-, __minus)
408ffeaf689SAlexander Kabaev     _DEFINE_EXPR_BINARY_OPERATOR(*, __multiplies)
409ffeaf689SAlexander Kabaev     _DEFINE_EXPR_BINARY_OPERATOR(/, __divides)
410ffeaf689SAlexander Kabaev     _DEFINE_EXPR_BINARY_OPERATOR(%, __modulus)
411ffeaf689SAlexander Kabaev     _DEFINE_EXPR_BINARY_OPERATOR(^, __bitwise_xor)
412ffeaf689SAlexander Kabaev     _DEFINE_EXPR_BINARY_OPERATOR(&, __bitwise_and)
413ffeaf689SAlexander Kabaev     _DEFINE_EXPR_BINARY_OPERATOR(|, __bitwise_or)
414ffeaf689SAlexander Kabaev     _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)
415ffeaf689SAlexander Kabaev     _DEFINE_EXPR_BINARY_OPERATOR(>>, __shift_right)
416ffeaf689SAlexander Kabaev     _DEFINE_EXPR_BINARY_OPERATOR(&&, __logical_and)
417ffeaf689SAlexander Kabaev     _DEFINE_EXPR_BINARY_OPERATOR(||, __logical_or)
418ffeaf689SAlexander Kabaev     _DEFINE_EXPR_BINARY_OPERATOR(==, __equal_to)
419ffeaf689SAlexander Kabaev     _DEFINE_EXPR_BINARY_OPERATOR(!=, __not_equal_to)
420ffeaf689SAlexander Kabaev     _DEFINE_EXPR_BINARY_OPERATOR(<, __less)
421ffeaf689SAlexander Kabaev     _DEFINE_EXPR_BINARY_OPERATOR(>, __greater)
422ffeaf689SAlexander Kabaev     _DEFINE_EXPR_BINARY_OPERATOR(<=, __less_equal)
423ffeaf689SAlexander Kabaev     _DEFINE_EXPR_BINARY_OPERATOR(>=, __greater_equal)
424ffeaf689SAlexander Kabaev 
425ffeaf689SAlexander Kabaev #undef _DEFINE_EXPR_BINARY_OPERATOR
426ffeaf689SAlexander Kabaev 
427ffeaf689SAlexander Kabaev #define _DEFINE_EXPR_UNARY_FUNCTION(_Name)                               \
428ffeaf689SAlexander Kabaev   template<class _Dom>                                                   \
429*f8a1b7d9SAlexander Kabaev     inline _Expr<_UnClos<__##_Name, _Expr, _Dom>,                        \
430*f8a1b7d9SAlexander Kabaev                  typename _Dom::value_type>                              \
431ffeaf689SAlexander Kabaev     _Name(const _Expr<_Dom, typename _Dom::value_type>& __e)             \
432ffeaf689SAlexander Kabaev     {                                                                    \
433ffeaf689SAlexander Kabaev       typedef typename _Dom::value_type _Tp;                             \
434ffeaf689SAlexander Kabaev       typedef _UnClos<__##_Name, _Expr, _Dom> _Closure;                  \
435ffeaf689SAlexander Kabaev       return _Expr<_Closure, _Tp>(_Closure(__e()));                      \
436ffeaf689SAlexander Kabaev     }                                                                    \
437ffeaf689SAlexander Kabaev                                                                          \
438ffeaf689SAlexander Kabaev   template<typename _Tp>                                                 \
439ffeaf689SAlexander Kabaev     inline _Expr<_UnClos<__##_Name, _ValArray, _Tp>, _Tp>                \
440ffeaf689SAlexander Kabaev     _Name(const valarray<_Tp>& __v)                                      \
441ffeaf689SAlexander Kabaev     {                                                                    \
442ffeaf689SAlexander Kabaev       typedef _UnClos<__##_Name, _ValArray, _Tp> _Closure;               \
443ffeaf689SAlexander Kabaev       return _Expr<_Closure, _Tp>(_Closure(__v));                        \
444ffeaf689SAlexander Kabaev     }
445ffeaf689SAlexander Kabaev 
446ffeaf689SAlexander Kabaev     _DEFINE_EXPR_UNARY_FUNCTION(abs)
447ffeaf689SAlexander Kabaev     _DEFINE_EXPR_UNARY_FUNCTION(cos)
448ffeaf689SAlexander Kabaev     _DEFINE_EXPR_UNARY_FUNCTION(acos)
449ffeaf689SAlexander Kabaev     _DEFINE_EXPR_UNARY_FUNCTION(cosh)
450ffeaf689SAlexander Kabaev     _DEFINE_EXPR_UNARY_FUNCTION(sin)
451ffeaf689SAlexander Kabaev     _DEFINE_EXPR_UNARY_FUNCTION(asin)
452ffeaf689SAlexander Kabaev     _DEFINE_EXPR_UNARY_FUNCTION(sinh)
453ffeaf689SAlexander Kabaev     _DEFINE_EXPR_UNARY_FUNCTION(tan)
454ffeaf689SAlexander Kabaev     _DEFINE_EXPR_UNARY_FUNCTION(tanh)
455ffeaf689SAlexander Kabaev     _DEFINE_EXPR_UNARY_FUNCTION(atan)
456ffeaf689SAlexander Kabaev     _DEFINE_EXPR_UNARY_FUNCTION(exp)
457ffeaf689SAlexander Kabaev     _DEFINE_EXPR_UNARY_FUNCTION(log)
458ffeaf689SAlexander Kabaev     _DEFINE_EXPR_UNARY_FUNCTION(log10)
459ffeaf689SAlexander Kabaev     _DEFINE_EXPR_UNARY_FUNCTION(sqrt)
460ffeaf689SAlexander Kabaev 
461ffeaf689SAlexander Kabaev #undef _DEFINE_EXPR_UNARY_FUNCTION
462ffeaf689SAlexander Kabaev 
463ffeaf689SAlexander Kabaev #define _DEFINE_EXPR_BINARY_FUNCTION(_Fun)                             \
464ffeaf689SAlexander Kabaev   template<class _Dom1, class _Dom2>                                   \
465ffeaf689SAlexander Kabaev     inline _Expr<_BinClos<__##_Fun, _Expr, _Expr, _Dom1, _Dom2>,       \
466ffeaf689SAlexander Kabaev 		 typename _Dom1::value_type>                           \
467ffeaf689SAlexander Kabaev     _Fun(const _Expr<_Dom1, typename _Dom1::value_type>& __e1,         \
468ffeaf689SAlexander Kabaev 	  const _Expr<_Dom2, typename _Dom2::value_type>& __e2)        \
469ffeaf689SAlexander Kabaev     {                                                                  \
470ffeaf689SAlexander Kabaev       typedef typename _Dom1::value_type _Tp;                          \
471ffeaf689SAlexander Kabaev       typedef _BinClos<__##_Fun, _Expr, _Expr, _Dom1, _Dom2> _Closure; \
472ffeaf689SAlexander Kabaev       return _Expr<_Closure, _Tp>(_Closure(__e1(), __e2()));           \
473ffeaf689SAlexander Kabaev     }                                                                  \
474ffeaf689SAlexander Kabaev                                                                        \
475ffeaf689SAlexander Kabaev   template<class _Dom>                                                 \
476ffeaf689SAlexander Kabaev     inline _Expr<_BinClos<__##_Fun, _Expr, _ValArray, _Dom,            \
477ffeaf689SAlexander Kabaev 			  typename _Dom::value_type>,                  \
478ffeaf689SAlexander Kabaev 		 typename _Dom::value_type>                            \
479ffeaf689SAlexander Kabaev     _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e,            \
480ffeaf689SAlexander Kabaev 	 const valarray<typename _Dom::value_type>& __v)               \
481ffeaf689SAlexander Kabaev     {                                                                  \
482ffeaf689SAlexander Kabaev       typedef typename _Dom::value_type _Tp;                           \
483ffeaf689SAlexander Kabaev       typedef _BinClos<__##_Fun, _Expr, _ValArray, _Dom, _Tp> _Closure; \
484ffeaf689SAlexander Kabaev       return _Expr<_Closure, _Tp>(_Closure(__e(), __v));               \
485ffeaf689SAlexander Kabaev     }                                                                  \
486ffeaf689SAlexander Kabaev                                                                        \
487ffeaf689SAlexander Kabaev   template<class _Dom>                                                 \
488ffeaf689SAlexander Kabaev     inline _Expr<_BinClos<__##_Fun, _ValArray, _Expr,                  \
489ffeaf689SAlexander Kabaev 			  typename _Dom::value_type, _Dom>,            \
490ffeaf689SAlexander Kabaev 		 typename _Dom::value_type>                            \
491ffeaf689SAlexander Kabaev     _Fun(const valarray<typename _Dom::valarray>& __v,                 \
492ffeaf689SAlexander Kabaev 	 const _Expr<_Dom, typename _Dom::value_type>& __e)            \
493ffeaf689SAlexander Kabaev     {                                                                  \
494ffeaf689SAlexander Kabaev       typedef typename _Dom::value_type _Tp;                           \
495ffeaf689SAlexander Kabaev       typedef _BinClos<__##_Fun, _ValArray, _Expr, _Tp, _Dom> _Closure; \
496ffeaf689SAlexander Kabaev       return _Expr<_Closure, _Tp>(_Closure(__v, __e()));               \
497ffeaf689SAlexander Kabaev     }                                                                  \
498ffeaf689SAlexander Kabaev                                                                        \
499ffeaf689SAlexander Kabaev   template<class _Dom>                                                 \
500ffeaf689SAlexander Kabaev     inline _Expr<_BinClos<__##_Fun, _Expr, _Constant, _Dom,            \
501ffeaf689SAlexander Kabaev 			  typename _Dom::value_type>,                  \
502ffeaf689SAlexander Kabaev 		 typename _Dom::value_type>                            \
503ffeaf689SAlexander Kabaev     _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e,            \
504ffeaf689SAlexander Kabaev 	 const typename _Dom::value_type& __t)                         \
505ffeaf689SAlexander Kabaev     {                                                                  \
506ffeaf689SAlexander Kabaev       typedef typename _Dom::value_type _Tp;                           \
507ffeaf689SAlexander Kabaev       typedef _BinClos<__##_Fun, _Expr, _Constant, _Dom, _Tp> _Closure;\
508ffeaf689SAlexander Kabaev       return _Expr<_Closure, _Tp>(_Closure(__e(), __t));               \
509ffeaf689SAlexander Kabaev     }                                                                  \
510ffeaf689SAlexander Kabaev                                                                        \
511ffeaf689SAlexander Kabaev   template<class _Dom>                                                 \
512ffeaf689SAlexander Kabaev     inline _Expr<_BinClos<__##_Fun, _Constant, _Expr,                  \
513ffeaf689SAlexander Kabaev 			  typename _Dom::value_type, _Dom>,            \
514ffeaf689SAlexander Kabaev 		 typename _Dom::value_type>                            \
515ffeaf689SAlexander Kabaev     _Fun(const typename _Dom::value_type& __t,                         \
516ffeaf689SAlexander Kabaev 	 const _Expr<_Dom, typename _Dom::value_type>& __e)            \
517ffeaf689SAlexander Kabaev     {                                                                  \
518ffeaf689SAlexander Kabaev       typedef typename _Dom::value_type _Tp;                           \
519ffeaf689SAlexander Kabaev       typedef _BinClos<__##_Fun, _Constant, _Expr, _Tp, _Dom> _Closure; \
520ffeaf689SAlexander Kabaev       return _Expr<_Closure, _Tp>(_Closure(__t, __e()));               \
521ffeaf689SAlexander Kabaev     }                                                                  \
522ffeaf689SAlexander Kabaev                                                                        \
523ffeaf689SAlexander Kabaev   template<typename _Tp>                                               \
524ffeaf689SAlexander Kabaev     inline _Expr<_BinClos<__##_Fun, _ValArray, _ValArray, _Tp, _Tp>, _Tp> \
525ffeaf689SAlexander Kabaev     _Fun(const valarray<_Tp>& __v, const valarray<_Tp>& __w)           \
526ffeaf689SAlexander Kabaev     {                                                                  \
527ffeaf689SAlexander Kabaev       typedef _BinClos<__##_Fun, _ValArray, _ValArray, _Tp, _Tp> _Closure; \
528ffeaf689SAlexander Kabaev       return _Expr<_Closure, _Tp>(_Closure(__v, __w));                 \
529ffeaf689SAlexander Kabaev     }                                                                  \
530ffeaf689SAlexander Kabaev                                                                        \
531ffeaf689SAlexander Kabaev   template<typename _Tp>                                               \
532ffeaf689SAlexander Kabaev     inline _Expr<_BinClos<__##_Fun, _ValArray, _Constant, _Tp, _Tp>, _Tp> \
533ffeaf689SAlexander Kabaev     _Fun(const valarray<_Tp>& __v, const _Tp& __t)                     \
534ffeaf689SAlexander Kabaev     {                                                                  \
535ffeaf689SAlexander Kabaev       typedef _BinClos<__##_Fun, _ValArray, _Constant, _Tp, _Tp> _Closure; \
536ffeaf689SAlexander Kabaev       return _Expr<_Closure, _Tp>(_Closure(__v, __t));                 \
537ffeaf689SAlexander Kabaev     }                                                                  \
538ffeaf689SAlexander Kabaev 								       \
539ffeaf689SAlexander Kabaev   template<typename _Tp>                                               \
540ffeaf689SAlexander Kabaev     inline _Expr<_BinClos<__##_Fun, _Constant, _ValArray, _Tp, _Tp>, _Tp> \
541ffeaf689SAlexander Kabaev     _Fun(const _Tp& __t, const valarray<_Tp>& __v)                     \
542ffeaf689SAlexander Kabaev     {                                                                  \
543ffeaf689SAlexander Kabaev       typedef _BinClos<__##_Fun, _Constant, _ValArray, _Tp, _Tp> _Closure; \
544ffeaf689SAlexander Kabaev       return _Expr<_Closure, _Tp>(_Closure(__t, __v));                 \
545ffeaf689SAlexander Kabaev     }
546ffeaf689SAlexander Kabaev 
547ffeaf689SAlexander Kabaev _DEFINE_EXPR_BINARY_FUNCTION(atan2)
548ffeaf689SAlexander Kabaev _DEFINE_EXPR_BINARY_FUNCTION(pow)
549ffeaf689SAlexander Kabaev 
550ffeaf689SAlexander Kabaev #undef _DEFINE_EXPR_BINARY_FUNCTION
551ffeaf689SAlexander Kabaev 
552*f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NAMESPACE
553ffeaf689SAlexander Kabaev 
554ffeaf689SAlexander Kabaev #endif /* _CPP_VALARRAY_AFTER_H */
555