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