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 
44 class slice;
45 class gslice;
46 
47 template <class _Tp> class valarray;
48 typedef valarray<bool>    _Valarray_bool;
49 typedef valarray<size_t>  _Valarray_size_t;
50 
51 template <class _Tp> class slice_array;
52 template <class _Tp> class gslice_array;
53 template <class _Tp> class mask_array;
54 template <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 
63 template <class _Tp>
64 struct _Valarray_base {
65   _Tp*   _M_first;
66   size_t _M_size;
67 
_Valarray_base_Valarray_base68   _Valarray_base() : _M_first(0), _M_size(0) {}
_Valarray_base_Valarray_base69   _Valarray_base(size_t __n) : _M_first(0), _M_size(0) { _M_allocate(__n); }
~_Valarray_base_Valarray_base70   ~_Valarray_base() { _M_deallocate(); }
71 
_M_allocate_Valarray_base72   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 
_M_deallocate_Valarray_base83   void _M_deallocate() {
84     __stl_delete(_M_first);
85     _M_first = 0;
86     _M_size = 0;
87   }
88 };
89 
90 template <class _Tp>
91 class valarray : private _Valarray_base<_Tp>
92 {
93   friend class gslice;
94 
95 public:
96   typedef _Tp value_type;
97 
98   // Basic constructors
valarray()99   valarray() : _Valarray_base<_Tp>() {}
valarray(size_t __n)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)); }
valarray(const value_type & __x,size_t __n)102   valarray(const value_type& __x, size_t __n) : _Valarray_base<_Tp>(__n)
103     { uninitialized_fill_n(this->_M_first, this->_M_size, __x); }
valarray(const value_type * __p,size_t __n)104   valarray(const value_type* __p, size_t __n) : _Valarray_base<_Tp>(__n)
105     { uninitialized_copy(__p, __p + __n, this->_M_first); }
valarray(const valarray<_Tp> & __x)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
~valarray()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.
122 private:
_M_initialize(const __true_type &)123   void _M_initialize(const __true_type&) {}
_M_initialize(const __false_type &)124   void _M_initialize(const __false_type&)
125     { uninitialized_fill_n(this->_M_first, this->_M_size, _STLP_DEFAULT_CONSTRUCTED(_Tp)); }
126 
127 public:
128   struct _NoInit {};
valarray(size_t __n,_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 
134 public:                         // 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 
155 public:                         // 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   }
size()164   size_t size() const { return this->_M_size; }
165 
166 public:                         // 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 
176 public:                         // 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 
195 public:                         // 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 
256 public:                         // 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 
327 public:                         // Other member functions.
328 
329   // The result is undefined for zero-length arrays
sum()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
value_type(min)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 
value_type(max)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 
apply(value_type __f (value_type))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   }
apply(value_type __f (const value_type &))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 
377 template <class _Tp>
378 inline 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 
388 template <class _Tp>
389 inline 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 
399 template <class _Tp>
400 inline 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 
410 template <class _Tp>
411 inline 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 
421 template <class _Tp>
422 inline 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 
432 template <class _Tp>
433 inline 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 
443 template <class _Tp>
444 inline 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 
454 template <class _Tp>
455 inline 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 
465 template <class _Tp>
466 inline 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 
476 template <class _Tp>
477 inline 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 
489 template <class _Tp>
490 inline 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 
498 template <class _Tp>
499 inline 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 
507 template <class _Tp>
508 inline 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 
516 template <class _Tp>
517 inline 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 
525 template <class _Tp>
526 inline 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 
534 template <class _Tp>
535 inline 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 
543 template <class _Tp>
544 inline 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 
552 template <class _Tp>
553 inline 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 
561 template <class _Tp>
562 inline 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 
570 template <class _Tp>
571 inline 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 
579 template <class _Tp>
580 inline 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 
588 template <class _Tp>
589 inline 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 
597 template <class _Tp>
598 inline 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 
606 template <class _Tp>
607 inline 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 
615 template <class _Tp>
616 inline 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 
624 template <class _Tp>
625 inline 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 
633 template <class _Tp>
634 inline 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 
642 template <class _Tp>
643 inline 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 
651 template <class _Tp>
652 inline 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 
660 template <class _Tp>
661 inline 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 
673 template <class _Tp>
674 inline _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 
683 template <class _Tp>
684 inline _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 
695 template <class _Tp>
696 inline _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 
705 template <class _Tp>
706 inline _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 
715 template <class _Tp>
716 inline _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 
725 template <class _Tp>
726 inline _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 
738 template <class _Tp>
739 inline _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 
748 template <class _Tp>
749 inline _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 
760 template <class _Tp>
761 inline _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 
768 template <class _Tp>
769 inline _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 
776 template <class _Tp>
777 inline _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 
784 template <class _Tp>
785 inline _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 
792 template <class _Tp>
793 inline _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 
800 template <class _Tp>
801 inline _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 
808 template <class _Tp>
809 inline _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 
816 template <class _Tp>
817 inline _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 
824 template <class _Tp>
825 inline _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 
832 template <class _Tp>
833 inline _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 
840 template <class _Tp>
841 inline _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 
848 template <class _Tp>
849 inline _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 
856 template <class _Tp>
857 inline _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 
864 template <class _Tp>
865 inline _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 
872 template <class _Tp>
873 inline _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 
880 template <class _Tp>
881 inline _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 
891 template <class _Tp>
abs(const valarray<_Tp> & __x)892 inline 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 
900 template <class _Tp>
acos(const valarray<_Tp> & __x)901 inline 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 
909 template <class _Tp>
asin(const valarray<_Tp> & __x)910 inline 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 
918 template <class _Tp>
atan(const valarray<_Tp> & __x)919 inline 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 
927 template <class _Tp>
atan2(const valarray<_Tp> & __x,const valarray<_Tp> & __y)928 inline 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 
937 template <class _Tp>
atan2(const valarray<_Tp> & __x,const _Tp & __c)938 inline 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 
946 template <class _Tp>
atan2(const _Tp & __c,const valarray<_Tp> & __x)947 inline 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 
955 template <class _Tp>
cos(const valarray<_Tp> & __x)956 inline 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 
964 template <class _Tp>
cosh(const valarray<_Tp> & __x)965 inline 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 
973 template <class _Tp>
exp(const valarray<_Tp> & __x)974 inline 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 
982 template <class _Tp>
log(const valarray<_Tp> & __x)983 inline 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 
991 template <class _Tp>
log10(const valarray<_Tp> & __x)992 inline 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 
1000 template <class _Tp>
pow(const valarray<_Tp> & __x,const valarray<_Tp> & __y)1001 inline 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 
1010 template <class _Tp>
pow(const valarray<_Tp> & __x,const _Tp & __c)1011 inline 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 
1019 template <class _Tp>
pow(const _Tp & __c,const valarray<_Tp> & __x)1020 inline 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 
1028 template <class _Tp>
sin(const valarray<_Tp> & __x)1029 inline 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 
1037 template <class _Tp>
sinh(const valarray<_Tp> & __x)1038 inline 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 
1046 template <class _Tp>
sqrt(const valarray<_Tp> & __x)1047 inline 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 
1055 template <class _Tp>
tan(const valarray<_Tp> & __x)1056 inline 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 
1064 template <class _Tp>
tanh(const valarray<_Tp> & __x)1065 inline 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 
1076 class slice {
1077 public:
slice()1078   slice() : _M_start(0), _M_length(0), _M_stride(0) {}
slice(size_t __start,size_t __length,size_t __stride)1079   slice(size_t __start, size_t __length, size_t __stride)
1080     : _M_start(__start), _M_length(__length), _M_stride(__stride)
1081     {}
__TRIVIAL_DESTRUCTOR(slice)1082   __TRIVIAL_DESTRUCTOR(slice)
1083 
1084   size_t start()  const { return _M_start; }
size()1085   size_t size()   const { return _M_length; }
stride()1086   size_t stride() const { return _M_stride; }
1087 
1088 private:
1089   size_t _M_start;
1090   size_t _M_length;
1091   size_t _M_stride;
1092 };
1093 
1094 template <class _Tp>
1095 class slice_array {
1096   friend class valarray<_Tp>;
1097 public:
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.
slice_array(const slice_array & __x)1197   slice_array(const slice_array &__x)
1198     : _M_slice(__x._M_slice), _M_array(__x._M_array)
1199     {}
1200 
~slice_array()1201   ~slice_array() {}
1202 
1203 private:
slice_array(const slice & __slice,valarray<_Tp> & __array)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 
1211 private:
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 
1219 template <class _Tp>
valarray(const slice_array<_Tp> & __x)1220 inline 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 
1229 template <class _Tp>
1230 inline slice_array<_Tp> valarray<_Tp>::operator[](slice __slice)
1231 { return slice_array<_Tp>(__slice, *this); }
1232 
1233 //----------------------------------------------------------------------
1234 // gslice and gslice_array
1235 
1236 template <class _Size>
1237 struct _Gslice_Iter_tmpl;
1238 
1239 class gslice {
1240   friend struct _Gslice_Iter_tmpl<size_t>;
1241 public:
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
1268 private:
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 
1282 template <class _Size>
1283 struct _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 
1301 typedef _Gslice_Iter_tmpl<size_t> _Gslice_Iter;
1302 
1303 template <class _Tp>
1304 class gslice_array {
1305   friend class valarray<_Tp>;
1306 public:
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 
1400 private:
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 
1408 private:
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 
1418 template <class _Tp>
1419 inline 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 
1427 template <class _Tp>
1428 inline gslice_array<_Tp> valarray<_Tp>::operator[](const gslice& __slice)
1429 { return gslice_array<_Tp>(__slice, *this); }
1430 
1431 
1432 //----------------------------------------------------------------------
1433 // mask_array
1434 
1435 template <class _Tp>
1436 class mask_array {
1437   friend class valarray<_Tp>;
1438 public:
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 
1527 private:
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 
1534 private:
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 
1542 template <class _Tp>
1543 inline 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()
1552 template <class _Tp>
1553 inline 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 
1560 template <class _Tp>
1561 inline 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 
1569 template <class _Tp>
1570 class indirect_array {
1571   friend class valarray<_Tp>;
1572 public:
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 
1642 private:
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 
1650 private:
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 
1658 template <class _Tp>
1659 inline 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 
1668 template <class _Tp>
1669 inline indirect_array<_Tp>
1670 valarray<_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