]> git.buserror.net Git - polintos/scott/priv.git/blob - include/c++/stl/stl/_valarray.h
Add STLport 5.1.4
[polintos/scott/priv.git] / include / c++ / stl / stl / _valarray.h
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 /* As we only need the _STLP_ASSERT macro from _debug.h we test it to include _debug.h */
43 #ifndef _STLP_ASSERT
44 #  include <stl/debug/_debug.h>
45 #endif
46
47 _STLP_BEGIN_NAMESPACE
48
49 class slice;
50 class gslice;
51
52 template <class _Tp> class valarray;
53 typedef valarray<bool>    _Valarray_bool;
54 typedef valarray<size_t>  _Valarray_size_t;
55
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;
60
61 //----------------------------------------------------------------------
62 // class valarray
63
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>.
67
68 template <class _Tp>
69 struct _Valarray_base
70 {
71   _Tp*   _M_first;
72   size_t _M_size;
73
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(); }
77
78   void _M_allocate(size_t __n) {
79     if (__n != 0) {
80       _M_first = __STATIC_CAST(_Tp*, (malloc(__n * sizeof(_Tp))));
81       _M_size  = __n;
82 #if !defined(_STLP_NO_BAD_ALLOC) && defined(_STLP_USE_EXCEPTIONS)
83       if (_M_first == 0) {
84         _M_size = 0;
85         throw _STLP_STD::bad_alloc();
86       }
87 #endif
88     }
89     else {
90       _M_first = 0;
91       _M_size = 0;
92     }
93   }
94
95   void _M_deallocate() {
96     free(_M_first);
97     _M_first = 0;
98     _M_size = 0;
99   }
100 };
101
102 template <class _Tp>
103 class valarray : private _Valarray_base<_Tp>
104 {
105   friend class gslice;
106
107 public:
108   typedef _Tp value_type;
109
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,
120                        this->_M_first);
121   }
122
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>&);
128
129   // Destructor
130   ~valarray() { _STLP_STD::_Destroy_Range(this->_M_first, this->_M_first + this->_M_size); }
131
132   // Extension: constructor that doesn't initialize valarray elements to a
133   // specific value.  This is faster for types such as int and double.
134 private:
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)); }
138
139 public:
140   struct _NoInit {};
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());
144   }
145
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())
150     if (this != &__x)
151       copy(__x._M_first, __x._M_first + __x._M_size, this->_M_first);
152     return *this;
153   }
154
155   // Scalar assignment
156   valarray<_Tp>& operator=(const value_type& __x) {
157     fill_n(this->_M_first, this->_M_size, __x);
158     return *this;
159   }
160
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>&);
166
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; }
171
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&);
181
182 public:                         // Unary operators.
183   valarray<_Tp> operator+() const { return *this; }
184
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];
189     return __tmp;
190   }
191
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];
196     return __tmp;
197   }
198
199   _Valarray_bool operator!() const;
200
201 public:                         // Scalar computed assignment.
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
256   valarray<_Tp>& operator>>= (const value_type& __x) {
257     for (size_t __i = 0; __i < this->size(); ++__i)
258       (*this)[__i] >>= __x;
259     return *this;
260   }
261
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];
266     return *this;
267   }
268
269   valarray<_Tp>& operator/= (const valarray<_Tp>& __x) {
270     for (size_t __i = 0; __i < this->size(); ++__i)
271       (*this)[__i] /= __x[__i];
272     return *this;
273   }
274
275   valarray<_Tp>& operator%= (const valarray<_Tp>& __x) {
276     for (size_t __i = 0; __i < this->size(); ++__i)
277       (*this)[__i] %= __x[__i];
278     return *this;
279   }
280
281   valarray<_Tp>& operator+= (const valarray<_Tp>& __x) {
282     for (size_t __i = 0; __i < this->size(); ++__i)
283       (*this)[__i] += __x[__i];
284     return *this;
285   }
286
287   valarray<_Tp>& operator-= (const valarray<_Tp>& __x) {
288     for (size_t __i = 0; __i < this->size(); ++__i)
289       (*this)[__i] -= __x[__i];
290     return *this;
291   }
292
293   valarray<_Tp>& operator^= (const valarray<_Tp>& __x) {
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     for (size_t __i = 0; __i < this->size(); ++__i)
301       (*this)[__i] &= __x[__i];
302     return *this;
303   }
304
305   valarray<_Tp>& operator|= (const valarray<_Tp>& __x) {
306     for (size_t __i = 0; __i < this->size(); ++__i)
307       (*this)[__i] |= __x[__i];
308     return *this;
309   }
310
311   valarray<_Tp>& operator<<= (const valarray<_Tp>& __x) {
312     for (size_t __i = 0; __i < this->size(); ++__i)
313       (*this)[__i] <<= __x[__i];
314     return *this;
315   }
316
317   valarray<_Tp>& operator>>= (const valarray<_Tp>& __x) {
318     for (size_t __i = 0; __i < this->size(); ++__i)
319       (*this)[__i] >>= __x[__i];
320     return *this;
321   }
322
323 public:                         // Other member functions.
324
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,
328                       (*this)[0]);
329   }
330
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);
334   }
335
336   value_type (max) () const {
337     return *max_element(this->_M_first + 0, this->_M_first + this->_M_size);
338   }
339
340   valarray<_Tp> shift(int __n) const;
341   valarray<_Tp> cshift(int __n) const;
342
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,
346               __f);
347     return __tmp;
348   }
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,
352               __f);
353     return __tmp;
354   }
355
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);
361   }
362 };
363
364 //----------------------------------------------------------------------
365 // valarray non-member functions.
366
367 // Binary arithmetic operations between two arrays.  Behavior is
368 // undefined if the two arrays do not have the same length.
369
370 template <class _Tp>
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];
377   return __tmp;
378 }
379
380 template <class _Tp>
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];
387   return __tmp;
388 }
389
390 template <class _Tp>
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];
397   return __tmp;
398 }
399
400 template <class _Tp>
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];
407   return __tmp;
408 }
409
410 template <class _Tp>
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];
417   return __tmp;
418 }
419
420 template <class _Tp>
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];
427   return __tmp;
428 }
429
430 template <class _Tp>
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];
437   return __tmp;
438 }
439
440 template <class _Tp>
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];
447   return __tmp;
448 }
449
450 template <class _Tp>
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];
457   return __tmp;
458 }
459
460 template <class _Tp>
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];
467   return __tmp;
468 }
469
470 // Binary arithmetic operations between an array and a scalar.
471
472 template <class _Tp>
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;
478   return __tmp;
479 }
480
481 template <class _Tp>
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];
487   return __tmp;
488 }
489
490 template <class _Tp>
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;
496   return __tmp;
497 }
498
499 template <class _Tp>
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];
505   return __tmp;
506 }
507
508 template <class _Tp>
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;
514   return __tmp;
515 }
516
517 template <class _Tp>
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];
523   return __tmp;
524 }
525
526 template <class _Tp>
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;
532   return __tmp;
533 }
534
535 template <class _Tp>
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];
541   return __tmp;
542 }
543
544 template <class _Tp>
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;
550   return __tmp;
551 }
552
553 template <class _Tp>
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];
559   return __tmp;
560 }
561
562 template <class _Tp>
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;
568   return __tmp;
569 }
570
571 template <class _Tp>
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];
577   return __tmp;
578 }
579
580 template <class _Tp>
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;
586   return __tmp;
587 }
588
589 template <class _Tp>
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];
595   return __tmp;
596 }
597
598 template <class _Tp>
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;
604   return __tmp;
605 }
606
607 template <class _Tp>
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];
613   return __tmp;
614 }
615
616 template <class _Tp>
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;
622   return __tmp;
623 }
624
625 template <class _Tp>
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];
631   return __tmp;
632 }
633
634 template <class _Tp>
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;
640   return __tmp;
641 }
642
643 template <class _Tp>
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];
649   return __tmp;
650 }
651
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.
655
656 template <class _Tp>
657 inline _Valarray_bool _STLP_CALL operator==(const valarray<_Tp>& __x,
658                                  const valarray<_Tp>& __y)
659 {
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];
663   return __tmp;
664 }
665
666 template <class _Tp>
667 inline _Valarray_bool _STLP_CALL operator<(const valarray<_Tp>& __x,
668                                 const valarray<_Tp>& __y)
669 {
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];
673   return __tmp;
674 }
675
676 #ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE
677
678 template <class _Tp>
679 inline _Valarray_bool _STLP_CALL operator!=(const valarray<_Tp>& __x,
680                                  const valarray<_Tp>& __y)
681 {
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];
685   return __tmp;
686 }
687
688 template <class _Tp>
689 inline _Valarray_bool _STLP_CALL operator>(const valarray<_Tp>& __x,
690                                 const valarray<_Tp>& __y)
691 {
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];
695   return __tmp;
696 }
697
698 template <class _Tp>
699 inline _Valarray_bool _STLP_CALL operator<=(const valarray<_Tp>& __x,
700                                  const valarray<_Tp>& __y)
701 {
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];
705   return __tmp;
706 }
707
708 template <class _Tp>
709 inline _Valarray_bool _STLP_CALL operator>=(const valarray<_Tp>& __x,
710                                  const valarray<_Tp>& __y)
711 {
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];
715   return __tmp;
716 }
717
718 #endif /* _STLP_USE_SEPARATE_RELOPS_NAMESPACE */
719 // fbp : swap ?
720
721 template <class _Tp>
722 inline _Valarray_bool _STLP_CALL operator&&(const valarray<_Tp>& __x,
723                                  const valarray<_Tp>& __y)
724 {
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];
728   return __tmp;
729 }
730
731 template <class _Tp>
732 inline _Valarray_bool _STLP_CALL operator||(const valarray<_Tp>& __x,
733                                  const valarray<_Tp>& __y)
734 {
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];
738   return __tmp;
739 }
740
741 // Logical operations between an array and a scalar.
742
743 template <class _Tp>
744 inline _Valarray_bool _STLP_CALL operator==(const valarray<_Tp>& __x, const _Tp& __c)
745 {
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;
749   return __tmp;
750 }
751
752 template <class _Tp>
753 inline _Valarray_bool _STLP_CALL operator==(const _Tp& __c, const valarray<_Tp>& __x)
754 {
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];
758   return __tmp;
759 }
760
761 template <class _Tp>
762 inline _Valarray_bool _STLP_CALL operator!=(const valarray<_Tp>& __x, const _Tp& __c)
763 {
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;
767   return __tmp;
768 }
769
770 template <class _Tp>
771 inline _Valarray_bool _STLP_CALL operator!=(const _Tp& __c, const valarray<_Tp>& __x)
772 {
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];
776   return __tmp;
777 }
778
779 template <class _Tp>
780 inline _Valarray_bool _STLP_CALL operator<(const valarray<_Tp>& __x, const _Tp& __c)
781 {
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;
785   return __tmp;
786 }
787
788 template <class _Tp>
789 inline _Valarray_bool _STLP_CALL operator<(const _Tp& __c, const valarray<_Tp>& __x)
790 {
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];
794   return __tmp;
795 }
796
797 template <class _Tp>
798 inline _Valarray_bool _STLP_CALL operator>(const valarray<_Tp>& __x, const _Tp& __c)
799 {
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;
803   return __tmp;
804 }
805
806 template <class _Tp>
807 inline _Valarray_bool _STLP_CALL operator>(const _Tp& __c, const valarray<_Tp>& __x)
808 {
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];
812   return __tmp;
813 }
814
815 template <class _Tp>
816 inline _Valarray_bool _STLP_CALL operator<=(const valarray<_Tp>& __x, const _Tp& __c)
817 {
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;
821   return __tmp;
822 }
823
824 template <class _Tp>
825 inline _Valarray_bool _STLP_CALL operator<=(const _Tp& __c, const valarray<_Tp>& __x)
826 {
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];
830   return __tmp;
831 }
832
833 template <class _Tp>
834 inline _Valarray_bool _STLP_CALL operator>=(const valarray<_Tp>& __x, const _Tp& __c)
835 {
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;
839   return __tmp;
840 }
841
842 template <class _Tp>
843 inline _Valarray_bool _STLP_CALL operator>=(const _Tp& __c, const valarray<_Tp>& __x)
844 {
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];
848   return __tmp;
849 }
850
851 template <class _Tp>
852 inline _Valarray_bool _STLP_CALL operator&&(const valarray<_Tp>& __x, const _Tp& __c)
853 {
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;
857   return __tmp;
858 }
859
860 template <class _Tp>
861 inline _Valarray_bool _STLP_CALL operator&&(const _Tp& __c, const valarray<_Tp>& __x)
862 {
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];
866   return __tmp;
867 }
868
869 template <class _Tp>
870 inline _Valarray_bool _STLP_CALL operator||(const valarray<_Tp>& __x, const _Tp& __c)
871 {
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;
875   return __tmp;
876 }
877
878 template <class _Tp>
879 inline _Valarray_bool _STLP_CALL operator||(const _Tp& __c, const valarray<_Tp>& __x)
880 {
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];
884   return __tmp;
885 }
886
887 // valarray "transcendentals" (the list includes abs and sqrt, which,
888 // of course, are not transcendental).
889
890 template <class _Tp>
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]);
896   return __tmp;
897 }
898
899 template <class _Tp>
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]);
905   return __tmp;
906 }
907
908 template <class _Tp>
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]);
914   return __tmp;
915 }
916
917 template <class _Tp>
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]);
923   return __tmp;
924 }
925
926 template <class _Tp>
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]);
933   return __tmp;
934 }
935
936 template <class _Tp>
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);
942   return __tmp;
943 }
944
945 template <class _Tp>
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]);
951   return __tmp;
952 }
953
954 template <class _Tp>
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]);
960   return __tmp;
961 }
962
963 template <class _Tp>
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]);
969   return __tmp;
970 }
971
972 template <class _Tp>
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]);
978   return __tmp;
979 }
980
981 template <class _Tp>
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]);
987   return __tmp;
988 }
989
990 template <class _Tp>
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]);
996   return __tmp;
997 }
998
999 template <class _Tp>
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]);
1006   return __tmp;
1007 }
1008
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);
1015   return __tmp;
1016 }
1017
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]);
1024   return __tmp;
1025 }
1026
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]);
1033   return __tmp;
1034 }
1035
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]);
1042   return __tmp;
1043 }
1044
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]);
1051   return __tmp;
1052 }
1053
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]);
1060   return __tmp;
1061 }
1062
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]);
1069   return __tmp;
1070 }
1071
1072 //----------------------------------------------------------------------
1073 // slice and slice_array
1074
1075 class slice {
1076 public:
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)
1080     {}
1081   __TRIVIAL_DESTRUCTOR(slice)
1082
1083   size_t start()  const { return _M_start; }
1084   size_t size()   const { return _M_length; }
1085   size_t stride() const { return _M_stride; }
1086
1087 private:
1088   size_t _M_start;
1089   size_t _M_length;
1090   size_t _M_stride;
1091 };
1092
1093 template <class _Tp>
1094 class slice_array {
1095   friend class valarray<_Tp>;
1096 public:
1097   typedef _Tp value_type;
1098
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];
1105   }
1106
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];
1113   }
1114
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];
1121   }
1122
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];
1129   }
1130
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];
1137   }
1138
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];
1145   }
1146
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];
1153   }
1154
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];
1161   }
1162
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];
1169   }
1170
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];
1177   }
1178
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];
1185   }
1186
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;
1193   }
1194
1195   ~slice_array() {}
1196
1197 private:
1198   slice_array(const slice& __slice, valarray<_Tp>& __array)
1199     : _M_slice(__slice), _M_array(__array)
1200     {}
1201
1202   slice          _M_slice;
1203   valarray<_Tp>& _M_array;
1204
1205 private:                        // Disable assignment and default constructor
1206   slice_array();
1207   slice_array(const slice_array&);
1208   slice_array& operator=(const slice_array&);
1209 };
1210
1211 // valarray member functions dealing with slice and slice_array
1212
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
1217           _Is_Trivial;
1218   _M_initialize(_Is_Trivial());
1219   *this = __x;
1220 }
1221
1222
1223 template <class _Tp>
1224 inline slice_array<_Tp> valarray<_Tp>::operator[](slice __slice) {
1225   return slice_array<_Tp>(__slice, *this);
1226 }
1227
1228 //----------------------------------------------------------------------
1229 // gslice and gslice_array
1230
1231 template <class _Size>
1232 struct _Gslice_Iter_tmpl;
1233
1234 class gslice {
1235   friend struct _Gslice_Iter_tmpl<size_t>;
1236 public:
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)
1241     {}
1242   __TRIVIAL_DESTRUCTOR(gslice)
1243
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; }
1247
1248   // Extension: check for an empty gslice.
1249   bool _M_empty() const { return _M_lengths.size() == 0; }
1250
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,
1257                    _M_lengths[0],
1258                    multiplies<size_t>())
1259       : 0;
1260   }
1261
1262 # ifndef __HP_aCC
1263 private:
1264 # endif
1265
1266   size_t _M_start;
1267   _Valarray_size_t _M_lengths;
1268   _Valarray_size_t _M_strides;
1269 };
1270
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.
1276
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()),
1282       _M_gslice(__gslice)
1283     {}
1284
1285   bool _M_done() const { return _M_indices[0] == _M_gslice._M_lengths[0]; }
1286
1287   bool _M_incr();
1288
1289   _Size _M_step;
1290   _Size _M_1d_idx;
1291
1292   valarray<_Size> _M_indices;
1293   const gslice& _M_gslice;
1294 };
1295
1296 typedef _Gslice_Iter_tmpl<size_t> _Gslice_Iter;
1297
1298 template <class _Tp>
1299 class gslice_array {
1300   friend class valarray<_Tp>;
1301 public:
1302   typedef _Tp value_type;
1303
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());
1308     }
1309   }
1310
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());
1315     }
1316   }
1317
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());
1322     }
1323   }
1324
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());
1329     }
1330   }
1331
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());
1336     }
1337   }
1338
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());
1343     }
1344   }
1345
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());
1350     }
1351   }
1352
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());
1357     }
1358   }
1359
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());
1364     }
1365   }
1366
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());
1371     }
1372   }
1373
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());
1378     }
1379   }
1380
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());
1385     }
1386   }
1387
1388   ~gslice_array() {}
1389
1390 private:
1391   gslice_array(const gslice& __gslice, valarray<_Tp>& __array)
1392     : _M_gslice(__gslice), _M_array(__array)
1393     {}
1394
1395   gslice                _M_gslice;
1396   valarray<value_type>& _M_array;
1397
1398 private:                        // Disable assignment
1399   void operator=(const gslice_array<_Tp>&);
1400 };
1401
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.
1405
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
1410           _Is_Trivial;
1411   _M_initialize(_Is_Trivial());
1412   *this = __x;
1413 }
1414
1415 template <class _Tp>
1416 inline gslice_array<_Tp> valarray<_Tp>::operator[](const gslice& __slice) {
1417   return gslice_array<_Tp>(__slice, *this);
1418 }
1419
1420
1421 //----------------------------------------------------------------------
1422 // mask_array
1423
1424 template <class _Tp>
1425 class mask_array {
1426   friend class valarray<_Tp>;
1427 public:
1428   typedef _Tp value_type;
1429
1430   void operator=(const valarray<value_type>& __x) const {
1431     size_t __idx = 0;
1432     for (size_t __i = 0; __i < _M_array.size(); ++__i)
1433       if (_M_mask[__i]) _M_array[__i] = __x[__idx++];
1434   }
1435
1436   void operator*=(const valarray<value_type>& __x) const {
1437     size_t __idx = 0;
1438     for (size_t __i = 0; __i < _M_array.size(); ++__i)
1439       if (_M_mask[__i]) _M_array[__i] *= __x[__idx++];
1440   }
1441
1442   void operator/=(const valarray<value_type>& __x) const {
1443     size_t __idx = 0;
1444     for (size_t __i = 0; __i < _M_array.size(); ++__i)
1445       if (_M_mask[__i]) _M_array[__i] /= __x[__idx++];
1446   }
1447
1448   void operator%=(const valarray<value_type>& __x) const {
1449     size_t __idx = 0;
1450     for (size_t __i = 0; __i < _M_array.size(); ++__i)
1451       if (_M_mask[__i]) _M_array[__i] %= __x[__idx++];
1452   }
1453
1454   void operator+=(const valarray<value_type>& __x) const {
1455     size_t __idx = 0;
1456     for (size_t __i = 0; __i < _M_array.size(); ++__i)
1457       if (_M_mask[__i]) _M_array[__i] += __x[__idx++];
1458   }
1459
1460   void operator-=(const valarray<value_type>& __x) const {
1461     size_t __idx = 0;
1462     for (size_t __i = 0; __i < _M_array.size(); ++__i)
1463       if (_M_mask[__i]) _M_array[__i] -= __x[__idx++];
1464   }
1465
1466   void operator^=(const valarray<value_type>& __x) const {
1467     size_t __idx = 0;
1468     for (size_t __i = 0; __i < _M_array.size(); ++__i)
1469       if (_M_mask[__i]) _M_array[__i] ^= __x[__idx++];
1470   }
1471
1472   void operator&=(const valarray<value_type>& __x) const {
1473     size_t __idx = 0;
1474     for (size_t __i = 0; __i < _M_array.size(); ++__i)
1475       if (_M_mask[__i]) _M_array[__i] &= __x[__idx++];
1476   }
1477
1478   void operator|=(const valarray<value_type>& __x) const {
1479     size_t __idx = 0;
1480     for (size_t __i = 0; __i < _M_array.size(); ++__i)
1481       if (_M_mask[__i]) _M_array[__i] |= __x[__idx++];
1482   }
1483
1484   void operator<<=(const valarray<value_type>& __x) const {
1485     size_t __idx = 0;
1486     for (size_t __i = 0; __i < _M_array.size(); ++__i)
1487       if (_M_mask[__i]) _M_array[__i] <<= __x[__idx++];
1488   }
1489
1490   void operator>>=(const valarray<value_type>& __x) const {
1491     size_t __idx = 0;
1492     for (size_t __i = 0; __i < _M_array.size(); ++__i)
1493       if (_M_mask[__i]) _M_array[__i] >>= __x[__idx++];
1494   }
1495
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;
1499   }
1500
1501   ~mask_array() {}
1502
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;
1508     return __result;
1509   }
1510
1511 private:
1512   mask_array(const _Valarray_bool& __mask, valarray<_Tp>& __array)
1513     : _M_mask(__mask), _M_array(__array)
1514     {}
1515
1516   _Valarray_bool _M_mask;
1517   valarray<_Tp>& _M_array;
1518
1519 private:                        // Disable assignment
1520   void operator=(const mask_array<_Tp>&);
1521 };
1522
1523 // valarray member functions dealing with mask_array
1524
1525 template <class _Tp>
1526 inline valarray<_Tp>::valarray(const mask_array<_Tp>& __x)
1527   : _Valarray_base<_Tp>(__x._M_num_true())
1528 {
1529   typedef typename __type_traits<_Tp>::has_trivial_default_constructor
1530           _Is_Trivial;
1531   _M_initialize(_Is_Trivial());
1532   *this = __x;
1533 }
1534
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) {
1538   size_t __idx = 0;
1539   for (size_t __i = 0; __i < __x._M_array.size(); ++__i)
1540     if (__x._M_mask[__i]) (*this)[__idx++] = __x._M_array[__i];
1541   return *this;
1542 }
1543
1544 template <class _Tp>
1545 inline mask_array<_Tp> valarray<_Tp>::operator[](const _Valarray_bool& __mask)
1546 {
1547   return mask_array<_Tp>(__mask, *this);
1548 }
1549
1550
1551 //----------------------------------------------------------------------
1552 // indirect_array
1553
1554 template <class _Tp>
1555 class indirect_array {
1556   friend class valarray<_Tp>;
1557 public:
1558   typedef _Tp value_type;
1559
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];
1563   }
1564
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];
1568   }
1569
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];
1573   }
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 value_type& __c) const {
1616     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
1617       _M_array[_M_addr[__i]] = __c;
1618   }
1619
1620   ~indirect_array() {}
1621
1622 private:
1623   indirect_array(const _Valarray_size_t& __addr, valarray<_Tp>& __array)
1624     : _M_addr(__addr), _M_array(__array)
1625     {}
1626
1627   _Valarray_size_t _M_addr;
1628   valarray<_Tp>&   _M_array;
1629
1630 private:                        // Disable assignment
1631   void operator=(const indirect_array<_Tp>&);
1632 };
1633
1634 // valarray member functions dealing with indirect_array
1635
1636 template <class _Tp>
1637 inline valarray<_Tp>::valarray(const indirect_array<_Tp>& __x)
1638   : _Valarray_base<_Tp>(__x._M_addr.size())
1639 {
1640   typedef typename __type_traits<_Tp>::has_trivial_default_constructor
1641           _Is_Trivial;
1642   _M_initialize(_Is_Trivial());
1643   *this = __x;
1644 }
1645
1646
1647 template <class _Tp>
1648 inline indirect_array<_Tp>
1649 valarray<_Tp>::operator[](const _Valarray_size_t& __addr)
1650 {
1651   return indirect_array<_Tp>(__addr, *this);
1652 }
1653
1654 _STLP_END_NAMESPACE
1655
1656 # if !defined (_STLP_LINK_TIME_INSTANTIATION)
1657 #  include <stl/_valarray.c>
1658 # endif
1659
1660 #endif /* _STLP_VALARRAY */
1661
1662
1663 // Local Variables:
1664 // mode:C++
1665 // End: