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 */
735