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