1 | // The template and inlines for the -*- C++ -*- internal _Meta class.
|
---|
2 |
|
---|
3 | // Copyright (C) 1997-2021 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 |
|
---|
39 | namespace 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& __t) const
|
---|
67 | { return abs(__t); }
|
---|
68 | };
|
---|
69 |
|
---|
70 | struct _Cos
|
---|
71 | {
|
---|
72 | template<typename _Tp>
|
---|
73 | _Tp operator()(const _Tp& __t) const
|
---|
74 | { return cos(__t); }
|
---|
75 | };
|
---|
76 |
|
---|
77 | struct _Acos
|
---|
78 | {
|
---|
79 | template<typename _Tp>
|
---|
80 | _Tp operator()(const _Tp& __t) const
|
---|
81 | { return acos(__t); }
|
---|
82 | };
|
---|
83 |
|
---|
84 | struct _Cosh
|
---|
85 | {
|
---|
86 | template<typename _Tp>
|
---|
87 | _Tp operator()(const _Tp& __t) const
|
---|
88 | { return cosh(__t); }
|
---|
89 | };
|
---|
90 |
|
---|
91 | struct _Sin
|
---|
92 | {
|
---|
93 | template<typename _Tp>
|
---|
94 | _Tp operator()(const _Tp& __t) const
|
---|
95 | { return sin(__t); }
|
---|
96 | };
|
---|
97 |
|
---|
98 | struct _Asin
|
---|
99 | {
|
---|
100 | template<typename _Tp>
|
---|
101 | _Tp operator()(const _Tp& __t) const
|
---|
102 | { return asin(__t); }
|
---|
103 | };
|
---|
104 |
|
---|
105 | struct _Sinh
|
---|
106 | {
|
---|
107 | template<typename _Tp>
|
---|
108 | _Tp operator()(const _Tp& __t) const
|
---|
109 | { return sinh(__t); }
|
---|
110 | };
|
---|
111 |
|
---|
112 | struct _Tan
|
---|
113 | {
|
---|
114 | template<typename _Tp>
|
---|
115 | _Tp operator()(const _Tp& __t) const
|
---|
116 | { return tan(__t); }
|
---|
117 | };
|
---|
118 |
|
---|
119 | struct _Atan
|
---|
120 | {
|
---|
121 | template<typename _Tp>
|
---|
122 | _Tp operator()(const _Tp& __t) const
|
---|
123 | { return atan(__t); }
|
---|
124 | };
|
---|
125 |
|
---|
126 | struct _Tanh
|
---|
127 | {
|
---|
128 | template<typename _Tp>
|
---|
129 | _Tp operator()(const _Tp& __t) const
|
---|
130 | { return tanh(__t); }
|
---|
131 | };
|
---|
132 |
|
---|
133 | struct _Exp
|
---|
134 | {
|
---|
135 | template<typename _Tp>
|
---|
136 | _Tp operator()(const _Tp& __t) const
|
---|
137 | { return exp(__t); }
|
---|
138 | };
|
---|
139 |
|
---|
140 | struct _Log
|
---|
141 | {
|
---|
142 | template<typename _Tp>
|
---|
143 | _Tp operator()(const _Tp& __t) const
|
---|
144 | { return log(__t); }
|
---|
145 | };
|
---|
146 |
|
---|
147 | struct _Log10
|
---|
148 | {
|
---|
149 | template<typename _Tp>
|
---|
150 | _Tp operator()(const _Tp& __t) const
|
---|
151 | { return log10(__t); }
|
---|
152 | };
|
---|
153 |
|
---|
154 | struct _Sqrt
|
---|
155 | {
|
---|
156 | template<typename _Tp>
|
---|
157 | _Tp operator()(const _Tp& __t) const
|
---|
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& __t) const
|
---|
169 | { return +__t; }
|
---|
170 | };
|
---|
171 |
|
---|
172 | struct __negate
|
---|
173 | {
|
---|
174 | template<typename _Tp>
|
---|
175 | _Tp operator()(const _Tp& __t) const
|
---|
176 | { return -__t; }
|
---|
177 | };
|
---|
178 |
|
---|
179 | struct __bitwise_not
|
---|
180 | {
|
---|
181 | template<typename _Tp>
|
---|
182 | _Tp operator()(const _Tp& __t) const
|
---|
183 | { return ~__t; }
|
---|
184 | };
|
---|
185 |
|
---|
186 | struct __plus
|
---|
187 | {
|
---|
188 | template<typename _Tp>
|
---|
189 | _Tp operator()(const _Tp& __x, const _Tp& __y) const
|
---|
190 | { return __x + __y; }
|
---|
191 | };
|
---|
192 |
|
---|
193 | struct __minus
|
---|
194 | {
|
---|
195 | template<typename _Tp>
|
---|
196 | _Tp operator()(const _Tp& __x, const _Tp& __y) const
|
---|
197 | { return __x - __y; }
|
---|
198 | };
|
---|
199 |
|
---|
200 | struct __multiplies
|
---|
201 | {
|
---|
202 | template<typename _Tp>
|
---|
203 | _Tp operator()(const _Tp& __x, const _Tp& __y) const
|
---|
204 | { return __x * __y; }
|
---|
205 | };
|
---|
206 |
|
---|
207 | struct __divides
|
---|
208 | {
|
---|
209 | template<typename _Tp>
|
---|
210 | _Tp operator()(const _Tp& __x, const _Tp& __y) const
|
---|
211 | { return __x / __y; }
|
---|
212 | };
|
---|
213 |
|
---|
214 | struct __modulus
|
---|
215 | {
|
---|
216 | template<typename _Tp>
|
---|
217 | _Tp operator()(const _Tp& __x, const _Tp& __y) const
|
---|
218 | { return __x % __y; }
|
---|
219 | };
|
---|
220 |
|
---|
221 | struct __bitwise_xor
|
---|
222 | {
|
---|
223 | template<typename _Tp>
|
---|
224 | _Tp operator()(const _Tp& __x, const _Tp& __y) const
|
---|
225 | { return __x ^ __y; }
|
---|
226 | };
|
---|
227 |
|
---|
228 | struct __bitwise_and
|
---|
229 | {
|
---|
230 | template<typename _Tp>
|
---|
231 | _Tp operator()(const _Tp& __x, const _Tp& __y) const
|
---|
232 | { return __x & __y; }
|
---|
233 | };
|
---|
234 |
|
---|
235 | struct __bitwise_or
|
---|
236 | {
|
---|
237 | template<typename _Tp>
|
---|
238 | _Tp operator()(const _Tp& __x, const _Tp& __y) const
|
---|
239 | { return __x | __y; }
|
---|
240 | };
|
---|
241 |
|
---|
242 | struct __shift_left
|
---|
243 | {
|
---|
244 | template<typename _Tp>
|
---|
245 | _Tp operator()(const _Tp& __x, const _Tp& __y) const
|
---|
246 | { return __x << __y; }
|
---|
247 | };
|
---|
248 |
|
---|
249 | struct __shift_right
|
---|
250 | {
|
---|
251 | template<typename _Tp>
|
---|
252 | _Tp operator()(const _Tp& __x, const _Tp& __y) const
|
---|
253 | { return __x >> __y; }
|
---|
254 | };
|
---|
255 |
|
---|
256 | struct __logical_and
|
---|
257 | {
|
---|
258 | template<typename _Tp>
|
---|
259 | bool operator()(const _Tp& __x, const _Tp& __y) const
|
---|
260 | { return __x && __y; }
|
---|
261 | };
|
---|
262 |
|
---|
263 | struct __logical_or
|
---|
264 | {
|
---|
265 | template<typename _Tp>
|
---|
266 | bool operator()(const _Tp& __x, const _Tp& __y) const
|
---|
267 | { return __x || __y; }
|
---|
268 | };
|
---|
269 |
|
---|
270 | struct __logical_not
|
---|
271 | {
|
---|
272 | template<typename _Tp>
|
---|
273 | bool operator()(const _Tp& __x) const
|
---|
274 | { return !__x; }
|
---|
275 | };
|
---|
276 |
|
---|
277 | struct __equal_to
|
---|
278 | {
|
---|
279 | template<typename _Tp>
|
---|
280 | bool operator()(const _Tp& __x, const _Tp& __y) const
|
---|
281 | { return __x == __y; }
|
---|
282 | };
|
---|
283 |
|
---|
284 | struct __not_equal_to
|
---|
285 | {
|
---|
286 | template<typename _Tp>
|
---|
287 | bool operator()(const _Tp& __x, const _Tp& __y) const
|
---|
288 | { return __x != __y; }
|
---|
289 | };
|
---|
290 |
|
---|
291 | struct __less
|
---|
292 | {
|
---|
293 | template<typename _Tp>
|
---|
294 | bool operator()(const _Tp& __x, const _Tp& __y) const
|
---|
295 | { return __x < __y; }
|
---|
296 | };
|
---|
297 |
|
---|
298 | struct __greater
|
---|
299 | {
|
---|
300 | template<typename _Tp>
|
---|
301 | bool operator()(const _Tp& __x, const _Tp& __y) const
|
---|
302 | { return __x > __y; }
|
---|
303 | };
|
---|
304 |
|
---|
305 | struct __less_equal
|
---|
306 | {
|
---|
307 | template<typename _Tp>
|
---|
308 | bool operator()(const _Tp& __x, const _Tp& __y) const
|
---|
309 | { return __x <= __y; }
|
---|
310 | };
|
---|
311 |
|
---|
312 | struct __greater_equal
|
---|
313 | {
|
---|
314 | template<typename _Tp>
|
---|
315 | bool operator()(const _Tp& __x, const _Tp& __y) const
|
---|
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& __x, const _Tp& __y) const
|
---|
324 | { return atan2(__x, __y); }
|
---|
325 | };
|
---|
326 |
|
---|
327 | struct _Pow
|
---|
328 | {
|
---|
329 | template<typename _Tp>
|
---|
330 | _Tp operator()(const _Tp& __x, const _Tp& __y) const
|
---|
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<typename, typename _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 | namespace __detail
|
---|
410 | {
|
---|
411 | // Closure types already have reference semantics and are often short-lived,
|
---|
412 | // so store them by value to avoid (some cases of) dangling references to
|
---|
413 | // out-of-scope temporaries.
|
---|
414 | template<typename _Tp>
|
---|
415 | struct _ValArrayRef
|
---|
416 | { typedef const _Tp __type; };
|
---|
417 |
|
---|
418 | // Use real references for std::valarray objects.
|
---|
419 | template<typename _Tp>
|
---|
420 | struct _ValArrayRef< valarray<_Tp> >
|
---|
421 | { typedef const valarray<_Tp>& __type; };
|
---|
422 |
|
---|
423 | //
|
---|
424 | // Apply function taking a value/const reference closure
|
---|
425 | //
|
---|
426 |
|
---|
427 | template<typename _Dom, typename _Arg>
|
---|
428 | class _FunBase
|
---|
429 | {
|
---|
430 | public:
|
---|
431 | typedef typename _Dom::value_type value_type;
|
---|
432 |
|
---|
433 | _FunBase(const _Dom& __e, value_type __f(_Arg))
|
---|
434 | : _M_expr(__e), _M_func(__f) {}
|
---|
435 |
|
---|
436 | value_type operator[](size_t __i) const
|
---|
437 | { return _M_func (_M_expr[__i]); }
|
---|
438 |
|
---|
439 | size_t size() const { return _M_expr.size ();}
|
---|
440 |
|
---|
441 | private:
|
---|
442 | typename _ValArrayRef<_Dom>::__type _M_expr;
|
---|
443 | value_type (*_M_func)(_Arg);
|
---|
444 | };
|
---|
445 |
|
---|
446 | template<class _Dom>
|
---|
447 | struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type>
|
---|
448 | {
|
---|
449 | typedef _FunBase<_Dom, typename _Dom::value_type> _Base;
|
---|
450 | typedef typename _Base::value_type value_type;
|
---|
451 | typedef value_type _Tp;
|
---|
452 |
|
---|
453 | _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {}
|
---|
454 | };
|
---|
455 |
|
---|
456 | template<typename _Tp>
|
---|
457 | struct _ValFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, _Tp>
|
---|
458 | {
|
---|
459 | typedef _FunBase<valarray<_Tp>, _Tp> _Base;
|
---|
460 | typedef _Tp value_type;
|
---|
461 |
|
---|
462 | _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {}
|
---|
463 | };
|
---|
464 |
|
---|
465 | template<class _Dom>
|
---|
466 | struct _RefFunClos<_Expr, _Dom>
|
---|
467 | : _FunBase<_Dom, const typename _Dom::value_type&>
|
---|
468 | {
|
---|
469 | typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base;
|
---|
470 | typedef typename _Base::value_type value_type;
|
---|
471 | typedef value_type _Tp;
|
---|
472 |
|
---|
473 | _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&))
|
---|
474 | : _Base(__e, __f) {}
|
---|
475 | };
|
---|
476 |
|
---|
477 | template<typename _Tp>
|
---|
478 | struct _RefFunClos<_ValArray, _Tp>
|
---|
479 | : _FunBase<valarray<_Tp>, const _Tp&>
|
---|
480 | {
|
---|
481 | typedef _FunBase<valarray<_Tp>, const _Tp&> _Base;
|
---|
482 | typedef _Tp value_type;
|
---|
483 |
|
---|
484 | _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&))
|
---|
485 | : _Base(__v, __f) {}
|
---|
486 | };
|
---|
487 |
|
---|
488 | //
|
---|
489 | // Unary expression closure.
|
---|
490 | //
|
---|
491 |
|
---|
492 | template<class _Oper, class _Arg>
|
---|
493 | class _UnBase
|
---|
494 | {
|
---|
495 | public:
|
---|
496 | typedef typename _Arg::value_type _Vt;
|
---|
497 | typedef typename __fun<_Oper, _Vt>::result_type value_type;
|
---|
498 |
|
---|
499 | _UnBase(const _Arg& __e) : _M_expr(__e) {}
|
---|
500 |
|
---|
501 | value_type operator[](size_t __i) const
|
---|
502 | { return _Oper()(_M_expr[__i]); }
|
---|
503 |
|
---|
504 | size_t size() const { return _M_expr.size(); }
|
---|
505 |
|
---|
506 | private:
|
---|
507 | typename _ValArrayRef<_Arg>::__type _M_expr;
|
---|
508 | };
|
---|
509 |
|
---|
510 | template<class _Oper, class _Dom>
|
---|
511 | struct _UnClos<_Oper, _Expr, _Dom>
|
---|
512 | : _UnBase<_Oper, _Dom>
|
---|
513 | {
|
---|
514 | typedef _Dom _Arg;
|
---|
515 | typedef _UnBase<_Oper, _Dom> _Base;
|
---|
516 | typedef typename _Base::value_type value_type;
|
---|
517 |
|
---|
518 | _UnClos(const _Arg& __e) : _Base(__e) {}
|
---|
519 | };
|
---|
520 |
|
---|
521 | template<class _Oper, typename _Tp>
|
---|
522 | struct _UnClos<_Oper, _ValArray, _Tp>
|
---|
523 | : _UnBase<_Oper, valarray<_Tp> >
|
---|
524 | {
|
---|
525 | typedef valarray<_Tp> _Arg;
|
---|
526 | typedef _UnBase<_Oper, valarray<_Tp> > _Base;
|
---|
527 | typedef typename _Base::value_type value_type;
|
---|
528 |
|
---|
529 | _UnClos(const _Arg& __e) : _Base(__e) {}
|
---|
530 | };
|
---|
531 |
|
---|
532 |
|
---|
533 | //
|
---|
534 | // Binary expression closure.
|
---|
535 | //
|
---|
536 |
|
---|
537 | template<class _Oper, class _FirstArg, class _SecondArg>
|
---|
538 | class _BinBase
|
---|
539 | {
|
---|
540 | public:
|
---|
541 | typedef typename _FirstArg::value_type _Vt;
|
---|
542 | typedef typename __fun<_Oper, _Vt>::result_type value_type;
|
---|
543 |
|
---|
544 | _BinBase(const _FirstArg& __e1, const _SecondArg& __e2)
|
---|
545 | : _M_expr1(__e1), _M_expr2(__e2) {}
|
---|
546 |
|
---|
547 | value_type operator[](size_t __i) const
|
---|
548 | { return _Oper()(_M_expr1[__i], _M_expr2[__i]); }
|
---|
549 |
|
---|
550 | size_t size() const { return _M_expr1.size(); }
|
---|
551 |
|
---|
552 | private:
|
---|
553 | typename _ValArrayRef<_FirstArg>::__type _M_expr1;
|
---|
554 | typename _ValArrayRef<_SecondArg>::__type _M_expr2;
|
---|
555 | };
|
---|
556 |
|
---|
557 |
|
---|
558 | template<class _Oper, class _Clos>
|
---|
559 | class _BinBase2
|
---|
560 | {
|
---|
561 | public:
|
---|
562 | typedef typename _Clos::value_type _Vt;
|
---|
563 | typedef typename __fun<_Oper, _Vt>::result_type value_type;
|
---|
564 |
|
---|
565 | _BinBase2(const _Clos& __e, const _Vt& __t)
|
---|
566 | : _M_expr1(__e), _M_expr2(__t) {}
|
---|
567 |
|
---|
568 | value_type operator[](size_t __i) const
|
---|
569 | { return _Oper()(_M_expr1[__i], _M_expr2); }
|
---|
570 |
|
---|
571 | size_t size() const { return _M_expr1.size(); }
|
---|
572 |
|
---|
573 | private:
|
---|
574 | typename _ValArrayRef<_Clos>::__type _M_expr1;
|
---|
575 | _Vt _M_expr2;
|
---|
576 | };
|
---|
577 |
|
---|
578 | template<class _Oper, class _Clos>
|
---|
579 | class _BinBase1
|
---|
580 | {
|
---|
581 | public:
|
---|
582 | typedef typename _Clos::value_type _Vt;
|
---|
583 | typedef typename __fun<_Oper, _Vt>::result_type value_type;
|
---|
584 |
|
---|
585 | _BinBase1(const _Vt& __t, const _Clos& __e)
|
---|
586 | : _M_expr1(__t), _M_expr2(__e) {}
|
---|
587 |
|
---|
588 | value_type operator[](size_t __i) const
|
---|
589 | { return _Oper()(_M_expr1, _M_expr2[__i]); }
|
---|
590 |
|
---|
591 | size_t size() const { return _M_expr2.size(); }
|
---|
592 |
|
---|
593 | private:
|
---|
594 | _Vt _M_expr1;
|
---|
595 | typename _ValArrayRef<_Clos>::__type _M_expr2;
|
---|
596 | };
|
---|
597 |
|
---|
598 | template<class _Oper, class _Dom1, class _Dom2>
|
---|
599 | struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2>
|
---|
600 | : _BinBase<_Oper, _Dom1, _Dom2>
|
---|
601 | {
|
---|
602 | typedef _BinBase<_Oper, _Dom1, _Dom2> _Base;
|
---|
603 | typedef typename _Base::value_type value_type;
|
---|
604 |
|
---|
605 | _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {}
|
---|
606 | };
|
---|
607 |
|
---|
608 | template<class _Oper, typename _Tp>
|
---|
609 | struct _BinClos<_Oper, _ValArray, _ValArray, _Tp, _Tp>
|
---|
610 | : _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> >
|
---|
611 | {
|
---|
612 | typedef _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > _Base;
|
---|
613 | typedef typename _Base::value_type value_type;
|
---|
614 |
|
---|
615 | _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w)
|
---|
616 | : _Base(__v, __w) {}
|
---|
617 | };
|
---|
618 |
|
---|
619 | template<class _Oper, class _Dom>
|
---|
620 | struct _BinClos<_Oper, _Expr, _ValArray, _Dom, typename _Dom::value_type>
|
---|
621 | : _BinBase<_Oper, _Dom, valarray<typename _Dom::value_type> >
|
---|
622 | {
|
---|
623 | typedef typename _Dom::value_type _Tp;
|
---|
624 | typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base;
|
---|
625 | typedef typename _Base::value_type value_type;
|
---|
626 |
|
---|
627 | _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2)
|
---|
628 | : _Base(__e1, __e2) {}
|
---|
629 | };
|
---|
630 |
|
---|
631 | template<class _Oper, class _Dom>
|
---|
632 | struct _BinClos<_Oper, _ValArray, _Expr, typename _Dom::value_type, _Dom>
|
---|
633 | : _BinBase<_Oper, valarray<typename _Dom::value_type>,_Dom>
|
---|
634 | {
|
---|
635 | typedef typename _Dom::value_type _Tp;
|
---|
636 | typedef _BinBase<_Oper, valarray<_Tp>, _Dom> _Base;
|
---|
637 | typedef typename _Base::value_type value_type;
|
---|
638 |
|
---|
639 | _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2)
|
---|
640 | : _Base(__e1, __e2) {}
|
---|
641 | };
|
---|
642 |
|
---|
643 | template<class _Oper, class _Dom>
|
---|
644 | struct _BinClos<_Oper, _Expr, _Constant, _Dom, typename _Dom::value_type>
|
---|
645 | : _BinBase2<_Oper, _Dom>
|
---|
646 | {
|
---|
647 | typedef typename _Dom::value_type _Tp;
|
---|
648 | typedef _BinBase2<_Oper,_Dom> _Base;
|
---|
649 | typedef typename _Base::value_type value_type;
|
---|
650 |
|
---|
651 | _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {}
|
---|
652 | };
|
---|
653 |
|
---|
654 | template<class _Oper, class _Dom>
|
---|
655 | struct _BinClos<_Oper, _Constant, _Expr, typename _Dom::value_type, _Dom>
|
---|
656 | : _BinBase1<_Oper, _Dom>
|
---|
657 | {
|
---|
658 | typedef typename _Dom::value_type _Tp;
|
---|
659 | typedef _BinBase1<_Oper, _Dom> _Base;
|
---|
660 | typedef typename _Base::value_type value_type;
|
---|
661 |
|
---|
662 | _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {}
|
---|
663 | };
|
---|
664 |
|
---|
665 | template<class _Oper, typename _Tp>
|
---|
666 | struct _BinClos<_Oper, _ValArray, _Constant, _Tp, _Tp>
|
---|
667 | : _BinBase2<_Oper, valarray<_Tp> >
|
---|
668 | {
|
---|
669 | typedef _BinBase2<_Oper,valarray<_Tp> > _Base;
|
---|
670 | typedef typename _Base::value_type value_type;
|
---|
671 |
|
---|
672 | _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {}
|
---|
673 | };
|
---|
674 |
|
---|
675 | template<class _Oper, typename _Tp>
|
---|
676 | struct _BinClos<_Oper, _Constant, _ValArray, _Tp, _Tp>
|
---|
677 | : _BinBase1<_Oper, valarray<_Tp> >
|
---|
678 | {
|
---|
679 | typedef _BinBase1<_Oper, valarray<_Tp> > _Base;
|
---|
680 | typedef typename _Base::value_type value_type;
|
---|
681 |
|
---|
682 | _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {}
|
---|
683 | };
|
---|
684 |
|
---|
685 | //
|
---|
686 | // slice_array closure.
|
---|
687 | //
|
---|
688 | template<typename _Dom>
|
---|
689 | class _SBase
|
---|
690 | {
|
---|
691 | public:
|
---|
692 | typedef typename _Dom::value_type value_type;
|
---|
693 |
|
---|
694 | _SBase (const _Dom& __e, const slice& __s)
|
---|
695 | : _M_expr (__e), _M_slice (__s) {}
|
---|
696 |
|
---|
697 | value_type
|
---|
698 | operator[] (size_t __i) const
|
---|
699 | { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; }
|
---|
700 |
|
---|
701 | size_t
|
---|
702 | size() const
|
---|
703 | { return _M_slice.size (); }
|
---|
704 |
|
---|
705 | private:
|
---|
706 | typename _ValArrayRef<_Dom>::__type _M_expr;
|
---|
707 | const slice& _M_slice;
|
---|
708 | };
|
---|
709 |
|
---|
710 | template<typename _Tp>
|
---|
711 | class _SBase<_Array<_Tp> >
|
---|
712 | {
|
---|
713 | public:
|
---|
714 | typedef _Tp value_type;
|
---|
715 |
|
---|
716 | _SBase (_Array<_Tp> __a, const slice& __s)
|
---|
717 | : _M_array (__a._M_data+__s.start()), _M_size (__s.size()),
|
---|
718 | _M_stride (__s.stride()) {}
|
---|
719 |
|
---|
720 | value_type
|
---|
721 | operator[] (size_t __i) const
|
---|
722 | { return _M_array._M_data[__i * _M_stride]; }
|
---|
723 |
|
---|
724 | size_t
|
---|
725 | size() const
|
---|
726 | { return _M_size; }
|
---|
727 |
|
---|
728 | private:
|
---|
729 | const _Array<_Tp> _M_array;
|
---|
730 | const size_t _M_size;
|
---|
731 | const size_t _M_stride;
|
---|
732 | };
|
---|
733 |
|
---|
734 | template<class _Dom>
|
---|
735 | struct _SClos<_Expr, _Dom>
|
---|
736 | : _SBase<_Dom>
|
---|
737 | {
|
---|
738 | typedef _SBase<_Dom> _Base;
|
---|
739 | typedef typename _Base::value_type value_type;
|
---|
740 |
|
---|
741 | _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {}
|
---|
742 | };
|
---|
743 |
|
---|
744 | template<typename _Tp>
|
---|
745 | struct _SClos<_ValArray, _Tp>
|
---|
746 | : _SBase<_Array<_Tp> >
|
---|
747 | {
|
---|
748 | typedef _SBase<_Array<_Tp> > _Base;
|
---|
749 | typedef _Tp value_type;
|
---|
750 |
|
---|
751 | _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {}
|
---|
752 | };
|
---|
753 | } // namespace __detail
|
---|
754 |
|
---|
755 | _GLIBCXX_END_NAMESPACE_VERSION
|
---|
756 | } // namespace
|
---|
757 |
|
---|
758 | #endif /* _CPP_VALARRAY_BEFORE_H */
|
---|