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