1/*
2 * Copyright (c) 1999
3 * Silicon Graphics Computer Systems, Inc.
4 *
5 * Copyright (c) 1999
6 * Boris Fomitchev
7 *
8 * This material is provided "as is", with absolutely no warranty expressed
9 * or implied. Any use is at your own risk.
10 *
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.
16 *
17 */
18
19#ifndef _STLP_VALARRAY_H
20#define _STLP_VALARRAY_H
21
22#ifndef _STLP_INTERNAL_CMATH
23#  include <stl/_cmath.h>
24#endif
25
26#ifndef _STLP_INTERNAL_NEW
27#  include <stl/_new.h>
28#endif
29
30#ifndef _STLP_INTERNAL_ALGO_H
31#  include <stl/_algo.h>
32#endif
33
34#ifndef _STLP_INTERNAL_NUMERIC_H
35#  include <stl/_numeric.h>
36#endif
37
38#ifndef _STLP_INTERNAL_LIMITS
39#  include <stl/_limits.h>
40#endif
41
42_STLP_BEGIN_NAMESPACE
43
44class slice;
45class gslice;
46
47template <class _Tp> class valarray;
48typedef valarray<bool>    _Valarray_bool;
49typedef valarray<size_t>  _Valarray_size_t;
50
51template <class _Tp> class slice_array;
52template <class _Tp> class gslice_array;
53template <class _Tp> class mask_array;
54template <class _Tp> class indirect_array;
55
56//----------------------------------------------------------------------
57// class valarray
58
59// Base class to handle memory allocation and deallocation.  We can't just
60// use vector<>, because vector<bool> would be unsuitable as an internal
61// representation for valarray<bool>.
62
63template <class _Tp>
64struct _Valarray_base {
65  _Tp*   _M_first;
66  size_t _M_size;
67
68  _Valarray_base() : _M_first(0), _M_size(0) {}
69  _Valarray_base(size_t __n) : _M_first(0), _M_size(0) { _M_allocate(__n); }
70  ~_Valarray_base() { _M_deallocate(); }
71
72  void _M_allocate(size_t __n) {
73    if (__n != 0) {
74      _M_first = __STATIC_CAST(_Tp*, __stl_new(__n * sizeof(_Tp)));
75      _M_size  = __n;
76    }
77    else {
78      _M_first = 0;
79      _M_size = 0;
80    }
81  }
82
83  void _M_deallocate() {
84    __stl_delete(_M_first);
85    _M_first = 0;
86    _M_size = 0;
87  }
88};
89
90template <class _Tp>
91class valarray : private _Valarray_base<_Tp>
92{
93  friend class gslice;
94
95public:
96  typedef _Tp value_type;
97
98  // Basic constructors
99  valarray() : _Valarray_base<_Tp>() {}
100  explicit valarray(size_t __n) : _Valarray_base<_Tp>(__n)
101    { uninitialized_fill_n(this->_M_first, this->_M_size, _STLP_DEFAULT_CONSTRUCTED(value_type)); }
102  valarray(const value_type& __x, size_t __n) : _Valarray_base<_Tp>(__n)
103    { uninitialized_fill_n(this->_M_first, this->_M_size, __x); }
104  valarray(const value_type* __p, size_t __n) : _Valarray_base<_Tp>(__n)
105    { uninitialized_copy(__p, __p + __n, this->_M_first); }
106  valarray(const valarray<_Tp>& __x) : _Valarray_base<_Tp>(__x._M_size) {
107    uninitialized_copy(__x._M_first, __x._M_first + __x._M_size,
108                       this->_M_first);
109  }
110
111  // Constructors from auxiliary array types
112  valarray(const slice_array<_Tp>&);
113  valarray(const gslice_array<_Tp>&);
114  valarray(const mask_array<_Tp>&);
115  valarray(const indirect_array<_Tp>&);
116
117  // Destructor
118  ~valarray() { _STLP_STD::_Destroy_Range(this->_M_first, this->_M_first + this->_M_size); }
119
120  // Extension: constructor that doesn't initialize valarray elements to a
121  // specific value.  This is faster for types such as int and double.
122private:
123  void _M_initialize(const __true_type&) {}
124  void _M_initialize(const __false_type&)
125    { uninitialized_fill_n(this->_M_first, this->_M_size, _STLP_DEFAULT_CONSTRUCTED(_Tp)); }
126
127public:
128  struct _NoInit {};
129  valarray(size_t __n, _NoInit) : _Valarray_base<_Tp>(__n) {
130    typedef typename __type_traits<_Tp>::has_trivial_default_constructor _Is_Trivial;
131    _M_initialize(_Is_Trivial());
132  }
133
134public:                         // Assignment
135  // Basic assignment.  Note that 'x = y' is undefined if x.size() != y.size()
136  valarray<_Tp>& operator=(const valarray<_Tp>& __x) {
137    _STLP_ASSERT(__x.size() == this->size())
138    if (this != &__x)
139      copy(__x._M_first, __x._M_first + __x._M_size, this->_M_first);
140    return *this;
141  }
142
143  // Scalar assignment
144  valarray<_Tp>& operator=(const value_type& __x) {
145    fill_n(this->_M_first, this->_M_size, __x);
146    return *this;
147  }
148
149  // Assignment of auxiliary array types
150  valarray<_Tp>& operator=(const slice_array<_Tp>&);
151  valarray<_Tp>& operator=(const gslice_array<_Tp>&);
152  valarray<_Tp>& operator=(const mask_array<_Tp>&);
153  valarray<_Tp>& operator=(const indirect_array<_Tp>&);
154
155public:                         // Element access
156  value_type  operator[](size_t __n) const {
157    _STLP_ASSERT(__n < this->size())
158    return this->_M_first[__n];
159  }
160  value_type& operator[](size_t __n) {
161    _STLP_ASSERT(__n < this->size())
162    return this->_M_first[__n];
163  }
164  size_t size() const { return this->_M_size; }
165
166public:                         // Subsetting operations with auxiliary type
167  valarray<_Tp>       operator[](slice) const;
168  slice_array<_Tp>    operator[](slice);
169  valarray<_Tp>       operator[](const gslice&) const;
170  gslice_array<_Tp>   operator[](const gslice&);
171  valarray<_Tp>       operator[](const _Valarray_bool&) const;
172  mask_array<_Tp>     operator[](const _Valarray_bool&);
173  valarray<_Tp>       operator[](const _Valarray_size_t&) const;
174  indirect_array<_Tp> operator[](const _Valarray_size_t&);
175
176public:                         // Unary operators.
177  valarray<_Tp> operator+() const { return *this; }
178
179  valarray<_Tp> operator-() const {
180    valarray<_Tp> __tmp(this->size(), _NoInit());
181    for (size_t __i = 0; __i < this->size(); ++__i)
182      __tmp[__i] = -(*this)[__i];
183    return __tmp;
184  }
185
186  valarray<_Tp> operator~() const {
187    valarray<_Tp> __tmp(this->size(), _NoInit());
188    for (size_t __i = 0; __i < this->size(); ++__i)
189      __tmp[__i] = ~(*this)[__i];
190    return __tmp;
191  }
192
193  _Valarray_bool operator!() const;
194
195public:                         // Scalar computed assignment.
196  valarray<_Tp>& operator*= (const value_type& __x) {
197    for (size_t __i = 0; __i < this->size(); ++__i)
198      (*this)[__i] *= __x;
199    return *this;
200  }
201
202  valarray<_Tp>& operator/= (const value_type& __x) {
203    for (size_t __i = 0; __i < this->size(); ++__i)
204      (*this)[__i] /= __x;
205    return *this;
206  }
207
208  valarray<_Tp>& operator%= (const value_type& __x) {
209    for (size_t __i = 0; __i < this->size(); ++__i)
210      (*this)[__i] %= __x;
211    return *this;
212  }
213
214  valarray<_Tp>& operator+= (const value_type& __x) {
215    for (size_t __i = 0; __i < this->size(); ++__i)
216      (*this)[__i] += __x;
217    return *this;
218  }
219
220  valarray<_Tp>& operator-= (const value_type& __x) {
221    for (size_t __i = 0; __i < this->size(); ++__i)
222      (*this)[__i] -= __x;
223    return *this;
224  }
225
226  valarray<_Tp>& operator^= (const value_type& __x) {
227    for (size_t __i = 0; __i < this->size(); ++__i)
228      (*this)[__i] ^= __x;
229    return *this;
230  }
231
232  valarray<_Tp>& operator&= (const value_type& __x) {
233    for (size_t __i = 0; __i < this->size(); ++__i)
234      (*this)[__i] &= __x;
235    return *this;
236  }
237
238  valarray<_Tp>& operator|= (const value_type& __x) {
239    for (size_t __i = 0; __i < this->size(); ++__i)
240      (*this)[__i] |= __x;
241    return *this;
242  }
243
244  valarray<_Tp>& operator<<= (const value_type& __x) {
245    for (size_t __i = 0; __i < this->size(); ++__i)
246      (*this)[__i] <<= __x;
247    return *this;
248  }
249
250  valarray<_Tp>& operator>>= (const value_type& __x) {
251    for (size_t __i = 0; __i < this->size(); ++__i)
252      (*this)[__i] >>= __x;
253    return *this;
254  }
255
256public:                         // Array computed assignment.
257  valarray<_Tp>& operator*= (const valarray<_Tp>& __x) {
258    _STLP_ASSERT(__x.size() == this->size())
259    for (size_t __i = 0; __i < this->size(); ++__i)
260      (*this)[__i] *= __x[__i];
261    return *this;
262  }
263
264  valarray<_Tp>& operator/= (const valarray<_Tp>& __x) {
265    _STLP_ASSERT(__x.size() == this->size())
266    for (size_t __i = 0; __i < this->size(); ++__i)
267      (*this)[__i] /= __x[__i];
268    return *this;
269  }
270
271  valarray<_Tp>& operator%= (const valarray<_Tp>& __x) {
272    _STLP_ASSERT(__x.size() == this->size())
273    for (size_t __i = 0; __i < this->size(); ++__i)
274      (*this)[__i] %= __x[__i];
275    return *this;
276  }
277
278  valarray<_Tp>& operator+= (const valarray<_Tp>& __x) {
279    _STLP_ASSERT(__x.size() == this->size())
280    for (size_t __i = 0; __i < this->size(); ++__i)
281      (*this)[__i] += __x[__i];
282    return *this;
283  }
284
285  valarray<_Tp>& operator-= (const valarray<_Tp>& __x) {
286    _STLP_ASSERT(__x.size() == this->size())
287    for (size_t __i = 0; __i < this->size(); ++__i)
288      (*this)[__i] -= __x[__i];
289    return *this;
290  }
291
292  valarray<_Tp>& operator^= (const valarray<_Tp>& __x) {
293    _STLP_ASSERT(__x.size() == this->size())
294    for (size_t __i = 0; __i < this->size(); ++__i)
295      (*this)[__i] ^= __x[__i];
296    return *this;
297  }
298
299  valarray<_Tp>& operator&= (const valarray<_Tp>& __x) {
300    _STLP_ASSERT(__x.size() == this->size())
301    for (size_t __i = 0; __i < this->size(); ++__i)
302      (*this)[__i] &= __x[__i];
303    return *this;
304  }
305
306  valarray<_Tp>& operator|= (const valarray<_Tp>& __x) {
307    _STLP_ASSERT(__x.size() == this->size())
308    for (size_t __i = 0; __i < this->size(); ++__i)
309      (*this)[__i] |= __x[__i];
310    return *this;
311  }
312
313  valarray<_Tp>& operator<<= (const valarray<_Tp>& __x) {
314    _STLP_ASSERT(__x.size() == this->size())
315    for (size_t __i = 0; __i < this->size(); ++__i)
316      (*this)[__i] <<= __x[__i];
317    return *this;
318  }
319
320  valarray<_Tp>& operator>>= (const valarray<_Tp>& __x) {
321    _STLP_ASSERT(__x.size() == this->size())
322    for (size_t __i = 0; __i < this->size(); ++__i)
323      (*this)[__i] >>= __x[__i];
324    return *this;
325  }
326
327public:                         // Other member functions.
328
329  // The result is undefined for zero-length arrays
330  value_type sum() const {
331    _STLP_ASSERT(this->size() != 0)
332    return accumulate(this->_M_first + 1, this->_M_first + this->_M_size,
333                      (*this)[0]);
334  }
335
336  // The result is undefined for zero-length arrays
337  value_type (min) () const {
338    _STLP_ASSERT(this->size() != 0)
339    return *min_element(this->_M_first + 0, this->_M_first + this->_M_size);
340  }
341
342  value_type (max) () const {
343    _STLP_ASSERT(this->size() != 0)
344    return *max_element(this->_M_first + 0, this->_M_first + this->_M_size);
345  }
346
347  valarray<_Tp> shift(int __n) const;
348  valarray<_Tp> cshift(int __n) const;
349
350  valarray<_Tp> apply(value_type __f(value_type)) const {
351    valarray<_Tp> __tmp(this->size());
352    transform(this->_M_first + 0, this->_M_first + this->_M_size, __tmp._M_first,
353              __f);
354    return __tmp;
355  }
356  valarray<_Tp> apply(value_type __f(const value_type&)) const {
357    valarray<_Tp> __tmp(this->size());
358    transform(this->_M_first + 0, this->_M_first + this->_M_size, __tmp._M_first,
359              __f);
360    return __tmp;
361  }
362
363  void resize(size_t __n, value_type __x = value_type()) {
364    _STLP_STD::_Destroy_Range(this->_M_first, this->_M_first + this->_M_size);
365    _Valarray_base<_Tp>::_M_deallocate();
366    _Valarray_base<_Tp>::_M_allocate(__n);
367    uninitialized_fill_n(this->_M_first, this->_M_size, __x);
368  }
369};
370
371//----------------------------------------------------------------------
372// valarray non-member functions.
373
374// Binary arithmetic operations between two arrays.  Behavior is
375// undefined if the two arrays do not have the same length.
376
377template <class _Tp>
378inline valarray<_Tp>  _STLP_CALL operator*(const valarray<_Tp>& __x,
379                                           const valarray<_Tp>& __y) {
380  _STLP_ASSERT(__x.size() == __y.size())
381  typedef typename valarray<_Tp>::_NoInit _NoInit;
382  valarray<_Tp> __tmp(__x.size(), _NoInit());
383  for (size_t __i = 0; __i < __x.size(); ++__i)
384    __tmp[__i] = __x[__i] * __y[__i];
385  return __tmp;
386}
387
388template <class _Tp>
389inline valarray<_Tp>  _STLP_CALL operator/(const valarray<_Tp>& __x,
390                                           const valarray<_Tp>& __y) {
391  _STLP_ASSERT(__x.size() == __y.size())
392  typedef typename valarray<_Tp>::_NoInit _NoInit;
393  valarray<_Tp> __tmp(__x.size(), _NoInit());
394  for (size_t __i = 0; __i < __x.size(); ++__i)
395    __tmp[__i] = __x[__i] / __y[__i];
396  return __tmp;
397}
398
399template <class _Tp>
400inline valarray<_Tp>  _STLP_CALL operator%(const valarray<_Tp>& __x,
401                                           const valarray<_Tp>& __y) {
402  _STLP_ASSERT(__x.size() == __y.size())
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];
407  return __tmp;
408}
409
410template <class _Tp>
411inline valarray<_Tp>  _STLP_CALL operator+(const valarray<_Tp>& __x,
412                                           const valarray<_Tp>& __y) {
413  _STLP_ASSERT(__x.size() == __y.size())
414  typedef typename valarray<_Tp>::_NoInit _NoInit;
415  valarray<_Tp> __tmp(__x.size(), _NoInit());
416  for (size_t __i = 0; __i < __x.size(); ++__i)
417    __tmp[__i] = __x[__i] + __y[__i];
418  return __tmp;
419}
420
421template <class _Tp>
422inline valarray<_Tp>  _STLP_CALL operator-(const valarray<_Tp>& __x,
423                                           const valarray<_Tp>& __y) {
424  _STLP_ASSERT(__x.size() == __y.size())
425  typedef typename valarray<_Tp>::_NoInit _NoInit;
426  valarray<_Tp> __tmp(__x.size(), _NoInit());
427  for (size_t __i = 0; __i < __x.size(); ++__i)
428    __tmp[__i] = __x[__i] - __y[__i];
429  return __tmp;
430}
431
432template <class _Tp>
433inline valarray<_Tp> _STLP_CALL operator^(const valarray<_Tp>& __x,
434                                          const valarray<_Tp>& __y) {
435  _STLP_ASSERT(__x.size() == __y.size())
436  typedef typename valarray<_Tp>::_NoInit _NoInit;
437  valarray<_Tp> __tmp(__x.size(), _NoInit());
438  for (size_t __i = 0; __i < __x.size(); ++__i)
439    __tmp[__i] = __x[__i] ^ __y[__i];
440  return __tmp;
441}
442
443template <class _Tp>
444inline valarray<_Tp> _STLP_CALL operator&(const valarray<_Tp>& __x,
445                                          const valarray<_Tp>& __y) {
446  _STLP_ASSERT(__x.size() == __y.size())
447  typedef typename valarray<_Tp>::_NoInit _NoInit;
448  valarray<_Tp> __tmp(__x.size(), _NoInit());
449  for (size_t __i = 0; __i < __x.size(); ++__i)
450    __tmp[__i] = __x[__i] & __y[__i];
451  return __tmp;
452}
453
454template <class _Tp>
455inline valarray<_Tp> _STLP_CALL operator|(const valarray<_Tp>& __x,
456                                          const valarray<_Tp>& __y) {
457  _STLP_ASSERT(__x.size() == __y.size())
458  typedef typename valarray<_Tp>::_NoInit _NoInit;
459  valarray<_Tp> __tmp(__x.size(), _NoInit());
460  for (size_t __i = 0; __i < __x.size(); ++__i)
461    __tmp[__i] = __x[__i] | __y[__i];
462  return __tmp;
463}
464
465template <class _Tp>
466inline valarray<_Tp> _STLP_CALL operator<<(const valarray<_Tp>& __x,
467                                           const valarray<_Tp>& __y) {
468  _STLP_ASSERT(__x.size() == __y.size())
469  typedef typename valarray<_Tp>::_NoInit _NoInit;
470  valarray<_Tp> __tmp(__x.size(), _NoInit());
471  for (size_t __i = 0; __i < __x.size(); ++__i)
472    __tmp[__i] = __x[__i] << __y[__i];
473  return __tmp;
474}
475
476template <class _Tp>
477inline valarray<_Tp> _STLP_CALL operator>>(const valarray<_Tp>& __x,
478                                           const valarray<_Tp>& __y) {
479  _STLP_ASSERT(__x.size() == __y.size())
480  typedef typename valarray<_Tp>::_NoInit _NoInit;
481  valarray<_Tp> __tmp(__x.size(), _NoInit());
482  for (size_t __i = 0; __i < __x.size(); ++__i)
483    __tmp[__i] = __x[__i] >> __y[__i];
484  return __tmp;
485}
486
487// Binary arithmetic operations between an array and a scalar.
488
489template <class _Tp>
490inline valarray<_Tp> _STLP_CALL operator*(const valarray<_Tp>& __x, const _Tp& __c) {
491  typedef typename valarray<_Tp>::_NoInit _NoInit;
492  valarray<_Tp> __tmp(__x.size(), _NoInit());
493  for (size_t __i = 0; __i < __x.size(); ++__i)
494    __tmp[__i] = __x[__i]  * __c;
495  return __tmp;
496}
497
498template <class _Tp>
499inline valarray<_Tp> _STLP_CALL operator*(const _Tp& __c, const valarray<_Tp>& __x) {
500  typedef typename valarray<_Tp>::_NoInit _NoInit;
501  valarray<_Tp> __tmp(__x.size(), _NoInit());
502  for (size_t __i = 0; __i < __x.size(); ++__i)
503    __tmp[__i] = __c * __x[__i];
504  return __tmp;
505}
506
507template <class _Tp>
508inline valarray<_Tp> _STLP_CALL operator/(const valarray<_Tp>& __x, const _Tp& __c) {
509  typedef typename valarray<_Tp>::_NoInit _NoInit;
510  valarray<_Tp> __tmp(__x.size(), _NoInit());
511  for (size_t __i = 0; __i < __x.size(); ++__i)
512    __tmp[__i] = __x[__i]  / __c;
513  return __tmp;
514}
515
516template <class _Tp>
517inline valarray<_Tp> _STLP_CALL operator/(const _Tp& __c, const valarray<_Tp>& __x) {
518  typedef typename valarray<_Tp>::_NoInit _NoInit;
519  valarray<_Tp> __tmp(__x.size(), _NoInit());
520  for (size_t __i = 0; __i < __x.size(); ++__i)
521    __tmp[__i] = __c / __x[__i];
522  return __tmp;
523}
524
525template <class _Tp>
526inline valarray<_Tp> _STLP_CALL operator%(const valarray<_Tp>& __x, const _Tp& __c) {
527  typedef typename valarray<_Tp>::_NoInit _NoInit;
528  valarray<_Tp> __tmp(__x.size(), _NoInit());
529  for (size_t __i = 0; __i < __x.size(); ++__i)
530    __tmp[__i] = __x[__i]  % __c;
531  return __tmp;
532}
533
534template <class _Tp>
535inline valarray<_Tp> _STLP_CALL operator%(const _Tp& __c, const valarray<_Tp>& __x) {
536  typedef typename valarray<_Tp>::_NoInit _NoInit;
537  valarray<_Tp> __tmp(__x.size(), _NoInit());
538  for (size_t __i = 0; __i < __x.size(); ++__i)
539    __tmp[__i] = __c % __x[__i];
540  return __tmp;
541}
542
543template <class _Tp>
544inline valarray<_Tp> _STLP_CALL operator+(const valarray<_Tp>& __x, const _Tp& __c) {
545  typedef typename valarray<_Tp>::_NoInit _NoInit;
546  valarray<_Tp> __tmp(__x.size(), _NoInit());
547  for (size_t __i = 0; __i < __x.size(); ++__i)
548    __tmp[__i] = __x[__i]  + __c;
549  return __tmp;
550}
551
552template <class _Tp>
553inline valarray<_Tp> _STLP_CALL operator+(const _Tp& __c, const valarray<_Tp>& __x) {
554  typedef typename valarray<_Tp>::_NoInit _NoInit;
555  valarray<_Tp> __tmp(__x.size(), _NoInit());
556  for (size_t __i = 0; __i < __x.size(); ++__i)
557    __tmp[__i] = __c + __x[__i];
558  return __tmp;
559}
560
561template <class _Tp>
562inline valarray<_Tp> _STLP_CALL operator-(const valarray<_Tp>& __x, const _Tp& __c) {
563  typedef typename valarray<_Tp>::_NoInit _NoInit;
564  valarray<_Tp> __tmp(__x.size(), _NoInit());
565  for (size_t __i = 0; __i < __x.size(); ++__i)
566    __tmp[__i] = __x[__i]  - __c;
567  return __tmp;
568}
569
570template <class _Tp>
571inline valarray<_Tp> _STLP_CALL operator-(const _Tp& __c, const valarray<_Tp>& __x) {
572  typedef typename valarray<_Tp>::_NoInit _NoInit;
573  valarray<_Tp> __tmp(__x.size(), _NoInit());
574  for (size_t __i = 0; __i < __x.size(); ++__i)
575    __tmp[__i] = __c - __x[__i];
576  return __tmp;
577}
578
579template <class _Tp>
580inline valarray<_Tp> _STLP_CALL operator^(const valarray<_Tp>& __x, const _Tp& __c) {
581  typedef typename valarray<_Tp>::_NoInit _NoInit;
582  valarray<_Tp> __tmp(__x.size(), _NoInit());
583  for (size_t __i = 0; __i < __x.size(); ++__i)
584    __tmp[__i] = __x[__i]  ^ __c;
585  return __tmp;
586}
587
588template <class _Tp>
589inline valarray<_Tp> _STLP_CALL operator^(const _Tp& __c, const valarray<_Tp>& __x) {
590  typedef typename valarray<_Tp>::_NoInit _NoInit;
591  valarray<_Tp> __tmp(__x.size(), _NoInit());
592  for (size_t __i = 0; __i < __x.size(); ++__i)
593    __tmp[__i] = __c ^ __x[__i];
594  return __tmp;
595}
596
597template <class _Tp>
598inline valarray<_Tp> _STLP_CALL operator&(const valarray<_Tp>& __x, const _Tp& __c) {
599  typedef typename valarray<_Tp>::_NoInit _NoInit;
600  valarray<_Tp> __tmp(__x.size(), _NoInit());
601  for (size_t __i = 0; __i < __x.size(); ++__i)
602    __tmp[__i] = __x[__i]  & __c;
603  return __tmp;
604}
605
606template <class _Tp>
607inline valarray<_Tp> _STLP_CALL operator&(const _Tp& __c, const valarray<_Tp>& __x) {
608  typedef typename valarray<_Tp>::_NoInit _NoInit;
609  valarray<_Tp> __tmp(__x.size(), _NoInit());
610  for (size_t __i = 0; __i < __x.size(); ++__i)
611    __tmp[__i] = __c & __x[__i];
612  return __tmp;
613}
614
615template <class _Tp>
616inline valarray<_Tp> _STLP_CALL operator|(const valarray<_Tp>& __x, const _Tp& __c) {
617  typedef typename valarray<_Tp>::_NoInit _NoInit;
618  valarray<_Tp> __tmp(__x.size(), _NoInit());
619  for (size_t __i = 0; __i < __x.size(); ++__i)
620    __tmp[__i] = __x[__i]  | __c;
621  return __tmp;
622}
623
624template <class _Tp>
625inline valarray<_Tp> _STLP_CALL operator|(const _Tp& __c, const valarray<_Tp>& __x) {
626  typedef typename valarray<_Tp>::_NoInit _NoInit;
627  valarray<_Tp> __tmp(__x.size(), _NoInit());
628  for (size_t __i = 0; __i < __x.size(); ++__i)
629    __tmp[__i] = __c | __x[__i];
630  return __tmp;
631}
632
633template <class _Tp>
634inline valarray<_Tp> _STLP_CALL operator<<(const valarray<_Tp>& __x, const _Tp& __c) {
635  typedef typename valarray<_Tp>::_NoInit _NoInit;
636  valarray<_Tp> __tmp(__x.size(), _NoInit());
637  for (size_t __i = 0; __i < __x.size(); ++__i)
638    __tmp[__i] = __x[__i]  << __c;
639  return __tmp;
640}
641
642template <class _Tp>
643inline valarray<_Tp> _STLP_CALL operator<<(const _Tp& __c, const valarray<_Tp>& __x) {
644  typedef typename valarray<_Tp>::_NoInit _NoInit;
645  valarray<_Tp> __tmp(__x.size(), _NoInit());
646  for (size_t __i = 0; __i < __x.size(); ++__i)
647    __tmp[__i] = __c << __x[__i];
648  return __tmp;
649}
650
651template <class _Tp>
652inline valarray<_Tp> _STLP_CALL operator>>(const valarray<_Tp>& __x, const _Tp& __c) {
653  typedef typename valarray<_Tp>::_NoInit _NoInit;
654  valarray<_Tp> __tmp(__x.size(), _NoInit());
655  for (size_t __i = 0; __i < __x.size(); ++__i)
656    __tmp[__i] = __x[__i]  >> __c;
657  return __tmp;
658}
659
660template <class _Tp>
661inline valarray<_Tp> _STLP_CALL operator>>(const _Tp& __c, const valarray<_Tp>& __x) {
662  typedef typename valarray<_Tp>::_NoInit _NoInit;
663  valarray<_Tp> __tmp(__x.size(), _NoInit());
664  for (size_t __i = 0; __i < __x.size(); ++__i)
665    __tmp[__i] = __c >> __x[__i];
666  return __tmp;
667}
668
669// Binary logical operations between two arrays.  Behavior is undefined
670// if the two arrays have different lengths.  Note that operator== does
671// not do what you might at first expect.
672
673template <class _Tp>
674inline _Valarray_bool _STLP_CALL operator==(const valarray<_Tp>& __x,
675                                            const valarray<_Tp>& __y) {
676  _STLP_ASSERT(__x.size() == __y.size())
677  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
678  for (size_t __i = 0; __i < __x.size(); ++__i)
679    __tmp[__i] = __x[__i] == __y[__i];
680  return __tmp;
681}
682
683template <class _Tp>
684inline _Valarray_bool _STLP_CALL operator<(const valarray<_Tp>& __x,
685                                           const valarray<_Tp>& __y) {
686  _STLP_ASSERT(__x.size() == __y.size())
687  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
688  for (size_t __i = 0; __i < __x.size(); ++__i)
689    __tmp[__i] = __x[__i] < __y[__i];
690  return __tmp;
691}
692
693#ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE
694
695template <class _Tp>
696inline _Valarray_bool _STLP_CALL operator!=(const valarray<_Tp>& __x,
697                                            const valarray<_Tp>& __y) {
698  _STLP_ASSERT(__x.size() == __y.size())
699  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
700  for (size_t __i = 0; __i < __x.size(); ++__i)
701    __tmp[__i] = __x[__i] != __y[__i];
702  return __tmp;
703}
704
705template <class _Tp>
706inline _Valarray_bool _STLP_CALL operator>(const valarray<_Tp>& __x,
707                                           const valarray<_Tp>& __y) {
708  _STLP_ASSERT(__x.size() == __y.size())
709  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
710  for (size_t __i = 0; __i < __x.size(); ++__i)
711    __tmp[__i] = __x[__i] > __y[__i];
712  return __tmp;
713}
714
715template <class _Tp>
716inline _Valarray_bool _STLP_CALL operator<=(const valarray<_Tp>& __x,
717                                            const valarray<_Tp>& __y) {
718  _STLP_ASSERT(__x.size() == __y.size())
719  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
720  for (size_t __i = 0; __i < __x.size(); ++__i)
721    __tmp[__i] = __x[__i] <= __y[__i];
722  return __tmp;
723}
724
725template <class _Tp>
726inline _Valarray_bool _STLP_CALL operator>=(const valarray<_Tp>& __x,
727                                            const valarray<_Tp>& __y) {
728  _STLP_ASSERT(__x.size() == __y.size())
729  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
730  for (size_t __i = 0; __i < __x.size(); ++__i)
731    __tmp[__i] = __x[__i] >= __y[__i];
732  return __tmp;
733}
734
735#endif /* _STLP_USE_SEPARATE_RELOPS_NAMESPACE */
736// fbp : swap ?
737
738template <class _Tp>
739inline _Valarray_bool _STLP_CALL operator&&(const valarray<_Tp>& __x,
740                                            const valarray<_Tp>& __y) {
741  _STLP_ASSERT(__x.size() == __y.size())
742  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
743  for (size_t __i = 0; __i < __x.size(); ++__i)
744    __tmp[__i] = __x[__i] && __y[__i];
745  return __tmp;
746}
747
748template <class _Tp>
749inline _Valarray_bool _STLP_CALL operator||(const valarray<_Tp>& __x,
750                                            const valarray<_Tp>& __y) {
751  _STLP_ASSERT(__x.size() == __y.size())
752  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
753  for (size_t __i = 0; __i < __x.size(); ++__i)
754    __tmp[__i] = __x[__i] || __y[__i];
755  return __tmp;
756}
757
758// Logical operations between an array and a scalar.
759
760template <class _Tp>
761inline _Valarray_bool _STLP_CALL operator==(const valarray<_Tp>& __x, const _Tp& __c) {
762  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
763  for (size_t __i = 0; __i < __x.size(); ++__i)
764    __tmp[__i] = __x[__i] == __c;
765  return __tmp;
766}
767
768template <class _Tp>
769inline _Valarray_bool _STLP_CALL operator==(const _Tp& __c, const valarray<_Tp>& __x) {
770  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
771  for (size_t __i = 0; __i < __x.size(); ++__i)
772    __tmp[__i] = __c == __x[__i];
773  return __tmp;
774}
775
776template <class _Tp>
777inline _Valarray_bool _STLP_CALL operator!=(const valarray<_Tp>& __x, const _Tp& __c) {
778  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
779  for (size_t __i = 0; __i < __x.size(); ++__i)
780    __tmp[__i] = __x[__i] != __c;
781  return __tmp;
782}
783
784template <class _Tp>
785inline _Valarray_bool _STLP_CALL operator!=(const _Tp& __c, const valarray<_Tp>& __x) {
786  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
787  for (size_t __i = 0; __i < __x.size(); ++__i)
788    __tmp[__i] = __c != __x[__i];
789  return __tmp;
790}
791
792template <class _Tp>
793inline _Valarray_bool _STLP_CALL operator<(const valarray<_Tp>& __x, const _Tp& __c) {
794  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
795  for (size_t __i = 0; __i < __x.size(); ++__i)
796    __tmp[__i] = __x[__i] < __c;
797  return __tmp;
798}
799
800template <class _Tp>
801inline _Valarray_bool _STLP_CALL operator<(const _Tp& __c, const valarray<_Tp>& __x) {
802  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
803  for (size_t __i = 0; __i < __x.size(); ++__i)
804    __tmp[__i] = __c < __x[__i];
805  return __tmp;
806}
807
808template <class _Tp>
809inline _Valarray_bool _STLP_CALL operator>(const valarray<_Tp>& __x, const _Tp& __c) {
810  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
811  for (size_t __i = 0; __i < __x.size(); ++__i)
812    __tmp[__i] = __x[__i] > __c;
813  return __tmp;
814}
815
816template <class _Tp>
817inline _Valarray_bool _STLP_CALL operator>(const _Tp& __c, const valarray<_Tp>& __x) {
818  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
819  for (size_t __i = 0; __i < __x.size(); ++__i)
820    __tmp[__i] = __c > __x[__i];
821  return __tmp;
822}
823
824template <class _Tp>
825inline _Valarray_bool _STLP_CALL operator<=(const valarray<_Tp>& __x, const _Tp& __c) {
826  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
827  for (size_t __i = 0; __i < __x.size(); ++__i)
828    __tmp[__i] = __x[__i]  <= __c;
829  return __tmp;
830}
831
832template <class _Tp>
833inline _Valarray_bool _STLP_CALL operator<=(const _Tp& __c, const valarray<_Tp>& __x) {
834  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
835  for (size_t __i = 0; __i < __x.size(); ++__i)
836    __tmp[__i] = __c <= __x[__i];
837  return __tmp;
838}
839
840template <class _Tp>
841inline _Valarray_bool _STLP_CALL operator>=(const valarray<_Tp>& __x, const _Tp& __c) {
842  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
843  for (size_t __i = 0; __i < __x.size(); ++__i)
844    __tmp[__i] = __x[__i] >= __c;
845  return __tmp;
846}
847
848template <class _Tp>
849inline _Valarray_bool _STLP_CALL operator>=(const _Tp& __c, const valarray<_Tp>& __x) {
850  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
851  for (size_t __i = 0; __i < __x.size(); ++__i)
852    __tmp[__i] = __c >= __x[__i];
853  return __tmp;
854}
855
856template <class _Tp>
857inline _Valarray_bool _STLP_CALL operator&&(const valarray<_Tp>& __x, const _Tp& __c) {
858  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
859  for (size_t __i = 0; __i < __x.size(); ++__i)
860    __tmp[__i] = __x[__i] && __c;
861  return __tmp;
862}
863
864template <class _Tp>
865inline _Valarray_bool _STLP_CALL operator&&(const _Tp& __c, const valarray<_Tp>& __x) {
866  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
867  for (size_t __i = 0; __i < __x.size(); ++__i)
868    __tmp[__i] = __c && __x[__i];
869  return __tmp;
870}
871
872template <class _Tp>
873inline _Valarray_bool _STLP_CALL operator||(const valarray<_Tp>& __x, const _Tp& __c) {
874  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
875  for (size_t __i = 0; __i < __x.size(); ++__i)
876    __tmp[__i] = __x[__i] || __c;
877  return __tmp;
878}
879
880template <class _Tp>
881inline _Valarray_bool _STLP_CALL operator||(const _Tp& __c, const valarray<_Tp>& __x) {
882  _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
883  for (size_t __i = 0; __i < __x.size(); ++__i)
884    __tmp[__i] = __c || __x[__i];
885  return __tmp;
886}
887
888// valarray "transcendentals" (the list includes abs and sqrt, which,
889// of course, are not transcendental).
890
891template <class _Tp>
892inline valarray<_Tp> abs(const valarray<_Tp>& __x) {
893  typedef typename valarray<_Tp>::_NoInit _NoInit;
894  valarray<_Tp> __tmp(__x.size(), _NoInit());
895  for (size_t __i = 0; __i < __x.size(); ++__i)
896    __tmp[__i] = ::abs(__x[__i]);
897  return __tmp;
898}
899
900template <class _Tp>
901inline valarray<_Tp> acos(const valarray<_Tp>& __x) {
902  typedef typename valarray<_Tp>::_NoInit _NoInit;
903  valarray<_Tp> __tmp(__x.size(), _NoInit());
904  for (size_t __i = 0; __i < __x.size(); ++__i)
905    __tmp[__i] = ::acos(__x[__i]);
906  return __tmp;
907}
908
909template <class _Tp>
910inline valarray<_Tp> asin(const valarray<_Tp>& __x) {
911  typedef typename valarray<_Tp>::_NoInit _NoInit;
912  valarray<_Tp> __tmp(__x.size(), _NoInit());
913  for (size_t __i = 0; __i < __x.size(); ++__i)
914    __tmp[__i] = ::asin(__x[__i]);
915  return __tmp;
916}
917
918template <class _Tp>
919inline valarray<_Tp> atan(const valarray<_Tp>& __x) {
920  typedef typename valarray<_Tp>::_NoInit _NoInit;
921  valarray<_Tp> __tmp(__x.size(), _NoInit());
922  for (size_t __i = 0; __i < __x.size(); ++__i)
923    __tmp[__i] = ::atan(__x[__i]);
924  return __tmp;
925}
926
927template <class _Tp>
928inline valarray<_Tp> atan2(const valarray<_Tp>& __x,
929                           const valarray<_Tp>& __y) {
930  typedef typename valarray<_Tp>::_NoInit _NoInit;
931  valarray<_Tp> __tmp(__x.size(), _NoInit());
932  for (size_t __i = 0; __i < __x.size(); ++__i)
933    __tmp[__i] = ::atan2(__x[__i], __y[__i]);
934  return __tmp;
935}
936
937template <class _Tp>
938inline valarray<_Tp> atan2(const valarray<_Tp>& __x, const _Tp& __c) {
939  typedef typename valarray<_Tp>::_NoInit _NoInit;
940  valarray<_Tp> __tmp(__x.size(), _NoInit());
941  for (size_t __i = 0; __i < __x.size(); ++__i)
942    __tmp[__i] = ::atan2(__x[__i], __c);
943  return __tmp;
944}
945
946template <class _Tp>
947inline valarray<_Tp> atan2(const _Tp& __c, const valarray<_Tp>& __x) {
948  typedef typename valarray<_Tp>::_NoInit _NoInit;
949  valarray<_Tp> __tmp(__x.size(), _NoInit());
950  for (size_t __i = 0; __i < __x.size(); ++__i)
951    __tmp[__i] = ::atan2(__c, __x[__i]);
952  return __tmp;
953}
954
955template <class _Tp>
956inline valarray<_Tp> cos(const valarray<_Tp>& __x) {
957  typedef typename valarray<_Tp>::_NoInit _NoInit;
958  valarray<_Tp> __tmp(__x.size(), _NoInit());
959  for (size_t __i = 0; __i < __x.size(); ++__i)
960    __tmp[__i] = ::cos(__x[__i]);
961  return __tmp;
962}
963
964template <class _Tp>
965inline valarray<_Tp> cosh(const valarray<_Tp>& __x) {
966  typedef typename valarray<_Tp>::_NoInit _NoInit;
967  valarray<_Tp> __tmp(__x.size(), _NoInit());
968  for (size_t __i = 0; __i < __x.size(); ++__i)
969    __tmp[__i] = ::cosh(__x[__i]);
970  return __tmp;
971}
972
973template <class _Tp>
974inline valarray<_Tp> exp(const valarray<_Tp>& __x) {
975  typedef typename valarray<_Tp>::_NoInit _NoInit;
976  valarray<_Tp> __tmp(__x.size(), _NoInit());
977  for (size_t __i = 0; __i < __x.size(); ++__i)
978    __tmp[__i] = ::exp(__x[__i]);
979  return __tmp;
980}
981
982template <class _Tp>
983inline valarray<_Tp> log(const valarray<_Tp>& __x) {
984  typedef typename valarray<_Tp>::_NoInit _NoInit;
985  valarray<_Tp> __tmp(__x.size(), _NoInit());
986  for (size_t __i = 0; __i < __x.size(); ++__i)
987    __tmp[__i] = ::log(__x[__i]);
988  return __tmp;
989}
990
991template <class _Tp>
992inline valarray<_Tp> log10(const valarray<_Tp>& __x) {
993  typedef typename valarray<_Tp>::_NoInit _NoInit;
994  valarray<_Tp> __tmp(__x.size(), _NoInit());
995  for (size_t __i = 0; __i < __x.size(); ++__i)
996    __tmp[__i] = ::log10(__x[__i]);
997  return __tmp;
998}
999
1000template <class _Tp>
1001inline valarray<_Tp> pow(const valarray<_Tp>& __x,
1002                         const valarray<_Tp>& __y) {
1003  typedef typename valarray<_Tp>::_NoInit _NoInit;
1004  valarray<_Tp> __tmp(__x.size(), _NoInit());
1005  for (size_t __i = 0; __i < __x.size(); ++__i)
1006    __tmp[__i] = ::pow(__x[__i], __y[__i]);
1007  return __tmp;
1008}
1009
1010template <class _Tp>
1011inline valarray<_Tp> pow(const valarray<_Tp>& __x, const _Tp& __c) {
1012  typedef typename valarray<_Tp>::_NoInit _NoInit;
1013  valarray<_Tp> __tmp(__x.size(), _NoInit());
1014  for (size_t __i = 0; __i < __x.size(); ++__i)
1015    __tmp[__i] = ::pow(__x[__i], __c);
1016  return __tmp;
1017}
1018
1019template <class _Tp>
1020inline valarray<_Tp> pow(const _Tp& __c, const valarray<_Tp>& __x) {
1021  typedef typename valarray<_Tp>::_NoInit _NoInit;
1022  valarray<_Tp> __tmp(__x.size(), _NoInit());
1023  for (size_t __i = 0; __i < __x.size(); ++__i)
1024    __tmp[__i] = ::pow(__c, __x[__i]);
1025  return __tmp;
1026}
1027
1028template <class _Tp>
1029inline valarray<_Tp> sin(const valarray<_Tp>& __x) {
1030  typedef typename valarray<_Tp>::_NoInit _NoInit;
1031  valarray<_Tp> __tmp(__x.size(), _NoInit());
1032  for (size_t __i = 0; __i < __x.size(); ++__i)
1033    __tmp[__i] = ::sin(__x[__i]);
1034  return __tmp;
1035}
1036
1037template <class _Tp>
1038inline valarray<_Tp> sinh(const valarray<_Tp>& __x) {
1039  typedef typename valarray<_Tp>::_NoInit _NoInit;
1040  valarray<_Tp> __tmp(__x.size(), _NoInit());
1041  for (size_t __i = 0; __i < __x.size(); ++__i)
1042    __tmp[__i] = ::sinh(__x[__i]);
1043  return __tmp;
1044}
1045
1046template <class _Tp>
1047inline valarray<_Tp> sqrt(const valarray<_Tp>& __x) {
1048  typedef typename valarray<_Tp>::_NoInit _NoInit;
1049  valarray<_Tp> __tmp(__x.size(), _NoInit());
1050  for (size_t __i = 0; __i < __x.size(); ++__i)
1051    __tmp[__i] = ::sqrt(__x[__i]);
1052  return __tmp;
1053}
1054
1055template <class _Tp>
1056inline valarray<_Tp> tan(const valarray<_Tp>& __x) {
1057  typedef typename valarray<_Tp>::_NoInit _NoInit;
1058  valarray<_Tp> __tmp(__x.size(), _NoInit());
1059  for (size_t __i = 0; __i < __x.size(); ++__i)
1060    __tmp[__i] = ::tan(__x[__i]);
1061  return __tmp;
1062}
1063
1064template <class _Tp>
1065inline valarray<_Tp> tanh(const valarray<_Tp>& __x) {
1066  typedef typename valarray<_Tp>::_NoInit _NoInit;
1067  valarray<_Tp> __tmp(__x.size(), _NoInit());
1068  for (size_t __i = 0; __i < __x.size(); ++__i)
1069    __tmp[__i] = ::tanh(__x[__i]);
1070  return __tmp;
1071}
1072
1073//----------------------------------------------------------------------
1074// slice and slice_array
1075
1076class slice {
1077public:
1078  slice() : _M_start(0), _M_length(0), _M_stride(0) {}
1079  slice(size_t __start, size_t __length, size_t __stride)
1080    : _M_start(__start), _M_length(__length), _M_stride(__stride)
1081    {}
1082  __TRIVIAL_DESTRUCTOR(slice)
1083
1084  size_t start()  const { return _M_start; }
1085  size_t size()   const { return _M_length; }
1086  size_t stride() const { return _M_stride; }
1087
1088private:
1089  size_t _M_start;
1090  size_t _M_length;
1091  size_t _M_stride;
1092};
1093
1094template <class _Tp>
1095class slice_array {
1096  friend class valarray<_Tp>;
1097public:
1098  typedef _Tp value_type;
1099
1100  void operator=(const valarray<value_type>& __x) const {
1101    size_t __index = _M_slice.start();
1102    for (size_t __i = 0;
1103         __i < _M_slice.size();
1104         ++__i, __index += _M_slice.stride())
1105      _M_array[__index] = __x[__i];
1106  }
1107
1108  void operator*=(const valarray<value_type>& __x) const {
1109    size_t __index = _M_slice.start();
1110    for (size_t __i = 0;
1111         __i < _M_slice.size();
1112         ++__i, __index += _M_slice.stride())
1113      _M_array[__index] *= __x[__i];
1114  }
1115
1116  void operator/=(const valarray<value_type>& __x) const {
1117    size_t __index = _M_slice.start();
1118    for (size_t __i = 0;
1119         __i < _M_slice.size();
1120         ++__i, __index += _M_slice.stride())
1121      _M_array[__index] /= __x[__i];
1122  }
1123
1124  void operator%=(const valarray<value_type>& __x) const {
1125    size_t __index = _M_slice.start();
1126    for (size_t __i = 0;
1127         __i < _M_slice.size();
1128         ++__i, __index += _M_slice.stride())
1129      _M_array[__index] %= __x[__i];
1130  }
1131
1132  void operator+=(const valarray<value_type>& __x) const {
1133    size_t __index = _M_slice.start();
1134    for (size_t __i = 0;
1135         __i < _M_slice.size();
1136         ++__i, __index += _M_slice.stride())
1137      _M_array[__index] += __x[__i];
1138  }
1139
1140  void operator-=(const valarray<value_type>& __x) const {
1141    size_t __index = _M_slice.start();
1142    for (size_t __i = 0;
1143         __i < _M_slice.size();
1144         ++__i, __index += _M_slice.stride())
1145      _M_array[__index] -= __x[__i];
1146  }
1147
1148  void operator^=(const valarray<value_type>& __x) const {
1149    size_t __index = _M_slice.start();
1150    for (size_t __i = 0;
1151         __i < _M_slice.size();
1152         ++__i, __index += _M_slice.stride())
1153      _M_array[__index] ^= __x[__i];
1154  }
1155
1156  void operator&=(const valarray<value_type>& __x) const {
1157    size_t __index = _M_slice.start();
1158    for (size_t __i = 0;
1159         __i < _M_slice.size();
1160         ++__i, __index += _M_slice.stride())
1161      _M_array[__index] &= __x[__i];
1162  }
1163
1164  void operator|=(const valarray<value_type>& __x) const {
1165    size_t __index = _M_slice.start();
1166    for (size_t __i = 0;
1167         __i < _M_slice.size();
1168         ++__i, __index += _M_slice.stride())
1169      _M_array[__index] |= __x[__i];
1170  }
1171
1172  void operator<<=(const valarray<value_type>& __x) const {
1173    size_t __index = _M_slice.start();
1174    for (size_t __i = 0;
1175         __i < _M_slice.size();
1176         ++__i, __index += _M_slice.stride())
1177      _M_array[__index] <<= __x[__i];
1178  }
1179
1180  void operator>>=(const valarray<value_type>& __x) const {
1181    size_t __index = _M_slice.start();
1182    for (size_t __i = 0;
1183         __i < _M_slice.size();
1184         ++__i, __index += _M_slice.stride())
1185      _M_array[__index] >>= __x[__i];
1186  }
1187
1188  void operator=(const value_type& __c) /*const could be const but standard says NO (26.3.5.4-1)*/ {
1189    size_t __index = _M_slice.start();
1190    for (size_t __i = 0;
1191         __i < _M_slice.size();
1192         ++__i, __index += _M_slice.stride())
1193      _M_array[__index] = __c;
1194  }
1195
1196  // C++ Standard defect 253, copy constructor must be public.
1197  slice_array(const slice_array &__x)
1198    : _M_slice(__x._M_slice), _M_array(__x._M_array)
1199    {}
1200
1201  ~slice_array() {}
1202
1203private:
1204  slice_array(const slice& __slice, valarray<_Tp> &__array)
1205    : _M_slice(__slice), _M_array(__array)
1206    {}
1207
1208  slice          _M_slice;
1209  valarray<_Tp>& _M_array;
1210
1211private:
1212  // Disable default constructor and assignment
1213  slice_array();
1214  slice_array& operator=(const slice_array&);
1215};
1216
1217// valarray member functions dealing with slice and slice_array
1218
1219template <class _Tp>
1220inline valarray<_Tp>::valarray(const slice_array<_Tp>& __x)
1221  : _Valarray_base<_Tp>(__x._M_slice.size()) {
1222  typedef typename __type_traits<_Tp>::has_trivial_default_constructor
1223          _Is_Trivial;
1224  _M_initialize(_Is_Trivial());
1225  *this = __x;
1226}
1227
1228
1229template <class _Tp>
1230inline slice_array<_Tp> valarray<_Tp>::operator[](slice __slice)
1231{ return slice_array<_Tp>(__slice, *this); }
1232
1233//----------------------------------------------------------------------
1234// gslice and gslice_array
1235
1236template <class _Size>
1237struct _Gslice_Iter_tmpl;
1238
1239class gslice {
1240  friend struct _Gslice_Iter_tmpl<size_t>;
1241public:
1242  gslice() : _M_start(0), _M_lengths(), _M_strides() {}
1243  gslice(size_t __start,
1244         const _Valarray_size_t& __lengths, const _Valarray_size_t& __strides)
1245    : _M_start(__start), _M_lengths(__lengths), _M_strides(__strides)
1246    {}
1247  __TRIVIAL_DESTRUCTOR(gslice)
1248
1249  size_t start()            const { return _M_start; }
1250  _Valarray_size_t size()   const { return _M_lengths; }
1251  _Valarray_size_t stride() const { return _M_strides; }
1252
1253  // Extension: check for an empty gslice.
1254  bool _M_empty() const { return _M_lengths.size() == 0; }
1255
1256  // Extension: number of indices this gslice represents.  (For a degenerate
1257  // gslice, they're not necessarily all distinct.)
1258  size_t _M_size() const {
1259    return !this->_M_empty()
1260      ? accumulate(_M_lengths._M_first + 1,
1261                   _M_lengths._M_first + _M_lengths._M_size,
1262                   _M_lengths[0],
1263                   multiplies<size_t>())
1264      : 0;
1265  }
1266
1267# ifndef __HP_aCC
1268private:
1269# endif
1270
1271  size_t _M_start;
1272  _Valarray_size_t _M_lengths;
1273  _Valarray_size_t _M_strides;
1274};
1275
1276// This is not an STL iterator.  It is constructed from a gslice, and it
1277// steps through the gslice indices in sequence.  See 23.3.6 of the C++
1278// standard, paragraphs 2-3, for an explanation of the sequence.  At
1279// each step we get two things: the ordinal (i.e. number of steps taken),
1280// and the one-dimensional index.
1281
1282template <class _Size>
1283struct _Gslice_Iter_tmpl {
1284  _Gslice_Iter_tmpl(const gslice& __gslice)
1285    : _M_step(0), _M_1d_idx(__gslice.start()),
1286      _M_indices(size_t(0), __gslice._M_lengths.size()),
1287      _M_gslice(__gslice)
1288    {}
1289
1290  bool _M_done() const { return _M_indices[0] == _M_gslice._M_lengths[0]; }
1291
1292  bool _M_incr();
1293
1294  _Size _M_step;
1295  _Size _M_1d_idx;
1296
1297  valarray<_Size> _M_indices;
1298  const gslice& _M_gslice;
1299};
1300
1301typedef _Gslice_Iter_tmpl<size_t> _Gslice_Iter;
1302
1303template <class _Tp>
1304class gslice_array {
1305  friend class valarray<_Tp>;
1306public:
1307  typedef _Tp value_type;
1308
1309  void operator= (const valarray<value_type>& __x) const {
1310    if (!_M_gslice._M_empty()) {
1311      _Gslice_Iter __i(_M_gslice);
1312      do _M_array[__i._M_1d_idx] = __x[__i._M_step]; while(__i._M_incr());
1313    }
1314  }
1315
1316  void operator*= (const valarray<value_type>& __x) const {
1317    if (!_M_gslice._M_empty()) {
1318      _Gslice_Iter __i(_M_gslice);
1319      do _M_array[__i._M_1d_idx] *= __x[__i._M_step]; while(__i._M_incr());
1320    }
1321  }
1322
1323  void operator/= (const valarray<value_type>& __x) const {
1324    if (!_M_gslice._M_empty()) {
1325      _Gslice_Iter __i(_M_gslice);
1326      do _M_array[__i._M_1d_idx] /= __x[__i._M_step]; while(__i._M_incr());
1327    }
1328  }
1329
1330  void operator%= (const valarray<value_type>& __x) const {
1331    if (!_M_gslice._M_empty()) {
1332      _Gslice_Iter __i(_M_gslice);
1333      do _M_array[__i._M_1d_idx] %= __x[__i._M_step]; while(__i._M_incr());
1334    }
1335  }
1336
1337  void operator+= (const valarray<value_type>& __x) const {
1338    if (!_M_gslice._M_empty()) {
1339      _Gslice_Iter __i(_M_gslice);
1340      do _M_array[__i._M_1d_idx] += __x[__i._M_step]; while(__i._M_incr());
1341    }
1342  }
1343
1344  void operator-= (const valarray<value_type>& __x) const {
1345    if (!_M_gslice._M_empty()) {
1346      _Gslice_Iter __i(_M_gslice);
1347      do _M_array[__i._M_1d_idx] -= __x[__i._M_step]; while(__i._M_incr());
1348    }
1349  }
1350
1351  void operator^= (const valarray<value_type>& __x) const {
1352    if (!_M_gslice._M_empty()) {
1353      _Gslice_Iter __i(_M_gslice);
1354      do _M_array[__i._M_1d_idx] ^= __x[__i._M_step]; while(__i._M_incr());
1355    }
1356  }
1357
1358  void operator&= (const valarray<value_type>& __x) const {
1359    if (!_M_gslice._M_empty()) {
1360      _Gslice_Iter __i(_M_gslice);
1361      do _M_array[__i._M_1d_idx] &= __x[__i._M_step]; while(__i._M_incr());
1362    }
1363  }
1364
1365  void operator|= (const valarray<value_type>& __x) const {
1366    if (!_M_gslice._M_empty()) {
1367      _Gslice_Iter __i(_M_gslice);
1368      do _M_array[__i._M_1d_idx] |= __x[__i._M_step]; while(__i._M_incr());
1369    }
1370  }
1371
1372  void operator<<= (const valarray<value_type>& __x) const {
1373    if (!_M_gslice._M_empty()) {
1374      _Gslice_Iter __i(_M_gslice);
1375      do _M_array[__i._M_1d_idx] <<= __x[__i._M_step]; while(__i._M_incr());
1376    }
1377  }
1378
1379  void operator>>= (const valarray<value_type>& __x) const {
1380    if (!_M_gslice._M_empty()) {
1381      _Gslice_Iter __i(_M_gslice);
1382      do _M_array[__i._M_1d_idx] >>= __x[__i._M_step]; while(__i._M_incr());
1383    }
1384  }
1385
1386  void operator= (const value_type& __c) /*const could be const but standard says NO (26.3.7.4-1)*/ {
1387    if (!_M_gslice._M_empty()) {
1388      _Gslice_Iter __i(_M_gslice);
1389      do _M_array[__i._M_1d_idx] = __c; while(__i._M_incr());
1390    }
1391  }
1392
1393  // C++ Standard defect 253, copy constructor must be public.
1394  gslice_array(const gslice_array& __x)
1395    : _M_gslice(__x._M_gslice), _M_array(__x._M_array)
1396    {}
1397
1398  ~gslice_array() {}
1399
1400private:
1401  gslice_array(const gslice &__gslice, valarray<_Tp> &__array)
1402    : _M_gslice(__gslice), _M_array(__array)
1403    {}
1404
1405  gslice                _M_gslice;
1406  valarray<value_type>& _M_array;
1407
1408private:
1409  // Disable default constructor and assignment
1410  gslice_array();
1411  void operator=(const gslice_array<_Tp>&);
1412};
1413
1414// valarray member functions dealing with gslice and gslice_array.  Note
1415// that it is illegal (behavior is undefined) to construct a gslice_array
1416// from a degenerate gslice.
1417
1418template <class _Tp>
1419inline valarray<_Tp>::valarray(const gslice_array<_Tp>& __x)
1420  : _Valarray_base<_Tp>(__x._M_gslice._M_size()) {
1421  typedef typename __type_traits<_Tp>::has_trivial_default_constructor
1422          _Is_Trivial;
1423  _M_initialize(_Is_Trivial());
1424  *this = __x;
1425}
1426
1427template <class _Tp>
1428inline gslice_array<_Tp> valarray<_Tp>::operator[](const gslice& __slice)
1429{ return gslice_array<_Tp>(__slice, *this); }
1430
1431
1432//----------------------------------------------------------------------
1433// mask_array
1434
1435template <class _Tp>
1436class mask_array {
1437  friend class valarray<_Tp>;
1438public:
1439  typedef _Tp value_type;
1440
1441  void operator=(const valarray<value_type>& __x) const {
1442    size_t __idx = 0;
1443    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1444      if (_M_mask[__i]) _M_array[__i] = __x[__idx++];
1445  }
1446
1447  void operator*=(const valarray<value_type>& __x) const {
1448    size_t __idx = 0;
1449    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1450      if (_M_mask[__i]) _M_array[__i] *= __x[__idx++];
1451  }
1452
1453  void operator/=(const valarray<value_type>& __x) const {
1454    size_t __idx = 0;
1455    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1456      if (_M_mask[__i]) _M_array[__i] /= __x[__idx++];
1457  }
1458
1459  void operator%=(const valarray<value_type>& __x) const {
1460    size_t __idx = 0;
1461    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1462      if (_M_mask[__i]) _M_array[__i] %= __x[__idx++];
1463  }
1464
1465  void operator+=(const valarray<value_type>& __x) const {
1466    size_t __idx = 0;
1467    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1468      if (_M_mask[__i]) _M_array[__i] += __x[__idx++];
1469  }
1470
1471  void operator-=(const valarray<value_type>& __x) const {
1472    size_t __idx = 0;
1473    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1474      if (_M_mask[__i]) _M_array[__i] -= __x[__idx++];
1475  }
1476
1477  void operator^=(const valarray<value_type>& __x) const {
1478    size_t __idx = 0;
1479    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1480      if (_M_mask[__i]) _M_array[__i] ^= __x[__idx++];
1481  }
1482
1483  void operator&=(const valarray<value_type>& __x) const {
1484    size_t __idx = 0;
1485    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1486      if (_M_mask[__i]) _M_array[__i] &= __x[__idx++];
1487  }
1488
1489  void operator|=(const valarray<value_type>& __x) const {
1490    size_t __idx = 0;
1491    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1492      if (_M_mask[__i]) _M_array[__i] |= __x[__idx++];
1493  }
1494
1495  void operator<<=(const valarray<value_type>& __x) const {
1496    size_t __idx = 0;
1497    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1498      if (_M_mask[__i]) _M_array[__i] <<= __x[__idx++];
1499  }
1500
1501  void operator>>=(const valarray<value_type>& __x) const {
1502    size_t __idx = 0;
1503    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1504      if (_M_mask[__i]) _M_array[__i] >>= __x[__idx++];
1505  }
1506
1507  void operator=(const value_type& __c) const {
1508    for (size_t __i = 0; __i < _M_array.size(); ++__i)
1509      if (_M_mask[__i]) _M_array[__i] = __c;
1510  }
1511
1512  // Extension: number of true values in the mask
1513  size_t _M_num_true() const {
1514    size_t __result = 0;
1515    for (size_t __i = 0; __i < _M_mask.size(); ++__i)
1516      if (_M_mask[__i]) ++__result;
1517    return __result;
1518  }
1519
1520  // C++ Standard defect 253, copy constructor must be public.
1521  mask_array(const mask_array& __x)
1522    : _M_mask(__x._M_mask), _M_array(__x._M_array)
1523    {}
1524
1525  ~mask_array() {}
1526
1527private:
1528  mask_array(const _Valarray_bool& __mask, valarray<_Tp>& __array)
1529    : _M_mask(__mask), _M_array(__array)
1530    {}
1531  _Valarray_bool _M_mask;
1532  valarray<_Tp>& _M_array;
1533
1534private:
1535  // Disable default constructor and assignment
1536  mask_array();
1537  void operator=(const mask_array<_Tp>&);
1538};
1539
1540// valarray member functions dealing with mask_array
1541
1542template <class _Tp>
1543inline valarray<_Tp>::valarray(const mask_array<_Tp>& __x)
1544  : _Valarray_base<_Tp>(__x._M_num_true()) {
1545  typedef typename __type_traits<_Tp>::has_trivial_default_constructor
1546          _Is_Trivial;
1547  _M_initialize(_Is_Trivial());
1548  *this = __x;
1549}
1550
1551// Behavior is undefined if __x._M_num_true() != this->size()
1552template <class _Tp>
1553inline valarray<_Tp>& valarray<_Tp>::operator=(const mask_array<_Tp>& __x) {
1554  size_t __idx = 0;
1555  for (size_t __i = 0; __i < __x._M_array.size(); ++__i)
1556    if (__x._M_mask[__i]) (*this)[__idx++] = __x._M_array[__i];
1557  return *this;
1558}
1559
1560template <class _Tp>
1561inline mask_array<_Tp> valarray<_Tp>::operator[](const _Valarray_bool& __mask) {
1562  _STLP_ASSERT(__mask.size() == this->size())
1563  return mask_array<_Tp>(__mask, *this);
1564}
1565
1566//----------------------------------------------------------------------
1567// indirect_array
1568
1569template <class _Tp>
1570class indirect_array {
1571  friend class valarray<_Tp>;
1572public:
1573  typedef _Tp value_type;
1574
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];
1578  }
1579
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];
1583  }
1584
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];
1588  }
1589
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];
1593  }
1594
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];
1598  }
1599
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];
1603  }
1604
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];
1608  }
1609
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];
1613  }
1614
1615  void operator|=(const valarray<value_type>& __x) const {
1616    for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1617      _M_array[_M_addr[__i]] |= __x[__i];
1618  }
1619
1620  void operator<<=(const valarray<value_type>& __x) const {
1621    for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1622      _M_array[_M_addr[__i]] <<= __x[__i];
1623  }
1624
1625  void operator>>=(const valarray<value_type>& __x) const {
1626    for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1627      _M_array[_M_addr[__i]] >>= __x[__i];
1628  }
1629
1630  void operator=(const value_type& __c) const {
1631    for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1632      _M_array[_M_addr[__i]] = __c;
1633  }
1634
1635  // C++ Standard defect 253, copy constructor must be public.
1636  indirect_array(const indirect_array& __x)
1637    : _M_addr(__x._M_addr), _M_array(__x._M_array)
1638    {}
1639
1640  ~indirect_array() {}
1641
1642private:
1643  indirect_array(const _Valarray_size_t& __addr, valarray<_Tp>& __array)
1644    : _M_addr(__addr), _M_array(__array)
1645  {}
1646
1647  _Valarray_size_t _M_addr;
1648  valarray<_Tp>&   _M_array;
1649
1650private:
1651  // Disable default constructor and assignment
1652  indirect_array();
1653  void operator=(const indirect_array<_Tp>&);
1654};
1655
1656// valarray member functions dealing with indirect_array
1657
1658template <class _Tp>
1659inline valarray<_Tp>::valarray(const indirect_array<_Tp>& __x)
1660  : _Valarray_base<_Tp>(__x._M_addr.size()) {
1661  typedef typename __type_traits<_Tp>::has_trivial_default_constructor
1662          _Is_Trivial;
1663  _M_initialize(_Is_Trivial());
1664  *this = __x;
1665}
1666
1667
1668template <class _Tp>
1669inline indirect_array<_Tp>
1670valarray<_Tp>::operator[](const _Valarray_size_t& __addr)
1671{ return indirect_array<_Tp>(__addr, *this); }
1672
1673_STLP_END_NAMESPACE
1674
1675# if !defined (_STLP_LINK_TIME_INSTANTIATION)
1676#  include <stl/_valarray.c>
1677# endif
1678
1679#endif /* _STLP_VALARRAY */
1680
1681
1682// Local Variables:
1683// mode:C++
1684// End:
1685