1132720Skan// The template and inlines for the -*- C++ -*- internal _Meta class.
2132720Skan
3169691Skan// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
4169691Skan// Free Software Foundation, Inc.
5132720Skan//
6132720Skan// This file is part of the GNU ISO C++ Library.  This library is free
7132720Skan// software; you can redistribute it and/or modify it under the
8132720Skan// terms of the GNU General Public License as published by the
9132720Skan// Free Software Foundation; either version 2, or (at your option)
10132720Skan// any later version.
11132720Skan
12132720Skan// This library is distributed in the hope that it will be useful,
13132720Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of
14132720Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15132720Skan// GNU General Public License for more details.
16132720Skan
17132720Skan// You should have received a copy of the GNU General Public License along
18132720Skan// with this library; see the file COPYING.  If not, write to the Free
19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20132720Skan// USA.
21132720Skan
22132720Skan// As a special exception, you may use this file as part of a free software
23132720Skan// library without restriction.  Specifically, if other files instantiate
24132720Skan// templates or use macros or inline functions from this file, or you compile
25132720Skan// this file and link it with other files to produce an executable, this
26132720Skan// file does not by itself cause the resulting executable to be covered by
27132720Skan// the GNU General Public License.  This exception does not however
28132720Skan// invalidate any other reasons why the executable file might be covered by
29132720Skan// the GNU General Public License.
30132720Skan
31169691Skan/** @file valarray_after.h
32132720Skan *  This is an internal header file, included by other library headers.
33132720Skan *  You should not attempt to use it directly.
34132720Skan */
35132720Skan
36169691Skan// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr>
37169691Skan
38132720Skan#ifndef _VALARRAY_AFTER_H
39132720Skan#define _VALARRAY_AFTER_H 1
40132720Skan
41132720Skan#pragma GCC system_header
42132720Skan
43169691Skan_GLIBCXX_BEGIN_NAMESPACE(std)
44132720Skan
45169691Skan  //
46169691Skan  // gslice_array closure.
47169691Skan  //
48169691Skan  template<class _Dom>
49169691Skan    class _GBase
50169691Skan    {
51132720Skan    public:
52169691Skan      typedef typename _Dom::value_type value_type;
53169691Skan
54169691Skan      _GBase (const _Dom& __e, const valarray<size_t>& __i)
55169691Skan      : _M_expr (__e), _M_index(__i) {}
56169691Skan
57169691Skan      value_type
58169691Skan      operator[] (size_t __i) const
59169691Skan      { return _M_expr[_M_index[__i]]; }
60169691Skan
61169691Skan      size_t
62169691Skan      size () const
63169691Skan      { return _M_index.size(); }
64132720Skan
65132720Skan    private:
66169691Skan      const _Dom&	      _M_expr;
67169691Skan      const valarray<size_t>& _M_index;
68132720Skan    };
69132720Skan
70169691Skan  template<typename _Tp>
71169691Skan    class _GBase<_Array<_Tp> >
72169691Skan    {
73132720Skan    public:
74169691Skan      typedef _Tp value_type;
75169691Skan
76169691Skan      _GBase (_Array<_Tp> __a, const valarray<size_t>& __i)
77169691Skan      : _M_array (__a), _M_index(__i) {}
78169691Skan
79169691Skan      value_type
80169691Skan      operator[] (size_t __i) const
81169691Skan      { return _M_array._M_data[_M_index[__i]]; }
82169691Skan
83169691Skan      size_t
84169691Skan      size () const
85169691Skan      { return _M_index.size(); }
86132720Skan
87132720Skan    private:
88169691Skan      const _Array<_Tp>       _M_array;
89169691Skan      const valarray<size_t>& _M_index;
90132720Skan    };
91132720Skan
92169691Skan  template<class _Dom>
93169691Skan    struct _GClos<_Expr, _Dom>
94169691Skan    : _GBase<_Dom>
95169691Skan    {
96169691Skan      typedef _GBase<_Dom> _Base;
97169691Skan      typedef typename _Base::value_type value_type;
98169691Skan
99169691Skan      _GClos (const _Dom& __e, const valarray<size_t>& __i)
100169691Skan      : _Base (__e, __i) {}
101132720Skan    };
102132720Skan
103169691Skan  template<typename _Tp>
104169691Skan    struct _GClos<_ValArray, _Tp>
105169691Skan    : _GBase<_Array<_Tp> >
106169691Skan    {
107169691Skan      typedef _GBase<_Array<_Tp> > _Base;
108169691Skan      typedef typename _Base::value_type value_type;
109169691Skan
110169691Skan      _GClos (_Array<_Tp> __a, const valarray<size_t>& __i)
111169691Skan      : _Base (__a, __i) {}
112132720Skan    };
113132720Skan
114169691Skan  //
115169691Skan  // indirect_array closure
116169691Skan  //
117169691Skan  template<class _Dom>
118169691Skan    class _IBase
119169691Skan    {
120132720Skan    public:
121169691Skan      typedef typename _Dom::value_type value_type;
122132720Skan
123169691Skan      _IBase (const _Dom& __e, const valarray<size_t>& __i)
124169691Skan      : _M_expr (__e), _M_index (__i) {}
125169691Skan
126169691Skan      value_type
127169691Skan      operator[] (size_t __i) const
128169691Skan      { return _M_expr[_M_index[__i]]; }
129169691Skan
130169691Skan      size_t
131169691Skan      size() const
132169691Skan      { return _M_index.size(); }
133132720Skan
134132720Skan    private:
135169691Skan      const _Dom&	      _M_expr;
136169691Skan      const valarray<size_t>& _M_index;
137132720Skan    };
138132720Skan
139169691Skan  template<class _Dom>
140169691Skan    struct _IClos<_Expr, _Dom>
141169691Skan    : _IBase<_Dom>
142169691Skan    {
143169691Skan      typedef _IBase<_Dom> _Base;
144169691Skan      typedef typename _Base::value_type value_type;
145169691Skan
146169691Skan      _IClos (const _Dom& __e, const valarray<size_t>& __i)
147169691Skan      : _Base (__e, __i) {}
148132720Skan    };
149132720Skan
150169691Skan  template<typename _Tp>
151169691Skan    struct _IClos<_ValArray, _Tp>
152169691Skan    : _IBase<valarray<_Tp> >
153169691Skan    {
154169691Skan      typedef _IBase<valarray<_Tp> > _Base;
155169691Skan      typedef _Tp value_type;
156169691Skan
157169691Skan      _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i)
158169691Skan      : _Base (__a, __i) {}
159132720Skan    };
160169691Skan
161132720Skan  //
162132720Skan  // class _Expr
163132720Skan  //
164132720Skan  template<class _Clos, typename _Tp>
165132720Skan    class _Expr
166132720Skan    {
167132720Skan    public:
168132720Skan      typedef _Tp value_type;
169132720Skan
170132720Skan      _Expr(const _Clos&);
171132720Skan
172132720Skan      const _Clos& operator()() const;
173132720Skan
174132720Skan      value_type operator[](size_t) const;
175132720Skan      valarray<value_type> operator[](slice) const;
176132720Skan      valarray<value_type> operator[](const gslice&) const;
177132720Skan      valarray<value_type> operator[](const valarray<bool>&) const;
178132720Skan      valarray<value_type> operator[](const valarray<size_t>&) const;
179132720Skan
180169691Skan      _Expr<_UnClos<__unary_plus, std::_Expr, _Clos>, value_type>
181169691Skan      operator+() const;
182132720Skan
183169691Skan      _Expr<_UnClos<__negate, std::_Expr, _Clos>, value_type>
184169691Skan      operator-() const;
185132720Skan
186169691Skan      _Expr<_UnClos<__bitwise_not, std::_Expr, _Clos>, value_type>
187169691Skan      operator~() const;
188132720Skan
189169691Skan      _Expr<_UnClos<__logical_not, std::_Expr, _Clos>, bool>
190169691Skan      operator!() const;
191132720Skan
192132720Skan      size_t size() const;
193132720Skan      value_type sum() const;
194132720Skan
195132720Skan      valarray<value_type> shift(int) const;
196132720Skan      valarray<value_type> cshift(int) const;
197132720Skan
198132720Skan      value_type min() const;
199132720Skan      value_type max() const;
200132720Skan
201132720Skan      valarray<value_type> apply(value_type (*)(const value_type&)) const;
202132720Skan      valarray<value_type> apply(value_type (*)(value_type)) const;
203132720Skan
204132720Skan    private:
205132720Skan      const _Clos _M_closure;
206132720Skan    };
207132720Skan
208132720Skan  template<class _Clos, typename _Tp>
209132720Skan    inline
210169691Skan    _Expr<_Clos, _Tp>::_Expr(const _Clos& __c) : _M_closure(__c) {}
211132720Skan
212132720Skan  template<class _Clos, typename _Tp>
213132720Skan    inline const _Clos&
214169691Skan    _Expr<_Clos, _Tp>::operator()() const
215132720Skan    { return _M_closure; }
216132720Skan
217132720Skan  template<class _Clos, typename _Tp>
218132720Skan    inline _Tp
219169691Skan    _Expr<_Clos, _Tp>::operator[](size_t __i) const
220132720Skan    { return _M_closure[__i]; }
221132720Skan
222132720Skan  template<class _Clos, typename _Tp>
223132720Skan    inline valarray<_Tp>
224169691Skan    _Expr<_Clos, _Tp>::operator[](slice __s) const
225169691Skan    {
226169691Skan      valarray<_Tp> __v = valarray<_Tp>(*this)[__s];
227169691Skan      return __v;
228169691Skan    }
229132720Skan
230132720Skan  template<class _Clos, typename _Tp>
231132720Skan    inline valarray<_Tp>
232169691Skan    _Expr<_Clos, _Tp>::operator[](const gslice& __gs) const
233169691Skan    {
234169691Skan      valarray<_Tp> __v = valarray<_Tp>(*this)[__gs];
235169691Skan      return __v;
236169691Skan    }
237132720Skan
238132720Skan  template<class _Clos, typename _Tp>
239132720Skan    inline valarray<_Tp>
240169691Skan    _Expr<_Clos, _Tp>::operator[](const valarray<bool>& __m) const
241169691Skan    {
242169691Skan      valarray<_Tp> __v = valarray<_Tp>(*this)[__m];
243169691Skan      return __v;
244169691Skan    }
245132720Skan
246132720Skan  template<class _Clos, typename _Tp>
247132720Skan    inline valarray<_Tp>
248169691Skan    _Expr<_Clos, _Tp>::operator[](const valarray<size_t>& __i) const
249169691Skan    {
250169691Skan      valarray<_Tp> __v = valarray<_Tp>(*this)[__i];
251169691Skan      return __v;
252169691Skan    }
253132720Skan
254132720Skan  template<class _Clos, typename _Tp>
255132720Skan    inline size_t
256169691Skan    _Expr<_Clos, _Tp>::size() const
257169691Skan    { return _M_closure.size(); }
258132720Skan
259132720Skan  template<class _Clos, typename _Tp>
260132720Skan    inline valarray<_Tp>
261132720Skan    _Expr<_Clos, _Tp>::shift(int __n) const
262169691Skan    {
263169691Skan      valarray<_Tp> __v = valarray<_Tp>(*this).shift(__n);
264169691Skan      return __v;
265169691Skan    }
266132720Skan
267132720Skan  template<class _Clos, typename _Tp>
268132720Skan    inline valarray<_Tp>
269132720Skan    _Expr<_Clos, _Tp>::cshift(int __n) const
270169691Skan    {
271169691Skan      valarray<_Tp> __v = valarray<_Tp>(*this).cshift(__n);
272169691Skan      return __v;
273169691Skan    }
274132720Skan
275132720Skan  template<class _Clos, typename _Tp>
276132720Skan    inline valarray<_Tp>
277132720Skan    _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const
278169691Skan    {
279169691Skan      valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f);
280169691Skan      return __v;
281169691Skan    }
282132720Skan
283132720Skan  template<class _Clos, typename _Tp>
284132720Skan    inline valarray<_Tp>
285132720Skan    _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const
286169691Skan    {
287169691Skan      valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f);
288169691Skan      return __v;
289169691Skan    }
290132720Skan
291132720Skan  // XXX: replace this with a more robust summation algorithm.
292132720Skan  template<class _Clos, typename _Tp>
293132720Skan    inline _Tp
294169691Skan    _Expr<_Clos, _Tp>::sum() const
295132720Skan    {
296132720Skan      size_t __n = _M_closure.size();
297132720Skan      if (__n == 0)
298132720Skan	return _Tp();
299132720Skan      else
300132720Skan	{
301132720Skan	  _Tp __s = _M_closure[--__n];
302132720Skan	  while (__n != 0)
303132720Skan	    __s += _M_closure[--__n];
304132720Skan	  return __s;
305132720Skan        }
306132720Skan    }
307132720Skan
308132720Skan  template<class _Clos, typename _Tp>
309132720Skan    inline _Tp
310132720Skan    _Expr<_Clos, _Tp>::min() const
311132720Skan    { return __valarray_min(_M_closure); }
312132720Skan
313132720Skan  template<class _Clos, typename _Tp>
314132720Skan    inline _Tp
315132720Skan    _Expr<_Clos, _Tp>::max() const
316132720Skan    { return __valarray_max(_M_closure); }
317132720Skan
318132720Skan  template<class _Dom, typename _Tp>
319169691Skan    inline _Expr<_UnClos<__logical_not, _Expr, _Dom>, bool>
320169691Skan    _Expr<_Dom, _Tp>::operator!() const
321132720Skan    {
322169691Skan      typedef _UnClos<__logical_not, std::_Expr, _Dom> _Closure;
323169691Skan      return _Expr<_Closure, _Tp>(_Closure(this->_M_closure));
324132720Skan    }
325132720Skan
326132720Skan#define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name)                           \
327132720Skan  template<class _Dom, typename _Tp>                                      \
328169691Skan    inline _Expr<_UnClos<_Name, std::_Expr, _Dom>, _Tp>                   \
329169691Skan    _Expr<_Dom, _Tp>::operator _Op() const                                \
330132720Skan    {                                                                     \
331169691Skan      typedef _UnClos<_Name, std::_Expr, _Dom> _Closure;                  \
332169691Skan      return _Expr<_Closure, _Tp>(_Closure(this->_M_closure));            \
333132720Skan    }
334132720Skan
335132720Skan    _DEFINE_EXPR_UNARY_OPERATOR(+, __unary_plus)
336132720Skan    _DEFINE_EXPR_UNARY_OPERATOR(-, __negate)
337132720Skan    _DEFINE_EXPR_UNARY_OPERATOR(~, __bitwise_not)
338132720Skan
339132720Skan#undef _DEFINE_EXPR_UNARY_OPERATOR
340132720Skan
341132720Skan#define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name)                        \
342132720Skan  template<class _Dom1, class _Dom2>					\
343169691Skan    inline _Expr<_BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2>,           \
344169691Skan           typename __fun<_Name, typename _Dom1::value_type>::result_type> \
345169691Skan    operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v,   \
346169691Skan	         const _Expr<_Dom2, typename _Dom2::value_type>& __w)   \
347169691Skan    {                                                                   \
348169691Skan      typedef typename _Dom1::value_type _Arg;                          \
349169691Skan      typedef typename __fun<_Name, _Arg>::result_type _Value;          \
350169691Skan      typedef _BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2> _Closure;     \
351169691Skan      return _Expr<_Closure, _Value>(_Closure(__v(), __w()));           \
352169691Skan    }                                                                   \
353132720Skan                                                                        \
354169691Skan  template<class _Dom>                                                  \
355169691Skan    inline _Expr<_BinClos<_Name, _Expr, _Constant, _Dom,                \
356169691Skan                          typename _Dom::value_type>,                   \
357169691Skan             typename __fun<_Name, typename _Dom::value_type>::result_type> \
358169691Skan    operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v,     \
359169691Skan                 const typename _Dom::value_type& __t)                  \
360169691Skan    {                                                                   \
361169691Skan      typedef typename _Dom::value_type _Arg;                           \
362169691Skan      typedef typename __fun<_Name, _Arg>::result_type _Value;          \
363169691Skan      typedef _BinClos<_Name, _Expr, _Constant, _Dom, _Arg> _Closure;   \
364169691Skan      return _Expr<_Closure, _Value>(_Closure(__v(), __t));             \
365169691Skan    }                                                                   \
366132720Skan                                                                        \
367169691Skan  template<class _Dom>                                                  \
368169691Skan    inline _Expr<_BinClos<_Name, _Constant, _Expr,                      \
369169691Skan                          typename _Dom::value_type, _Dom>,             \
370169691Skan             typename __fun<_Name, typename _Dom::value_type>::result_type> \
371169691Skan    operator _Op(const typename _Dom::value_type& __t,                  \
372169691Skan                 const _Expr<_Dom, typename _Dom::value_type>& __v)     \
373169691Skan    {                                                                   \
374169691Skan      typedef typename _Dom::value_type _Arg;                           \
375169691Skan      typedef typename __fun<_Name, _Arg>::result_type _Value;          \
376169691Skan      typedef _BinClos<_Name, _Constant, _Expr, _Arg, _Dom> _Closure;   \
377169691Skan      return _Expr<_Closure, _Value>(_Closure(__t, __v()));             \
378169691Skan    }                                                                   \
379132720Skan                                                                        \
380169691Skan  template<class _Dom>                                                  \
381169691Skan    inline _Expr<_BinClos<_Name, _Expr, _ValArray,                      \
382169691Skan                          _Dom, typename _Dom::value_type>,             \
383169691Skan             typename __fun<_Name, typename _Dom::value_type>::result_type> \
384169691Skan    operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e,      \
385169691Skan                 const valarray<typename _Dom::value_type>& __v)        \
386169691Skan    {                                                                   \
387169691Skan      typedef typename _Dom::value_type _Arg;                           \
388169691Skan      typedef typename __fun<_Name, _Arg>::result_type _Value;          \
389169691Skan      typedef _BinClos<_Name, _Expr, _ValArray, _Dom, _Arg> _Closure;   \
390169691Skan      return _Expr<_Closure, _Value>(_Closure(__e(), __v));             \
391169691Skan    }                                                                   \
392132720Skan                                                                        \
393169691Skan  template<class _Dom>                                                  \
394169691Skan    inline _Expr<_BinClos<_Name, _ValArray, _Expr,                      \
395169691Skan                 typename _Dom::value_type, _Dom>,                      \
396169691Skan             typename __fun<_Name, typename _Dom::value_type>::result_type> \
397169691Skan    operator _Op(const valarray<typename _Dom::value_type>& __v,        \
398169691Skan                 const _Expr<_Dom, typename _Dom::value_type>& __e)     \
399169691Skan    {                                                                   \
400169691Skan      typedef typename _Dom::value_type _Tp;                            \
401169691Skan      typedef typename __fun<_Name, _Tp>::result_type _Value;           \
402169691Skan      typedef _BinClos<_Name, _ValArray, _Expr, _Tp, _Dom> _Closure;    \
403169691Skan      return _Expr<_Closure, _Value>(_Closure(__v, __e ()));            \
404169691Skan    }
405132720Skan
406132720Skan    _DEFINE_EXPR_BINARY_OPERATOR(+, __plus)
407132720Skan    _DEFINE_EXPR_BINARY_OPERATOR(-, __minus)
408132720Skan    _DEFINE_EXPR_BINARY_OPERATOR(*, __multiplies)
409132720Skan    _DEFINE_EXPR_BINARY_OPERATOR(/, __divides)
410132720Skan    _DEFINE_EXPR_BINARY_OPERATOR(%, __modulus)
411132720Skan    _DEFINE_EXPR_BINARY_OPERATOR(^, __bitwise_xor)
412132720Skan    _DEFINE_EXPR_BINARY_OPERATOR(&, __bitwise_and)
413132720Skan    _DEFINE_EXPR_BINARY_OPERATOR(|, __bitwise_or)
414132720Skan    _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)
415132720Skan    _DEFINE_EXPR_BINARY_OPERATOR(>>, __shift_right)
416132720Skan    _DEFINE_EXPR_BINARY_OPERATOR(&&, __logical_and)
417132720Skan    _DEFINE_EXPR_BINARY_OPERATOR(||, __logical_or)
418132720Skan    _DEFINE_EXPR_BINARY_OPERATOR(==, __equal_to)
419132720Skan    _DEFINE_EXPR_BINARY_OPERATOR(!=, __not_equal_to)
420132720Skan    _DEFINE_EXPR_BINARY_OPERATOR(<, __less)
421132720Skan    _DEFINE_EXPR_BINARY_OPERATOR(>, __greater)
422132720Skan    _DEFINE_EXPR_BINARY_OPERATOR(<=, __less_equal)
423132720Skan    _DEFINE_EXPR_BINARY_OPERATOR(>=, __greater_equal)
424132720Skan
425132720Skan#undef _DEFINE_EXPR_BINARY_OPERATOR
426132720Skan
427132720Skan#define _DEFINE_EXPR_UNARY_FUNCTION(_Name)                               \
428132720Skan  template<class _Dom>                                                   \
429169691Skan    inline _Expr<_UnClos<__##_Name, _Expr, _Dom>,                        \
430169691Skan                 typename _Dom::value_type>                              \
431169691Skan    _Name(const _Expr<_Dom, typename _Dom::value_type>& __e)             \
432132720Skan    {                                                                    \
433132720Skan      typedef typename _Dom::value_type _Tp;                             \
434169691Skan      typedef _UnClos<__##_Name, _Expr, _Dom> _Closure;                  \
435169691Skan      return _Expr<_Closure, _Tp>(_Closure(__e()));                      \
436132720Skan    }                                                                    \
437132720Skan                                                                         \
438132720Skan  template<typename _Tp>                                                 \
439169691Skan    inline _Expr<_UnClos<__##_Name, _ValArray, _Tp>, _Tp>                \
440132720Skan    _Name(const valarray<_Tp>& __v)                                      \
441132720Skan    {                                                                    \
442169691Skan      typedef _UnClos<__##_Name, _ValArray, _Tp> _Closure;               \
443169691Skan      return _Expr<_Closure, _Tp>(_Closure(__v));                        \
444132720Skan    }
445132720Skan
446132720Skan    _DEFINE_EXPR_UNARY_FUNCTION(abs)
447132720Skan    _DEFINE_EXPR_UNARY_FUNCTION(cos)
448132720Skan    _DEFINE_EXPR_UNARY_FUNCTION(acos)
449132720Skan    _DEFINE_EXPR_UNARY_FUNCTION(cosh)
450132720Skan    _DEFINE_EXPR_UNARY_FUNCTION(sin)
451132720Skan    _DEFINE_EXPR_UNARY_FUNCTION(asin)
452132720Skan    _DEFINE_EXPR_UNARY_FUNCTION(sinh)
453132720Skan    _DEFINE_EXPR_UNARY_FUNCTION(tan)
454132720Skan    _DEFINE_EXPR_UNARY_FUNCTION(tanh)
455132720Skan    _DEFINE_EXPR_UNARY_FUNCTION(atan)
456132720Skan    _DEFINE_EXPR_UNARY_FUNCTION(exp)
457132720Skan    _DEFINE_EXPR_UNARY_FUNCTION(log)
458132720Skan    _DEFINE_EXPR_UNARY_FUNCTION(log10)
459132720Skan    _DEFINE_EXPR_UNARY_FUNCTION(sqrt)
460132720Skan
461132720Skan#undef _DEFINE_EXPR_UNARY_FUNCTION
462132720Skan
463132720Skan#define _DEFINE_EXPR_BINARY_FUNCTION(_Fun)                             \
464132720Skan  template<class _Dom1, class _Dom2>                                   \
465169691Skan    inline _Expr<_BinClos<__##_Fun, _Expr, _Expr, _Dom1, _Dom2>,       \
466132720Skan		 typename _Dom1::value_type>                           \
467169691Skan    _Fun(const _Expr<_Dom1, typename _Dom1::value_type>& __e1,         \
468169691Skan	  const _Expr<_Dom2, typename _Dom2::value_type>& __e2)        \
469132720Skan    {                                                                  \
470132720Skan      typedef typename _Dom1::value_type _Tp;                          \
471169691Skan      typedef _BinClos<__##_Fun, _Expr, _Expr, _Dom1, _Dom2> _Closure; \
472169691Skan      return _Expr<_Closure, _Tp>(_Closure(__e1(), __e2()));           \
473132720Skan    }                                                                  \
474132720Skan                                                                       \
475132720Skan  template<class _Dom>                                                 \
476132720Skan    inline _Expr<_BinClos<__##_Fun, _Expr, _ValArray, _Dom,            \
477132720Skan			  typename _Dom::value_type>,                  \
478132720Skan		 typename _Dom::value_type>                            \
479169691Skan    _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e,            \
480132720Skan	 const valarray<typename _Dom::value_type>& __v)               \
481132720Skan    {                                                                  \
482132720Skan      typedef typename _Dom::value_type _Tp;                           \
483169691Skan      typedef _BinClos<__##_Fun, _Expr, _ValArray, _Dom, _Tp> _Closure; \
484169691Skan      return _Expr<_Closure, _Tp>(_Closure(__e(), __v));               \
485132720Skan    }                                                                  \
486132720Skan                                                                       \
487132720Skan  template<class _Dom>                                                 \
488132720Skan    inline _Expr<_BinClos<__##_Fun, _ValArray, _Expr,                  \
489169691Skan			  typename _Dom::value_type, _Dom>,            \
490132720Skan		 typename _Dom::value_type>                            \
491132720Skan    _Fun(const valarray<typename _Dom::valarray>& __v,                 \
492169691Skan	 const _Expr<_Dom, typename _Dom::value_type>& __e)            \
493132720Skan    {                                                                  \
494132720Skan      typedef typename _Dom::value_type _Tp;                           \
495169691Skan      typedef _BinClos<__##_Fun, _ValArray, _Expr, _Tp, _Dom> _Closure; \
496169691Skan      return _Expr<_Closure, _Tp>(_Closure(__v, __e()));               \
497132720Skan    }                                                                  \
498132720Skan                                                                       \
499132720Skan  template<class _Dom>                                                 \
500169691Skan    inline _Expr<_BinClos<__##_Fun, _Expr, _Constant, _Dom,            \
501132720Skan			  typename _Dom::value_type>,                  \
502132720Skan		 typename _Dom::value_type>                            \
503132720Skan    _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e,            \
504132720Skan	 const typename _Dom::value_type& __t)                         \
505132720Skan    {                                                                  \
506132720Skan      typedef typename _Dom::value_type _Tp;                           \
507169691Skan      typedef _BinClos<__##_Fun, _Expr, _Constant, _Dom, _Tp> _Closure;\
508169691Skan      return _Expr<_Closure, _Tp>(_Closure(__e(), __t));               \
509132720Skan    }                                                                  \
510132720Skan                                                                       \
511132720Skan  template<class _Dom>                                                 \
512169691Skan    inline _Expr<_BinClos<__##_Fun, _Constant, _Expr,                  \
513169691Skan			  typename _Dom::value_type, _Dom>,            \
514132720Skan		 typename _Dom::value_type>                            \
515132720Skan    _Fun(const typename _Dom::value_type& __t,                         \
516169691Skan	 const _Expr<_Dom, typename _Dom::value_type>& __e)            \
517132720Skan    {                                                                  \
518132720Skan      typedef typename _Dom::value_type _Tp;                           \
519169691Skan      typedef _BinClos<__##_Fun, _Constant, _Expr, _Tp, _Dom> _Closure; \
520169691Skan      return _Expr<_Closure, _Tp>(_Closure(__t, __e()));               \
521132720Skan    }                                                                  \
522132720Skan                                                                       \
523132720Skan  template<typename _Tp>                                               \
524169691Skan    inline _Expr<_BinClos<__##_Fun, _ValArray, _ValArray, _Tp, _Tp>, _Tp> \
525132720Skan    _Fun(const valarray<_Tp>& __v, const valarray<_Tp>& __w)           \
526132720Skan    {                                                                  \
527169691Skan      typedef _BinClos<__##_Fun, _ValArray, _ValArray, _Tp, _Tp> _Closure; \
528169691Skan      return _Expr<_Closure, _Tp>(_Closure(__v, __w));                 \
529132720Skan    }                                                                  \
530132720Skan                                                                       \
531132720Skan  template<typename _Tp>                                               \
532169691Skan    inline _Expr<_BinClos<__##_Fun, _ValArray, _Constant, _Tp, _Tp>, _Tp> \
533132720Skan    _Fun(const valarray<_Tp>& __v, const _Tp& __t)                     \
534132720Skan    {                                                                  \
535169691Skan      typedef _BinClos<__##_Fun, _ValArray, _Constant, _Tp, _Tp> _Closure; \
536169691Skan      return _Expr<_Closure, _Tp>(_Closure(__v, __t));                 \
537132720Skan    }                                                                  \
538132720Skan								       \
539132720Skan  template<typename _Tp>                                               \
540169691Skan    inline _Expr<_BinClos<__##_Fun, _Constant, _ValArray, _Tp, _Tp>, _Tp> \
541132720Skan    _Fun(const _Tp& __t, const valarray<_Tp>& __v)                     \
542132720Skan    {                                                                  \
543169691Skan      typedef _BinClos<__##_Fun, _Constant, _ValArray, _Tp, _Tp> _Closure; \
544169691Skan      return _Expr<_Closure, _Tp>(_Closure(__t, __v));                 \
545132720Skan    }
546132720Skan
547132720Skan_DEFINE_EXPR_BINARY_FUNCTION(atan2)
548132720Skan_DEFINE_EXPR_BINARY_FUNCTION(pow)
549132720Skan
550132720Skan#undef _DEFINE_EXPR_BINARY_FUNCTION
551132720Skan
552169691Skan_GLIBCXX_END_NAMESPACE
553132720Skan
554132720Skan#endif /* _CPP_VALARRAY_AFTER_H */
555