1163953Srrs// The template and inlines for the -*- C++ -*- internal _Meta class.
2169382Srrs
3235828Stuexen// Copyright (C) 1997-2020 Free Software Foundation, Inc.
4235828Stuexen//
5163953Srrs// This file is part of the GNU ISO C++ Library.  This library is free
6163953Srrs// software; you can redistribute it and/or modify it under the
7163953Srrs// terms of the GNU General Public License as published by the
8163953Srrs// Free Software Foundation; either version 3, or (at your option)
9163953Srrs// any later version.
10163953Srrs
11163953Srrs// This library is distributed in the hope that it will be useful,
12163953Srrs// but WITHOUT ANY WARRANTY; without even the implied warranty of
13163953Srrs// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14163953Srrs// GNU General Public License for more details.
15163953Srrs
16163953Srrs// Under Section 7 of GPL version 3, you are granted additional
17163953Srrs// permissions described in the GCC Runtime Library Exception, version
18163953Srrs// 3.1, as published by the Free Software Foundation.
19163953Srrs
20163953Srrs// You should have received a copy of the GNU General Public License and
21163953Srrs// a copy of the GCC Runtime Library Exception along with this program;
22163953Srrs// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23163953Srrs// <http://www.gnu.org/licenses/>.
24163953Srrs
25163953Srrs/** @file bits/valarray_after.h
26163953Srrs *  This is an internal header file, included by other library headers.
27163953Srrs *  Do not attempt to use it directly. @headername{valarray}
28163953Srrs */
29163953Srrs
30163953Srrs// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr>
31163953Srrs
32163953Srrs#ifndef _VALARRAY_AFTER_H
33163953Srrs#define _VALARRAY_AFTER_H 1
34163953Srrs
35163953Srrs#pragma GCC system_header
36191845Szec
37188067Srrsnamespace std _GLIBCXX_VISIBILITY(default)
38163953Srrs{
39188067Srrs_GLIBCXX_BEGIN_NAMESPACE_VERSION
40163953Srrs
41191891Srrsnamespace __detail
42188067Srrs{
43163953Srrs  //
44163953Srrs  // gslice_array closure.
45188605Srrs  //
46163953Srrs  template<class _Dom>
47163953Srrs    class _GBase
48163953Srrs    {
49163953Srrs    public:
50163953Srrs      typedef typename _Dom::value_type value_type;
51163953Srrs
52163953Srrs      _GBase (const _Dom& __e, const valarray<size_t>& __i)
53163953Srrs      : _M_expr (__e), _M_index(__i) {}
54168709Srrs
55163953Srrs      value_type
56163953Srrs      operator[] (size_t __i) const
57163953Srrs      { return _M_expr[_M_index[__i]]; }
58163953Srrs
59163953Srrs      size_t
60163953Srrs      size () const
61163953Srrs      { return _M_index.size(); }
62163953Srrs
63163953Srrs    private:
64163953Srrs      typename _ValArrayRef<_Dom>::__type	_M_expr;
65168709Srrs      const valarray<size_t>&			_M_index;
66163953Srrs    };
67163953Srrs
68163953Srrs  template<typename _Tp>
69163953Srrs    class _GBase<_Array<_Tp> >
70163953Srrs    {
71163953Srrs    public:
72168709Srrs      typedef _Tp value_type;
73163953Srrs
74168709Srrs      _GBase (_Array<_Tp> __a, const valarray<size_t>& __i)
75163953Srrs      : _M_array (__a), _M_index(__i) {}
76188388Srrs
77188299Spiso      value_type
78188067Srrs      operator[] (size_t __i) const
79188067Srrs      { return _M_array._M_data[_M_index[__i]]; }
80188067Srrs
81188067Srrs      size_t
82188067Srrs      size () const
83188067Srrs      { return _M_index.size(); }
84188067Srrs
85188067Srrs    private:
86188067Srrs      const _Array<_Tp>       _M_array;
87188067Srrs      const valarray<size_t>& _M_index;
88188067Srrs    };
89188067Srrs
90188067Srrs  template<class _Dom>
91188067Srrs    struct _GClos<_Expr, _Dom>
92188067Srrs    : _GBase<_Dom>
93188067Srrs    {
94188067Srrs      typedef _GBase<_Dom> _Base;
95188067Srrs      typedef typename _Base::value_type value_type;
96188067Srrs
97188067Srrs      _GClos (const _Dom& __e, const valarray<size_t>& __i)
98188067Srrs      : _Base (__e, __i) {}
99188067Srrs    };
100188605Srrs
101188605Srrs  template<typename _Tp>
102188605Srrs    struct _GClos<_ValArray, _Tp>
103188067Srrs    : _GBase<_Array<_Tp> >
104188067Srrs    {
105188605Srrs      typedef _GBase<_Array<_Tp> > _Base;
106188067Srrs      typedef typename _Base::value_type value_type;
107188067Srrs
108188067Srrs      _GClos (_Array<_Tp> __a, const valarray<size_t>& __i)
109188067Srrs      : _Base (__a, __i) {}
110188067Srrs    };
111188067Srrs
112188067Srrs  //
113188605Srrs  // indirect_array closure
114188067Srrs  //
115188067Srrs  template<class _Dom>
116188067Srrs    class _IBase
117188605Srrs    {
118188605Srrs    public:
119188605Srrs      typedef typename _Dom::value_type value_type;
120188067Srrs
121205104Srrs      _IBase (const _Dom& __e, const valarray<size_t>& __i)
122188067Srrs      : _M_expr (__e), _M_index (__i) {}
123211969Stuexen
124234996Stuexen      value_type
125211969Stuexen      operator[] (size_t __i) const
126234996Stuexen      { return _M_expr[_M_index[__i]]; }
127211969Stuexen
128188067Srrs      size_t
129188067Srrs      size() const
130188067Srrs      { return _M_index.size(); }
131188067Srrs
132188067Srrs    private:
133188067Srrs      typename _ValArrayRef<_Dom>::__type	_M_expr;
134188067Srrs      const valarray<size_t>&			_M_index;
135188067Srrs    };
136234995Stuexen
137215301Stuexen  template<class _Dom>
138188067Srrs    struct _IClos<_Expr, _Dom>
139188067Srrs    : _IBase<_Dom>
140188067Srrs    {
141188067Srrs      typedef _IBase<_Dom> _Base;
142188067Srrs      typedef typename _Base::value_type value_type;
143188067Srrs
144188067Srrs      _IClos (const _Dom& __e, const valarray<size_t>& __i)
145188067Srrs      : _Base (__e, __i) {}
146211969Stuexen    };
147188067Srrs
148  template<typename _Tp>
149    struct _IClos<_ValArray, _Tp>
150    : _IBase<valarray<_Tp> >
151    {
152      typedef _IBase<valarray<_Tp> > _Base;
153      typedef _Tp value_type;
154
155      _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i)
156      : _Base (__a, __i) {}
157    };
158} // namespace __detail
159
160  //
161  // class _Expr
162  //
163  template<class _Clos, typename _Tp>
164    class _Expr
165    {
166    public:
167      typedef _Tp value_type;
168
169      _Expr(const _Clos&);
170
171      const _Clos& operator()() const;
172
173      value_type operator[](size_t) const;
174      valarray<value_type> operator[](slice) const;
175      valarray<value_type> operator[](const gslice&) const;
176      valarray<value_type> operator[](const valarray<bool>&) const;
177      valarray<value_type> operator[](const valarray<size_t>&) const;
178
179      _Expr<_UnClos<__unary_plus, std::_Expr, _Clos>, value_type>
180      operator+() const;
181
182      _Expr<_UnClos<__negate, std::_Expr, _Clos>, value_type>
183      operator-() const;
184
185      _Expr<_UnClos<__bitwise_not, std::_Expr, _Clos>, value_type>
186      operator~() const;
187
188      _Expr<_UnClos<__logical_not, std::_Expr, _Clos>, bool>
189      operator!() const;
190
191      size_t size() const;
192      value_type sum() const;
193
194      valarray<value_type> shift(int) const;
195      valarray<value_type> cshift(int) const;
196
197      value_type min() const;
198      value_type max() const;
199
200      valarray<value_type> apply(value_type (*)(const value_type&)) const;
201      valarray<value_type> apply(value_type (*)(value_type)) const;
202
203    private:
204      const _Clos _M_closure;
205    };
206
207  template<class _Clos, typename _Tp>
208    inline
209    _Expr<_Clos, _Tp>::_Expr(const _Clos& __c) : _M_closure(__c) {}
210
211  template<class _Clos, typename _Tp>
212    inline const _Clos&
213    _Expr<_Clos, _Tp>::operator()() const
214    { return _M_closure; }
215
216  template<class _Clos, typename _Tp>
217    inline _Tp
218    _Expr<_Clos, _Tp>::operator[](size_t __i) const
219    { return _M_closure[__i]; }
220
221  template<class _Clos, typename _Tp>
222    inline valarray<_Tp>
223    _Expr<_Clos, _Tp>::operator[](slice __s) const
224    {
225      valarray<_Tp> __v = valarray<_Tp>(*this)[__s];
226      return __v;
227    }
228
229  template<class _Clos, typename _Tp>
230    inline valarray<_Tp>
231    _Expr<_Clos, _Tp>::operator[](const gslice& __gs) const
232    {
233      valarray<_Tp> __v = valarray<_Tp>(*this)[__gs];
234      return __v;
235    }
236
237  template<class _Clos, typename _Tp>
238    inline valarray<_Tp>
239    _Expr<_Clos, _Tp>::operator[](const valarray<bool>& __m) const
240    {
241      valarray<_Tp> __v = valarray<_Tp>(*this)[__m];
242      return __v;
243    }
244
245  template<class _Clos, typename _Tp>
246    inline valarray<_Tp>
247    _Expr<_Clos, _Tp>::operator[](const valarray<size_t>& __i) const
248    {
249      valarray<_Tp> __v = valarray<_Tp>(*this)[__i];
250      return __v;
251    }
252
253  template<class _Clos, typename _Tp>
254    inline size_t
255    _Expr<_Clos, _Tp>::size() const
256    { return _M_closure.size(); }
257
258  template<class _Clos, typename _Tp>
259    inline valarray<_Tp>
260    _Expr<_Clos, _Tp>::shift(int __n) const
261    {
262      valarray<_Tp> __v = valarray<_Tp>(*this).shift(__n);
263      return __v;
264    }
265
266  template<class _Clos, typename _Tp>
267    inline valarray<_Tp>
268    _Expr<_Clos, _Tp>::cshift(int __n) const
269    {
270      valarray<_Tp> __v = valarray<_Tp>(*this).cshift(__n);
271      return __v;
272    }
273
274  template<class _Clos, typename _Tp>
275    inline valarray<_Tp>
276    _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const
277    {
278      valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f);
279      return __v;
280    }
281
282  template<class _Clos, typename _Tp>
283    inline valarray<_Tp>
284    _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const
285    {
286      valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f);
287      return __v;
288    }
289
290  // XXX: replace this with a more robust summation algorithm.
291  template<class _Clos, typename _Tp>
292    inline _Tp
293    _Expr<_Clos, _Tp>::sum() const
294    {
295      size_t __n = _M_closure.size();
296      if (__n == 0)
297	return _Tp();
298      else
299	{
300	  _Tp __s = _M_closure[--__n];
301	  while (__n != 0)
302	    __s += _M_closure[--__n];
303	  return __s;
304        }
305    }
306
307  template<class _Clos, typename _Tp>
308    inline _Tp
309    _Expr<_Clos, _Tp>::min() const
310    { return __valarray_min(_M_closure); }
311
312  template<class _Clos, typename _Tp>
313    inline _Tp
314    _Expr<_Clos, _Tp>::max() const
315    { return __valarray_max(_M_closure); }
316
317  template<class _Dom, typename _Tp>
318    inline _Expr<_UnClos<__logical_not, _Expr, _Dom>, bool>
319    _Expr<_Dom, _Tp>::operator!() const
320    {
321      typedef _UnClos<__logical_not, std::_Expr, _Dom> _Closure;
322      return _Expr<_Closure, bool>(_Closure(this->_M_closure));
323    }
324
325#define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name)                           \
326  template<class _Dom, typename _Tp>                                      \
327    inline _Expr<_UnClos<_Name, std::_Expr, _Dom>, _Tp>                   \
328    _Expr<_Dom, _Tp>::operator _Op() const                                \
329    {                                                                     \
330      typedef _UnClos<_Name, std::_Expr, _Dom> _Closure;                  \
331      return _Expr<_Closure, _Tp>(_Closure(this->_M_closure));            \
332    }
333
334    _DEFINE_EXPR_UNARY_OPERATOR(+, struct std::__unary_plus)
335    _DEFINE_EXPR_UNARY_OPERATOR(-, struct std::__negate)
336    _DEFINE_EXPR_UNARY_OPERATOR(~, struct std::__bitwise_not)
337
338#undef _DEFINE_EXPR_UNARY_OPERATOR
339
340#define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name)                        \
341  template<class _Dom1, class _Dom2>					\
342    inline _Expr<_BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2>,           \
343           typename __fun<_Name, typename _Dom1::value_type>::result_type> \
344    operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v,   \
345	         const _Expr<_Dom2, typename _Dom2::value_type>& __w)   \
346    {                                                                   \
347      typedef typename _Dom1::value_type _Arg;                          \
348      typedef typename __fun<_Name, _Arg>::result_type _Value;          \
349      typedef _BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2> _Closure;     \
350      return _Expr<_Closure, _Value>(_Closure(__v(), __w()));           \
351    }                                                                   \
352                                                                        \
353  template<class _Dom>                                                  \
354    inline _Expr<_BinClos<_Name, _Expr, _Constant, _Dom,                \
355                          typename _Dom::value_type>,                   \
356             typename __fun<_Name, typename _Dom::value_type>::result_type> \
357    operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v,     \
358                 const typename _Dom::value_type& __t)                  \
359    {                                                                   \
360      typedef typename _Dom::value_type _Arg;                           \
361      typedef typename __fun<_Name, _Arg>::result_type _Value;          \
362      typedef _BinClos<_Name, _Expr, _Constant, _Dom, _Arg> _Closure;   \
363      return _Expr<_Closure, _Value>(_Closure(__v(), __t));             \
364    }                                                                   \
365                                                                        \
366  template<class _Dom>                                                  \
367    inline _Expr<_BinClos<_Name, _Constant, _Expr,                      \
368                          typename _Dom::value_type, _Dom>,             \
369             typename __fun<_Name, typename _Dom::value_type>::result_type> \
370    operator _Op(const typename _Dom::value_type& __t,                  \
371                 const _Expr<_Dom, typename _Dom::value_type>& __v)     \
372    {                                                                   \
373      typedef typename _Dom::value_type _Arg;                           \
374      typedef typename __fun<_Name, _Arg>::result_type _Value;          \
375      typedef _BinClos<_Name, _Constant, _Expr, _Arg, _Dom> _Closure;   \
376      return _Expr<_Closure, _Value>(_Closure(__t, __v()));             \
377    }                                                                   \
378                                                                        \
379  template<class _Dom>                                                  \
380    inline _Expr<_BinClos<_Name, _Expr, _ValArray,                      \
381                          _Dom, typename _Dom::value_type>,             \
382             typename __fun<_Name, typename _Dom::value_type>::result_type> \
383    operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e,      \
384                 const valarray<typename _Dom::value_type>& __v)        \
385    {                                                                   \
386      typedef typename _Dom::value_type _Arg;                           \
387      typedef typename __fun<_Name, _Arg>::result_type _Value;          \
388      typedef _BinClos<_Name, _Expr, _ValArray, _Dom, _Arg> _Closure;   \
389      return _Expr<_Closure, _Value>(_Closure(__e(), __v));             \
390    }                                                                   \
391                                                                        \
392  template<class _Dom>                                                  \
393    inline _Expr<_BinClos<_Name, _ValArray, _Expr,                      \
394                 typename _Dom::value_type, _Dom>,                      \
395             typename __fun<_Name, typename _Dom::value_type>::result_type> \
396    operator _Op(const valarray<typename _Dom::value_type>& __v,        \
397                 const _Expr<_Dom, typename _Dom::value_type>& __e)     \
398    {                                                                   \
399      typedef typename _Dom::value_type _Tp;                            \
400      typedef typename __fun<_Name, _Tp>::result_type _Value;           \
401      typedef _BinClos<_Name, _ValArray, _Expr, _Tp, _Dom> _Closure;    \
402      return _Expr<_Closure, _Value>(_Closure(__v, __e ()));            \
403    }
404
405    _DEFINE_EXPR_BINARY_OPERATOR(+, struct std::__plus)
406    _DEFINE_EXPR_BINARY_OPERATOR(-, struct std::__minus)
407    _DEFINE_EXPR_BINARY_OPERATOR(*, struct std::__multiplies)
408    _DEFINE_EXPR_BINARY_OPERATOR(/, struct std::__divides)
409    _DEFINE_EXPR_BINARY_OPERATOR(%, struct std::__modulus)
410    _DEFINE_EXPR_BINARY_OPERATOR(^, struct std::__bitwise_xor)
411    _DEFINE_EXPR_BINARY_OPERATOR(&, struct std::__bitwise_and)
412    _DEFINE_EXPR_BINARY_OPERATOR(|, struct std::__bitwise_or)
413    _DEFINE_EXPR_BINARY_OPERATOR(<<, struct std::__shift_left)
414    _DEFINE_EXPR_BINARY_OPERATOR(>>, struct std::__shift_right)
415    _DEFINE_EXPR_BINARY_OPERATOR(&&, struct std::__logical_and)
416    _DEFINE_EXPR_BINARY_OPERATOR(||, struct std::__logical_or)
417    _DEFINE_EXPR_BINARY_OPERATOR(==, struct std::__equal_to)
418    _DEFINE_EXPR_BINARY_OPERATOR(!=, struct std::__not_equal_to)
419    _DEFINE_EXPR_BINARY_OPERATOR(<, struct std::__less)
420    _DEFINE_EXPR_BINARY_OPERATOR(>, struct std::__greater)
421    _DEFINE_EXPR_BINARY_OPERATOR(<=, struct std::__less_equal)
422    _DEFINE_EXPR_BINARY_OPERATOR(>=, struct std::__greater_equal)
423
424#undef _DEFINE_EXPR_BINARY_OPERATOR
425
426#define _DEFINE_EXPR_UNARY_FUNCTION(_Name, _UName)                       \
427  template<class _Dom>                                                   \
428    inline _Expr<_UnClos<_UName, _Expr, _Dom>,                           \
429                 typename _Dom::value_type>                              \
430    _Name(const _Expr<_Dom, typename _Dom::value_type>& __e)             \
431    {                                                                    \
432      typedef typename _Dom::value_type _Tp;                             \
433      typedef _UnClos<_UName, _Expr, _Dom> _Closure;                     \
434      return _Expr<_Closure, _Tp>(_Closure(__e()));                      \
435    }                                                                    \
436                                                                         \
437  template<typename _Tp>                                                 \
438    inline _Expr<_UnClos<_UName, _ValArray, _Tp>, _Tp>                   \
439    _Name(const valarray<_Tp>& __v)                                      \
440    {                                                                    \
441      typedef _UnClos<_UName, _ValArray, _Tp> _Closure;                  \
442      return _Expr<_Closure, _Tp>(_Closure(__v));                        \
443    }
444
445    _DEFINE_EXPR_UNARY_FUNCTION(abs, struct std::_Abs)
446    _DEFINE_EXPR_UNARY_FUNCTION(cos, struct std::_Cos)
447    _DEFINE_EXPR_UNARY_FUNCTION(acos, struct std::_Acos)
448    _DEFINE_EXPR_UNARY_FUNCTION(cosh, struct std::_Cosh)
449    _DEFINE_EXPR_UNARY_FUNCTION(sin, struct std::_Sin)
450    _DEFINE_EXPR_UNARY_FUNCTION(asin, struct std::_Asin)
451    _DEFINE_EXPR_UNARY_FUNCTION(sinh, struct std::_Sinh)
452    _DEFINE_EXPR_UNARY_FUNCTION(tan, struct std::_Tan)
453    _DEFINE_EXPR_UNARY_FUNCTION(tanh, struct std::_Tanh)
454    _DEFINE_EXPR_UNARY_FUNCTION(atan, struct std::_Atan)
455    _DEFINE_EXPR_UNARY_FUNCTION(exp, struct std::_Exp)
456    _DEFINE_EXPR_UNARY_FUNCTION(log, struct std::_Log)
457    _DEFINE_EXPR_UNARY_FUNCTION(log10, struct std::_Log10)
458    _DEFINE_EXPR_UNARY_FUNCTION(sqrt, struct std::_Sqrt)
459
460#undef _DEFINE_EXPR_UNARY_FUNCTION
461
462#define _DEFINE_EXPR_BINARY_FUNCTION(_Fun, _UFun)		       \
463  template<class _Dom1, class _Dom2>                                   \
464    inline _Expr<_BinClos<_UFun, _Expr, _Expr, _Dom1, _Dom2>,          \
465		 typename _Dom1::value_type>                           \
466    _Fun(const _Expr<_Dom1, typename _Dom1::value_type>& __e1,         \
467	 const _Expr<_Dom2, typename _Dom2::value_type>& __e2)	       \
468    {                                                                  \
469      typedef typename _Dom1::value_type _Tp;                          \
470      typedef _BinClos<_UFun, _Expr, _Expr, _Dom1, _Dom2> _Closure;    \
471      return _Expr<_Closure, _Tp>(_Closure(__e1(), __e2()));           \
472    }                                                                  \
473                                                                       \
474  template<class _Dom>                                                 \
475    inline _Expr<_BinClos<_UFun, _Expr, _ValArray, _Dom,               \
476			  typename _Dom::value_type>,                  \
477		 typename _Dom::value_type>                            \
478    _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e,            \
479	 const valarray<typename _Dom::value_type>& __v)               \
480    {                                                                  \
481      typedef typename _Dom::value_type _Tp;                           \
482      typedef _BinClos<_UFun, _Expr, _ValArray, _Dom, _Tp> _Closure;   \
483      return _Expr<_Closure, _Tp>(_Closure(__e(), __v));               \
484    }                                                                  \
485                                                                       \
486  template<class _Dom>                                                 \
487    inline _Expr<_BinClos<_UFun, _ValArray, _Expr,                     \
488			  typename _Dom::value_type, _Dom>,            \
489		 typename _Dom::value_type>                            \
490    _Fun(const valarray<typename _Dom::valarray>& __v,                 \
491	 const _Expr<_Dom, typename _Dom::value_type>& __e)            \
492    {                                                                  \
493      typedef typename _Dom::value_type _Tp;                           \
494      typedef _BinClos<_UFun, _ValArray, _Expr, _Tp, _Dom> _Closure;   \
495      return _Expr<_Closure, _Tp>(_Closure(__v, __e()));               \
496    }                                                                  \
497                                                                       \
498  template<class _Dom>                                                 \
499    inline _Expr<_BinClos<_UFun, _Expr, _Constant, _Dom,               \
500			  typename _Dom::value_type>,                  \
501		 typename _Dom::value_type>                            \
502    _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e,            \
503	 const typename _Dom::value_type& __t)                         \
504    {                                                                  \
505      typedef typename _Dom::value_type _Tp;                           \
506      typedef _BinClos<_UFun, _Expr, _Constant, _Dom, _Tp> _Closure;   \
507      return _Expr<_Closure, _Tp>(_Closure(__e(), __t));               \
508    }                                                                  \
509                                                                       \
510  template<class _Dom>                                                 \
511    inline _Expr<_BinClos<_UFun, _Constant, _Expr,                     \
512			  typename _Dom::value_type, _Dom>,            \
513		 typename _Dom::value_type>                            \
514    _Fun(const typename _Dom::value_type& __t,                         \
515	 const _Expr<_Dom, typename _Dom::value_type>& __e)            \
516    {                                                                  \
517      typedef typename _Dom::value_type _Tp;                           \
518      typedef _BinClos<_UFun, _Constant, _Expr, _Tp, _Dom> _Closure;   \
519      return _Expr<_Closure, _Tp>(_Closure(__t, __e()));               \
520    }                                                                  \
521                                                                       \
522  template<typename _Tp>                                               \
523    inline _Expr<_BinClos<_UFun, _ValArray, _ValArray, _Tp, _Tp>, _Tp> \
524    _Fun(const valarray<_Tp>& __v, const valarray<_Tp>& __w)           \
525    {                                                                  \
526      typedef _BinClos<_UFun, _ValArray, _ValArray, _Tp, _Tp> _Closure;\
527      return _Expr<_Closure, _Tp>(_Closure(__v, __w));                 \
528    }                                                                  \
529                                                                       \
530  template<typename _Tp>                                               \
531    inline _Expr<_BinClos<_UFun, _ValArray, _Constant, _Tp, _Tp>, _Tp> \
532    _Fun(const valarray<_Tp>& __v,				       \
533	 const typename valarray<_Tp>::value_type& __t)                \
534    {                                                                  \
535      typedef _BinClos<_UFun, _ValArray, _Constant, _Tp, _Tp> _Closure;\
536      return _Expr<_Closure, _Tp>(_Closure(__v, __t));                 \
537    }                                                                  \
538								       \
539  template<typename _Tp>                                               \
540    inline _Expr<_BinClos<_UFun, _Constant, _ValArray, _Tp, _Tp>, _Tp> \
541    _Fun(const typename valarray<_Tp>::value_type& __t,		       \
542	 const valarray<_Tp>& __v)                                     \
543    {                                                                  \
544      typedef _BinClos<_UFun, _Constant, _ValArray, _Tp, _Tp> _Closure;\
545      return _Expr<_Closure, _Tp>(_Closure(__t, __v));                 \
546    }
547
548_DEFINE_EXPR_BINARY_FUNCTION(atan2, struct std::_Atan2)
549_DEFINE_EXPR_BINARY_FUNCTION(pow, struct std::_Pow)
550
551#undef _DEFINE_EXPR_BINARY_FUNCTION
552
553_GLIBCXX_END_NAMESPACE_VERSION
554} // namespace
555
556#endif /* _CPP_VALARRAY_AFTER_H */
557