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
40namespace 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