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