1 // The template and inlines for the -*- C++ -*- internal _Meta class.
3 // Copyright (C) 1997-2025 Free Software Foundation, Inc.
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)
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.
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.
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/>.
25 /** @file bits/valarray_after.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{valarray}
30 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr>
32 #ifndef _VALARRAY_AFTER_H
33 #define _VALARRAY_AFTER_H 1
35 #ifdef _GLIBCXX_SYSHDR
36 #pragma GCC system_header
39 namespace std
_GLIBCXX_VISIBILITY(default)
41 _GLIBCXX_BEGIN_NAMESPACE_VERSION
46 // gslice_array closure.
52 typedef typename
_Dom::value_type value_type
;
54 _GBase (const _Dom
& __e
, const valarray
<size_t>& __i
)
55 : _M_expr (__e
), _M_index(__i
) {}
58 operator[] (size_t __i
) const
59 { return _M_expr
[_M_index
[__i
]]; }
63 { return _M_index
.size(); }
66 typename _ValArrayRef
<_Dom
>::__type _M_expr
;
67 const valarray
<size_t>& _M_index
;
70 template<typename _Tp
>
71 class _GBase
<_Array
<_Tp
> >
74 typedef _Tp value_type
;
76 _GBase (_Array
<_Tp
> __a
, const valarray
<size_t>& __i
)
77 : _M_array (__a
), _M_index(__i
) {}
80 operator[] (size_t __i
) const
81 { return _M_array
._M_data
[_M_index
[__i
]]; }
85 { return _M_index
.size(); }
88 const _Array
<_Tp
> _M_array
;
89 const valarray
<size_t>& _M_index
;
93 struct _GClos
<_Expr
, _Dom
>
96 typedef _GBase
<_Dom
> _Base
;
97 typedef typename
_Base::value_type value_type
;
99 _GClos (const _Dom
& __e
, const valarray
<size_t>& __i
)
100 : _Base (__e
, __i
) {}
103 template<typename _Tp
>
104 struct _GClos
<_ValArray
, _Tp
>
105 : _GBase
<_Array
<_Tp
> >
107 typedef _GBase
<_Array
<_Tp
> > _Base
;
108 typedef typename
_Base::value_type value_type
;
110 _GClos (_Array
<_Tp
> __a
, const valarray
<size_t>& __i
)
111 : _Base (__a
, __i
) {}
115 // indirect_array closure
121 typedef typename
_Dom::value_type value_type
;
123 _IBase (const _Dom
& __e
, const valarray
<size_t>& __i
)
124 : _M_expr (__e
), _M_index (__i
) {}
127 operator[] (size_t __i
) const
128 { return _M_expr
[_M_index
[__i
]]; }
132 { return _M_index
.size(); }
135 typename _ValArrayRef
<_Dom
>::__type _M_expr
;
136 const valarray
<size_t>& _M_index
;
140 struct _IClos
<_Expr
, _Dom
>
143 typedef _IBase
<_Dom
> _Base
;
144 typedef typename
_Base::value_type value_type
;
146 _IClos (const _Dom
& __e
, const valarray
<size_t>& __i
)
147 : _Base (__e
, __i
) {}
150 template<typename _Tp
>
151 struct _IClos
<_ValArray
, _Tp
>
152 : _IBase
<valarray
<_Tp
> >
154 typedef _IBase
<valarray
<_Tp
> > _Base
;
155 typedef _Tp value_type
;
157 _IClos (const valarray
<_Tp
>& __a
, const valarray
<size_t>& __i
)
158 : _Base (__a
, __i
) {}
160 } // namespace __detail
165 template<class _Clos
, typename _Tp
>
169 typedef _Tp value_type
;
173 const _Clos
& operator()() const;
175 value_type
operator[](size_t) const;
176 valarray
<value_type
> operator[](slice
) const;
177 valarray
<value_type
> operator[](const gslice
&) const;
178 valarray
<value_type
> operator[](const valarray
<bool>&) const;
179 valarray
<value_type
> operator[](const valarray
<size_t>&) const;
181 _Expr
<_UnClos
<__unary_plus
, std::_Expr
, _Clos
>, value_type
>
184 _Expr
<_UnClos
<__negate
, std::_Expr
, _Clos
>, value_type
>
187 _Expr
<_UnClos
<__bitwise_not
, std::_Expr
, _Clos
>, value_type
>
190 _Expr
<_UnClos
<__logical_not
, std::_Expr
, _Clos
>, bool>
194 value_type
sum() const;
196 valarray
<value_type
> shift(int) const;
197 valarray
<value_type
> cshift(int) const;
199 value_type
min() const;
200 value_type
max() const;
202 valarray
<value_type
> apply(value_type (*)(const value_type
&)) const;
203 valarray
<value_type
> apply(value_type (*)(value_type
)) const;
206 const _Clos _M_closure
;
209 template<class _Clos
, typename _Tp
>
211 _Expr
<_Clos
, _Tp
>::_Expr(const _Clos
& __c
) : _M_closure(__c
) {}
213 template<class _Clos
, typename _Tp
>
215 _Expr
<_Clos
, _Tp
>::operator()() const
216 { return _M_closure
; }
218 template<class _Clos
, typename _Tp
>
220 _Expr
<_Clos
, _Tp
>::operator[](size_t __i
) const
221 { return _M_closure
[__i
]; }
223 template<class _Clos
, typename _Tp
>
225 _Expr
<_Clos
, _Tp
>::operator[](slice __s
) const
227 valarray
<_Tp
> __v
= valarray
<_Tp
>(*this)[__s
];
231 template<class _Clos
, typename _Tp
>
233 _Expr
<_Clos
, _Tp
>::operator[](const gslice
& __gs
) const
235 valarray
<_Tp
> __v
= valarray
<_Tp
>(*this)[__gs
];
239 template<class _Clos
, typename _Tp
>
241 _Expr
<_Clos
, _Tp
>::operator[](const valarray
<bool>& __m
) const
243 valarray
<_Tp
> __v
= valarray
<_Tp
>(*this)[__m
];
247 template<class _Clos
, typename _Tp
>
249 _Expr
<_Clos
, _Tp
>::operator[](const valarray
<size_t>& __i
) const
251 valarray
<_Tp
> __v
= valarray
<_Tp
>(*this)[__i
];
255 template<class _Clos
, typename _Tp
>
257 _Expr
<_Clos
, _Tp
>::size() const
258 { return _M_closure
.size(); }
260 template<class _Clos
, typename _Tp
>
262 _Expr
<_Clos
, _Tp
>::shift(int __n
) const
264 valarray
<_Tp
> __v
= valarray
<_Tp
>(*this).shift(__n
);
268 template<class _Clos
, typename _Tp
>
270 _Expr
<_Clos
, _Tp
>::cshift(int __n
) const
272 valarray
<_Tp
> __v
= valarray
<_Tp
>(*this).cshift(__n
);
276 template<class _Clos
, typename _Tp
>
278 _Expr
<_Clos
, _Tp
>::apply(_Tp
__f(const _Tp
&)) const
280 valarray
<_Tp
> __v
= valarray
<_Tp
>(*this).apply(__f
);
284 template<class _Clos
, typename _Tp
>
286 _Expr
<_Clos
, _Tp
>::apply(_Tp
__f(_Tp
)) const
288 valarray
<_Tp
> __v
= valarray
<_Tp
>(*this).apply(__f
);
292 // XXX: replace this with a more robust summation algorithm.
293 template<class _Clos
, typename _Tp
>
295 _Expr
<_Clos
, _Tp
>::sum() const
297 size_t __n
= _M_closure
.size();
302 _Tp __s
= _M_closure
[--__n
];
304 __s
+= _M_closure
[--__n
];
309 template<class _Clos
, typename _Tp
>
311 _Expr
<_Clos
, _Tp
>::min() const
312 { return __valarray_min(_M_closure
); }
314 template<class _Clos
, typename _Tp
>
316 _Expr
<_Clos
, _Tp
>::max() const
317 { return __valarray_max(_M_closure
); }
319 template<class _Dom
, typename _Tp
>
320 inline _Expr
<_UnClos
<__logical_not
, _Expr
, _Dom
>, bool>
321 _Expr
<_Dom
, _Tp
>::operator!() const
323 typedef _UnClos
<__logical_not
, std::_Expr
, _Dom
> _Closure
;
324 return _Expr
<_Closure
, bool>(_Closure(this->_M_closure
));
327 #define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \
328 template<class _Dom, typename _Tp> \
329 inline _Expr<_UnClos<_Name, std::_Expr, _Dom>, _Tp> \
330 _Expr<_Dom, _Tp>::operator _Op() const \
332 typedef _UnClos<_Name, std::_Expr, _Dom> _Closure; \
333 return _Expr<_Closure, _Tp>(_Closure(this->_M_closure)); \
336 _DEFINE_EXPR_UNARY_OPERATOR(+, struct std::__unary_plus
)
337 _DEFINE_EXPR_UNARY_OPERATOR(-, struct std::__negate
)
338 _DEFINE_EXPR_UNARY_OPERATOR(~, struct std::__bitwise_not
)
340 #undef _DEFINE_EXPR_UNARY_OPERATOR
342 #define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \
343 template<class _Dom1, class _Dom2> \
344 inline _Expr<_BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2>, \
345 typename __fun<_Name, typename _Dom1::value_type>::result_type> \
346 operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \
347 const _Expr<_Dom2, typename _Dom2::value_type>& __w) \
349 typedef typename _Dom1::value_type _Arg; \
350 typedef typename __fun<_Name, _Arg>::result_type _Value; \
351 typedef _BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2> _Closure; \
352 return _Expr<_Closure, _Value>(_Closure(__v(), __w())); \
355 template<class _Dom> \
356 inline _Expr<_BinClos<_Name, _Expr, _Constant, _Dom, \
357 typename _Dom::value_type>, \
358 typename __fun<_Name, typename _Dom::value_type>::result_type> \
359 operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \
360 const typename _Dom::value_type& __t) \
362 typedef typename _Dom::value_type _Arg; \
363 typedef typename __fun<_Name, _Arg>::result_type _Value; \
364 typedef _BinClos<_Name, _Expr, _Constant, _Dom, _Arg> _Closure; \
365 return _Expr<_Closure, _Value>(_Closure(__v(), __t)); \
368 template<class _Dom> \
369 inline _Expr<_BinClos<_Name, _Constant, _Expr, \
370 typename _Dom::value_type, _Dom>, \
371 typename __fun<_Name, typename _Dom::value_type>::result_type> \
372 operator _Op(const typename _Dom::value_type& __t, \
373 const _Expr<_Dom, typename _Dom::value_type>& __v) \
375 typedef typename _Dom::value_type _Arg; \
376 typedef typename __fun<_Name, _Arg>::result_type _Value; \
377 typedef _BinClos<_Name, _Constant, _Expr, _Arg, _Dom> _Closure; \
378 return _Expr<_Closure, _Value>(_Closure(__t, __v())); \
381 template<class _Dom> \
382 inline _Expr<_BinClos<_Name, _Expr, _ValArray, \
383 _Dom, typename _Dom::value_type>, \
384 typename __fun<_Name, typename _Dom::value_type>::result_type> \
385 operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \
386 const valarray<typename _Dom::value_type>& __v) \
388 typedef typename _Dom::value_type _Arg; \
389 typedef typename __fun<_Name, _Arg>::result_type _Value; \
390 typedef _BinClos<_Name, _Expr, _ValArray, _Dom, _Arg> _Closure; \
391 return _Expr<_Closure, _Value>(_Closure(__e(), __v)); \
394 template<class _Dom> \
395 inline _Expr<_BinClos<_Name, _ValArray, _Expr, \
396 typename _Dom::value_type, _Dom>, \
397 typename __fun<_Name, typename _Dom::value_type>::result_type> \
398 operator _Op(const valarray<typename _Dom::value_type>& __v, \
399 const _Expr<_Dom, typename _Dom::value_type>& __e) \
401 typedef typename _Dom::value_type _Tp; \
402 typedef typename __fun<_Name, _Tp>::result_type _Value; \
403 typedef _BinClos<_Name, _ValArray, _Expr, _Tp, _Dom> _Closure; \
404 return _Expr<_Closure, _Value>(_Closure(__v, __e ())); \
407 _DEFINE_EXPR_BINARY_OPERATOR(+, struct std::__plus
)
408 _DEFINE_EXPR_BINARY_OPERATOR(-, struct std::__minus
)
409 _DEFINE_EXPR_BINARY_OPERATOR(*, struct std::__multiplies
)
410 _DEFINE_EXPR_BINARY_OPERATOR(/, struct std::__divides
)
411 _DEFINE_EXPR_BINARY_OPERATOR(%, struct std::__modulus
)
412 _DEFINE_EXPR_BINARY_OPERATOR(^, struct std::__bitwise_xor
)
413 _DEFINE_EXPR_BINARY_OPERATOR(&, struct std::__bitwise_and
)
414 _DEFINE_EXPR_BINARY_OPERATOR(|, struct std::__bitwise_or
)
415 _DEFINE_EXPR_BINARY_OPERATOR(<<, struct std::__shift_left
)
416 _DEFINE_EXPR_BINARY_OPERATOR(>>, struct std::__shift_right
)
417 _DEFINE_EXPR_BINARY_OPERATOR(&&, struct std::__logical_and
)
418 _DEFINE_EXPR_BINARY_OPERATOR(||, struct std::__logical_or
)
419 _DEFINE_EXPR_BINARY_OPERATOR(==, struct std::__equal_to
)
420 _DEFINE_EXPR_BINARY_OPERATOR(!=, struct std::__not_equal_to
)
421 _DEFINE_EXPR_BINARY_OPERATOR(<, struct std::__less
)
422 _DEFINE_EXPR_BINARY_OPERATOR(>, struct std::__greater
)
423 _DEFINE_EXPR_BINARY_OPERATOR(<=, struct std::__less_equal
)
424 _DEFINE_EXPR_BINARY_OPERATOR(>=, struct std::__greater_equal
)
426 #undef _DEFINE_EXPR_BINARY_OPERATOR
428 #define _DEFINE_EXPR_UNARY_FUNCTION(_Name, _UName) \
429 template<class _Dom> \
430 inline _Expr<_UnClos<_UName, _Expr, _Dom>, \
431 typename _Dom::value_type> \
432 _Name(const _Expr<_Dom, typename _Dom::value_type>& __e) \
434 typedef typename _Dom::value_type _Tp; \
435 typedef _UnClos<_UName, _Expr, _Dom> _Closure; \
436 return _Expr<_Closure, _Tp>(_Closure(__e())); \
439 template<typename _Tp> \
440 inline _Expr<_UnClos<_UName, _ValArray, _Tp>, _Tp> \
441 _Name(const valarray<_Tp>& __v) \
443 typedef _UnClos<_UName, _ValArray, _Tp> _Closure; \
444 return _Expr<_Closure, _Tp>(_Closure(__v)); \
447 _DEFINE_EXPR_UNARY_FUNCTION(abs
, struct std::_Abs
)
448 _DEFINE_EXPR_UNARY_FUNCTION(cos
, struct std::_Cos
)
449 _DEFINE_EXPR_UNARY_FUNCTION(acos
, struct std::_Acos
)
450 _DEFINE_EXPR_UNARY_FUNCTION(cosh
, struct std::_Cosh
)
451 _DEFINE_EXPR_UNARY_FUNCTION(sin
, struct std::_Sin
)
452 _DEFINE_EXPR_UNARY_FUNCTION(asin
, struct std::_Asin
)
453 _DEFINE_EXPR_UNARY_FUNCTION(sinh
, struct std::_Sinh
)
454 _DEFINE_EXPR_UNARY_FUNCTION(tan
, struct std::_Tan
)
455 _DEFINE_EXPR_UNARY_FUNCTION(tanh
, struct std::_Tanh
)
456 _DEFINE_EXPR_UNARY_FUNCTION(atan
, struct std::_Atan
)
457 _DEFINE_EXPR_UNARY_FUNCTION(exp
, struct std::_Exp
)
458 _DEFINE_EXPR_UNARY_FUNCTION(log
, struct std::_Log
)
459 _DEFINE_EXPR_UNARY_FUNCTION(log10
, struct std::_Log10
)
460 _DEFINE_EXPR_UNARY_FUNCTION(sqrt
, struct std::_Sqrt
)
462 #undef _DEFINE_EXPR_UNARY_FUNCTION
464 #define _DEFINE_EXPR_BINARY_FUNCTION(_Fun, _UFun) \
465 template<class _Dom1, class _Dom2> \
466 inline _Expr<_BinClos<_UFun, _Expr, _Expr, _Dom1, _Dom2>, \
467 typename _Dom1::value_type> \
468 _Fun(const _Expr<_Dom1, typename _Dom1::value_type>& __e1, \
469 const _Expr<_Dom2, typename _Dom2::value_type>& __e2) \
471 typedef typename _Dom1::value_type _Tp; \
472 typedef _BinClos<_UFun, _Expr, _Expr, _Dom1, _Dom2> _Closure; \
473 return _Expr<_Closure, _Tp>(_Closure(__e1(), __e2())); \
476 template<class _Dom> \
477 inline _Expr<_BinClos<_UFun, _Expr, _ValArray, _Dom, \
478 typename _Dom::value_type>, \
479 typename _Dom::value_type> \
480 _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \
481 const valarray<typename _Dom::value_type>& __v) \
483 typedef typename _Dom::value_type _Tp; \
484 typedef _BinClos<_UFun, _Expr, _ValArray, _Dom, _Tp> _Closure; \
485 return _Expr<_Closure, _Tp>(_Closure(__e(), __v)); \
488 template<class _Dom> \
489 inline _Expr<_BinClos<_UFun, _ValArray, _Expr, \
490 typename _Dom::value_type, _Dom>, \
491 typename _Dom::value_type> \
492 _Fun(const valarray<typename _Dom::valarray>& __v, \
493 const _Expr<_Dom, typename _Dom::value_type>& __e) \
495 typedef typename _Dom::value_type _Tp; \
496 typedef _BinClos<_UFun, _ValArray, _Expr, _Tp, _Dom> _Closure; \
497 return _Expr<_Closure, _Tp>(_Closure(__v, __e())); \
500 template<class _Dom> \
501 inline _Expr<_BinClos<_UFun, _Expr, _Constant, _Dom, \
502 typename _Dom::value_type>, \
503 typename _Dom::value_type> \
504 _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \
505 const typename _Dom::value_type& __t) \
507 typedef typename _Dom::value_type _Tp; \
508 typedef _BinClos<_UFun, _Expr, _Constant, _Dom, _Tp> _Closure; \
509 return _Expr<_Closure, _Tp>(_Closure(__e(), __t)); \
512 template<class _Dom> \
513 inline _Expr<_BinClos<_UFun, _Constant, _Expr, \
514 typename _Dom::value_type, _Dom>, \
515 typename _Dom::value_type> \
516 _Fun(const typename _Dom::value_type& __t, \
517 const _Expr<_Dom, typename _Dom::value_type>& __e) \
519 typedef typename _Dom::value_type _Tp; \
520 typedef _BinClos<_UFun, _Constant, _Expr, _Tp, _Dom> _Closure; \
521 return _Expr<_Closure, _Tp>(_Closure(__t, __e())); \
524 template<typename _Tp> \
525 inline _Expr<_BinClos<_UFun, _ValArray, _ValArray, _Tp, _Tp>, _Tp> \
526 _Fun(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \
528 typedef _BinClos<_UFun, _ValArray, _ValArray, _Tp, _Tp> _Closure;\
529 return _Expr<_Closure, _Tp>(_Closure(__v, __w)); \
532 template<typename _Tp> \
533 inline _Expr<_BinClos<_UFun, _ValArray, _Constant, _Tp, _Tp>, _Tp> \
534 _Fun(const valarray<_Tp>& __v, \
535 const typename valarray<_Tp>::value_type& __t) \
537 typedef _BinClos<_UFun, _ValArray, _Constant, _Tp, _Tp> _Closure;\
538 return _Expr<_Closure, _Tp>(_Closure(__v, __t)); \
541 template<typename _Tp> \
542 inline _Expr<_BinClos<_UFun, _Constant, _ValArray, _Tp, _Tp>, _Tp> \
543 _Fun(const typename valarray<_Tp>::value_type& __t, \
544 const valarray<_Tp>& __v) \
546 typedef _BinClos<_UFun, _Constant, _ValArray, _Tp, _Tp> _Closure;\
547 return _Expr<_Closure, _Tp>(_Closure(__t, __v)); \
550 _DEFINE_EXPR_BINARY_FUNCTION(atan2
, struct std::_Atan2
)
551 _DEFINE_EXPR_BINARY_FUNCTION(pow
, struct std::_Pow
)
553 #undef _DEFINE_EXPR_BINARY_FUNCTION
555 _GLIBCXX_END_NAMESPACE_VERSION
558 #endif /* _CPP_VALARRAY_AFTER_H */