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