1 // The template and inlines for the -*- C++ -*- internal _Meta class.
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4 // 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
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)
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.
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.
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/>.
26 /** @file valarray_before.h
27 * This is an internal header file, included by other library headers.
28 * You should not attempt to use it directly.
31 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr>
33 #ifndef _VALARRAY_BEFORE_H
34 #define _VALARRAY_BEFORE_H 1
36 #pragma GCC system_header
38 #include <bits/slice_array.h>
40 _GLIBCXX_BEGIN_NAMESPACE(std
)
43 // Implementing a loosened valarray return value is tricky.
44 // First we need to meet 26.3.1/3: we should not add more than
45 // two levels of template nesting. Therefore we resort to template
46 // template to "flatten" loosened return value types.
47 // At some point we use partial specialization to remove one level
48 // template nesting due to _Expr<>
51 // This class is NOT defined. It doesn't need to.
52 template<typename _Tp1
, typename _Tp2
> class _Constant
;
54 // Implementations of unary functions applied to valarray<>s.
55 // I use hard-coded object functions here instead of a generic
56 // approach like pointers to function:
57 // 1) correctness: some functions take references, others values.
58 // we can't deduce the correct type afterwards.
59 // 2) efficiency -- object functions can be easily inlined
60 // 3) be Koenig-lookup-friendly
64 template<typename _Tp
>
65 _Tp
operator()(const _Tp
& __t
) const
71 template<typename _Tp
>
72 _Tp
operator()(const _Tp
& __t
) const
78 template<typename _Tp
>
79 _Tp
operator()(const _Tp
& __t
) const
85 template<typename _Tp
>
86 _Tp
operator()(const _Tp
& __t
) const
92 template<typename _Tp
>
93 _Tp
operator()(const _Tp
& __t
) const
99 template<typename _Tp
>
100 _Tp
operator()(const _Tp
& __t
) const
101 { return asin(__t
); }
106 template<typename _Tp
>
107 _Tp
operator()(const _Tp
& __t
) const
108 { return sinh(__t
); }
113 template<typename _Tp
>
114 _Tp
operator()(const _Tp
& __t
) const
120 template<typename _Tp
>
121 _Tp
operator()(const _Tp
& __t
) const
122 { return atan(__t
); }
127 template<typename _Tp
>
128 _Tp
operator()(const _Tp
& __t
) const
129 { return tanh(__t
); }
134 template<typename _Tp
>
135 _Tp
operator()(const _Tp
& __t
) const
141 template<typename _Tp
>
142 _Tp
operator()(const _Tp
& __t
) const
148 template<typename _Tp
>
149 _Tp
operator()(const _Tp
& __t
) const
150 { return log10(__t
); }
155 template<typename _Tp
>
156 _Tp
operator()(const _Tp
& __t
) const
157 { return sqrt(__t
); }
160 // In the past, we used to tailor operator applications semantics
161 // to the specialization of standard function objects (i.e. plus<>, etc.)
162 // That is incorrect. Therefore we provide our own surrogates.
166 template<typename _Tp
>
167 _Tp
operator()(const _Tp
& __t
) const
173 template<typename _Tp
>
174 _Tp
operator()(const _Tp
& __t
) const
180 template<typename _Tp
>
181 _Tp
operator()(const _Tp
& __t
) const
187 template<typename _Tp
>
188 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
189 { return __x
+ __y
; }
194 template<typename _Tp
>
195 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
196 { return __x
- __y
; }
201 template<typename _Tp
>
202 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
203 { return __x
* __y
; }
208 template<typename _Tp
>
209 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
210 { return __x
/ __y
; }
215 template<typename _Tp
>
216 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
217 { return __x
% __y
; }
222 template<typename _Tp
>
223 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
224 { return __x
^ __y
; }
229 template<typename _Tp
>
230 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
231 { return __x
& __y
; }
236 template<typename _Tp
>
237 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
238 { return __x
| __y
; }
243 template<typename _Tp
>
244 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
245 { return __x
<< __y
; }
250 template<typename _Tp
>
251 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
252 { return __x
>> __y
; }
257 template<typename _Tp
>
258 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
259 { return __x
&& __y
; }
264 template<typename _Tp
>
265 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
266 { return __x
|| __y
; }
271 template<typename _Tp
>
272 bool operator()(const _Tp
& __x
) const
278 template<typename _Tp
>
279 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
280 { return __x
== __y
; }
283 struct __not_equal_to
285 template<typename _Tp
>
286 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
287 { return __x
!= __y
; }
292 template<typename _Tp
>
293 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
294 { return __x
< __y
; }
299 template<typename _Tp
>
300 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
301 { return __x
> __y
; }
306 template<typename _Tp
>
307 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
308 { return __x
<= __y
; }
311 struct __greater_equal
313 template<typename _Tp
>
314 bool operator()(const _Tp
& __x
, const _Tp
& __y
) const
315 { return __x
>= __y
; }
318 // The few binary functions we miss.
321 template<typename _Tp
>
322 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
323 { return atan2(__x
, __y
); }
328 template<typename _Tp
>
329 _Tp
operator()(const _Tp
& __x
, const _Tp
& __y
) const
330 { return pow(__x
, __y
); }
334 // We need these bits in order to recover the return type of
335 // some functions/operators now that we're no longer using
336 // function templates.
337 template<typename
, typename _Tp
>
340 typedef _Tp result_type
;
343 // several specializations for relational operators.
344 template<typename _Tp
>
345 struct __fun
<__logical_not
, _Tp
>
347 typedef bool result_type
;
350 template<typename _Tp
>
351 struct __fun
<__logical_and
, _Tp
>
353 typedef bool result_type
;
356 template<typename _Tp
>
357 struct __fun
<__logical_or
, _Tp
>
359 typedef bool result_type
;
362 template<typename _Tp
>
363 struct __fun
<__less
, _Tp
>
365 typedef bool result_type
;
368 template<typename _Tp
>
369 struct __fun
<__greater
, _Tp
>
371 typedef bool result_type
;
374 template<typename _Tp
>
375 struct __fun
<__less_equal
, _Tp
>
377 typedef bool result_type
;
380 template<typename _Tp
>
381 struct __fun
<__greater_equal
, _Tp
>
383 typedef bool result_type
;
386 template<typename _Tp
>
387 struct __fun
<__equal_to
, _Tp
>
389 typedef bool result_type
;
392 template<typename _Tp
>
393 struct __fun
<__not_equal_to
, _Tp
>
395 typedef bool result_type
;
399 // Apply function taking a value/const reference closure
402 template<typename _Dom
, typename _Arg
>
406 typedef typename
_Dom::value_type value_type
;
408 _FunBase(const _Dom
& __e
, value_type
__f(_Arg
))
409 : _M_expr(__e
), _M_func(__f
) {}
411 value_type
operator[](size_t __i
) const
412 { return _M_func (_M_expr
[__i
]); }
414 size_t size() const { return _M_expr
.size ();}
418 value_type (*_M_func
)(_Arg
);
422 struct _ValFunClos
<_Expr
,_Dom
> : _FunBase
<_Dom
, typename
_Dom::value_type
>
424 typedef _FunBase
<_Dom
, typename
_Dom::value_type
> _Base
;
425 typedef typename
_Base::value_type value_type
;
426 typedef value_type _Tp
;
428 _ValFunClos(const _Dom
& __e
, _Tp
__f(_Tp
)) : _Base(__e
, __f
) {}
431 template<typename _Tp
>
432 struct _ValFunClos
<_ValArray
,_Tp
> : _FunBase
<valarray
<_Tp
>, _Tp
>
434 typedef _FunBase
<valarray
<_Tp
>, _Tp
> _Base
;
435 typedef _Tp value_type
;
437 _ValFunClos(const valarray
<_Tp
>& __v
, _Tp
__f(_Tp
)) : _Base(__v
, __f
) {}
441 struct _RefFunClos
<_Expr
, _Dom
>
442 : _FunBase
<_Dom
, const typename
_Dom::value_type
&>
444 typedef _FunBase
<_Dom
, const typename
_Dom::value_type
&> _Base
;
445 typedef typename
_Base::value_type value_type
;
446 typedef value_type _Tp
;
448 _RefFunClos(const _Dom
& __e
, _Tp
__f(const _Tp
&))
452 template<typename _Tp
>
453 struct _RefFunClos
<_ValArray
, _Tp
>
454 : _FunBase
<valarray
<_Tp
>, const _Tp
&>
456 typedef _FunBase
<valarray
<_Tp
>, const _Tp
&> _Base
;
457 typedef _Tp value_type
;
459 _RefFunClos(const valarray
<_Tp
>& __v
, _Tp
__f(const _Tp
&))
464 // Unary expression closure.
467 template<class _Oper
, class _Arg
>
471 typedef typename
_Arg::value_type _Vt
;
472 typedef typename __fun
<_Oper
, _Vt
>::result_type value_type
;
474 _UnBase(const _Arg
& __e
) : _M_expr(__e
) {}
476 value_type
operator[](size_t __i
) const
477 { return _Oper()(_M_expr
[__i
]); }
479 size_t size() const { return _M_expr
.size(); }
485 template<class _Oper
, class _Dom
>
486 struct _UnClos
<_Oper
, _Expr
, _Dom
>
487 : _UnBase
<_Oper
, _Dom
>
490 typedef _UnBase
<_Oper
, _Dom
> _Base
;
491 typedef typename
_Base::value_type value_type
;
493 _UnClos(const _Arg
& __e
) : _Base(__e
) {}
496 template<class _Oper
, typename _Tp
>
497 struct _UnClos
<_Oper
, _ValArray
, _Tp
>
498 : _UnBase
<_Oper
, valarray
<_Tp
> >
500 typedef valarray
<_Tp
> _Arg
;
501 typedef _UnBase
<_Oper
, valarray
<_Tp
> > _Base
;
502 typedef typename
_Base::value_type value_type
;
504 _UnClos(const _Arg
& __e
) : _Base(__e
) {}
509 // Binary expression closure.
512 template<class _Oper
, class _FirstArg
, class _SecondArg
>
516 typedef typename
_FirstArg::value_type _Vt
;
517 typedef typename __fun
<_Oper
, _Vt
>::result_type value_type
;
519 _BinBase(const _FirstArg
& __e1
, const _SecondArg
& __e2
)
520 : _M_expr1(__e1
), _M_expr2(__e2
) {}
522 value_type
operator[](size_t __i
) const
523 { return _Oper()(_M_expr1
[__i
], _M_expr2
[__i
]); }
525 size_t size() const { return _M_expr1
.size(); }
528 const _FirstArg
& _M_expr1
;
529 const _SecondArg
& _M_expr2
;
533 template<class _Oper
, class _Clos
>
537 typedef typename
_Clos::value_type _Vt
;
538 typedef typename __fun
<_Oper
, _Vt
>::result_type value_type
;
540 _BinBase2(const _Clos
& __e
, const _Vt
& __t
)
541 : _M_expr1(__e
), _M_expr2(__t
) {}
543 value_type
operator[](size_t __i
) const
544 { return _Oper()(_M_expr1
[__i
], _M_expr2
); }
546 size_t size() const { return _M_expr1
.size(); }
549 const _Clos
& _M_expr1
;
553 template<class _Oper
, class _Clos
>
557 typedef typename
_Clos::value_type _Vt
;
558 typedef typename __fun
<_Oper
, _Vt
>::result_type value_type
;
560 _BinBase1(const _Vt
& __t
, const _Clos
& __e
)
561 : _M_expr1(__t
), _M_expr2(__e
) {}
563 value_type
operator[](size_t __i
) const
564 { return _Oper()(_M_expr1
, _M_expr2
[__i
]); }
566 size_t size() const { return _M_expr2
.size(); }
570 const _Clos
& _M_expr2
;
573 template<class _Oper
, class _Dom1
, class _Dom2
>
574 struct _BinClos
<_Oper
, _Expr
, _Expr
, _Dom1
, _Dom2
>
575 : _BinBase
<_Oper
, _Dom1
, _Dom2
>
577 typedef _BinBase
<_Oper
, _Dom1
, _Dom2
> _Base
;
578 typedef typename
_Base::value_type value_type
;
580 _BinClos(const _Dom1
& __e1
, const _Dom2
& __e2
) : _Base(__e1
, __e2
) {}
583 template<class _Oper
, typename _Tp
>
584 struct _BinClos
<_Oper
,_ValArray
, _ValArray
, _Tp
, _Tp
>
585 : _BinBase
<_Oper
, valarray
<_Tp
>, valarray
<_Tp
> >
587 typedef _BinBase
<_Oper
, valarray
<_Tp
>, valarray
<_Tp
> > _Base
;
588 typedef typename
_Base::value_type value_type
;
590 _BinClos(const valarray
<_Tp
>& __v
, const valarray
<_Tp
>& __w
)
594 template<class _Oper
, class _Dom
>
595 struct _BinClos
<_Oper
, _Expr
, _ValArray
, _Dom
, typename
_Dom::value_type
>
596 : _BinBase
<_Oper
, _Dom
, valarray
<typename
_Dom::value_type
> >
598 typedef typename
_Dom::value_type _Tp
;
599 typedef _BinBase
<_Oper
,_Dom
,valarray
<_Tp
> > _Base
;
600 typedef typename
_Base::value_type value_type
;
602 _BinClos(const _Dom
& __e1
, const valarray
<_Tp
>& __e2
)
603 : _Base(__e1
, __e2
) {}
606 template<class _Oper
, class _Dom
>
607 struct _BinClos
<_Oper
, _ValArray
, _Expr
, typename
_Dom::value_type
, _Dom
>
608 : _BinBase
<_Oper
, valarray
<typename
_Dom::value_type
>,_Dom
>
610 typedef typename
_Dom::value_type _Tp
;
611 typedef _BinBase
<_Oper
, valarray
<_Tp
>, _Dom
> _Base
;
612 typedef typename
_Base::value_type value_type
;
614 _BinClos(const valarray
<_Tp
>& __e1
, const _Dom
& __e2
)
615 : _Base(__e1
, __e2
) {}
618 template<class _Oper
, class _Dom
>
619 struct _BinClos
<_Oper
, _Expr
, _Constant
, _Dom
, typename
_Dom::value_type
>
620 : _BinBase2
<_Oper
, _Dom
>
622 typedef typename
_Dom::value_type _Tp
;
623 typedef _BinBase2
<_Oper
,_Dom
> _Base
;
624 typedef typename
_Base::value_type value_type
;
626 _BinClos(const _Dom
& __e1
, const _Tp
& __e2
) : _Base(__e1
, __e2
) {}
629 template<class _Oper
, class _Dom
>
630 struct _BinClos
<_Oper
, _Constant
, _Expr
, typename
_Dom::value_type
, _Dom
>
631 : _BinBase1
<_Oper
, _Dom
>
633 typedef typename
_Dom::value_type _Tp
;
634 typedef _BinBase1
<_Oper
, _Dom
> _Base
;
635 typedef typename
_Base::value_type value_type
;
637 _BinClos(const _Tp
& __e1
, const _Dom
& __e2
) : _Base(__e1
, __e2
) {}
640 template<class _Oper
, typename _Tp
>
641 struct _BinClos
<_Oper
, _ValArray
, _Constant
, _Tp
, _Tp
>
642 : _BinBase2
<_Oper
, valarray
<_Tp
> >
644 typedef _BinBase2
<_Oper
,valarray
<_Tp
> > _Base
;
645 typedef typename
_Base::value_type value_type
;
647 _BinClos(const valarray
<_Tp
>& __v
, const _Tp
& __t
) : _Base(__v
, __t
) {}
650 template<class _Oper
, typename _Tp
>
651 struct _BinClos
<_Oper
, _Constant
, _ValArray
, _Tp
, _Tp
>
652 : _BinBase1
<_Oper
, valarray
<_Tp
> >
654 typedef _BinBase1
<_Oper
, valarray
<_Tp
> > _Base
;
655 typedef typename
_Base::value_type value_type
;
657 _BinClos(const _Tp
& __t
, const valarray
<_Tp
>& __v
) : _Base(__t
, __v
) {}
661 // slice_array closure.
663 template<typename _Dom
>
667 typedef typename
_Dom::value_type value_type
;
669 _SBase (const _Dom
& __e
, const slice
& __s
)
670 : _M_expr (__e
), _M_slice (__s
) {}
673 operator[] (size_t __i
) const
674 { return _M_expr
[_M_slice
.start () + __i
* _M_slice
.stride ()]; }
678 { return _M_slice
.size (); }
682 const slice
& _M_slice
;
685 template<typename _Tp
>
686 class _SBase
<_Array
<_Tp
> >
689 typedef _Tp value_type
;
691 _SBase (_Array
<_Tp
> __a
, const slice
& __s
)
692 : _M_array (__a
._M_data
+__s
.start()), _M_size (__s
.size()),
693 _M_stride (__s
.stride()) {}
696 operator[] (size_t __i
) const
697 { return _M_array
._M_data
[__i
* _M_stride
]; }
704 const _Array
<_Tp
> _M_array
;
705 const size_t _M_size
;
706 const size_t _M_stride
;
710 struct _SClos
<_Expr
, _Dom
>
713 typedef _SBase
<_Dom
> _Base
;
714 typedef typename
_Base::value_type value_type
;
716 _SClos (const _Dom
& __e
, const slice
& __s
) : _Base (__e
, __s
) {}
719 template<typename _Tp
>
720 struct _SClos
<_ValArray
, _Tp
>
721 : _SBase
<_Array
<_Tp
> >
723 typedef _SBase
<_Array
<_Tp
> > _Base
;
724 typedef _Tp value_type
;
726 _SClos (_Array
<_Tp
> __a
, const slice
& __s
) : _Base (__a
, __s
) {}
729 _GLIBCXX_END_NAMESPACE
731 #endif /* _CPP_VALARRAY_BEFORE_H */