OSDN Git Service

2010-08-05 Paolo Carlini <paolo.carlini@oracle.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / bits / valarray_before.h
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 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
273       { return !__x; }
274   };
275
276   struct __equal_to
277   {
278     template<typename _Tp>
279       bool operator()(const _Tp& __x, const _Tp& __y) const
280       { return __x == __y; }
281   };
282
283   struct __not_equal_to
284   {
285     template<typename _Tp>
286       bool operator()(const _Tp& __x, const _Tp& __y) const
287       { return __x != __y; }
288   };
289
290   struct __less
291   {
292     template<typename _Tp>
293       bool operator()(const _Tp& __x, const _Tp& __y) const
294       { return __x < __y; }
295   };
296
297   struct __greater
298   {
299     template<typename _Tp>
300       bool operator()(const _Tp& __x, const _Tp& __y) const
301       { return __x > __y; }
302   };
303
304   struct __less_equal
305   {
306     template<typename _Tp>
307       bool operator()(const _Tp& __x, const _Tp& __y) const
308       { return __x <= __y; }
309   };
310
311   struct __greater_equal
312   {
313     template<typename _Tp>
314       bool operator()(const _Tp& __x, const _Tp& __y) const
315       { return __x >= __y; }
316   };
317
318   // The few binary functions we miss.
319   struct _Atan2
320   {
321     template<typename _Tp>
322       _Tp operator()(const _Tp& __x, const _Tp& __y) const
323       { return atan2(__x, __y); }
324   };
325
326   struct _Pow
327   {
328     template<typename _Tp>
329       _Tp operator()(const _Tp& __x, const _Tp& __y) const
330       { return pow(__x, __y); }
331   };
332
333
334   // We need these bits in order to recover the return type of
335   // some functions/operators now that we're no longer using
336   // function templates.
337   template<typename, typename _Tp>
338     struct __fun
339     {
340       typedef _Tp result_type;
341     };
342
343   // several specializations for relational operators.
344   template<typename _Tp>
345     struct __fun<__logical_not, _Tp>
346     {
347       typedef bool result_type;
348     };
349
350   template<typename _Tp>
351     struct __fun<__logical_and, _Tp>
352     {
353       typedef bool result_type;
354     };
355
356   template<typename _Tp>
357     struct __fun<__logical_or, _Tp>
358     {
359       typedef bool result_type;
360     };
361
362   template<typename _Tp>
363     struct __fun<__less, _Tp>
364     {
365       typedef bool result_type;
366     };
367
368   template<typename _Tp>
369     struct __fun<__greater, _Tp>
370     {
371       typedef bool result_type;
372     };
373
374   template<typename _Tp>
375     struct __fun<__less_equal, _Tp>
376     {
377       typedef bool result_type;
378     };
379
380   template<typename _Tp>
381     struct __fun<__greater_equal, _Tp>
382     {
383       typedef bool result_type;
384     };
385
386   template<typename _Tp>
387     struct __fun<__equal_to, _Tp>
388     {
389       typedef bool result_type;
390     };
391
392   template<typename _Tp>
393     struct __fun<__not_equal_to, _Tp>
394     {
395       typedef bool result_type;
396     };
397
398   //
399   // Apply function taking a value/const reference closure
400   //
401
402   template<typename _Dom, typename _Arg>
403     class _FunBase
404     {
405     public:
406       typedef typename _Dom::value_type value_type;
407
408       _FunBase(const _Dom& __e, value_type __f(_Arg))
409       : _M_expr(__e), _M_func(__f) {}
410
411       value_type operator[](size_t __i) const
412       { return _M_func (_M_expr[__i]); }
413
414       size_t size() const { return _M_expr.size ();}
415
416     private:
417       const _Dom& _M_expr;
418       value_type (*_M_func)(_Arg);
419     };
420
421   template<class _Dom>
422     struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type>
423     {
424       typedef _FunBase<_Dom, typename _Dom::value_type> _Base;
425       typedef typename _Base::value_type value_type;
426       typedef value_type _Tp;
427
428       _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {}
429     };
430
431   template<typename _Tp>
432     struct _ValFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, _Tp>
433     {
434       typedef _FunBase<valarray<_Tp>, _Tp> _Base;
435       typedef _Tp value_type;
436
437       _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {}
438     };
439
440   template<class _Dom>
441     struct _RefFunClos<_Expr, _Dom>
442     : _FunBase<_Dom, const typename _Dom::value_type&>
443     {
444       typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base;
445       typedef typename _Base::value_type value_type;
446       typedef value_type _Tp;
447
448       _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&))
449       : _Base(__e, __f) {}
450     };
451
452   template<typename _Tp>
453     struct _RefFunClos<_ValArray, _Tp>
454     : _FunBase<valarray<_Tp>, const _Tp&>
455     {
456       typedef _FunBase<valarray<_Tp>, const _Tp&> _Base;
457       typedef _Tp value_type;
458
459       _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&))
460       : _Base(__v, __f) {}
461     };
462
463   //
464   // Unary expression closure.
465   //
466
467   template<class _Oper, class _Arg>
468     class _UnBase
469     {
470     public:
471       typedef typename _Arg::value_type _Vt;
472       typedef typename __fun<_Oper, _Vt>::result_type value_type;
473
474       _UnBase(const _Arg& __e) : _M_expr(__e) {}
475
476       value_type operator[](size_t __i) const
477       { return _Oper()(_M_expr[__i]); }
478
479       size_t size() const { return _M_expr.size(); }
480       
481     private:
482       const _Arg& _M_expr;
483     };
484
485   template<class _Oper, class _Dom>
486     struct _UnClos<_Oper, _Expr, _Dom>
487     : _UnBase<_Oper, _Dom>
488     {
489       typedef _Dom _Arg;
490       typedef _UnBase<_Oper, _Dom> _Base;
491       typedef typename _Base::value_type value_type;
492
493       _UnClos(const _Arg& __e) : _Base(__e) {}
494     };
495
496   template<class _Oper, typename _Tp>
497     struct _UnClos<_Oper, _ValArray, _Tp>
498     : _UnBase<_Oper, valarray<_Tp> >
499     {
500       typedef valarray<_Tp> _Arg;
501       typedef _UnBase<_Oper, valarray<_Tp> > _Base;
502       typedef typename _Base::value_type value_type;
503
504       _UnClos(const _Arg& __e) : _Base(__e) {}
505     };
506
507
508   //
509   // Binary expression closure.
510   //
511
512   template<class _Oper, class _FirstArg, class _SecondArg>
513     class _BinBase
514     {
515     public:
516       typedef typename _FirstArg::value_type _Vt;
517       typedef typename __fun<_Oper, _Vt>::result_type value_type;
518
519       _BinBase(const _FirstArg& __e1, const _SecondArg& __e2)
520       : _M_expr1(__e1), _M_expr2(__e2) {}
521
522       value_type operator[](size_t __i) const
523       { return _Oper()(_M_expr1[__i], _M_expr2[__i]); }
524
525       size_t size() const { return _M_expr1.size(); }
526
527     private:
528       const _FirstArg& _M_expr1;
529       const _SecondArg& _M_expr2;
530     };
531
532
533   template<class _Oper, class _Clos>
534     class _BinBase2
535     {
536     public:
537       typedef typename _Clos::value_type _Vt;
538       typedef typename __fun<_Oper, _Vt>::result_type value_type;
539
540       _BinBase2(const _Clos& __e, const _Vt& __t)
541       : _M_expr1(__e), _M_expr2(__t) {}
542
543       value_type operator[](size_t __i) const
544       { return _Oper()(_M_expr1[__i], _M_expr2); }
545
546       size_t size() const { return _M_expr1.size(); }
547
548     private:
549       const _Clos& _M_expr1;
550       const _Vt& _M_expr2;
551     };
552
553   template<class _Oper, class _Clos>
554     class _BinBase1
555     {
556     public:
557       typedef typename _Clos::value_type _Vt;
558       typedef typename __fun<_Oper, _Vt>::result_type value_type;
559
560       _BinBase1(const _Vt& __t, const _Clos& __e)
561       : _M_expr1(__t), _M_expr2(__e) {}
562
563       value_type operator[](size_t __i) const
564       { return _Oper()(_M_expr1, _M_expr2[__i]); }
565
566       size_t size() const { return _M_expr2.size(); }
567
568     private:
569       const _Vt& _M_expr1;
570       const _Clos& _M_expr2;
571     };
572
573   template<class _Oper, class _Dom1, class _Dom2>
574     struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2>
575     : _BinBase<_Oper, _Dom1, _Dom2>
576     {
577       typedef _BinBase<_Oper, _Dom1, _Dom2> _Base;
578       typedef typename _Base::value_type value_type;
579
580       _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {}
581     };
582
583   template<class _Oper, typename _Tp>
584     struct _BinClos<_Oper,_ValArray, _ValArray, _Tp, _Tp>
585     : _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> >
586     {
587       typedef _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > _Base;
588       typedef typename _Base::value_type value_type;
589
590       _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w)
591       : _Base(__v, __w) {}
592     };
593
594   template<class _Oper, class _Dom>
595     struct _BinClos<_Oper, _Expr, _ValArray, _Dom, typename _Dom::value_type>
596     : _BinBase<_Oper, _Dom, valarray<typename _Dom::value_type> >
597     {
598       typedef typename _Dom::value_type _Tp;
599       typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base;
600       typedef typename _Base::value_type value_type;
601
602       _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2)
603       : _Base(__e1, __e2) {}
604     };
605
606   template<class _Oper, class _Dom>
607     struct _BinClos<_Oper, _ValArray, _Expr, typename _Dom::value_type, _Dom>
608     : _BinBase<_Oper, valarray<typename _Dom::value_type>,_Dom>
609     {
610       typedef typename _Dom::value_type _Tp;
611       typedef _BinBase<_Oper, valarray<_Tp>, _Dom> _Base;
612       typedef typename _Base::value_type value_type;
613
614       _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2)
615       : _Base(__e1, __e2) {}
616     };
617
618   template<class _Oper, class _Dom>
619     struct _BinClos<_Oper, _Expr, _Constant, _Dom, typename _Dom::value_type>
620     : _BinBase2<_Oper, _Dom>
621     {
622       typedef typename _Dom::value_type _Tp;
623       typedef _BinBase2<_Oper,_Dom> _Base;
624       typedef typename _Base::value_type value_type;
625
626       _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {}
627     };
628
629   template<class _Oper, class _Dom>
630     struct _BinClos<_Oper, _Constant, _Expr, typename _Dom::value_type, _Dom>
631     : _BinBase1<_Oper, _Dom>
632     {
633       typedef typename _Dom::value_type _Tp;
634       typedef _BinBase1<_Oper, _Dom> _Base;
635       typedef typename _Base::value_type value_type;
636
637       _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {}
638     };
639
640   template<class _Oper, typename _Tp>
641     struct _BinClos<_Oper, _ValArray, _Constant, _Tp, _Tp>
642     : _BinBase2<_Oper, valarray<_Tp> >
643     {
644       typedef _BinBase2<_Oper,valarray<_Tp> > _Base;
645       typedef typename _Base::value_type value_type;
646
647       _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {}
648     };
649
650   template<class _Oper, typename _Tp>
651     struct _BinClos<_Oper, _Constant, _ValArray, _Tp, _Tp>
652     : _BinBase1<_Oper, valarray<_Tp> >
653     {
654       typedef _BinBase1<_Oper, valarray<_Tp> > _Base;
655       typedef typename _Base::value_type value_type;
656
657       _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {}
658     };
659
660     //
661     // slice_array closure.
662     //
663   template<typename _Dom> 
664     class _SBase
665     {
666     public:
667       typedef typename _Dom::value_type value_type;
668       
669       _SBase (const _Dom& __e, const slice& __s)
670       : _M_expr (__e), _M_slice (__s) {}
671         
672       value_type
673       operator[] (size_t __i) const
674       { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; }
675         
676       size_t
677       size() const
678       { return _M_slice.size (); }
679
680     private:
681       const _Dom& _M_expr;
682       const slice& _M_slice;
683     };
684
685   template<typename _Tp>
686     class _SBase<_Array<_Tp> >
687     {
688     public:
689       typedef _Tp value_type;
690       
691       _SBase (_Array<_Tp> __a, const slice& __s)
692       : _M_array (__a._M_data+__s.start()), _M_size (__s.size()),
693         _M_stride (__s.stride()) {}
694         
695       value_type
696       operator[] (size_t __i) const
697       { return _M_array._M_data[__i * _M_stride]; }
698       
699       size_t
700       size() const
701       { return _M_size; }
702
703     private:
704       const _Array<_Tp> _M_array;
705       const size_t _M_size;
706       const size_t _M_stride;
707     };
708
709   template<class _Dom>
710     struct _SClos<_Expr, _Dom>
711     : _SBase<_Dom>
712     {
713       typedef _SBase<_Dom> _Base;
714       typedef typename _Base::value_type value_type;
715       
716       _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {}
717     };
718
719   template<typename _Tp>
720     struct _SClos<_ValArray, _Tp>
721     : _SBase<_Array<_Tp> >
722     {
723       typedef  _SBase<_Array<_Tp> > _Base;
724       typedef _Tp value_type;
725       
726       _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {}
727     };
728
729 _GLIBCXX_END_NAMESPACE
730
731 #endif /* _CPP_VALARRAY_BEFORE_H */