Import gcc-4.7.2 to new vendor branch
[dragonfly.git] / contrib / gcc-4.7 / 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 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 */