1// The template and inlines for the -*- C++ -*- internal _Meta class.
2
3// Copyright (C) 1997-2018 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_after.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_AFTER_H
33#define _VALARRAY_AFTER_H 1
34
35#pragma GCC system_header
36
37namespace std _GLIBCXX_VISIBILITY(default)
38{
39_GLIBCXX_BEGIN_NAMESPACE_VERSION
40
41 //
42 // gslice_array closure.
43 //
44 template<class _Dom>
45 class _GBase
46 {
47 public:
48 typedef typename _Dom::value_type value_type;
49
50 _GBase (const _Dom& __e, const valarray<size_t>& __i)
51 : _M_expr (__e), _M_index(__i) {}
52
53 value_type
54 operator[] (size_t __i) const
55 { return _M_expr[_M_index[__i]]; }
56
57 size_t
58 size () const
59 { return _M_index.size(); }
60
61 private:
62 const _Dom& _M_expr;
63 const valarray<size_t>& _M_index;
64 };
65
66 template<typename _Tp>
67 class _GBase<_Array<_Tp> >
68 {
69 public:
70 typedef _Tp value_type;
71
72 _GBase (_Array<_Tp> __a, const valarray<size_t>& __i)
73 : _M_array (__a), _M_index(__i) {}
74
75 value_type
76 operator[] (size_t __i) const
77 { return _M_array._M_data[_M_index[__i]]; }
78
79 size_t
80 size () const
81 { return _M_index.size(); }
82
83 private:
84 const _Array<_Tp> _M_array;
85 const valarray<size_t>& _M_index;
86 };
87
88 template<class _Dom>
89 struct _GClos<_Expr, _Dom>
90 : _GBase<_Dom>
91 {
92 typedef _GBase<_Dom> _Base;
93 typedef typename _Base::value_type value_type;
94
95 _GClos (const _Dom& __e, const valarray<size_t>& __i)
96 : _Base (__e, __i) {}
97 };
98
99 template<typename _Tp>
100 struct _GClos<_ValArray, _Tp>
101 : _GBase<_Array<_Tp> >
102 {
103 typedef _GBase<_Array<_Tp> > _Base;
104 typedef typename _Base::value_type value_type;
105
106 _GClos (_Array<_Tp> __a, const valarray<size_t>& __i)
107 : _Base (__a, __i) {}
108 };
109
110 //
111 // indirect_array closure
112 //
113 template<class _Dom>
114 class _IBase
115 {
116 public:
117 typedef typename _Dom::value_type value_type;
118
119 _IBase (const _Dom& __e, const valarray<size_t>& __i)
120 : _M_expr (__e), _M_index (__i) {}
121
122 value_type
123 operator[] (size_t __i) const
124 { return _M_expr[_M_index[__i]]; }
125
126 size_t
127 size() const
128 { return _M_index.size(); }
129
130 private:
131 const _Dom& _M_expr;
132 const valarray<size_t>& _M_index;
133 };
134
135 template<class _Dom>
136 struct _IClos<_Expr, _Dom>
137 : _IBase<_Dom>
138 {
139 typedef _IBase<_Dom> _Base;
140 typedef typename _Base::value_type value_type;
141
142 _IClos (const _Dom& __e, const valarray<size_t>& __i)
143 : _Base (__e, __i) {}
144 };
145
146 template<typename _Tp>
147 struct _IClos<_ValArray, _Tp>
148 : _IBase<valarray<_Tp> >
149 {
150 typedef _IBase<valarray<_Tp> > _Base;
151 typedef _Tp value_type;
152
153 _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i)
154 : _Base (__a, __i) {}
155 };
156
157 //
158 // class _Expr
159 //
160 template<class _Clos, typename _Tp>
161 class _Expr
162 {
163 public:
164 typedef _Tp value_type;
165
166 _Expr(const _Clos&);
167
168 const _Clos& operator()() const;
169
170 value_type operator[](size_t) const;
171 valarray<value_type> operator[](slice) const;
172 valarray<value_type> operator[](const gslice&) const;
173 valarray<value_type> operator[](const valarray<bool>&) const;
174 valarray<value_type> operator[](const valarray<size_t>&) const;
175
176 _Expr<_UnClos<__unary_plus, std::_Expr, _Clos>, value_type>
177 operator+() const;
178
179 _Expr<_UnClos<__negate, std::_Expr, _Clos>, value_type>
180 operator-() const;
181
182 _Expr<_UnClos<__bitwise_not, std::_Expr, _Clos>, value_type>
183 operator~() const;
184
185 _Expr<_UnClos<__logical_not, std::_Expr, _Clos>, bool>
186 operator!() const;
187
188 size_t size() const;
189 value_type sum() const;
190
191 valarray<value_type> shift(int) const;
192 valarray<value_type> cshift(int) const;
193
194 value_type min() const;
195 value_type max() const;
196
197 valarray<value_type> apply(value_type (*)(const value_type&)) const;
198 valarray<value_type> apply(value_type (*)(value_type)) const;
199
200 private:
201 const _Clos _M_closure;
202 };
203
204 template<class _Clos, typename _Tp>
205 inline
206 _Expr<_Clos, _Tp>::_Expr(const _Clos& __c) : _M_closure(__c) {}
207
208 template<class _Clos, typename _Tp>
209 inline const _Clos&
210 _Expr<_Clos, _Tp>::operator()() const
211 { return _M_closure; }
212
213 template<class _Clos, typename _Tp>
214 inline _Tp
215 _Expr<_Clos, _Tp>::operator[](size_t __i) const
216 { return _M_closure[__i]; }
217
218 template<class _Clos, typename _Tp>
219 inline valarray<_Tp>
220 _Expr<_Clos, _Tp>::operator[](slice __s) const
221 {
222 valarray<_Tp> __v = valarray<_Tp>(*this)[__s];
223 return __v;
224 }
225
226 template<class _Clos, typename _Tp>
227 inline valarray<_Tp>
228 _Expr<_Clos, _Tp>::operator[](const gslice& __gs) const
229 {
230 valarray<_Tp> __v = valarray<_Tp>(*this)[__gs];
231 return __v;
232 }
233
234 template<class _Clos, typename _Tp>
235 inline valarray<_Tp>
236 _Expr<_Clos, _Tp>::operator[](const valarray<bool>& __m) const
237 {
238 valarray<_Tp> __v = valarray<_Tp>(*this)[__m];
239 return __v;
240 }
241
242 template<class _Clos, typename _Tp>
243 inline valarray<_Tp>
244 _Expr<_Clos, _Tp>::operator[](const valarray<size_t>& __i) const
245 {
246 valarray<_Tp> __v = valarray<_Tp>(*this)[__i];
247 return __v;
248 }
249
250 template<class _Clos, typename _Tp>
251 inline size_t
252 _Expr<_Clos, _Tp>::size() const
253 { return _M_closure.size(); }
254
255 template<class _Clos, typename _Tp>
256 inline valarray<_Tp>
257 _Expr<_Clos, _Tp>::shift(int __n) const
258 {
259 valarray<_Tp> __v = valarray<_Tp>(*this).shift(__n);
260 return __v;
261 }
262
263 template<class _Clos, typename _Tp>
264 inline valarray<_Tp>
265 _Expr<_Clos, _Tp>::cshift(int __n) const
266 {
267 valarray<_Tp> __v = valarray<_Tp>(*this).cshift(__n);
268 return __v;
269 }
270
271 template<class _Clos, typename _Tp>
272 inline valarray<_Tp>
273 _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const
274 {
275 valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f);
276 return __v;
277 }
278
279 template<class _Clos, typename _Tp>
280 inline valarray<_Tp>
281 _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const
282 {
283 valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f);
284 return __v;
285 }
286
287 // XXX: replace this with a more robust summation algorithm.
288 template<class _Clos, typename _Tp>
289 inline _Tp
290 _Expr<_Clos, _Tp>::sum() const
291 {
292 size_t __n = _M_closure.size();
293 if (__n == 0)
294 return _Tp();
295 else
296 {
297 _Tp __s = _M_closure[--__n];
298 while (__n != 0)
299 __s += _M_closure[--__n];
300 return __s;
301 }
302 }
303
304 template<class _Clos, typename _Tp>
305 inline _Tp
306 _Expr<_Clos, _Tp>::min() const
307 { return __valarray_min(_M_closure); }
308
309 template<class _Clos, typename _Tp>
310 inline _Tp
311 _Expr<_Clos, _Tp>::max() const
312 { return __valarray_max(_M_closure); }
313
314 template<class _Dom, typename _Tp>
315 inline _Expr<_UnClos<__logical_not, _Expr, _Dom>, bool>
316 _Expr<_Dom, _Tp>::operator!() const
317 {
318 typedef _UnClos<__logical_not, std::_Expr, _Dom> _Closure;
319 return _Expr<_Closure, bool>(_Closure(this->_M_closure));
320 }
321
322#define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \
323 template<class _Dom, typename _Tp> \
324 inline _Expr<_UnClos<_Name, std::_Expr, _Dom>, _Tp> \
325 _Expr<_Dom, _Tp>::operator _Op() const \
326 { \
327 typedef _UnClos<_Name, std::_Expr, _Dom> _Closure; \
328 return _Expr<_Closure, _Tp>(_Closure(this->_M_closure)); \
329 }
330
331 _DEFINE_EXPR_UNARY_OPERATOR(+, __unary_plus)
332 _DEFINE_EXPR_UNARY_OPERATOR(-, __negate)
333 _DEFINE_EXPR_UNARY_OPERATOR(~, __bitwise_not)
334
335#undef _DEFINE_EXPR_UNARY_OPERATOR
336
337#define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \
338 template<class _Dom1, class _Dom2> \
339 inline _Expr<_BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2>, \
340 typename __fun<_Name, typename _Dom1::value_type>::result_type> \
341 operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \
342 const _Expr<_Dom2, typename _Dom2::value_type>& __w) \
343 { \
344 typedef typename _Dom1::value_type _Arg; \
345 typedef typename __fun<_Name, _Arg>::result_type _Value; \
346 typedef _BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2> _Closure; \
347 return _Expr<_Closure, _Value>(_Closure(__v(), __w())); \
348 } \
349 \
350 template<class _Dom> \
351 inline _Expr<_BinClos<_Name, _Expr, _Constant, _Dom, \
352 typename _Dom::value_type>, \
353 typename __fun<_Name, typename _Dom::value_type>::result_type> \
354 operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \
355 const typename _Dom::value_type& __t) \
356 { \
357 typedef typename _Dom::value_type _Arg; \
358 typedef typename __fun<_Name, _Arg>::result_type _Value; \
359 typedef _BinClos<_Name, _Expr, _Constant, _Dom, _Arg> _Closure; \
360 return _Expr<_Closure, _Value>(_Closure(__v(), __t)); \
361 } \
362 \
363 template<class _Dom> \
364 inline _Expr<_BinClos<_Name, _Constant, _Expr, \
365 typename _Dom::value_type, _Dom>, \
366 typename __fun<_Name, typename _Dom::value_type>::result_type> \
367 operator _Op(const typename _Dom::value_type& __t, \
368 const _Expr<_Dom, typename _Dom::value_type>& __v) \
369 { \
370 typedef typename _Dom::value_type _Arg; \
371 typedef typename __fun<_Name, _Arg>::result_type _Value; \
372 typedef _BinClos<_Name, _Constant, _Expr, _Arg, _Dom> _Closure; \
373 return _Expr<_Closure, _Value>(_Closure(__t, __v())); \
374 } \
375 \
376 template<class _Dom> \
377 inline _Expr<_BinClos<_Name, _Expr, _ValArray, \
378 _Dom, typename _Dom::value_type>, \
379 typename __fun<_Name, typename _Dom::value_type>::result_type> \
380 operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \
381 const valarray<typename _Dom::value_type>& __v) \
382 { \
383 typedef typename _Dom::value_type _Arg; \
384 typedef typename __fun<_Name, _Arg>::result_type _Value; \
385 typedef _BinClos<_Name, _Expr, _ValArray, _Dom, _Arg> _Closure; \
386 return _Expr<_Closure, _Value>(_Closure(__e(), __v)); \
387 } \
388 \
389 template<class _Dom> \
390 inline _Expr<_BinClos<_Name, _ValArray, _Expr, \
391 typename _Dom::value_type, _Dom>, \
392 typename __fun<_Name, typename _Dom::value_type>::result_type> \
393 operator _Op(const valarray<typename _Dom::value_type>& __v, \
394 const _Expr<_Dom, typename _Dom::value_type>& __e) \
395 { \
396 typedef typename _Dom::value_type _Tp; \
397 typedef typename __fun<_Name, _Tp>::result_type _Value; \
398 typedef _BinClos<_Name, _ValArray, _Expr, _Tp, _Dom> _Closure; \
399 return _Expr<_Closure, _Value>(_Closure(__v, __e ())); \
400 }
401
402 _DEFINE_EXPR_BINARY_OPERATOR(+, __plus)
403 _DEFINE_EXPR_BINARY_OPERATOR(-, __minus)
404 _DEFINE_EXPR_BINARY_OPERATOR(*, __multiplies)
405 _DEFINE_EXPR_BINARY_OPERATOR(/, __divides)
406 _DEFINE_EXPR_BINARY_OPERATOR(%, __modulus)
407 _DEFINE_EXPR_BINARY_OPERATOR(^, __bitwise_xor)
408 _DEFINE_EXPR_BINARY_OPERATOR(&, __bitwise_and)
409 _DEFINE_EXPR_BINARY_OPERATOR(|, __bitwise_or)
410 _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)
411 _DEFINE_EXPR_BINARY_OPERATOR(>>, __shift_right)
412 _DEFINE_EXPR_BINARY_OPERATOR(&&, __logical_and)
413 _DEFINE_EXPR_BINARY_OPERATOR(||, __logical_or)
414 _DEFINE_EXPR_BINARY_OPERATOR(==, __equal_to)
415 _DEFINE_EXPR_BINARY_OPERATOR(!=, __not_equal_to)
416 _DEFINE_EXPR_BINARY_OPERATOR(<, __less)
417 _DEFINE_EXPR_BINARY_OPERATOR(>, __greater)
418 _DEFINE_EXPR_BINARY_OPERATOR(<=, __less_equal)
419 _DEFINE_EXPR_BINARY_OPERATOR(>=, __greater_equal)
420
421#undef _DEFINE_EXPR_BINARY_OPERATOR
422
423#define _DEFINE_EXPR_UNARY_FUNCTION(_Name, _UName) \
424 template<class _Dom> \
425 inline _Expr<_UnClos<_UName, _Expr, _Dom>, \
426 typename _Dom::value_type> \
427 _Name(const _Expr<_Dom, typename _Dom::value_type>& __e) \
428 { \
429 typedef typename _Dom::value_type _Tp; \
430 typedef _UnClos<_UName, _Expr, _Dom> _Closure; \
431 return _Expr<_Closure, _Tp>(_Closure(__e())); \
432 } \
433 \
434 template<typename _Tp> \
435 inline _Expr<_UnClos<_UName, _ValArray, _Tp>, _Tp> \
436 _Name(const valarray<_Tp>& __v) \
437 { \
438 typedef _UnClos<_UName, _ValArray, _Tp> _Closure; \
439 return _Expr<_Closure, _Tp>(_Closure(__v)); \
440 }
441
442 _DEFINE_EXPR_UNARY_FUNCTION(abs, _Abs)
443 _DEFINE_EXPR_UNARY_FUNCTION(cos, _Cos)
444 _DEFINE_EXPR_UNARY_FUNCTION(acos, _Acos)
445 _DEFINE_EXPR_UNARY_FUNCTION(cosh, _Cosh)
446 _DEFINE_EXPR_UNARY_FUNCTION(sin, _Sin)
447 _DEFINE_EXPR_UNARY_FUNCTION(asin, _Asin)
448 _DEFINE_EXPR_UNARY_FUNCTION(sinh, _Sinh)
449 _DEFINE_EXPR_UNARY_FUNCTION(tan, _Tan)
450 _DEFINE_EXPR_UNARY_FUNCTION(tanh, _Tanh)
451 _DEFINE_EXPR_UNARY_FUNCTION(atan, _Atan)
452 _DEFINE_EXPR_UNARY_FUNCTION(exp, _Exp)
453 _DEFINE_EXPR_UNARY_FUNCTION(log, _Log)
454 _DEFINE_EXPR_UNARY_FUNCTION(log10, _Log10)
455 _DEFINE_EXPR_UNARY_FUNCTION(sqrt, _Sqrt)
456
457#undef _DEFINE_EXPR_UNARY_FUNCTION
458
459#define _DEFINE_EXPR_BINARY_FUNCTION(_Fun, _UFun) \
460 template<class _Dom1, class _Dom2> \
461 inline _Expr<_BinClos<_UFun, _Expr, _Expr, _Dom1, _Dom2>, \
462 typename _Dom1::value_type> \
463 _Fun(const _Expr<_Dom1, typename _Dom1::value_type>& __e1, \
464 const _Expr<_Dom2, typename _Dom2::value_type>& __e2) \
465 { \
466 typedef typename _Dom1::value_type _Tp; \
467 typedef _BinClos<_UFun, _Expr, _Expr, _Dom1, _Dom2> _Closure; \
468 return _Expr<_Closure, _Tp>(_Closure(__e1(), __e2())); \
469 } \
470 \
471 template<class _Dom> \
472 inline _Expr<_BinClos<_UFun, _Expr, _ValArray, _Dom, \
473 typename _Dom::value_type>, \
474 typename _Dom::value_type> \
475 _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \
476 const valarray<typename _Dom::value_type>& __v) \
477 { \
478 typedef typename _Dom::value_type _Tp; \
479 typedef _BinClos<_UFun, _Expr, _ValArray, _Dom, _Tp> _Closure; \
480 return _Expr<_Closure, _Tp>(_Closure(__e(), __v)); \
481 } \
482 \
483 template<class _Dom> \
484 inline _Expr<_BinClos<_UFun, _ValArray, _Expr, \
485 typename _Dom::value_type, _Dom>, \
486 typename _Dom::value_type> \
487 _Fun(const valarray<typename _Dom::valarray>& __v, \
488 const _Expr<_Dom, typename _Dom::value_type>& __e) \
489 { \
490 typedef typename _Dom::value_type _Tp; \
491 typedef _BinClos<_UFun, _ValArray, _Expr, _Tp, _Dom> _Closure; \
492 return _Expr<_Closure, _Tp>(_Closure(__v, __e())); \
493 } \
494 \
495 template<class _Dom> \
496 inline _Expr<_BinClos<_UFun, _Expr, _Constant, _Dom, \
497 typename _Dom::value_type>, \
498 typename _Dom::value_type> \
499 _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \
500 const typename _Dom::value_type& __t) \
501 { \
502 typedef typename _Dom::value_type _Tp; \
503 typedef _BinClos<_UFun, _Expr, _Constant, _Dom, _Tp> _Closure; \
504 return _Expr<_Closure, _Tp>(_Closure(__e(), __t)); \
505 } \
506 \
507 template<class _Dom> \
508 inline _Expr<_BinClos<_UFun, _Constant, _Expr, \
509 typename _Dom::value_type, _Dom>, \
510 typename _Dom::value_type> \
511 _Fun(const typename _Dom::value_type& __t, \
512 const _Expr<_Dom, typename _Dom::value_type>& __e) \
513 { \
514 typedef typename _Dom::value_type _Tp; \
515 typedef _BinClos<_UFun, _Constant, _Expr, _Tp, _Dom> _Closure; \
516 return _Expr<_Closure, _Tp>(_Closure(__t, __e())); \
517 } \
518 \
519 template<typename _Tp> \
520 inline _Expr<_BinClos<_UFun, _ValArray, _ValArray, _Tp, _Tp>, _Tp> \
521 _Fun(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \
522 { \
523 typedef _BinClos<_UFun, _ValArray, _ValArray, _Tp, _Tp> _Closure;\
524 return _Expr<_Closure, _Tp>(_Closure(__v, __w)); \
525 } \
526 \
527 template<typename _Tp> \
528 inline _Expr<_BinClos<_UFun, _ValArray, _Constant, _Tp, _Tp>, _Tp> \
529 _Fun(const valarray<_Tp>& __v, const _Tp& __t) \
530 { \
531 typedef _BinClos<_UFun, _ValArray, _Constant, _Tp, _Tp> _Closure;\
532 return _Expr<_Closure, _Tp>(_Closure(__v, __t)); \
533 } \
534 \
535 template<typename _Tp> \
536 inline _Expr<_BinClos<_UFun, _Constant, _ValArray, _Tp, _Tp>, _Tp> \
537 _Fun(const _Tp& __t, const valarray<_Tp>& __v) \
538 { \
539 typedef _BinClos<_UFun, _Constant, _ValArray, _Tp, _Tp> _Closure;\
540 return _Expr<_Closure, _Tp>(_Closure(__t, __v)); \
541 }
542
543_DEFINE_EXPR_BINARY_FUNCTION(atan2, _Atan2)
544_DEFINE_EXPR_BINARY_FUNCTION(pow, _Pow)
545
546#undef _DEFINE_EXPR_BINARY_FUNCTION
547
548_GLIBCXX_END_NAMESPACE_VERSION
549} // namespace
550
551#endif /* _CPP_VALARRAY_AFTER_H */
552