Clang Project

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