libstdc++
valarray_before.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_before.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 <Gabriel.Dos-Reis@cmla.ens-cachan.fr>
32 
33 #ifndef _VALARRAY_BEFORE_H
34 #define _VALARRAY_BEFORE_H 1
35 
36 #pragma GCC system_header
37 
38 #include <bits/slice_array.h>
39 
40 namespace std _GLIBCXX_VISIBILITY(default)
41 {
42 _GLIBCXX_BEGIN_NAMESPACE_VERSION
43 
44  //
45  // Implementing a loosened valarray return value is tricky.
46  // First we need to meet 26.3.1/3: we should not add more than
47  // two levels of template nesting. Therefore we resort to template
48  // template to "flatten" loosened return value types.
49  // At some point we use partial specialization to remove one level
50  // template nesting due to _Expr<>
51  //
52 
53  // This class is NOT defined. It doesn't need to.
54  template<typename _Tp1, typename _Tp2> class _Constant;
55 
56  // Implementations of unary functions applied to valarray<>s.
57  // I use hard-coded object functions here instead of a generic
58  // approach like pointers to function:
59  // 1) correctness: some functions take references, others values.
60  // we can't deduce the correct type afterwards.
61  // 2) efficiency -- object functions can be easily inlined
62  // 3) be Koenig-lookup-friendly
63 
64  struct _Abs
65  {
66  template<typename _Tp>
67  _Tp operator()(const _Tp& __t) const
68  { return abs(__t); }
69  };
70 
71  struct _Cos
72  {
73  template<typename _Tp>
74  _Tp operator()(const _Tp& __t) const
75  { return cos(__t); }
76  };
77 
78  struct _Acos
79  {
80  template<typename _Tp>
81  _Tp operator()(const _Tp& __t) const
82  { return acos(__t); }
83  };
84 
85  struct _Cosh
86  {
87  template<typename _Tp>
88  _Tp operator()(const _Tp& __t) const
89  { return cosh(__t); }
90  };
91 
92  struct _Sin
93  {
94  template<typename _Tp>
95  _Tp operator()(const _Tp& __t) const
96  { return sin(__t); }
97  };
98 
99  struct _Asin
100  {
101  template<typename _Tp>
102  _Tp operator()(const _Tp& __t) const
103  { return asin(__t); }
104  };
105 
106  struct _Sinh
107  {
108  template<typename _Tp>
109  _Tp operator()(const _Tp& __t) const
110  { return sinh(__t); }
111  };
112 
113  struct _Tan
114  {
115  template<typename _Tp>
116  _Tp operator()(const _Tp& __t) const
117  { return tan(__t); }
118  };
119 
120  struct _Atan
121  {
122  template<typename _Tp>
123  _Tp operator()(const _Tp& __t) const
124  { return atan(__t); }
125  };
126 
127  struct _Tanh
128  {
129  template<typename _Tp>
130  _Tp operator()(const _Tp& __t) const
131  { return tanh(__t); }
132  };
133 
134  struct _Exp
135  {
136  template<typename _Tp>
137  _Tp operator()(const _Tp& __t) const
138  { return exp(__t); }
139  };
140 
141  struct _Log
142  {
143  template<typename _Tp>
144  _Tp operator()(const _Tp& __t) const
145  { return log(__t); }
146  };
147 
148  struct _Log10
149  {
150  template<typename _Tp>
151  _Tp operator()(const _Tp& __t) const
152  { return log10(__t); }
153  };
154 
155  struct _Sqrt
156  {
157  template<typename _Tp>
158  _Tp operator()(const _Tp& __t) const
159  { return sqrt(__t); }
160  };
161 
162  // In the past, we used to tailor operator applications semantics
163  // to the specialization of standard function objects (i.e. plus<>, etc.)
164  // That is incorrect. Therefore we provide our own surrogates.
165 
166  struct __unary_plus
167  {
168  template<typename _Tp>
169  _Tp operator()(const _Tp& __t) const
170  { return +__t; }
171  };
172 
173  struct __negate
174  {
175  template<typename _Tp>
176  _Tp operator()(const _Tp& __t) const
177  { return -__t; }
178  };
179 
180  struct __bitwise_not
181  {
182  template<typename _Tp>
183  _Tp operator()(const _Tp& __t) const
184  { return ~__t; }
185  };
186 
187  struct __plus
188  {
189  template<typename _Tp>
190  _Tp operator()(const _Tp& __x, const _Tp& __y) const
191  { return __x + __y; }
192  };
193 
194  struct __minus
195  {
196  template<typename _Tp>
197  _Tp operator()(const _Tp& __x, const _Tp& __y) const
198  { return __x - __y; }
199  };
200 
201  struct __multiplies
202  {
203  template<typename _Tp>
204  _Tp operator()(const _Tp& __x, const _Tp& __y) const
205  { return __x * __y; }
206  };
207 
208  struct __divides
209  {
210  template<typename _Tp>
211  _Tp operator()(const _Tp& __x, const _Tp& __y) const
212  { return __x / __y; }
213  };
214 
215  struct __modulus
216  {
217  template<typename _Tp>
218  _Tp operator()(const _Tp& __x, const _Tp& __y) const
219  { return __x % __y; }
220  };
221 
222  struct __bitwise_xor
223  {
224  template<typename _Tp>
225  _Tp operator()(const _Tp& __x, const _Tp& __y) const
226  { return __x ^ __y; }
227  };
228 
229  struct __bitwise_and
230  {
231  template<typename _Tp>
232  _Tp operator()(const _Tp& __x, const _Tp& __y) const
233  { return __x & __y; }
234  };
235 
236  struct __bitwise_or
237  {
238  template<typename _Tp>
239  _Tp operator()(const _Tp& __x, const _Tp& __y) const
240  { return __x | __y; }
241  };
242 
243  struct __shift_left
244  {
245  template<typename _Tp>
246  _Tp operator()(const _Tp& __x, const _Tp& __y) const
247  { return __x << __y; }
248  };
249 
250  struct __shift_right
251  {
252  template<typename _Tp>
253  _Tp operator()(const _Tp& __x, const _Tp& __y) const
254  { return __x >> __y; }
255  };
256 
257  struct __logical_and
258  {
259  template<typename _Tp>
260  bool operator()(const _Tp& __x, const _Tp& __y) const
261  { return __x && __y; }
262  };
263 
264  struct __logical_or
265  {
266  template<typename _Tp>
267  bool operator()(const _Tp& __x, const _Tp& __y) const
268  { return __x || __y; }
269  };
270 
271  struct __logical_not
272  {
273  template<typename _Tp>
274  bool operator()(const _Tp& __x) const
275  { return !__x; }
276  };
277 
278  struct __equal_to
279  {
280  template<typename _Tp>
281  bool operator()(const _Tp& __x, const _Tp& __y) const
282  { return __x == __y; }
283  };
284 
285  struct __not_equal_to
286  {
287  template<typename _Tp>
288  bool operator()(const _Tp& __x, const _Tp& __y) const
289  { return __x != __y; }
290  };
291 
292  struct __less
293  {
294  template<typename _Tp>
295  bool operator()(const _Tp& __x, const _Tp& __y) const
296  { return __x < __y; }
297  };
298 
299  struct __greater
300  {
301  template<typename _Tp>
302  bool operator()(const _Tp& __x, const _Tp& __y) const
303  { return __x > __y; }
304  };
305 
306  struct __less_equal
307  {
308  template<typename _Tp>
309  bool operator()(const _Tp& __x, const _Tp& __y) const
310  { return __x <= __y; }
311  };
312 
313  struct __greater_equal
314  {
315  template<typename _Tp>
316  bool operator()(const _Tp& __x, const _Tp& __y) const
317  { return __x >= __y; }
318  };
319 
320  // The few binary functions we miss.
321  struct _Atan2
322  {
323  template<typename _Tp>
324  _Tp operator()(const _Tp& __x, const _Tp& __y) const
325  { return atan2(__x, __y); }
326  };
327 
328  struct _Pow
329  {
330  template<typename _Tp>
331  _Tp operator()(const _Tp& __x, const _Tp& __y) const
332  { return pow(__x, __y); }
333  };
334 
335 
336  // We need these bits in order to recover the return type of
337  // some functions/operators now that we're no longer using
338  // function templates.
339  template<typename, typename _Tp>
340  struct __fun
341  {
342  typedef _Tp result_type;
343  };
344 
345  // several specializations for relational operators.
346  template<typename _Tp>
347  struct __fun<__logical_not, _Tp>
348  {
349  typedef bool result_type;
350  };
351 
352  template<typename _Tp>
353  struct __fun<__logical_and, _Tp>
354  {
355  typedef bool result_type;
356  };
357 
358  template<typename _Tp>
359  struct __fun<__logical_or, _Tp>
360  {
361  typedef bool result_type;
362  };
363 
364  template<typename _Tp>
365  struct __fun<__less, _Tp>
366  {
367  typedef bool result_type;
368  };
369 
370  template<typename _Tp>
371  struct __fun<__greater, _Tp>
372  {
373  typedef bool result_type;
374  };
375 
376  template<typename _Tp>
377  struct __fun<__less_equal, _Tp>
378  {
379  typedef bool result_type;
380  };
381 
382  template<typename _Tp>
383  struct __fun<__greater_equal, _Tp>
384  {
385  typedef bool result_type;
386  };
387 
388  template<typename _Tp>
389  struct __fun<__equal_to, _Tp>
390  {
391  typedef bool result_type;
392  };
393 
394  template<typename _Tp>
395  struct __fun<__not_equal_to, _Tp>
396  {
397  typedef bool result_type;
398  };
399 
400  //
401  // Apply function taking a value/const reference closure
402  //
403 
404  template<typename _Dom, typename _Arg>
405  class _FunBase
406  {
407  public:
408  typedef typename _Dom::value_type value_type;
409 
410  _FunBase(const _Dom& __e, value_type __f(_Arg))
411  : _M_expr(__e), _M_func(__f) {}
412 
413  value_type operator[](size_t __i) const
414  { return _M_func (_M_expr[__i]); }
415 
416  size_t size() const { return _M_expr.size ();}
417 
418  private:
419  const _Dom& _M_expr;
420  value_type (*_M_func)(_Arg);
421  };
422 
423  template<class _Dom>
424  struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type>
425  {
426  typedef _FunBase<_Dom, typename _Dom::value_type> _Base;
427  typedef typename _Base::value_type value_type;
428  typedef value_type _Tp;
429 
430  _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {}
431  };
432 
433  template<typename _Tp>
434  struct _ValFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, _Tp>
435  {
436  typedef _FunBase<valarray<_Tp>, _Tp> _Base;
437  typedef _Tp value_type;
438 
439  _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {}
440  };
441 
442  template<class _Dom>
443  struct _RefFunClos<_Expr, _Dom>
444  : _FunBase<_Dom, const typename _Dom::value_type&>
445  {
446  typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base;
447  typedef typename _Base::value_type value_type;
448  typedef value_type _Tp;
449 
450  _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&))
451  : _Base(__e, __f) {}
452  };
453 
454  template<typename _Tp>
455  struct _RefFunClos<_ValArray, _Tp>
456  : _FunBase<valarray<_Tp>, const _Tp&>
457  {
458  typedef _FunBase<valarray<_Tp>, const _Tp&> _Base;
459  typedef _Tp value_type;
460 
461  _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&))
462  : _Base(__v, __f) {}
463  };
464 
465  //
466  // Unary expression closure.
467  //
468 
469  template<class _Oper, class _Arg>
470  class _UnBase
471  {
472  public:
473  typedef typename _Arg::value_type _Vt;
474  typedef typename __fun<_Oper, _Vt>::result_type value_type;
475 
476  _UnBase(const _Arg& __e) : _M_expr(__e) {}
477 
478  value_type operator[](size_t __i) const
479  { return _Oper()(_M_expr[__i]); }
480 
481  size_t size() const { return _M_expr.size(); }
482 
483  private:
484  const _Arg& _M_expr;
485  };
486 
487  template<class _Oper, class _Dom>
488  struct _UnClos<_Oper, _Expr, _Dom>
489  : _UnBase<_Oper, _Dom>
490  {
491  typedef _Dom _Arg;
492  typedef _UnBase<_Oper, _Dom> _Base;
493  typedef typename _Base::value_type value_type;
494 
495  _UnClos(const _Arg& __e) : _Base(__e) {}
496  };
497 
498  template<class _Oper, typename _Tp>
499  struct _UnClos<_Oper, _ValArray, _Tp>
500  : _UnBase<_Oper, valarray<_Tp> >
501  {
502  typedef valarray<_Tp> _Arg;
503  typedef _UnBase<_Oper, valarray<_Tp> > _Base;
504  typedef typename _Base::value_type value_type;
505 
506  _UnClos(const _Arg& __e) : _Base(__e) {}
507  };
508 
509 
510  //
511  // Binary expression closure.
512  //
513 
514  template<class _Oper, class _FirstArg, class _SecondArg>
515  class _BinBase
516  {
517  public:
518  typedef typename _FirstArg::value_type _Vt;
519  typedef typename __fun<_Oper, _Vt>::result_type value_type;
520 
521  _BinBase(const _FirstArg& __e1, const _SecondArg& __e2)
522  : _M_expr1(__e1), _M_expr2(__e2) {}
523 
524  value_type operator[](size_t __i) const
525  { return _Oper()(_M_expr1[__i], _M_expr2[__i]); }
526 
527  size_t size() const { return _M_expr1.size(); }
528 
529  private:
530  const _FirstArg& _M_expr1;
531  const _SecondArg& _M_expr2;
532  };
533 
534 
535  template<class _Oper, class _Clos>
536  class _BinBase2
537  {
538  public:
539  typedef typename _Clos::value_type _Vt;
540  typedef typename __fun<_Oper, _Vt>::result_type value_type;
541 
542  _BinBase2(const _Clos& __e, const _Vt& __t)
543  : _M_expr1(__e), _M_expr2(__t) {}
544 
545  value_type operator[](size_t __i) const
546  { return _Oper()(_M_expr1[__i], _M_expr2); }
547 
548  size_t size() const { return _M_expr1.size(); }
549 
550  private:
551  const _Clos& _M_expr1;
552  const _Vt& _M_expr2;
553  };
554 
555  template<class _Oper, class _Clos>
556  class _BinBase1
557  {
558  public:
559  typedef typename _Clos::value_type _Vt;
560  typedef typename __fun<_Oper, _Vt>::result_type value_type;
561 
562  _BinBase1(const _Vt& __t, const _Clos& __e)
563  : _M_expr1(__t), _M_expr2(__e) {}
564 
565  value_type operator[](size_t __i) const
566  { return _Oper()(_M_expr1, _M_expr2[__i]); }
567 
568  size_t size() const { return _M_expr2.size(); }
569 
570  private:
571  const _Vt& _M_expr1;
572  const _Clos& _M_expr2;
573  };
574 
575  template<class _Oper, class _Dom1, class _Dom2>
576  struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2>
577  : _BinBase<_Oper, _Dom1, _Dom2>
578  {
579  typedef _BinBase<_Oper, _Dom1, _Dom2> _Base;
580  typedef typename _Base::value_type value_type;
581 
582  _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {}
583  };
584 
585  template<class _Oper, typename _Tp>
586  struct _BinClos<_Oper,_ValArray, _ValArray, _Tp, _Tp>
587  : _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> >
588  {
589  typedef _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > _Base;
590  typedef typename _Base::value_type value_type;
591 
592  _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w)
593  : _Base(__v, __w) {}
594  };
595 
596  template<class _Oper, class _Dom>
597  struct _BinClos<_Oper, _Expr, _ValArray, _Dom, typename _Dom::value_type>
598  : _BinBase<_Oper, _Dom, valarray<typename _Dom::value_type> >
599  {
600  typedef typename _Dom::value_type _Tp;
601  typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base;
602  typedef typename _Base::value_type value_type;
603 
604  _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2)
605  : _Base(__e1, __e2) {}
606  };
607 
608  template<class _Oper, class _Dom>
609  struct _BinClos<_Oper, _ValArray, _Expr, typename _Dom::value_type, _Dom>
610  : _BinBase<_Oper, valarray<typename _Dom::value_type>,_Dom>
611  {
612  typedef typename _Dom::value_type _Tp;
613  typedef _BinBase<_Oper, valarray<_Tp>, _Dom> _Base;
614  typedef typename _Base::value_type value_type;
615 
616  _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2)
617  : _Base(__e1, __e2) {}
618  };
619 
620  template<class _Oper, class _Dom>
621  struct _BinClos<_Oper, _Expr, _Constant, _Dom, typename _Dom::value_type>
622  : _BinBase2<_Oper, _Dom>
623  {
624  typedef typename _Dom::value_type _Tp;
625  typedef _BinBase2<_Oper,_Dom> _Base;
626  typedef typename _Base::value_type value_type;
627 
628  _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {}
629  };
630 
631  template<class _Oper, class _Dom>
632  struct _BinClos<_Oper, _Constant, _Expr, typename _Dom::value_type, _Dom>
633  : _BinBase1<_Oper, _Dom>
634  {
635  typedef typename _Dom::value_type _Tp;
636  typedef _BinBase1<_Oper, _Dom> _Base;
637  typedef typename _Base::value_type value_type;
638 
639  _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {}
640  };
641 
642  template<class _Oper, typename _Tp>
643  struct _BinClos<_Oper, _ValArray, _Constant, _Tp, _Tp>
644  : _BinBase2<_Oper, valarray<_Tp> >
645  {
646  typedef _BinBase2<_Oper,valarray<_Tp> > _Base;
647  typedef typename _Base::value_type value_type;
648 
649  _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {}
650  };
651 
652  template<class _Oper, typename _Tp>
653  struct _BinClos<_Oper, _Constant, _ValArray, _Tp, _Tp>
654  : _BinBase1<_Oper, valarray<_Tp> >
655  {
656  typedef _BinBase1<_Oper, valarray<_Tp> > _Base;
657  typedef typename _Base::value_type value_type;
658 
659  _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {}
660  };
661 
662  //
663  // slice_array closure.
664  //
665  template<typename _Dom>
666  class _SBase
667  {
668  public:
669  typedef typename _Dom::value_type value_type;
670 
671  _SBase (const _Dom& __e, const slice& __s)
672  : _M_expr (__e), _M_slice (__s) {}
673 
674  value_type
675  operator[] (size_t __i) const
676  { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; }
677 
678  size_t
679  size() const
680  { return _M_slice.size (); }
681 
682  private:
683  const _Dom& _M_expr;
684  const slice& _M_slice;
685  };
686 
687  template<typename _Tp>
688  class _SBase<_Array<_Tp> >
689  {
690  public:
691  typedef _Tp value_type;
692 
693  _SBase (_Array<_Tp> __a, const slice& __s)
694  : _M_array (__a._M_data+__s.start()), _M_size (__s.size()),
695  _M_stride (__s.stride()) {}
696 
697  value_type
698  operator[] (size_t __i) const
699  { return _M_array._M_data[__i * _M_stride]; }
700 
701  size_t
702  size() const
703  { return _M_size; }
704 
705  private:
706  const _Array<_Tp> _M_array;
707  const size_t _M_size;
708  const size_t _M_stride;
709  };
710 
711  template<class _Dom>
712  struct _SClos<_Expr, _Dom>
713  : _SBase<_Dom>
714  {
715  typedef _SBase<_Dom> _Base;
716  typedef typename _Base::value_type value_type;
717 
718  _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {}
719  };
720 
721  template<typename _Tp>
722  struct _SClos<_ValArray, _Tp>
723  : _SBase<_Array<_Tp> >
724  {
725  typedef _SBase<_Array<_Tp> > _Base;
726  typedef _Tp value_type;
727 
728  _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {}
729  };
730 
731 _GLIBCXX_END_NAMESPACE_VERSION
732 } // namespace
733 
734 #endif /* _CPP_VALARRAY_BEFORE_H */