3 * Silicon Graphics Computer Systems, Inc.
8 * This material is provided "as is", with absolutely no warranty expressed
9 * or implied. Any use is at your own risk.
11 * Permission to use or copy this software for any purpose is hereby granted
12 * without fee, provided the above notices are retained on all copies.
13 * Permission to modify the code and to distribute modified code is granted,
14 * provided the above notices are retained, and a notice that the code was
15 * modified is included with the above copyright notice.
19 #ifndef _STLP_VALARRAY_H
20 #define _STLP_VALARRAY_H
22 #ifndef _STLP_INTERNAL_CMATH
23 # include <stl/_cmath.h>
26 #ifndef _STLP_INTERNAL_NEW
27 # include <stl/_new.h>
30 #ifndef _STLP_INTERNAL_ALGO_H
31 # include <stl/_algo.h>
34 #ifndef _STLP_INTERNAL_NUMERIC_H
35 # include <stl/_numeric.h>
38 #ifndef _STLP_INTERNAL_LIMITS
39 # include <stl/_limits.h>
42 /* As we only need the _STLP_ASSERT macro from _debug.h we test it to include _debug.h */
44 # include <stl/debug/_debug.h>
52 template <class _Tp> class valarray;
53 typedef valarray<bool> _Valarray_bool;
54 typedef valarray<size_t> _Valarray_size_t;
56 template <class _Tp> class slice_array;
57 template <class _Tp> class gslice_array;
58 template <class _Tp> class mask_array;
59 template <class _Tp> class indirect_array;
61 //----------------------------------------------------------------------
64 // Base class to handle memory allocation and deallocation. We can't just
65 // use vector<>, because vector<bool> would be unsuitable as an internal
66 // representation for valarray<bool>.
74 _Valarray_base() : _M_first(0), _M_size(0) {}
75 _Valarray_base(size_t __n) : _M_first(0), _M_size(0) { _M_allocate(__n); }
76 ~_Valarray_base() { _M_deallocate(); }
78 void _M_allocate(size_t __n) {
80 _M_first = __STATIC_CAST(_Tp*, (malloc(__n * sizeof(_Tp))));
82 #if !defined(_STLP_NO_BAD_ALLOC) && defined(_STLP_USE_EXCEPTIONS)
85 throw _STLP_STD::bad_alloc();
95 void _M_deallocate() {
103 class valarray : private _Valarray_base<_Tp>
108 typedef _Tp value_type;
110 // Basic constructors
111 valarray() : _Valarray_base<_Tp>() {}
112 explicit valarray(size_t __n) : _Valarray_base<_Tp>(__n)
113 { uninitialized_fill_n(this->_M_first, this->_M_size, _STLP_DEFAULT_CONSTRUCTED(value_type)); }
114 valarray(const value_type& __x, size_t __n) : _Valarray_base<_Tp>(__n)
115 { uninitialized_fill_n(this->_M_first, this->_M_size, __x); }
116 valarray(const value_type* __p, size_t __n) : _Valarray_base<_Tp>(__n)
117 { uninitialized_copy(__p, __p + __n, this->_M_first); }
118 valarray(const valarray<_Tp>& __x) : _Valarray_base<_Tp>(__x._M_size) {
119 uninitialized_copy(__x._M_first, __x._M_first + __x._M_size,
123 // Constructors from auxiliary array types
124 valarray(const slice_array<_Tp>&);
125 valarray(const gslice_array<_Tp>&);
126 valarray(const mask_array<_Tp>&);
127 valarray(const indirect_array<_Tp>&);
130 ~valarray() { _STLP_STD::_Destroy_Range(this->_M_first, this->_M_first + this->_M_size); }
132 // Extension: constructor that doesn't initialize valarray elements to a
133 // specific value. This is faster for types such as int and double.
135 void _M_initialize(const __true_type&) {}
136 void _M_initialize(const __false_type&)
137 { uninitialized_fill_n(this->_M_first, this->_M_size, _STLP_DEFAULT_CONSTRUCTED(_Tp)); }
141 valarray(size_t __n, _NoInit) : _Valarray_base<_Tp>(__n) {
142 typedef typename __type_traits<_Tp>::has_trivial_default_constructor _Is_Trivial;
143 _M_initialize(_Is_Trivial());
146 public: // Assignment
147 // Basic assignment. Note that 'x = y' is undefined if x.size() != y.size()
148 valarray<_Tp>& operator=(const valarray<_Tp>& __x) {
149 _STLP_ASSERT(__x.size() == this->size())
151 copy(__x._M_first, __x._M_first + __x._M_size, this->_M_first);
156 valarray<_Tp>& operator=(const value_type& __x) {
157 fill_n(this->_M_first, this->_M_size, __x);
161 // Assignment of auxiliary array types
162 valarray<_Tp>& operator=(const slice_array<_Tp>&);
163 valarray<_Tp>& operator=(const gslice_array<_Tp>&);
164 valarray<_Tp>& operator=(const mask_array<_Tp>&);
165 valarray<_Tp>& operator=(const indirect_array<_Tp>&);
167 public: // Element access
168 value_type operator[](size_t __n) const { return this->_M_first[__n]; }
169 value_type& operator[](size_t __n) { return this->_M_first[__n]; }
170 size_t size() const { return this->_M_size; }
172 public: // Subsetting operations with auxiliary type
173 valarray<_Tp> operator[](slice) const;
174 slice_array<_Tp> operator[](slice);
175 valarray<_Tp> operator[](const gslice&) const;
176 gslice_array<_Tp> operator[](const gslice&);
177 valarray<_Tp> operator[](const _Valarray_bool&) const;
178 mask_array<_Tp> operator[](const _Valarray_bool&);
179 valarray<_Tp> operator[](const _Valarray_size_t&) const;
180 indirect_array<_Tp> operator[](const _Valarray_size_t&);
182 public: // Unary operators.
183 valarray<_Tp> operator+() const { return *this; }
185 valarray<_Tp> operator-() const {
186 valarray<_Tp> __tmp(this->size(), _NoInit());
187 for (size_t __i = 0; __i < this->size(); ++__i)
188 __tmp[__i] = -(*this)[__i];
192 valarray<_Tp> operator~() const {
193 valarray<_Tp> __tmp(this->size(), _NoInit());
194 for (size_t __i = 0; __i < this->size(); ++__i)
195 __tmp[__i] = ~(*this)[__i];
199 _Valarray_bool operator!() const;
201 public: // Scalar computed assignment.
202 valarray<_Tp>& operator*= (const value_type& __x) {
203 for (size_t __i = 0; __i < this->size(); ++__i)
208 valarray<_Tp>& operator/= (const value_type& __x) {
209 for (size_t __i = 0; __i < this->size(); ++__i)
214 valarray<_Tp>& operator%= (const value_type& __x) {
215 for (size_t __i = 0; __i < this->size(); ++__i)
220 valarray<_Tp>& operator+= (const value_type& __x) {
221 for (size_t __i = 0; __i < this->size(); ++__i)
226 valarray<_Tp>& operator-= (const value_type& __x) {
227 for (size_t __i = 0; __i < this->size(); ++__i)
232 valarray<_Tp>& operator^= (const value_type& __x) {
233 for (size_t __i = 0; __i < this->size(); ++__i)
238 valarray<_Tp>& operator&= (const value_type& __x) {
239 for (size_t __i = 0; __i < this->size(); ++__i)
244 valarray<_Tp>& operator|= (const value_type& __x) {
245 for (size_t __i = 0; __i < this->size(); ++__i)
250 valarray<_Tp>& operator<<= (const value_type& __x) {
251 for (size_t __i = 0; __i < this->size(); ++__i)
252 (*this)[__i] <<= __x;
256 valarray<_Tp>& operator>>= (const value_type& __x) {
257 for (size_t __i = 0; __i < this->size(); ++__i)
258 (*this)[__i] >>= __x;
262 public: // Array computed assignment.
263 valarray<_Tp>& operator*= (const valarray<_Tp>& __x) {
264 for (size_t __i = 0; __i < this->size(); ++__i)
265 (*this)[__i] *= __x[__i];
269 valarray<_Tp>& operator/= (const valarray<_Tp>& __x) {
270 for (size_t __i = 0; __i < this->size(); ++__i)
271 (*this)[__i] /= __x[__i];
275 valarray<_Tp>& operator%= (const valarray<_Tp>& __x) {
276 for (size_t __i = 0; __i < this->size(); ++__i)
277 (*this)[__i] %= __x[__i];
281 valarray<_Tp>& operator+= (const valarray<_Tp>& __x) {
282 for (size_t __i = 0; __i < this->size(); ++__i)
283 (*this)[__i] += __x[__i];
287 valarray<_Tp>& operator-= (const valarray<_Tp>& __x) {
288 for (size_t __i = 0; __i < this->size(); ++__i)
289 (*this)[__i] -= __x[__i];
293 valarray<_Tp>& operator^= (const valarray<_Tp>& __x) {
294 for (size_t __i = 0; __i < this->size(); ++__i)
295 (*this)[__i] ^= __x[__i];
299 valarray<_Tp>& operator&= (const valarray<_Tp>& __x) {
300 for (size_t __i = 0; __i < this->size(); ++__i)
301 (*this)[__i] &= __x[__i];
305 valarray<_Tp>& operator|= (const valarray<_Tp>& __x) {
306 for (size_t __i = 0; __i < this->size(); ++__i)
307 (*this)[__i] |= __x[__i];
311 valarray<_Tp>& operator<<= (const valarray<_Tp>& __x) {
312 for (size_t __i = 0; __i < this->size(); ++__i)
313 (*this)[__i] <<= __x[__i];
317 valarray<_Tp>& operator>>= (const valarray<_Tp>& __x) {
318 for (size_t __i = 0; __i < this->size(); ++__i)
319 (*this)[__i] >>= __x[__i];
323 public: // Other member functions.
325 // The result is undefined for zero-length arrays
326 value_type sum() const {
327 return accumulate(this->_M_first + 1, this->_M_first + this->_M_size,
331 // The result is undefined for zero-length arrays
332 value_type (min) () const {
333 return *min_element(this->_M_first + 0, this->_M_first + this->_M_size);
336 value_type (max) () const {
337 return *max_element(this->_M_first + 0, this->_M_first + this->_M_size);
340 valarray<_Tp> shift(int __n) const;
341 valarray<_Tp> cshift(int __n) const;
343 valarray<_Tp> apply(value_type __f(value_type)) const {
344 valarray<_Tp> __tmp(this->size());
345 transform(this->_M_first + 0, this->_M_first + this->_M_size, __tmp._M_first,
349 valarray<_Tp> apply(value_type __f(const value_type&)) const {
350 valarray<_Tp> __tmp(this->size());
351 transform(this->_M_first + 0, this->_M_first + this->_M_size, __tmp._M_first,
356 void resize(size_t __n, value_type __x = value_type()) {
357 _STLP_STD::_Destroy_Range(this->_M_first, this->_M_first + this->_M_size);
358 _Valarray_base<_Tp>::_M_deallocate();
359 _Valarray_base<_Tp>::_M_allocate(__n);
360 uninitialized_fill_n(this->_M_first, this->_M_size, __x);
364 //----------------------------------------------------------------------
365 // valarray non-member functions.
367 // Binary arithmetic operations between two arrays. Behavior is
368 // undefined if the two arrays do not have the same length.
371 inline valarray<_Tp> _STLP_CALL operator*(const valarray<_Tp>& __x,
372 const valarray<_Tp>& __y) {
373 typedef typename valarray<_Tp>::_NoInit _NoInit;
374 valarray<_Tp> __tmp(__x.size(), _NoInit());
375 for (size_t __i = 0; __i < __x.size(); ++__i)
376 __tmp[__i] = __x[__i] * __y[__i];
381 inline valarray<_Tp> _STLP_CALL operator/(const valarray<_Tp>& __x,
382 const valarray<_Tp>& __y) {
383 typedef typename valarray<_Tp>::_NoInit _NoInit;
384 valarray<_Tp> __tmp(__x.size(), _NoInit());
385 for (size_t __i = 0; __i < __x.size(); ++__i)
386 __tmp[__i] = __x[__i] / __y[__i];
391 inline valarray<_Tp> _STLP_CALL operator%(const valarray<_Tp>& __x,
392 const valarray<_Tp>& __y) {
393 typedef typename valarray<_Tp>::_NoInit _NoInit;
394 valarray<_Tp> __tmp(__x.size(), _NoInit());
395 for (size_t __i = 0; __i < __x.size(); ++__i)
396 __tmp[__i] = __x[__i] % __y[__i];
401 inline valarray<_Tp> _STLP_CALL operator+(const valarray<_Tp>& __x,
402 const valarray<_Tp>& __y) {
403 typedef typename valarray<_Tp>::_NoInit _NoInit;
404 valarray<_Tp> __tmp(__x.size(), _NoInit());
405 for (size_t __i = 0; __i < __x.size(); ++__i)
406 __tmp[__i] = __x[__i] + __y[__i];
411 inline valarray<_Tp> _STLP_CALL operator-(const valarray<_Tp>& __x,
412 const valarray<_Tp>& __y) {
413 typedef typename valarray<_Tp>::_NoInit _NoInit;
414 valarray<_Tp> __tmp(__x.size(), _NoInit());
415 for (size_t __i = 0; __i < __x.size(); ++__i)
416 __tmp[__i] = __x[__i] - __y[__i];
421 inline valarray<_Tp> _STLP_CALL operator^(const valarray<_Tp>& __x,
422 const valarray<_Tp>& __y) {
423 typedef typename valarray<_Tp>::_NoInit _NoInit;
424 valarray<_Tp> __tmp(__x.size(), _NoInit());
425 for (size_t __i = 0; __i < __x.size(); ++__i)
426 __tmp[__i] = __x[__i] ^ __y[__i];
431 inline valarray<_Tp> _STLP_CALL operator&(const valarray<_Tp>& __x,
432 const valarray<_Tp>& __y) {
433 typedef typename valarray<_Tp>::_NoInit _NoInit;
434 valarray<_Tp> __tmp(__x.size(), _NoInit());
435 for (size_t __i = 0; __i < __x.size(); ++__i)
436 __tmp[__i] = __x[__i] & __y[__i];
441 inline valarray<_Tp> _STLP_CALL operator|(const valarray<_Tp>& __x,
442 const valarray<_Tp>& __y) {
443 typedef typename valarray<_Tp>::_NoInit _NoInit;
444 valarray<_Tp> __tmp(__x.size(), _NoInit());
445 for (size_t __i = 0; __i < __x.size(); ++__i)
446 __tmp[__i] = __x[__i] | __y[__i];
451 inline valarray<_Tp> _STLP_CALL operator<<(const valarray<_Tp>& __x,
452 const valarray<_Tp>& __y) {
453 typedef typename valarray<_Tp>::_NoInit _NoInit;
454 valarray<_Tp> __tmp(__x.size(), _NoInit());
455 for (size_t __i = 0; __i < __x.size(); ++__i)
456 __tmp[__i] = __x[__i] << __y[__i];
461 inline valarray<_Tp> _STLP_CALL operator>>(const valarray<_Tp>& __x,
462 const valarray<_Tp>& __y) {
463 typedef typename valarray<_Tp>::_NoInit _NoInit;
464 valarray<_Tp> __tmp(__x.size(), _NoInit());
465 for (size_t __i = 0; __i < __x.size(); ++__i)
466 __tmp[__i] = __x[__i] >> __y[__i];
470 // Binary arithmetic operations between an array and a scalar.
473 inline valarray<_Tp> _STLP_CALL operator*(const valarray<_Tp>& __x, const _Tp& __c) {
474 typedef typename valarray<_Tp>::_NoInit _NoInit;
475 valarray<_Tp> __tmp(__x.size(), _NoInit());
476 for (size_t __i = 0; __i < __x.size(); ++__i)
477 __tmp[__i] = __x[__i] * __c;
482 inline valarray<_Tp> _STLP_CALL operator*(const _Tp& __c, const valarray<_Tp>& __x) {
483 typedef typename valarray<_Tp>::_NoInit _NoInit;
484 valarray<_Tp> __tmp(__x.size(), _NoInit());
485 for (size_t __i = 0; __i < __x.size(); ++__i)
486 __tmp[__i] = __c * __x[__i];
491 inline valarray<_Tp> _STLP_CALL operator/(const valarray<_Tp>& __x, const _Tp& __c) {
492 typedef typename valarray<_Tp>::_NoInit _NoInit;
493 valarray<_Tp> __tmp(__x.size(), _NoInit());
494 for (size_t __i = 0; __i < __x.size(); ++__i)
495 __tmp[__i] = __x[__i] / __c;
500 inline valarray<_Tp> _STLP_CALL operator/(const _Tp& __c, const valarray<_Tp>& __x) {
501 typedef typename valarray<_Tp>::_NoInit _NoInit;
502 valarray<_Tp> __tmp(__x.size(), _NoInit());
503 for (size_t __i = 0; __i < __x.size(); ++__i)
504 __tmp[__i] = __c / __x[__i];
509 inline valarray<_Tp> _STLP_CALL operator%(const valarray<_Tp>& __x, const _Tp& __c) {
510 typedef typename valarray<_Tp>::_NoInit _NoInit;
511 valarray<_Tp> __tmp(__x.size(), _NoInit());
512 for (size_t __i = 0; __i < __x.size(); ++__i)
513 __tmp[__i] = __x[__i] % __c;
518 inline valarray<_Tp> _STLP_CALL operator%(const _Tp& __c, const valarray<_Tp>& __x) {
519 typedef typename valarray<_Tp>::_NoInit _NoInit;
520 valarray<_Tp> __tmp(__x.size(), _NoInit());
521 for (size_t __i = 0; __i < __x.size(); ++__i)
522 __tmp[__i] = __c % __x[__i];
527 inline valarray<_Tp> _STLP_CALL operator+(const valarray<_Tp>& __x, const _Tp& __c) {
528 typedef typename valarray<_Tp>::_NoInit _NoInit;
529 valarray<_Tp> __tmp(__x.size(), _NoInit());
530 for (size_t __i = 0; __i < __x.size(); ++__i)
531 __tmp[__i] = __x[__i] + __c;
536 inline valarray<_Tp> _STLP_CALL operator+(const _Tp& __c, const valarray<_Tp>& __x) {
537 typedef typename valarray<_Tp>::_NoInit _NoInit;
538 valarray<_Tp> __tmp(__x.size(), _NoInit());
539 for (size_t __i = 0; __i < __x.size(); ++__i)
540 __tmp[__i] = __c + __x[__i];
545 inline valarray<_Tp> _STLP_CALL operator-(const valarray<_Tp>& __x, const _Tp& __c) {
546 typedef typename valarray<_Tp>::_NoInit _NoInit;
547 valarray<_Tp> __tmp(__x.size(), _NoInit());
548 for (size_t __i = 0; __i < __x.size(); ++__i)
549 __tmp[__i] = __x[__i] - __c;
554 inline valarray<_Tp> _STLP_CALL operator-(const _Tp& __c, const valarray<_Tp>& __x) {
555 typedef typename valarray<_Tp>::_NoInit _NoInit;
556 valarray<_Tp> __tmp(__x.size(), _NoInit());
557 for (size_t __i = 0; __i < __x.size(); ++__i)
558 __tmp[__i] = __c - __x[__i];
563 inline valarray<_Tp> _STLP_CALL operator^(const valarray<_Tp>& __x, const _Tp& __c) {
564 typedef typename valarray<_Tp>::_NoInit _NoInit;
565 valarray<_Tp> __tmp(__x.size(), _NoInit());
566 for (size_t __i = 0; __i < __x.size(); ++__i)
567 __tmp[__i] = __x[__i] ^ __c;
572 inline valarray<_Tp> _STLP_CALL operator^(const _Tp& __c, const valarray<_Tp>& __x) {
573 typedef typename valarray<_Tp>::_NoInit _NoInit;
574 valarray<_Tp> __tmp(__x.size(), _NoInit());
575 for (size_t __i = 0; __i < __x.size(); ++__i)
576 __tmp[__i] = __c ^ __x[__i];
581 inline valarray<_Tp> _STLP_CALL operator&(const valarray<_Tp>& __x, const _Tp& __c) {
582 typedef typename valarray<_Tp>::_NoInit _NoInit;
583 valarray<_Tp> __tmp(__x.size(), _NoInit());
584 for (size_t __i = 0; __i < __x.size(); ++__i)
585 __tmp[__i] = __x[__i] & __c;
590 inline valarray<_Tp> _STLP_CALL operator&(const _Tp& __c, const valarray<_Tp>& __x) {
591 typedef typename valarray<_Tp>::_NoInit _NoInit;
592 valarray<_Tp> __tmp(__x.size(), _NoInit());
593 for (size_t __i = 0; __i < __x.size(); ++__i)
594 __tmp[__i] = __c & __x[__i];
599 inline valarray<_Tp> _STLP_CALL operator|(const valarray<_Tp>& __x, const _Tp& __c) {
600 typedef typename valarray<_Tp>::_NoInit _NoInit;
601 valarray<_Tp> __tmp(__x.size(), _NoInit());
602 for (size_t __i = 0; __i < __x.size(); ++__i)
603 __tmp[__i] = __x[__i] | __c;
608 inline valarray<_Tp> _STLP_CALL operator|(const _Tp& __c, const valarray<_Tp>& __x) {
609 typedef typename valarray<_Tp>::_NoInit _NoInit;
610 valarray<_Tp> __tmp(__x.size(), _NoInit());
611 for (size_t __i = 0; __i < __x.size(); ++__i)
612 __tmp[__i] = __c | __x[__i];
617 inline valarray<_Tp> _STLP_CALL operator<<(const valarray<_Tp>& __x, const _Tp& __c) {
618 typedef typename valarray<_Tp>::_NoInit _NoInit;
619 valarray<_Tp> __tmp(__x.size(), _NoInit());
620 for (size_t __i = 0; __i < __x.size(); ++__i)
621 __tmp[__i] = __x[__i] << __c;
626 inline valarray<_Tp> _STLP_CALL operator<<(const _Tp& __c, const valarray<_Tp>& __x) {
627 typedef typename valarray<_Tp>::_NoInit _NoInit;
628 valarray<_Tp> __tmp(__x.size(), _NoInit());
629 for (size_t __i = 0; __i < __x.size(); ++__i)
630 __tmp[__i] = __c << __x[__i];
635 inline valarray<_Tp> _STLP_CALL operator>>(const valarray<_Tp>& __x, const _Tp& __c) {
636 typedef typename valarray<_Tp>::_NoInit _NoInit;
637 valarray<_Tp> __tmp(__x.size(), _NoInit());
638 for (size_t __i = 0; __i < __x.size(); ++__i)
639 __tmp[__i] = __x[__i] >> __c;
644 inline valarray<_Tp> _STLP_CALL operator>>(const _Tp& __c, const valarray<_Tp>& __x) {
645 typedef typename valarray<_Tp>::_NoInit _NoInit;
646 valarray<_Tp> __tmp(__x.size(), _NoInit());
647 for (size_t __i = 0; __i < __x.size(); ++__i)
648 __tmp[__i] = __c >> __x[__i];
652 // Binary logical operations between two arrays. Behavior is undefined
653 // if the two arrays have different lengths. Note that operator== does
654 // not do what you might at first expect.
657 inline _Valarray_bool _STLP_CALL operator==(const valarray<_Tp>& __x,
658 const valarray<_Tp>& __y)
660 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
661 for (size_t __i = 0; __i < __x.size(); ++__i)
662 __tmp[__i] = __x[__i] == __y[__i];
667 inline _Valarray_bool _STLP_CALL operator<(const valarray<_Tp>& __x,
668 const valarray<_Tp>& __y)
670 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
671 for (size_t __i = 0; __i < __x.size(); ++__i)
672 __tmp[__i] = __x[__i] < __y[__i];
676 #ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE
679 inline _Valarray_bool _STLP_CALL operator!=(const valarray<_Tp>& __x,
680 const valarray<_Tp>& __y)
682 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
683 for (size_t __i = 0; __i < __x.size(); ++__i)
684 __tmp[__i] = __x[__i] != __y[__i];
689 inline _Valarray_bool _STLP_CALL operator>(const valarray<_Tp>& __x,
690 const valarray<_Tp>& __y)
692 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
693 for (size_t __i = 0; __i < __x.size(); ++__i)
694 __tmp[__i] = __x[__i] > __y[__i];
699 inline _Valarray_bool _STLP_CALL operator<=(const valarray<_Tp>& __x,
700 const valarray<_Tp>& __y)
702 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
703 for (size_t __i = 0; __i < __x.size(); ++__i)
704 __tmp[__i] = __x[__i] <= __y[__i];
709 inline _Valarray_bool _STLP_CALL operator>=(const valarray<_Tp>& __x,
710 const valarray<_Tp>& __y)
712 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
713 for (size_t __i = 0; __i < __x.size(); ++__i)
714 __tmp[__i] = __x[__i] >= __y[__i];
718 #endif /* _STLP_USE_SEPARATE_RELOPS_NAMESPACE */
722 inline _Valarray_bool _STLP_CALL operator&&(const valarray<_Tp>& __x,
723 const valarray<_Tp>& __y)
725 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
726 for (size_t __i = 0; __i < __x.size(); ++__i)
727 __tmp[__i] = __x[__i] && __y[__i];
732 inline _Valarray_bool _STLP_CALL operator||(const valarray<_Tp>& __x,
733 const valarray<_Tp>& __y)
735 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
736 for (size_t __i = 0; __i < __x.size(); ++__i)
737 __tmp[__i] = __x[__i] || __y[__i];
741 // Logical operations between an array and a scalar.
744 inline _Valarray_bool _STLP_CALL operator==(const valarray<_Tp>& __x, const _Tp& __c)
746 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
747 for (size_t __i = 0; __i < __x.size(); ++__i)
748 __tmp[__i] = __x[__i] == __c;
753 inline _Valarray_bool _STLP_CALL operator==(const _Tp& __c, const valarray<_Tp>& __x)
755 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
756 for (size_t __i = 0; __i < __x.size(); ++__i)
757 __tmp[__i] = __c == __x[__i];
762 inline _Valarray_bool _STLP_CALL operator!=(const valarray<_Tp>& __x, const _Tp& __c)
764 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
765 for (size_t __i = 0; __i < __x.size(); ++__i)
766 __tmp[__i] = __x[__i] != __c;
771 inline _Valarray_bool _STLP_CALL operator!=(const _Tp& __c, const valarray<_Tp>& __x)
773 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
774 for (size_t __i = 0; __i < __x.size(); ++__i)
775 __tmp[__i] = __c != __x[__i];
780 inline _Valarray_bool _STLP_CALL operator<(const valarray<_Tp>& __x, const _Tp& __c)
782 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
783 for (size_t __i = 0; __i < __x.size(); ++__i)
784 __tmp[__i] = __x[__i] < __c;
789 inline _Valarray_bool _STLP_CALL operator<(const _Tp& __c, const valarray<_Tp>& __x)
791 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
792 for (size_t __i = 0; __i < __x.size(); ++__i)
793 __tmp[__i] = __c < __x[__i];
798 inline _Valarray_bool _STLP_CALL operator>(const valarray<_Tp>& __x, const _Tp& __c)
800 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
801 for (size_t __i = 0; __i < __x.size(); ++__i)
802 __tmp[__i] = __x[__i] > __c;
807 inline _Valarray_bool _STLP_CALL operator>(const _Tp& __c, const valarray<_Tp>& __x)
809 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
810 for (size_t __i = 0; __i < __x.size(); ++__i)
811 __tmp[__i] = __c > __x[__i];
816 inline _Valarray_bool _STLP_CALL operator<=(const valarray<_Tp>& __x, const _Tp& __c)
818 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
819 for (size_t __i = 0; __i < __x.size(); ++__i)
820 __tmp[__i] = __x[__i] <= __c;
825 inline _Valarray_bool _STLP_CALL operator<=(const _Tp& __c, const valarray<_Tp>& __x)
827 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
828 for (size_t __i = 0; __i < __x.size(); ++__i)
829 __tmp[__i] = __c <= __x[__i];
834 inline _Valarray_bool _STLP_CALL operator>=(const valarray<_Tp>& __x, const _Tp& __c)
836 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
837 for (size_t __i = 0; __i < __x.size(); ++__i)
838 __tmp[__i] = __x[__i] >= __c;
843 inline _Valarray_bool _STLP_CALL operator>=(const _Tp& __c, const valarray<_Tp>& __x)
845 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
846 for (size_t __i = 0; __i < __x.size(); ++__i)
847 __tmp[__i] = __c >= __x[__i];
852 inline _Valarray_bool _STLP_CALL operator&&(const valarray<_Tp>& __x, const _Tp& __c)
854 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
855 for (size_t __i = 0; __i < __x.size(); ++__i)
856 __tmp[__i] = __x[__i] && __c;
861 inline _Valarray_bool _STLP_CALL operator&&(const _Tp& __c, const valarray<_Tp>& __x)
863 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
864 for (size_t __i = 0; __i < __x.size(); ++__i)
865 __tmp[__i] = __c && __x[__i];
870 inline _Valarray_bool _STLP_CALL operator||(const valarray<_Tp>& __x, const _Tp& __c)
872 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
873 for (size_t __i = 0; __i < __x.size(); ++__i)
874 __tmp[__i] = __x[__i] || __c;
879 inline _Valarray_bool _STLP_CALL operator||(const _Tp& __c, const valarray<_Tp>& __x)
881 _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
882 for (size_t __i = 0; __i < __x.size(); ++__i)
883 __tmp[__i] = __c || __x[__i];
887 // valarray "transcendentals" (the list includes abs and sqrt, which,
888 // of course, are not transcendental).
891 inline valarray<_Tp> abs(const valarray<_Tp>& __x) {
892 typedef typename valarray<_Tp>::_NoInit _NoInit;
893 valarray<_Tp> __tmp(__x.size(), _NoInit());
894 for (size_t __i = 0; __i < __x.size(); ++__i)
895 __tmp[__i] = ::abs(__x[__i]);
900 inline valarray<_Tp> acos(const valarray<_Tp>& __x) {
901 typedef typename valarray<_Tp>::_NoInit _NoInit;
902 valarray<_Tp> __tmp(__x.size(), _NoInit());
903 for (size_t __i = 0; __i < __x.size(); ++__i)
904 __tmp[__i] = ::acos(__x[__i]);
909 inline valarray<_Tp> asin(const valarray<_Tp>& __x) {
910 typedef typename valarray<_Tp>::_NoInit _NoInit;
911 valarray<_Tp> __tmp(__x.size(), _NoInit());
912 for (size_t __i = 0; __i < __x.size(); ++__i)
913 __tmp[__i] = ::asin(__x[__i]);
918 inline valarray<_Tp> atan(const valarray<_Tp>& __x) {
919 typedef typename valarray<_Tp>::_NoInit _NoInit;
920 valarray<_Tp> __tmp(__x.size(), _NoInit());
921 for (size_t __i = 0; __i < __x.size(); ++__i)
922 __tmp[__i] = ::atan(__x[__i]);
927 inline valarray<_Tp> atan2(const valarray<_Tp>& __x,
928 const valarray<_Tp>& __y) {
929 typedef typename valarray<_Tp>::_NoInit _NoInit;
930 valarray<_Tp> __tmp(__x.size(), _NoInit());
931 for (size_t __i = 0; __i < __x.size(); ++__i)
932 __tmp[__i] = ::atan2(__x[__i], __y[__i]);
937 inline valarray<_Tp> atan2(const valarray<_Tp>& __x, const _Tp& __c) {
938 typedef typename valarray<_Tp>::_NoInit _NoInit;
939 valarray<_Tp> __tmp(__x.size(), _NoInit());
940 for (size_t __i = 0; __i < __x.size(); ++__i)
941 __tmp[__i] = ::atan2(__x[__i], __c);
946 inline valarray<_Tp> atan2(const _Tp& __c, const valarray<_Tp>& __x) {
947 typedef typename valarray<_Tp>::_NoInit _NoInit;
948 valarray<_Tp> __tmp(__x.size(), _NoInit());
949 for (size_t __i = 0; __i < __x.size(); ++__i)
950 __tmp[__i] = ::atan2(__c, __x[__i]);
955 inline valarray<_Tp> cos(const valarray<_Tp>& __x) {
956 typedef typename valarray<_Tp>::_NoInit _NoInit;
957 valarray<_Tp> __tmp(__x.size(), _NoInit());
958 for (size_t __i = 0; __i < __x.size(); ++__i)
959 __tmp[__i] = ::cos(__x[__i]);
964 inline valarray<_Tp> cosh(const valarray<_Tp>& __x) {
965 typedef typename valarray<_Tp>::_NoInit _NoInit;
966 valarray<_Tp> __tmp(__x.size(), _NoInit());
967 for (size_t __i = 0; __i < __x.size(); ++__i)
968 __tmp[__i] = ::cosh(__x[__i]);
973 inline valarray<_Tp> exp(const valarray<_Tp>& __x) {
974 typedef typename valarray<_Tp>::_NoInit _NoInit;
975 valarray<_Tp> __tmp(__x.size(), _NoInit());
976 for (size_t __i = 0; __i < __x.size(); ++__i)
977 __tmp[__i] = ::exp(__x[__i]);
982 inline valarray<_Tp> log(const valarray<_Tp>& __x) {
983 typedef typename valarray<_Tp>::_NoInit _NoInit;
984 valarray<_Tp> __tmp(__x.size(), _NoInit());
985 for (size_t __i = 0; __i < __x.size(); ++__i)
986 __tmp[__i] = ::log(__x[__i]);
991 inline valarray<_Tp> log10(const valarray<_Tp>& __x) {
992 typedef typename valarray<_Tp>::_NoInit _NoInit;
993 valarray<_Tp> __tmp(__x.size(), _NoInit());
994 for (size_t __i = 0; __i < __x.size(); ++__i)
995 __tmp[__i] = ::log10(__x[__i]);
1000 inline valarray<_Tp> pow(const valarray<_Tp>& __x,
1001 const valarray<_Tp>& __y) {
1002 typedef typename valarray<_Tp>::_NoInit _NoInit;
1003 valarray<_Tp> __tmp(__x.size(), _NoInit());
1004 for (size_t __i = 0; __i < __x.size(); ++__i)
1005 __tmp[__i] = ::pow(__x[__i], __y[__i]);
1009 template <class _Tp>
1010 inline valarray<_Tp> pow(const valarray<_Tp>& __x, const _Tp& __c) {
1011 typedef typename valarray<_Tp>::_NoInit _NoInit;
1012 valarray<_Tp> __tmp(__x.size(), _NoInit());
1013 for (size_t __i = 0; __i < __x.size(); ++__i)
1014 __tmp[__i] = ::pow(__x[__i], __c);
1018 template <class _Tp>
1019 inline valarray<_Tp> pow(const _Tp& __c, const valarray<_Tp>& __x) {
1020 typedef typename valarray<_Tp>::_NoInit _NoInit;
1021 valarray<_Tp> __tmp(__x.size(), _NoInit());
1022 for (size_t __i = 0; __i < __x.size(); ++__i)
1023 __tmp[__i] = ::pow(__c, __x[__i]);
1027 template <class _Tp>
1028 inline valarray<_Tp> sin(const valarray<_Tp>& __x) {
1029 typedef typename valarray<_Tp>::_NoInit _NoInit;
1030 valarray<_Tp> __tmp(__x.size(), _NoInit());
1031 for (size_t __i = 0; __i < __x.size(); ++__i)
1032 __tmp[__i] = ::sin(__x[__i]);
1036 template <class _Tp>
1037 inline valarray<_Tp> sinh(const valarray<_Tp>& __x) {
1038 typedef typename valarray<_Tp>::_NoInit _NoInit;
1039 valarray<_Tp> __tmp(__x.size(), _NoInit());
1040 for (size_t __i = 0; __i < __x.size(); ++__i)
1041 __tmp[__i] = ::sinh(__x[__i]);
1045 template <class _Tp>
1046 inline valarray<_Tp> sqrt(const valarray<_Tp>& __x) {
1047 typedef typename valarray<_Tp>::_NoInit _NoInit;
1048 valarray<_Tp> __tmp(__x.size(), _NoInit());
1049 for (size_t __i = 0; __i < __x.size(); ++__i)
1050 __tmp[__i] = ::sqrt(__x[__i]);
1054 template <class _Tp>
1055 inline valarray<_Tp> tan(const valarray<_Tp>& __x) {
1056 typedef typename valarray<_Tp>::_NoInit _NoInit;
1057 valarray<_Tp> __tmp(__x.size(), _NoInit());
1058 for (size_t __i = 0; __i < __x.size(); ++__i)
1059 __tmp[__i] = ::tan(__x[__i]);
1063 template <class _Tp>
1064 inline valarray<_Tp> tanh(const valarray<_Tp>& __x) {
1065 typedef typename valarray<_Tp>::_NoInit _NoInit;
1066 valarray<_Tp> __tmp(__x.size(), _NoInit());
1067 for (size_t __i = 0; __i < __x.size(); ++__i)
1068 __tmp[__i] = ::tanh(__x[__i]);
1072 //----------------------------------------------------------------------
1073 // slice and slice_array
1077 slice() : _M_start(0), _M_length(0), _M_stride(0) {}
1078 slice(size_t __start, size_t __length, size_t __stride)
1079 : _M_start(__start), _M_length(__length), _M_stride(__stride)
1081 __TRIVIAL_DESTRUCTOR(slice)
1083 size_t start() const { return _M_start; }
1084 size_t size() const { return _M_length; }
1085 size_t stride() const { return _M_stride; }
1093 template <class _Tp>
1095 friend class valarray<_Tp>;
1097 typedef _Tp value_type;
1099 void operator=(const valarray<value_type>& __x) const {
1100 size_t __index = _M_slice.start();
1101 for (size_t __i = 0;
1102 __i < _M_slice.size();
1103 ++__i, __index += _M_slice.stride())
1104 _M_array[__index] = __x[__i];
1107 void operator*=(const valarray<value_type>& __x) const {
1108 size_t __index = _M_slice.start();
1109 for (size_t __i = 0;
1110 __i < _M_slice.size();
1111 ++__i, __index += _M_slice.stride())
1112 _M_array[__index] *= __x[__i];
1115 void operator/=(const valarray<value_type>& __x) const {
1116 size_t __index = _M_slice.start();
1117 for (size_t __i = 0;
1118 __i < _M_slice.size();
1119 ++__i, __index += _M_slice.stride())
1120 _M_array[__index] /= __x[__i];
1123 void operator%=(const valarray<value_type>& __x) const {
1124 size_t __index = _M_slice.start();
1125 for (size_t __i = 0;
1126 __i < _M_slice.size();
1127 ++__i, __index += _M_slice.stride())
1128 _M_array[__index] %= __x[__i];
1131 void operator+=(const valarray<value_type>& __x) const {
1132 size_t __index = _M_slice.start();
1133 for (size_t __i = 0;
1134 __i < _M_slice.size();
1135 ++__i, __index += _M_slice.stride())
1136 _M_array[__index] += __x[__i];
1139 void operator-=(const valarray<value_type>& __x) const {
1140 size_t __index = _M_slice.start();
1141 for (size_t __i = 0;
1142 __i < _M_slice.size();
1143 ++__i, __index += _M_slice.stride())
1144 _M_array[__index] -= __x[__i];
1147 void operator^=(const valarray<value_type>& __x) const {
1148 size_t __index = _M_slice.start();
1149 for (size_t __i = 0;
1150 __i < _M_slice.size();
1151 ++__i, __index += _M_slice.stride())
1152 _M_array[__index] ^= __x[__i];
1155 void operator&=(const valarray<value_type>& __x) const {
1156 size_t __index = _M_slice.start();
1157 for (size_t __i = 0;
1158 __i < _M_slice.size();
1159 ++__i, __index += _M_slice.stride())
1160 _M_array[__index] &= __x[__i];
1163 void operator|=(const valarray<value_type>& __x) const {
1164 size_t __index = _M_slice.start();
1165 for (size_t __i = 0;
1166 __i < _M_slice.size();
1167 ++__i, __index += _M_slice.stride())
1168 _M_array[__index] |= __x[__i];
1171 void operator<<=(const valarray<value_type>& __x) const {
1172 size_t __index = _M_slice.start();
1173 for (size_t __i = 0;
1174 __i < _M_slice.size();
1175 ++__i, __index += _M_slice.stride())
1176 _M_array[__index] <<= __x[__i];
1179 void operator>>=(const valarray<value_type>& __x) const {
1180 size_t __index = _M_slice.start();
1181 for (size_t __i = 0;
1182 __i < _M_slice.size();
1183 ++__i, __index += _M_slice.stride())
1184 _M_array[__index] >>= __x[__i];
1187 void operator=(const value_type& __c) /*const could be const but standard says NO (26.3.5.4-1)*/ {
1188 size_t __index = _M_slice.start();
1189 for (size_t __i = 0;
1190 __i < _M_slice.size();
1191 ++__i, __index += _M_slice.stride())
1192 _M_array[__index] = __c;
1198 slice_array(const slice& __slice, valarray<_Tp>& __array)
1199 : _M_slice(__slice), _M_array(__array)
1203 valarray<_Tp>& _M_array;
1205 private: // Disable assignment and default constructor
1207 slice_array(const slice_array&);
1208 slice_array& operator=(const slice_array&);
1211 // valarray member functions dealing with slice and slice_array
1213 template <class _Tp>
1214 inline valarray<_Tp>::valarray(const slice_array<_Tp>& __x)
1215 : _Valarray_base<_Tp>(__x._M_slice.size()) {
1216 typedef typename __type_traits<_Tp>::has_trivial_default_constructor
1218 _M_initialize(_Is_Trivial());
1223 template <class _Tp>
1224 inline slice_array<_Tp> valarray<_Tp>::operator[](slice __slice) {
1225 return slice_array<_Tp>(__slice, *this);
1228 //----------------------------------------------------------------------
1229 // gslice and gslice_array
1231 template <class _Size>
1232 struct _Gslice_Iter_tmpl;
1235 friend struct _Gslice_Iter_tmpl<size_t>;
1237 gslice() : _M_start(0), _M_lengths(0), _M_strides(0) {}
1238 gslice(size_t __start,
1239 const _Valarray_size_t& __lengths, const _Valarray_size_t& __strides)
1240 : _M_start(__start), _M_lengths(__lengths), _M_strides(__strides)
1242 __TRIVIAL_DESTRUCTOR(gslice)
1244 size_t start() const { return _M_start; }
1245 _Valarray_size_t size() const { return _M_lengths; }
1246 _Valarray_size_t stride() const { return _M_strides; }
1248 // Extension: check for an empty gslice.
1249 bool _M_empty() const { return _M_lengths.size() == 0; }
1251 // Extension: number of indices this gslice represents. (For a degenerate
1252 // gslice, they're not necessarily all distinct.)
1253 size_t _M_size() const {
1254 return !this->_M_empty()
1255 ? accumulate(_M_lengths._M_first + 1,
1256 _M_lengths._M_first + _M_lengths._M_size,
1258 multiplies<size_t>())
1267 _Valarray_size_t _M_lengths;
1268 _Valarray_size_t _M_strides;
1271 // This is not an STL iterator. It is constructed from a gslice, and it
1272 // steps through the gslice indices in sequence. See 23.3.6 of the C++
1273 // standard, paragraphs 2-3, for an explanation of the sequence. At
1274 // each step we get two things: the ordinal (i.e. number of steps taken),
1275 // and the one-dimensional index.
1277 template <class _Size>
1278 struct _Gslice_Iter_tmpl {
1279 _Gslice_Iter_tmpl(const gslice& __gslice)
1280 : _M_step(0), _M_1d_idx(__gslice.start()),
1281 _M_indices(size_t(0), __gslice._M_lengths.size()),
1285 bool _M_done() const { return _M_indices[0] == _M_gslice._M_lengths[0]; }
1292 valarray<_Size> _M_indices;
1293 const gslice& _M_gslice;
1296 typedef _Gslice_Iter_tmpl<size_t> _Gslice_Iter;
1298 template <class _Tp>
1299 class gslice_array {
1300 friend class valarray<_Tp>;
1302 typedef _Tp value_type;
1304 void operator= (const valarray<value_type>& __x) const {
1305 if (!_M_gslice._M_empty()) {
1306 _Gslice_Iter __i(_M_gslice);
1307 do _M_array[__i._M_1d_idx] = __x[__i._M_step]; while(__i._M_incr());
1311 void operator*= (const valarray<value_type>& __x) const {
1312 if (!_M_gslice._M_empty()) {
1313 _Gslice_Iter __i(_M_gslice);
1314 do _M_array[__i._M_1d_idx] *= __x[__i._M_step]; while(__i._M_incr());
1318 void operator/= (const valarray<value_type>& __x) const {
1319 if (!_M_gslice._M_empty()) {
1320 _Gslice_Iter __i(_M_gslice);
1321 do _M_array[__i._M_1d_idx] /= __x[__i._M_step]; while(__i._M_incr());
1325 void operator%= (const valarray<value_type>& __x) const {
1326 if (!_M_gslice._M_empty()) {
1327 _Gslice_Iter __i(_M_gslice);
1328 do _M_array[__i._M_1d_idx] %= __x[__i._M_step]; while(__i._M_incr());
1332 void operator+= (const valarray<value_type>& __x) const {
1333 if (!_M_gslice._M_empty()) {
1334 _Gslice_Iter __i(_M_gslice);
1335 do _M_array[__i._M_1d_idx] += __x[__i._M_step]; while(__i._M_incr());
1339 void operator-= (const valarray<value_type>& __x) const {
1340 if (!_M_gslice._M_empty()) {
1341 _Gslice_Iter __i(_M_gslice);
1342 do _M_array[__i._M_1d_idx] -= __x[__i._M_step]; while(__i._M_incr());
1346 void operator^= (const valarray<value_type>& __x) const {
1347 if (!_M_gslice._M_empty()) {
1348 _Gslice_Iter __i(_M_gslice);
1349 do _M_array[__i._M_1d_idx] ^= __x[__i._M_step]; while(__i._M_incr());
1353 void operator&= (const valarray<value_type>& __x) const {
1354 if (!_M_gslice._M_empty()) {
1355 _Gslice_Iter __i(_M_gslice);
1356 do _M_array[__i._M_1d_idx] &= __x[__i._M_step]; while(__i._M_incr());
1360 void operator|= (const valarray<value_type>& __x) const {
1361 if (!_M_gslice._M_empty()) {
1362 _Gslice_Iter __i(_M_gslice);
1363 do _M_array[__i._M_1d_idx] |= __x[__i._M_step]; while(__i._M_incr());
1367 void operator<<= (const valarray<value_type>& __x) const {
1368 if (!_M_gslice._M_empty()) {
1369 _Gslice_Iter __i(_M_gslice);
1370 do _M_array[__i._M_1d_idx] <<= __x[__i._M_step]; while(__i._M_incr());
1374 void operator>>= (const valarray<value_type>& __x) const {
1375 if (!_M_gslice._M_empty()) {
1376 _Gslice_Iter __i(_M_gslice);
1377 do _M_array[__i._M_1d_idx] >>= __x[__i._M_step]; while(__i._M_incr());
1381 void operator= (const value_type& __c) /*const could be const but standard says NO (26.3.7.4-1)*/ {
1382 if (!_M_gslice._M_empty()) {
1383 _Gslice_Iter __i(_M_gslice);
1384 do _M_array[__i._M_1d_idx] = __c; while(__i._M_incr());
1391 gslice_array(const gslice& __gslice, valarray<_Tp>& __array)
1392 : _M_gslice(__gslice), _M_array(__array)
1396 valarray<value_type>& _M_array;
1398 private: // Disable assignment
1399 void operator=(const gslice_array<_Tp>&);
1402 // valarray member functions dealing with gslice and gslice_array. Note
1403 // that it is illegal (behavior is undefined) to construct a gslice_array
1404 // from a degenerate gslice.
1406 template <class _Tp>
1407 inline valarray<_Tp>::valarray(const gslice_array<_Tp>& __x)
1408 : _Valarray_base<_Tp>(__x._M_gslice._M_size()) {
1409 typedef typename __type_traits<_Tp>::has_trivial_default_constructor
1411 _M_initialize(_Is_Trivial());
1415 template <class _Tp>
1416 inline gslice_array<_Tp> valarray<_Tp>::operator[](const gslice& __slice) {
1417 return gslice_array<_Tp>(__slice, *this);
1421 //----------------------------------------------------------------------
1424 template <class _Tp>
1426 friend class valarray<_Tp>;
1428 typedef _Tp value_type;
1430 void operator=(const valarray<value_type>& __x) const {
1432 for (size_t __i = 0; __i < _M_array.size(); ++__i)
1433 if (_M_mask[__i]) _M_array[__i] = __x[__idx++];
1436 void operator*=(const valarray<value_type>& __x) const {
1438 for (size_t __i = 0; __i < _M_array.size(); ++__i)
1439 if (_M_mask[__i]) _M_array[__i] *= __x[__idx++];
1442 void operator/=(const valarray<value_type>& __x) const {
1444 for (size_t __i = 0; __i < _M_array.size(); ++__i)
1445 if (_M_mask[__i]) _M_array[__i] /= __x[__idx++];
1448 void operator%=(const valarray<value_type>& __x) const {
1450 for (size_t __i = 0; __i < _M_array.size(); ++__i)
1451 if (_M_mask[__i]) _M_array[__i] %= __x[__idx++];
1454 void operator+=(const valarray<value_type>& __x) const {
1456 for (size_t __i = 0; __i < _M_array.size(); ++__i)
1457 if (_M_mask[__i]) _M_array[__i] += __x[__idx++];
1460 void operator-=(const valarray<value_type>& __x) const {
1462 for (size_t __i = 0; __i < _M_array.size(); ++__i)
1463 if (_M_mask[__i]) _M_array[__i] -= __x[__idx++];
1466 void operator^=(const valarray<value_type>& __x) const {
1468 for (size_t __i = 0; __i < _M_array.size(); ++__i)
1469 if (_M_mask[__i]) _M_array[__i] ^= __x[__idx++];
1472 void operator&=(const valarray<value_type>& __x) const {
1474 for (size_t __i = 0; __i < _M_array.size(); ++__i)
1475 if (_M_mask[__i]) _M_array[__i] &= __x[__idx++];
1478 void operator|=(const valarray<value_type>& __x) const {
1480 for (size_t __i = 0; __i < _M_array.size(); ++__i)
1481 if (_M_mask[__i]) _M_array[__i] |= __x[__idx++];
1484 void operator<<=(const valarray<value_type>& __x) const {
1486 for (size_t __i = 0; __i < _M_array.size(); ++__i)
1487 if (_M_mask[__i]) _M_array[__i] <<= __x[__idx++];
1490 void operator>>=(const valarray<value_type>& __x) const {
1492 for (size_t __i = 0; __i < _M_array.size(); ++__i)
1493 if (_M_mask[__i]) _M_array[__i] >>= __x[__idx++];
1496 void operator=(const value_type& __c) const {
1497 for (size_t __i = 0; __i < _M_array.size(); ++__i)
1498 if (_M_mask[__i]) _M_array[__i] = __c;
1503 // Extension: number of true values in the mask
1504 size_t _M_num_true() const {
1505 size_t __result = 0;
1506 for (size_t __i = 0; __i < _M_mask.size(); ++__i)
1507 if (_M_mask[__i]) ++__result;
1512 mask_array(const _Valarray_bool& __mask, valarray<_Tp>& __array)
1513 : _M_mask(__mask), _M_array(__array)
1516 _Valarray_bool _M_mask;
1517 valarray<_Tp>& _M_array;
1519 private: // Disable assignment
1520 void operator=(const mask_array<_Tp>&);
1523 // valarray member functions dealing with mask_array
1525 template <class _Tp>
1526 inline valarray<_Tp>::valarray(const mask_array<_Tp>& __x)
1527 : _Valarray_base<_Tp>(__x._M_num_true())
1529 typedef typename __type_traits<_Tp>::has_trivial_default_constructor
1531 _M_initialize(_Is_Trivial());
1535 // Behavior is undefined if __x._M_num_true() != this->size()
1536 template <class _Tp>
1537 inline valarray<_Tp>& valarray<_Tp>::operator=(const mask_array<_Tp>& __x) {
1539 for (size_t __i = 0; __i < __x._M_array.size(); ++__i)
1540 if (__x._M_mask[__i]) (*this)[__idx++] = __x._M_array[__i];
1544 template <class _Tp>
1545 inline mask_array<_Tp> valarray<_Tp>::operator[](const _Valarray_bool& __mask)
1547 return mask_array<_Tp>(__mask, *this);
1551 //----------------------------------------------------------------------
1554 template <class _Tp>
1555 class indirect_array {
1556 friend class valarray<_Tp>;
1558 typedef _Tp value_type;
1560 void operator=(const valarray<value_type>& __x) const {
1561 for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1562 _M_array[_M_addr[__i]] = __x[__i];
1565 void operator*=(const valarray<value_type>& __x) const {
1566 for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1567 _M_array[_M_addr[__i]] *= __x[__i];
1570 void operator/=(const valarray<value_type>& __x) const {
1571 for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1572 _M_array[_M_addr[__i]] /= __x[__i];
1575 void operator%=(const valarray<value_type>& __x) const {
1576 for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1577 _M_array[_M_addr[__i]] %= __x[__i];
1580 void operator+=(const valarray<value_type>& __x) const {
1581 for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1582 _M_array[_M_addr[__i]] += __x[__i];
1585 void operator-=(const valarray<value_type>& __x) const {
1586 for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1587 _M_array[_M_addr[__i]] -= __x[__i];
1590 void operator^=(const valarray<value_type>& __x) const {
1591 for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1592 _M_array[_M_addr[__i]] ^= __x[__i];
1595 void operator&=(const valarray<value_type>& __x) const {
1596 for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1597 _M_array[_M_addr[__i]] &= __x[__i];
1600 void operator|=(const valarray<value_type>& __x) const {
1601 for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1602 _M_array[_M_addr[__i]] |= __x[__i];
1605 void operator<<=(const valarray<value_type>& __x) const {
1606 for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1607 _M_array[_M_addr[__i]] <<= __x[__i];
1610 void operator>>=(const valarray<value_type>& __x) const {
1611 for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1612 _M_array[_M_addr[__i]] >>= __x[__i];
1615 void operator=(const value_type& __c) const {
1616 for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1617 _M_array[_M_addr[__i]] = __c;
1620 ~indirect_array() {}
1623 indirect_array(const _Valarray_size_t& __addr, valarray<_Tp>& __array)
1624 : _M_addr(__addr), _M_array(__array)
1627 _Valarray_size_t _M_addr;
1628 valarray<_Tp>& _M_array;
1630 private: // Disable assignment
1631 void operator=(const indirect_array<_Tp>&);
1634 // valarray member functions dealing with indirect_array
1636 template <class _Tp>
1637 inline valarray<_Tp>::valarray(const indirect_array<_Tp>& __x)
1638 : _Valarray_base<_Tp>(__x._M_addr.size())
1640 typedef typename __type_traits<_Tp>::has_trivial_default_constructor
1642 _M_initialize(_Is_Trivial());
1647 template <class _Tp>
1648 inline indirect_array<_Tp>
1649 valarray<_Tp>::operator[](const _Valarray_size_t& __addr)
1651 return indirect_array<_Tp>(__addr, *this);
1656 # if !defined (_STLP_LINK_TIME_INSTANTIATION)
1657 # include <stl/_valarray.c>
1660 #endif /* _STLP_VALARRAY */