_valarray.h

00001 /*
00002  * Copyright (c) 1999
00003  * Silicon Graphics Computer Systems, Inc.
00004  *
00005  * Copyright (c) 1999 
00006  * Boris Fomitchev
00007  *
00008  * This material is provided "as is", with absolutely no warranty expressed
00009  * or implied. Any use is at your own risk.
00010  *
00011  * Permission to use or copy this software for any purpose is hereby granted 
00012  * without fee, provided the above notices are retained on all copies.
00013  * Permission to modify the code and to distribute modified code is granted,
00014  * provided the above notices are retained, and a notice that the code was
00015  * modified is included with the above copyright notice.
00016  *
00017  */ 
00018 
00019 #ifndef _STLP_VALARRAY_H
00020 #define _STLP_VALARRAY_H
00021 
00022 #ifndef _STLP_CMATH
00023 #include <cmath>
00024 #endif
00025 #ifndef _STLP_NEW_HEADER
00026 #include <new>
00027 #endif
00028 #ifndef _STLP_INTERNAL_ALGO_H
00029 #include <stl/_algo.h>
00030 #endif
00031 #ifndef _STLP_INTERNAL_NUMERIC_H
00032 #include <stl/_numeric.h>
00033 #endif
00034 #ifndef _STLP_LIMITS_H
00035 #include <limits>
00036 #endif
00037 
00038 _STLP_BEGIN_NAMESPACE
00039 
00040 class slice;
00041 class gslice;
00042 
00043 template <class _Tp> class valarray;
00044 // fbp : those are for MSVC
00045 typedef valarray<bool>    _Valarray_bool;
00046 typedef valarray<size_t>  _Valarray_size_t;
00047 
00048 template <class _Tp> class slice_array;
00049 template <class _Tp> class gslice_array;
00050 template <class _Tp> class mask_array;
00051 template <class _Tp> class indirect_array;
00052 
00053 //----------------------------------------------------------------------
00054 // class valarray
00055 
00056 // Base class to handle memory allocation and deallocation.  We can't just
00057 // use vector<>, because vector<bool> would be unsuitable as an internal 
00058 // representation for valarray<bool>.
00059 
00060 template <class _Tp> 
00061 struct _Valarray_base
00062 {
00063   _Tp*   _M_first;
00064   size_t _M_size;
00065 
00066   _Valarray_base() : _M_first(0), _M_size(0) {}
00067   _Valarray_base(size_t __n) : _M_first(0), _M_size(0) { _M_allocate(__n); }
00068   ~_Valarray_base() { _M_deallocate(); }
00069 
00070   void _M_allocate(size_t __n) {
00071     if (__n != 0) {
00072       _M_first = __STATIC_CAST(_Tp*, (malloc(__n * sizeof(_Tp))));
00073       _M_size  = __n;
00074 #   if !defined(_STLP_NO_BAD_ALLOC) && defined(_STLP_USE_EXCEPTIONS)
00075       if (_M_first == 0) {
00076         _M_size = 0;
00077         throw _STLP_STD::bad_alloc();
00078       }
00079 #   endif
00080     }
00081     else {
00082       _M_first = 0;
00083       _M_size = 0;
00084     }
00085   }
00086 
00087   void _M_deallocate() {
00088     free(_M_first);
00089     _M_first = 0;
00090     _M_size = 0;
00091   }
00092 };
00093 
00094 template <class _Tp> 
00095 class valarray : private _Valarray_base<_Tp>
00096 {
00097   friend class gslice;
00098 
00099 public:
00100   typedef _Tp value_type;
00101 
00102   // Basic constructors
00103   valarray() : _Valarray_base<_Tp>() {}
00104   valarray(size_t __n) : _Valarray_base<_Tp>(__n)
00105     { uninitialized_fill_n(this->_M_first, this->_M_size, value_type()); }
00106   valarray(const value_type& __x, size_t __n) : _Valarray_base<_Tp>(__n)
00107     { uninitialized_fill_n(this->_M_first, this->_M_size, __x); }
00108   valarray(const value_type* __p, size_t __n) : _Valarray_base<_Tp>(__n)
00109     { uninitialized_copy(__p, __p + __n, this->_M_first); } 
00110   valarray(const valarray<_Tp>& __x) : _Valarray_base<_Tp>(__x._M_size) {
00111     uninitialized_copy(__x._M_first, __x._M_first + __x._M_size,
00112                        this->_M_first);
00113   }
00114 
00115   // Constructors from auxiliary array types
00116   valarray(const slice_array<_Tp>&);
00117   valarray(const gslice_array<_Tp>&);
00118   valarray(const mask_array<_Tp>&);
00119   valarray(const indirect_array<_Tp>&);
00120 
00121   // Destructor
00122   ~valarray() { _Destroy(this->_M_first, this->_M_first + this->_M_size); }
00123 
00124   // Extension: constructor that doesn't initialize valarray elements to a
00125   // specific value.  This is faster for types such as int and double.
00126 private:
00127   void _M_initialize(const __true_type&) {}
00128   void _M_initialize(const __false_type&)
00129     { uninitialized_fill_n(this->_M_first, this->_M_size, value_type()); }
00130 
00131 public:
00132   struct _NoInit {};
00133   valarray(size_t __n, _NoInit) : _Valarray_base<_Tp>(__n) {
00134     typedef typename __type_traits<_Tp>::has_trivial_default_constructor _Is_Trivial;
00135     _M_initialize(_Is_Trivial());
00136   }
00137 
00138 public:                         // Assignment
00139   // Basic assignment.  Note that 'x = y' is undefined if x.size() != y.size()
00140   valarray<_Tp>& operator=(const valarray<_Tp>& __x) {
00141     _STLP_ASSERT(__x.size() == this->size())
00142     if (this != &__x)
00143       copy(__x._M_first, __x._M_first + __x._M_size, this->_M_first);
00144     return *this;
00145   }
00146 
00147   // Scalar assignment
00148   valarray<_Tp>& operator=(const value_type& __x) {
00149     fill_n(this->_M_first, this->_M_size, __x);
00150     return *this;
00151   }
00152 
00153   // Assignment of auxiliary array types
00154   valarray<_Tp>& operator=(const slice_array<_Tp>&);
00155   valarray<_Tp>& operator=(const gslice_array<_Tp>&);
00156   valarray<_Tp>& operator=(const mask_array<_Tp>&);
00157   valarray<_Tp>& operator=(const indirect_array<_Tp>&);
00158 
00159 public:                         // Element access
00160   value_type  operator[](size_t __n) const { return this->_M_first[__n]; }
00161   value_type& operator[](size_t __n)       { return this->_M_first[__n]; }
00162   size_t size() const { return this->_M_size; }
00163 
00164 public:                         // Subsetting operations with auxiliary type
00165   valarray<_Tp>            operator[](slice) const;
00166   slice_array<_Tp>    operator[](slice);
00167   valarray<_Tp>            operator[](gslice) const;
00168   gslice_array<_Tp>   operator[](gslice);  
00169   valarray<_Tp>            operator[](const _Valarray_bool&) const;
00170   mask_array<_Tp>     operator[](const _Valarray_bool&);
00171   valarray<_Tp>            operator[](const _Valarray_size_t&) const;
00172   indirect_array<_Tp> operator[](const _Valarray_size_t&);
00173   
00174 public:                         // Unary operators.
00175   valarray<_Tp> operator+() const { return *this; }
00176 
00177   valarray<_Tp> operator-() const {
00178     valarray<_Tp> __tmp(this->size(), _NoInit());
00179     for (size_t __i = 0; __i < this->size(); ++__i)
00180       __tmp[__i] = -(*this)[__i];
00181     return __tmp;
00182   }
00183   
00184   valarray<_Tp> operator~() const {
00185     valarray<_Tp> __tmp(this->size(), _NoInit());
00186     for (size_t __i = 0; __i < this->size(); ++__i)
00187       __tmp[__i] = ~(*this)[__i];
00188     return __tmp;
00189   }
00190 
00191   _Valarray_bool operator!() const {
00192     _Valarray_bool __tmp(this->size(), _Valarray_bool::_NoInit());
00193     for (size_t __i = 0; __i < this->size(); ++__i)
00194       __tmp[__i] = !(*this)[__i];
00195     return __tmp;
00196   }
00197 
00198 public:                         // Scalar computed assignment.
00199   valarray<_Tp>& operator*= (const value_type& __x) {
00200     for (size_t __i = 0; __i < this->size(); ++__i)
00201       (*this)[__i] *= __x;
00202     return *this;
00203   }
00204     
00205   valarray<_Tp>& operator/= (const value_type& __x) {
00206     for (size_t __i = 0; __i < this->size(); ++__i)
00207       (*this)[__i] /= __x;
00208     return *this;
00209   }
00210 
00211   valarray<_Tp>& operator%= (const value_type& __x) {
00212     for (size_t __i = 0; __i < this->size(); ++__i)
00213       (*this)[__i] %= __x;
00214     return *this;
00215   }
00216 
00217   valarray<_Tp>& operator+= (const value_type& __x) {
00218     for (size_t __i = 0; __i < this->size(); ++__i)
00219       (*this)[__i] += __x;
00220     return *this;
00221   }
00222 
00223   valarray<_Tp>& operator-= (const value_type& __x) {
00224     for (size_t __i = 0; __i < this->size(); ++__i)
00225       (*this)[__i] -= __x;
00226     return *this;
00227   }
00228 
00229   valarray<_Tp>& operator^= (const value_type& __x) {
00230     for (size_t __i = 0; __i < this->size(); ++__i)
00231       (*this)[__i] ^= __x;
00232     return *this;
00233   }
00234 
00235   valarray<_Tp>& operator&= (const value_type& __x) {
00236     for (size_t __i = 0; __i < this->size(); ++__i)
00237       (*this)[__i] &= __x;
00238     return *this;
00239   }
00240 
00241   valarray<_Tp>& operator|= (const value_type& __x) {
00242     for (size_t __i = 0; __i < this->size(); ++__i)
00243       (*this)[__i] |= __x;
00244     return *this;
00245   }
00246 
00247   valarray<_Tp>& operator<<= (const value_type& __x) {
00248     for (size_t __i = 0; __i < this->size(); ++__i)
00249       (*this)[__i] <<= __x;
00250     return *this;
00251   }
00252 
00253   valarray<_Tp>& operator>>= (const value_type& __x) {
00254     for (size_t __i = 0; __i < this->size(); ++__i)
00255       (*this)[__i] >>= __x;
00256     return *this;
00257   }
00258 
00259 public:                         // Array computed assignment.
00260   valarray<_Tp>& operator*= (const valarray<_Tp>& __x) {
00261     for (size_t __i = 0; __i < this->size(); ++__i)
00262       (*this)[__i] *= __x[__i];
00263     return *this;
00264   }
00265     
00266   valarray<_Tp>& operator/= (const valarray<_Tp>& __x) {
00267     for (size_t __i = 0; __i < this->size(); ++__i)
00268       (*this)[__i] /= __x[__i];
00269     return *this;
00270   }
00271 
00272   valarray<_Tp>& operator%= (const valarray<_Tp>& __x) {
00273     for (size_t __i = 0; __i < this->size(); ++__i)
00274       (*this)[__i] %= __x[__i];
00275     return *this;
00276   }
00277 
00278   valarray<_Tp>& operator+= (const valarray<_Tp>& __x) {
00279     for (size_t __i = 0; __i < this->size(); ++__i)
00280       (*this)[__i] += __x[__i];
00281     return *this;
00282   }
00283 
00284   valarray<_Tp>& operator-= (const valarray<_Tp>& __x) {
00285     for (size_t __i = 0; __i < this->size(); ++__i)
00286       (*this)[__i] -= __x[__i];
00287     return *this;
00288   }
00289 
00290   valarray<_Tp>& operator^= (const valarray<_Tp>& __x) {
00291     for (size_t __i = 0; __i < this->size(); ++__i)
00292       (*this)[__i] ^= __x[__i];
00293     return *this;
00294   }
00295 
00296   valarray<_Tp>& operator&= (const valarray<_Tp>& __x) {
00297     for (size_t __i = 0; __i < this->size(); ++__i)
00298       (*this)[__i] &= __x[__i];
00299     return *this;
00300   }
00301 
00302   valarray<_Tp>& operator|= (const valarray<_Tp>& __x) {
00303     for (size_t __i = 0; __i < this->size(); ++__i)
00304       (*this)[__i] |= __x[__i];
00305     return *this;
00306   }
00307 
00308   valarray<_Tp>& operator<<= (const valarray<_Tp>& __x) {
00309     for (size_t __i = 0; __i < this->size(); ++__i)
00310       (*this)[__i] <<= __x[__i];
00311     return *this;
00312   }
00313 
00314   valarray<_Tp>& operator>>= (const valarray<_Tp>& __x) {
00315     for (size_t __i = 0; __i < this->size(); ++__i)
00316       (*this)[__i] >>= __x[__i];
00317     return *this;
00318   }
00319 
00320 public:                         // Other member functions.
00321 
00322   // The result is undefined for zero-length arrays
00323   value_type sum() const {
00324     return accumulate(this->_M_first + 1, this->_M_first + this->_M_size,
00325                       (*this)[0]);
00326   }
00327 
00328   // The result is undefined for zero-length arrays
00329   value_type (min) () const {
00330     return *min_element(this->_M_first + 0, this->_M_first + this->_M_size);
00331   }
00332 
00333   value_type (max) () const {
00334     return *max_element(this->_M_first + 0, this->_M_first + this->_M_size);
00335   }
00336 
00337   valarray<_Tp> shift(int __n) const;
00338   valarray<_Tp> cshift(int __n) const;
00339 
00340   valarray<_Tp> apply(value_type __f(value_type)) const {
00341     valarray<_Tp> __tmp(this->size());
00342     transform(this->_M_first + 0, this->_M_first + this->_M_size, __tmp._M_first,
00343               __f);
00344     return __tmp;
00345   }
00346   valarray<_Tp> apply(value_type __f(const value_type&)) const {
00347     valarray<_Tp> __tmp(this->size());
00348     transform(this->_M_first + 0, this->_M_first + this->_M_size, __tmp._M_first,
00349               __f);
00350     return __tmp;
00351   }
00352   
00353   void resize(size_t __n, value_type __x = value_type()) {
00354     _Destroy(this->_M_first, this->_M_first + this->_M_size);
00355     this->_Valarray_base<_Tp>::_M_deallocate();
00356     this->_Valarray_base<_Tp>::_M_allocate(__n);
00357     uninitialized_fill_n(this->_M_first, this->_M_size, __x);
00358   }
00359 };
00360 
00361 //----------------------------------------------------------------------
00362 // valarray non-member functions.
00363 
00364 // Binary arithmetic operations between two arrays.  Behavior is
00365 // undefined if the two arrays do not have the same length.
00366 
00367 template <class _Tp> 
00368 inline valarray<_Tp>  _STLP_CALL operator*(const valarray<_Tp>& __x,
00369                                            const valarray<_Tp>& __y) {
00370   typedef typename valarray<_Tp>::_NoInit _NoInit;
00371   valarray<_Tp> __tmp(__x.size(), _NoInit());
00372   for (size_t __i = 0; __i < __x.size(); ++__i)
00373     __tmp[__i] = __x[__i] * __y[__i];
00374   return __tmp;
00375 }
00376 
00377 template <class _Tp> 
00378 inline valarray<_Tp>  _STLP_CALL operator/(const valarray<_Tp>& __x,
00379                                            const valarray<_Tp>& __y) {
00380   typedef typename valarray<_Tp>::_NoInit _NoInit;
00381   valarray<_Tp> __tmp(__x.size(), _NoInit());
00382   for (size_t __i = 0; __i < __x.size(); ++__i)
00383     __tmp[__i] = __x[__i] / __y[__i];
00384   return __tmp;
00385 }
00386 
00387 template <class _Tp> 
00388 inline valarray<_Tp>  _STLP_CALL operator%(const valarray<_Tp>& __x,
00389                                            const valarray<_Tp>& __y) {
00390   typedef typename valarray<_Tp>::_NoInit _NoInit;
00391   valarray<_Tp> __tmp(__x.size(), _NoInit());
00392   for (size_t __i = 0; __i < __x.size(); ++__i)
00393     __tmp[__i] = __x[__i] % __y[__i];
00394   return __tmp;
00395 }
00396 
00397 template <class _Tp> 
00398 inline valarray<_Tp>  _STLP_CALL operator+(const valarray<_Tp>& __x,
00399                                            const valarray<_Tp>& __y) {
00400   typedef typename valarray<_Tp>::_NoInit _NoInit;
00401   valarray<_Tp> __tmp(__x.size(), _NoInit());
00402   for (size_t __i = 0; __i < __x.size(); ++__i)
00403     __tmp[__i] = __x[__i] + __y[__i];
00404   return __tmp;
00405 }
00406 
00407 template <class _Tp> 
00408 inline valarray<_Tp>  _STLP_CALL operator-(const valarray<_Tp>& __x,
00409                                            const valarray<_Tp>& __y) {
00410   typedef typename valarray<_Tp>::_NoInit _NoInit;
00411   valarray<_Tp> __tmp(__x.size(), _NoInit());
00412   for (size_t __i = 0; __i < __x.size(); ++__i)
00413     __tmp[__i] = __x[__i] - __y[__i];
00414   return __tmp;
00415 }
00416 
00417 template <class _Tp> 
00418 inline valarray<_Tp> _STLP_CALL operator^(const valarray<_Tp>& __x,
00419                                const valarray<_Tp>& __y) {
00420   typedef typename valarray<_Tp>::_NoInit _NoInit;
00421   valarray<_Tp> __tmp(__x.size(), _NoInit());
00422   for (size_t __i = 0; __i < __x.size(); ++__i)
00423     __tmp[__i] = __x[__i] ^ __y[__i];
00424   return __tmp;
00425 }
00426 
00427 template <class _Tp> 
00428 inline valarray<_Tp> _STLP_CALL operator&(const valarray<_Tp>& __x,
00429                                const valarray<_Tp>& __y) {
00430   typedef typename valarray<_Tp>::_NoInit _NoInit;
00431   valarray<_Tp> __tmp(__x.size(), _NoInit());
00432   for (size_t __i = 0; __i < __x.size(); ++__i)
00433     __tmp[__i] = __x[__i] & __y[__i];
00434   return __tmp;
00435 }
00436 
00437 template <class _Tp> 
00438 inline valarray<_Tp> _STLP_CALL operator|(const valarray<_Tp>& __x,
00439                                const valarray<_Tp>& __y) {
00440   typedef typename valarray<_Tp>::_NoInit _NoInit;
00441   valarray<_Tp> __tmp(__x.size(), _NoInit());
00442   for (size_t __i = 0; __i < __x.size(); ++__i)
00443     __tmp[__i] = __x[__i] | __y[__i];
00444   return __tmp;
00445 }
00446 
00447 template <class _Tp> 
00448 inline valarray<_Tp> _STLP_CALL operator<<(const valarray<_Tp>& __x,
00449                                const valarray<_Tp>& __y) {
00450   typedef typename valarray<_Tp>::_NoInit _NoInit;
00451   valarray<_Tp> __tmp(__x.size(), _NoInit());
00452   for (size_t __i = 0; __i < __x.size(); ++__i)
00453     __tmp[__i] = __x[__i] << __y[__i];
00454   return __tmp;
00455 }
00456 
00457 template <class _Tp> 
00458 inline valarray<_Tp> _STLP_CALL operator>>(const valarray<_Tp>& __x,
00459                                const valarray<_Tp>& __y) {
00460   typedef typename valarray<_Tp>::_NoInit _NoInit;
00461   valarray<_Tp> __tmp(__x.size(), _NoInit());
00462   for (size_t __i = 0; __i < __x.size(); ++__i)
00463     __tmp[__i] = __x[__i] >> __y[__i];
00464   return __tmp;
00465 }
00466 
00467 // Binary arithmetic operations between an array and a scalar.
00468 
00469 template <class _Tp> 
00470 inline valarray<_Tp> _STLP_CALL operator*(const valarray<_Tp>& __x, const _Tp& __c) {
00471   typedef typename valarray<_Tp>::_NoInit _NoInit;
00472   valarray<_Tp> __tmp(__x.size(), _NoInit());
00473   for (size_t __i = 0; __i < __x.size(); ++__i)
00474     __tmp[__i] = __x[__i]  * __c;
00475   return __tmp;
00476 }
00477 
00478 template <class _Tp> 
00479 inline valarray<_Tp> _STLP_CALL operator*(const _Tp& __c, const valarray<_Tp>& __x) {
00480   typedef typename valarray<_Tp>::_NoInit _NoInit;
00481   valarray<_Tp> __tmp(__x.size(), _NoInit());
00482   for (size_t __i = 0; __i < __x.size(); ++__i)
00483     __tmp[__i] = __c * __x[__i];
00484   return __tmp;
00485 }
00486 
00487 template <class _Tp> 
00488 inline valarray<_Tp> _STLP_CALL operator/(const valarray<_Tp>& __x, const _Tp& __c) {
00489   typedef typename valarray<_Tp>::_NoInit _NoInit;
00490   valarray<_Tp> __tmp(__x.size(), _NoInit());
00491   for (size_t __i = 0; __i < __x.size(); ++__i)
00492     __tmp[__i] = __x[__i]  / __c;
00493   return __tmp;
00494 }
00495 
00496 template <class _Tp> 
00497 inline valarray<_Tp> _STLP_CALL operator/(const _Tp& __c, const valarray<_Tp>& __x) {
00498   typedef typename valarray<_Tp>::_NoInit _NoInit;
00499   valarray<_Tp> __tmp(__x.size(), _NoInit());
00500   for (size_t __i = 0; __i < __x.size(); ++__i)
00501     __tmp[__i] = __c / __x[__i];
00502   return __tmp;
00503 }
00504 
00505 template <class _Tp> 
00506 inline valarray<_Tp> _STLP_CALL operator%(const valarray<_Tp>& __x, const _Tp& __c) {
00507   typedef typename valarray<_Tp>::_NoInit _NoInit;
00508   valarray<_Tp> __tmp(__x.size(), _NoInit());
00509   for (size_t __i = 0; __i < __x.size(); ++__i)
00510     __tmp[__i] = __x[__i]  % __c;
00511   return __tmp;
00512 }
00513 
00514 template <class _Tp> 
00515 inline valarray<_Tp> _STLP_CALL operator%(const _Tp& __c, const valarray<_Tp>& __x) {
00516   typedef typename valarray<_Tp>::_NoInit _NoInit;
00517   valarray<_Tp> __tmp(__x.size(), _NoInit());
00518   for (size_t __i = 0; __i < __x.size(); ++__i)
00519     __tmp[__i] = __c % __x[__i];
00520   return __tmp;
00521 }
00522 
00523 template <class _Tp> 
00524 inline valarray<_Tp> _STLP_CALL operator+(const valarray<_Tp>& __x, const _Tp& __c) {
00525   typedef typename valarray<_Tp>::_NoInit _NoInit;
00526   valarray<_Tp> __tmp(__x.size(), _NoInit());
00527   for (size_t __i = 0; __i < __x.size(); ++__i)
00528     __tmp[__i] = __x[__i]  + __c;
00529   return __tmp;
00530 }
00531 
00532 template <class _Tp> 
00533 inline valarray<_Tp> _STLP_CALL operator+(const _Tp& __c, const valarray<_Tp>& __x) {
00534   typedef typename valarray<_Tp>::_NoInit _NoInit;
00535   valarray<_Tp> __tmp(__x.size(), _NoInit());
00536   for (size_t __i = 0; __i < __x.size(); ++__i)
00537     __tmp[__i] = __c + __x[__i];
00538   return __tmp;
00539 }
00540 
00541 template <class _Tp> 
00542 inline valarray<_Tp> _STLP_CALL operator-(const valarray<_Tp>& __x, const _Tp& __c) {
00543   typedef typename valarray<_Tp>::_NoInit _NoInit;
00544   valarray<_Tp> __tmp(__x.size(), _NoInit());
00545   for (size_t __i = 0; __i < __x.size(); ++__i)
00546     __tmp[__i] = __x[__i]  - __c;
00547   return __tmp;
00548 }
00549 
00550 template <class _Tp> 
00551 inline valarray<_Tp> _STLP_CALL operator-(const _Tp& __c, const valarray<_Tp>& __x) {
00552   typedef typename valarray<_Tp>::_NoInit _NoInit;
00553   valarray<_Tp> __tmp(__x.size(), _NoInit());
00554   for (size_t __i = 0; __i < __x.size(); ++__i)
00555     __tmp[__i] = __c - __x[__i];
00556   return __tmp;
00557 }
00558 
00559 template <class _Tp> 
00560 inline valarray<_Tp> _STLP_CALL operator^(const valarray<_Tp>& __x, const _Tp& __c) {
00561   typedef typename valarray<_Tp>::_NoInit _NoInit;
00562   valarray<_Tp> __tmp(__x.size(), _NoInit());
00563   for (size_t __i = 0; __i < __x.size(); ++__i)
00564     __tmp[__i] = __x[__i]  ^ __c;
00565   return __tmp;
00566 }
00567 
00568 template <class _Tp> 
00569 inline valarray<_Tp> _STLP_CALL operator^(const _Tp& __c, const valarray<_Tp>& __x) {
00570   typedef typename valarray<_Tp>::_NoInit _NoInit;
00571   valarray<_Tp> __tmp(__x.size(), _NoInit());
00572   for (size_t __i = 0; __i < __x.size(); ++__i)
00573     __tmp[__i] = __c ^ __x[__i];
00574   return __tmp;
00575 }
00576 
00577 template <class _Tp> 
00578 inline valarray<_Tp> _STLP_CALL operator&(const valarray<_Tp>& __x, const _Tp& __c) {
00579   typedef typename valarray<_Tp>::_NoInit _NoInit;
00580   valarray<_Tp> __tmp(__x.size(), _NoInit());
00581   for (size_t __i = 0; __i < __x.size(); ++__i)
00582     __tmp[__i] = __x[__i]  & __c;
00583   return __tmp;
00584 }
00585 
00586 template <class _Tp> 
00587 inline valarray<_Tp> _STLP_CALL operator&(const _Tp& __c, const valarray<_Tp>& __x) {
00588   typedef typename valarray<_Tp>::_NoInit _NoInit;
00589   valarray<_Tp> __tmp(__x.size(), _NoInit());
00590   for (size_t __i = 0; __i < __x.size(); ++__i)
00591     __tmp[__i] = __c & __x[__i];
00592   return __tmp;
00593 }
00594 
00595 template <class _Tp> 
00596 inline valarray<_Tp> _STLP_CALL operator|(const valarray<_Tp>& __x, const _Tp& __c) {
00597   typedef typename valarray<_Tp>::_NoInit _NoInit;
00598   valarray<_Tp> __tmp(__x.size(), _NoInit());
00599   for (size_t __i = 0; __i < __x.size(); ++__i)
00600     __tmp[__i] = __x[__i]  | __c;
00601   return __tmp;
00602 }
00603 
00604 template <class _Tp> 
00605 inline valarray<_Tp> _STLP_CALL operator|(const _Tp& __c, const valarray<_Tp>& __x) {
00606   typedef typename valarray<_Tp>::_NoInit _NoInit;
00607   valarray<_Tp> __tmp(__x.size(), _NoInit());
00608   for (size_t __i = 0; __i < __x.size(); ++__i)
00609     __tmp[__i] = __c | __x[__i];
00610   return __tmp;
00611 }
00612 
00613 template <class _Tp> 
00614 inline valarray<_Tp> _STLP_CALL operator<<(const valarray<_Tp>& __x, const _Tp& __c) {
00615   typedef typename valarray<_Tp>::_NoInit _NoInit;
00616   valarray<_Tp> __tmp(__x.size(), _NoInit());
00617   for (size_t __i = 0; __i < __x.size(); ++__i)
00618     __tmp[__i] = __x[__i]  << __c;
00619   return __tmp;
00620 }
00621 
00622 template <class _Tp> 
00623 inline valarray<_Tp> _STLP_CALL operator<<(const _Tp& __c, const valarray<_Tp>& __x) {
00624   typedef typename valarray<_Tp>::_NoInit _NoInit;
00625   valarray<_Tp> __tmp(__x.size(), _NoInit());
00626   for (size_t __i = 0; __i < __x.size(); ++__i)
00627     __tmp[__i] = __c << __x[__i];
00628   return __tmp;
00629 }
00630 
00631 template <class _Tp> 
00632 inline valarray<_Tp> _STLP_CALL operator>>(const valarray<_Tp>& __x, const _Tp& __c) {
00633   typedef typename valarray<_Tp>::_NoInit _NoInit;
00634   valarray<_Tp> __tmp(__x.size(), _NoInit());
00635   for (size_t __i = 0; __i < __x.size(); ++__i)
00636     __tmp[__i] = __x[__i]  >> __c;
00637   return __tmp;
00638 }
00639 
00640 template <class _Tp> 
00641 inline valarray<_Tp> _STLP_CALL operator>>(const _Tp& __c, const valarray<_Tp>& __x) {
00642   typedef typename valarray<_Tp>::_NoInit _NoInit;
00643   valarray<_Tp> __tmp(__x.size(), _NoInit());
00644   for (size_t __i = 0; __i < __x.size(); ++__i)
00645     __tmp[__i] = __c >> __x[__i];
00646   return __tmp;
00647 }
00648 
00649 // Binary logical operations between two arrays.  Behavior is undefined
00650 // if the two arrays have different lengths.  Note that operator== does
00651 // not do what you might at first expect.
00652 
00653 template <class _Tp> 
00654 inline _Valarray_bool _STLP_CALL operator==(const valarray<_Tp>& __x,
00655                                  const valarray<_Tp>& __y)
00656 {
00657   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00658   for (size_t __i = 0; __i < __x.size(); ++__i)
00659     __tmp[__i] = __x[__i] == __y[__i];
00660   return __tmp;  
00661 }
00662 
00663 template <class _Tp> 
00664 inline _Valarray_bool _STLP_CALL operator<(const valarray<_Tp>& __x,
00665                                 const valarray<_Tp>& __y)
00666 {
00667   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00668   for (size_t __i = 0; __i < __x.size(); ++__i)
00669     __tmp[__i] = __x[__i] < __y[__i];
00670   return __tmp;  
00671 }
00672 
00673 #ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE
00674 
00675 template <class _Tp> 
00676 inline _Valarray_bool _STLP_CALL operator!=(const valarray<_Tp>& __x,
00677                                  const valarray<_Tp>& __y)
00678 {
00679   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00680   for (size_t __i = 0; __i < __x.size(); ++__i)
00681     __tmp[__i] = __x[__i] != __y[__i];
00682   return __tmp;  
00683 }
00684 
00685 template <class _Tp> 
00686 inline _Valarray_bool _STLP_CALL operator>(const valarray<_Tp>& __x,
00687                                 const valarray<_Tp>& __y)
00688 {
00689   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00690   for (size_t __i = 0; __i < __x.size(); ++__i)
00691     __tmp[__i] = __x[__i] > __y[__i];
00692   return __tmp;  
00693 }
00694 
00695 template <class _Tp> 
00696 inline _Valarray_bool _STLP_CALL operator<=(const valarray<_Tp>& __x,
00697                                  const valarray<_Tp>& __y)
00698 {
00699   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00700   for (size_t __i = 0; __i < __x.size(); ++__i)
00701     __tmp[__i] = __x[__i] <= __y[__i];
00702   return __tmp;  
00703 }
00704 
00705 template <class _Tp> 
00706 inline _Valarray_bool _STLP_CALL operator>=(const valarray<_Tp>& __x,
00707                                  const valarray<_Tp>& __y)
00708 {
00709   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00710   for (size_t __i = 0; __i < __x.size(); ++__i)
00711     __tmp[__i] = __x[__i] >= __y[__i];
00712   return __tmp;  
00713 }
00714 
00715 #endif /* _STLP_USE_SEPARATE_RELOPS_NAMESPACE */
00716 // fbp : swap ?
00717 
00718 template <class _Tp> 
00719 inline _Valarray_bool _STLP_CALL operator&&(const valarray<_Tp>& __x,
00720                                  const valarray<_Tp>& __y)
00721 {
00722   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00723   for (size_t __i = 0; __i < __x.size(); ++__i)
00724     __tmp[__i] = __x[__i] && __y[__i];
00725   return __tmp;  
00726 }
00727 
00728 template <class _Tp> 
00729 inline _Valarray_bool _STLP_CALL operator||(const valarray<_Tp>& __x,
00730                                  const valarray<_Tp>& __y)
00731 {
00732   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00733   for (size_t __i = 0; __i < __x.size(); ++__i)
00734     __tmp[__i] = __x[__i] || __y[__i];
00735   return __tmp;  
00736 }
00737 
00738 // Logical operations between an array and a scalar.
00739 
00740 template <class _Tp>
00741 inline _Valarray_bool _STLP_CALL operator==(const valarray<_Tp>& __x, const _Tp& __c)
00742 {
00743   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00744   for (size_t __i = 0; __i < __x.size(); ++__i)
00745     __tmp[__i] = __x[__i] == __c;
00746   return __tmp;  
00747 }
00748 
00749 template <class _Tp>
00750 inline _Valarray_bool _STLP_CALL operator==(const _Tp& __c, const valarray<_Tp>& __x)
00751 {
00752   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00753   for (size_t __i = 0; __i < __x.size(); ++__i)
00754     __tmp[__i] = __c == __x[__i];
00755   return __tmp;  
00756 }
00757 
00758 template <class _Tp>
00759 inline _Valarray_bool _STLP_CALL operator!=(const valarray<_Tp>& __x, const _Tp& __c)
00760 {
00761   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00762   for (size_t __i = 0; __i < __x.size(); ++__i)
00763     __tmp[__i] = __x[__i] != __c;
00764   return __tmp;  
00765 }
00766 
00767 template <class _Tp>
00768 inline _Valarray_bool _STLP_CALL operator!=(const _Tp& __c, const valarray<_Tp>& __x)
00769 {
00770   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00771   for (size_t __i = 0; __i < __x.size(); ++__i)
00772     __tmp[__i] = __c != __x[__i];
00773   return __tmp;  
00774 }
00775 
00776 template <class _Tp>
00777 inline _Valarray_bool _STLP_CALL operator<(const valarray<_Tp>& __x, const _Tp& __c)
00778 {
00779   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00780   for (size_t __i = 0; __i < __x.size(); ++__i)
00781     __tmp[__i] = __x[__i] < __c;
00782   return __tmp;  
00783 }
00784 
00785 template <class _Tp>
00786 inline _Valarray_bool _STLP_CALL operator<(const _Tp& __c, const valarray<_Tp>& __x)
00787 {
00788   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00789   for (size_t __i = 0; __i < __x.size(); ++__i)
00790     __tmp[__i] = __c < __x[__i];
00791   return __tmp;  
00792 }
00793 
00794 template <class _Tp>
00795 inline _Valarray_bool _STLP_CALL operator>(const valarray<_Tp>& __x, const _Tp& __c)
00796 {
00797   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00798   for (size_t __i = 0; __i < __x.size(); ++__i)
00799     __tmp[__i] = __x[__i] > __c;
00800   return __tmp;  
00801 }
00802 
00803 template <class _Tp>
00804 inline _Valarray_bool _STLP_CALL operator>(const _Tp& __c, const valarray<_Tp>& __x)
00805 {
00806   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00807   for (size_t __i = 0; __i < __x.size(); ++__i)
00808     __tmp[__i] = __c > __x[__i];
00809   return __tmp;  
00810 }
00811 
00812 template <class _Tp>
00813 inline _Valarray_bool _STLP_CALL operator<=(const valarray<_Tp>& __x, const _Tp& __c)
00814 {
00815   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00816   for (size_t __i = 0; __i < __x.size(); ++__i)
00817     __tmp[__i] = __x[__i]  <= __c;
00818   return __tmp;  
00819 }
00820 
00821 template <class _Tp>
00822 inline _Valarray_bool _STLP_CALL operator<=(const _Tp& __c, const valarray<_Tp>& __x)
00823 {
00824   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00825   for (size_t __i = 0; __i < __x.size(); ++__i)
00826     __tmp[__i] = __c <= __x[__i];
00827   return __tmp;  
00828 }
00829 
00830 template <class _Tp>
00831 inline _Valarray_bool _STLP_CALL operator>=(const valarray<_Tp>& __x, const _Tp& __c)
00832 {
00833   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00834   for (size_t __i = 0; __i < __x.size(); ++__i)
00835     __tmp[__i] = __x[__i] >= __c;
00836   return __tmp;  
00837 }
00838 
00839 template <class _Tp>
00840 inline _Valarray_bool _STLP_CALL operator>=(const _Tp& __c, const valarray<_Tp>& __x)
00841 {
00842   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00843   for (size_t __i = 0; __i < __x.size(); ++__i)
00844     __tmp[__i] = __c >= __x[__i];
00845   return __tmp;  
00846 }
00847 
00848 template <class _Tp>
00849 inline _Valarray_bool _STLP_CALL operator&&(const valarray<_Tp>& __x, const _Tp& __c)
00850 {
00851   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00852   for (size_t __i = 0; __i < __x.size(); ++__i)
00853     __tmp[__i] = __x[__i] && __c;
00854   return __tmp;  
00855 }
00856 
00857 template <class _Tp>
00858 inline _Valarray_bool _STLP_CALL operator&&(const _Tp& __c, const valarray<_Tp>& __x)
00859 {
00860   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00861   for (size_t __i = 0; __i < __x.size(); ++__i)
00862     __tmp[__i] = __c && __x[__i];
00863   return __tmp;  
00864 }
00865 
00866 template <class _Tp>
00867 inline _Valarray_bool _STLP_CALL operator||(const valarray<_Tp>& __x, const _Tp& __c)
00868 {
00869   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00870   for (size_t __i = 0; __i < __x.size(); ++__i)
00871     __tmp[__i] = __x[__i] || __c;
00872   return __tmp;  
00873 }
00874 
00875 template <class _Tp>
00876 inline _Valarray_bool _STLP_CALL operator||(const _Tp& __c, const valarray<_Tp>& __x)
00877 {
00878   _Valarray_bool __tmp(__x.size(), _Valarray_bool::_NoInit());
00879   for (size_t __i = 0; __i < __x.size(); ++__i)
00880     __tmp[__i] = __c || __x[__i];
00881   return __tmp;  
00882 }
00883 
00884 // valarray "transcendentals" (the list includes abs and sqrt, which,
00885 // of course, are not transcendental).
00886 
00887 template <class _Tp>
00888 inline valarray<_Tp> abs(const valarray<_Tp>& __x) {
00889   typedef typename valarray<_Tp>::_NoInit _NoInit;
00890   valarray<_Tp> __tmp(__x.size(), _NoInit());
00891   for (size_t __i = 0; __i < __x.size(); ++__i)
00892     __tmp[__i] = _STLP_DO_ABS(_Tp)(__x[__i]);
00893   return __tmp;
00894 }
00895 
00896 template <class _Tp>
00897 inline valarray<_Tp> acos(const valarray<_Tp>& __x) {
00898   typedef typename valarray<_Tp>::_NoInit _NoInit;
00899   valarray<_Tp> __tmp(__x.size(), _NoInit());
00900   for (size_t __i = 0; __i < __x.size(); ++__i)
00901     __tmp[__i] = _STLP_DO_ACOS(_Tp)(__x[__i]);
00902   return __tmp;
00903 }
00904 
00905 template <class _Tp>
00906 inline valarray<_Tp> asin(const valarray<_Tp>& __x) {
00907   typedef typename valarray<_Tp>::_NoInit _NoInit;
00908   valarray<_Tp> __tmp(__x.size(), _NoInit());
00909   for (size_t __i = 0; __i < __x.size(); ++__i)
00910     __tmp[__i] = _STLP_DO_ASIN(_Tp)(__x[__i]);
00911   return __tmp;
00912 }
00913 
00914 template <class _Tp>
00915 inline valarray<_Tp> atan(const valarray<_Tp>& __x) {
00916   typedef typename valarray<_Tp>::_NoInit _NoInit;
00917   valarray<_Tp> __tmp(__x.size(), _NoInit());
00918   for (size_t __i = 0; __i < __x.size(); ++__i)
00919     __tmp[__i] = _STLP_DO_ATAN(_Tp)(__x[__i]);
00920   return __tmp;
00921 }
00922 
00923 template <class _Tp>
00924 inline valarray<_Tp> atan2(const valarray<_Tp>& __x,
00925                            const valarray<_Tp>& __y) {
00926   typedef typename valarray<_Tp>::_NoInit _NoInit;
00927   valarray<_Tp> __tmp(__x.size(), _NoInit());
00928   for (size_t __i = 0; __i < __x.size(); ++__i)
00929     __tmp[__i] = _STLP_DO_ATAN2(_Tp)(__x[__i], __y[__i]);
00930   return __tmp;
00931 }
00932 
00933 template <class _Tp>
00934 inline valarray<_Tp> atan2(const valarray<_Tp>& __x, const _Tp& __c) {
00935   typedef typename valarray<_Tp>::_NoInit _NoInit;
00936   valarray<_Tp> __tmp(__x.size(), _NoInit());
00937   for (size_t __i = 0; __i < __x.size(); ++__i)
00938     __tmp[__i] = _STLP_DO_ATAN2(_Tp)(__x[__i], __c);
00939   return __tmp;
00940 }
00941 
00942 template <class _Tp>
00943 inline valarray<_Tp> atan2(const _Tp& __c, const valarray<_Tp>& __x) {
00944   typedef typename valarray<_Tp>::_NoInit _NoInit;
00945   valarray<_Tp> __tmp(__x.size(), _NoInit());
00946   for (size_t __i = 0; __i < __x.size(); ++__i)
00947     __tmp[__i] = _STLP_DO_ATAN2(_Tp)(__c, __x[__i]);
00948   return __tmp;
00949 }
00950 
00951 template <class _Tp>
00952 inline valarray<_Tp> cos(const valarray<_Tp>& __x) {
00953   typedef typename valarray<_Tp>::_NoInit _NoInit;
00954   valarray<_Tp> __tmp(__x.size(), _NoInit());
00955   for (size_t __i = 0; __i < __x.size(); ++__i)
00956     __tmp[__i] = _STLP_DO_COS(_Tp)(__x[__i]);
00957   return __tmp;
00958 }
00959 
00960 template <class _Tp>
00961 inline valarray<_Tp> cosh(const valarray<_Tp>& __x) {
00962   typedef typename valarray<_Tp>::_NoInit _NoInit;
00963   valarray<_Tp> __tmp(__x.size(), _NoInit());
00964   for (size_t __i = 0; __i < __x.size(); ++__i)
00965     __tmp[__i] = _STLP_DO_COSH(_Tp)(__x[__i]);
00966   return __tmp;
00967 }
00968 
00969 template <class _Tp>
00970 inline valarray<_Tp> exp(const valarray<_Tp>& __x) {
00971   typedef typename valarray<_Tp>::_NoInit _NoInit;
00972   valarray<_Tp> __tmp(__x.size(), _NoInit());
00973   for (size_t __i = 0; __i < __x.size(); ++__i)
00974     __tmp[__i] = _STLP_DO_EXP(_Tp)(__x[__i]);
00975   return __tmp;
00976 }
00977 
00978 template <class _Tp>
00979 inline valarray<_Tp> log(const valarray<_Tp>& __x) {
00980   typedef typename valarray<_Tp>::_NoInit _NoInit;
00981   valarray<_Tp> __tmp(__x.size(), _NoInit());
00982   for (size_t __i = 0; __i < __x.size(); ++__i)
00983     __tmp[__i] = _STLP_DO_LOG(_Tp)(__x[__i]);
00984   return __tmp;
00985 }
00986 
00987 template <class _Tp>
00988 inline valarray<_Tp> log10(const valarray<_Tp>& __x) {
00989   typedef typename valarray<_Tp>::_NoInit _NoInit;
00990   valarray<_Tp> __tmp(__x.size(), _NoInit());
00991   for (size_t __i = 0; __i < __x.size(); ++__i)
00992     __tmp[__i] = _STLP_DO_LOG10(_Tp)(__x[__i]);
00993   return __tmp;
00994 }
00995 
00996 template <class _Tp>
00997 inline valarray<_Tp> pow(const valarray<_Tp>& __x,
00998                            const valarray<_Tp>& __y) {
00999   typedef typename valarray<_Tp>::_NoInit _NoInit;
01000   valarray<_Tp> __tmp(__x.size(), _NoInit());
01001   for (size_t __i = 0; __i < __x.size(); ++__i)
01002     __tmp[__i] = _STLP_DO_POW(_Tp)(__x[__i], __y[__i]);
01003   return __tmp;
01004 }
01005 
01006 template <class _Tp>
01007 inline valarray<_Tp> pow(const valarray<_Tp>& __x, const _Tp& __c) {
01008   typedef typename valarray<_Tp>::_NoInit _NoInit;
01009   valarray<_Tp> __tmp(__x.size(), _NoInit());
01010   for (size_t __i = 0; __i < __x.size(); ++__i)
01011     __tmp[__i] = _STLP_DO_POW(_Tp)(__x[__i], __c);
01012   return __tmp;
01013 }
01014 
01015 template <class _Tp>
01016 inline valarray<_Tp> pow(const _Tp& __c, const valarray<_Tp>& __x) {
01017   typedef typename valarray<_Tp>::_NoInit _NoInit;
01018   valarray<_Tp> __tmp(__x.size(), _NoInit());
01019   for (size_t __i = 0; __i < __x.size(); ++__i)
01020     __tmp[__i] = _STLP_DO_POW(_Tp)(__c, __x[__i]);
01021   return __tmp;
01022 }
01023 
01024 template <class _Tp>
01025 inline valarray<_Tp> sin(const valarray<_Tp>& __x) {
01026   typedef typename valarray<_Tp>::_NoInit _NoInit;
01027   valarray<_Tp> __tmp(__x.size(), _NoInit());
01028   for (size_t __i = 0; __i < __x.size(); ++__i)
01029     __tmp[__i] = _STLP_DO_SIN(_Tp)(__x[__i]);
01030   return __tmp;
01031 }
01032 
01033 template <class _Tp>
01034 inline valarray<_Tp> sinh(const valarray<_Tp>& __x) {
01035   typedef typename valarray<_Tp>::_NoInit _NoInit;
01036   valarray<_Tp> __tmp(__x.size(), _NoInit());
01037   for (size_t __i = 0; __i < __x.size(); ++__i)
01038     __tmp[__i] = _STLP_DO_SINH(_Tp)(__x[__i]);
01039   return __tmp;
01040 }
01041 
01042 template <class _Tp>
01043 inline valarray<_Tp> sqrt(const valarray<_Tp>& __x) {
01044   typedef typename valarray<_Tp>::_NoInit _NoInit;
01045   valarray<_Tp> __tmp(__x.size(), _NoInit());
01046   for (size_t __i = 0; __i < __x.size(); ++__i)
01047     __tmp[__i] = _STLP_DO_SQRT(_Tp)(__x[__i]);
01048   return __tmp;
01049 }
01050 
01051 template <class _Tp>
01052 inline valarray<_Tp> tan(const valarray<_Tp>& __x) {
01053   typedef typename valarray<_Tp>::_NoInit _NoInit;
01054   valarray<_Tp> __tmp(__x.size(), _NoInit());
01055   for (size_t __i = 0; __i < __x.size(); ++__i)
01056     __tmp[__i] = _STLP_DO_TAN(_Tp)(__x[__i]);
01057   return __tmp;
01058 }
01059 
01060 template <class _Tp>
01061 inline valarray<_Tp> tanh(const valarray<_Tp>& __x) {
01062   typedef typename valarray<_Tp>::_NoInit _NoInit;
01063   valarray<_Tp> __tmp(__x.size(), _NoInit());
01064   for (size_t __i = 0; __i < __x.size(); ++__i)
01065     __tmp[__i] = _STLP_DO_TANH(_Tp)(__x[__i]);
01066   return __tmp;
01067 }
01068 
01069 //----------------------------------------------------------------------
01070 // slice and slice_array
01071 
01072 class slice {
01073 public:
01074   slice() : _M_start(0), _M_length(0), _M_stride(0) {}
01075   slice(size_t __start, size_t __length, size_t __stride)
01076     : _M_start(__start), _M_length(__length), _M_stride(__stride)
01077     {}
01078   __TRIVIAL_DESTRUCTOR(slice)
01079 
01080   size_t start()  const { return _M_start; }
01081   size_t size()   const { return _M_length; }
01082   size_t stride() const { return _M_stride; }
01083 
01084    
01085 private:
01086   size_t _M_start;
01087   size_t _M_length;
01088   size_t _M_stride;
01089 };
01090 
01091 template <class _Tp>
01092 class slice_array {
01093   friend class valarray<_Tp>;
01094 public:
01095   typedef _Tp value_type;
01096 
01097   void operator=(const valarray<value_type>& __x) const {
01098     size_t __index = _M_slice.start();
01099     for (size_t __i = 0;
01100          __i < _M_slice.size();
01101          ++__i, __index += _M_slice.stride())
01102       _M_array[__index] = __x[__i];
01103   }
01104 
01105   void operator*=(const valarray<value_type>& __x) const {
01106     size_t __index = _M_slice.start();
01107     for (size_t __i = 0;
01108          __i < _M_slice.size();
01109          ++__i, __index += _M_slice.stride())
01110       _M_array[__index] *= __x[__i];
01111   }
01112 
01113   void operator/=(const valarray<value_type>& __x) const {
01114     size_t __index = _M_slice.start();
01115     for (size_t __i = 0;
01116          __i < _M_slice.size();
01117          ++__i, __index += _M_slice.stride())
01118       _M_array[__index] /= __x[__i];
01119   }
01120 
01121   void operator%=(const valarray<value_type>& __x) const {
01122     size_t __index = _M_slice.start();
01123     for (size_t __i = 0;
01124          __i < _M_slice.size();
01125          ++__i, __index += _M_slice.stride())
01126       _M_array[__index] %= __x[__i];
01127   }
01128 
01129   void operator+=(const valarray<value_type>& __x) const {
01130     size_t __index = _M_slice.start();
01131     for (size_t __i = 0;
01132          __i < _M_slice.size();
01133          ++__i, __index += _M_slice.stride())
01134       _M_array[__index] += __x[__i];
01135   }
01136 
01137   void operator-=(const valarray<value_type>& __x) const {
01138     size_t __index = _M_slice.start();
01139     for (size_t __i = 0;
01140          __i < _M_slice.size();
01141          ++__i, __index += _M_slice.stride())
01142       _M_array[__index] -= __x[__i];
01143   }
01144 
01145   void operator^=(const valarray<value_type>& __x) const {
01146     size_t __index = _M_slice.start();
01147     for (size_t __i = 0;
01148          __i < _M_slice.size();
01149          ++__i, __index += _M_slice.stride())
01150       _M_array[__index] ^= __x[__i];
01151   }
01152 
01153   void operator&=(const valarray<value_type>& __x) const {
01154     size_t __index = _M_slice.start();
01155     for (size_t __i = 0;
01156          __i < _M_slice.size();
01157          ++__i, __index += _M_slice.stride())
01158       _M_array[__index] &= __x[__i];
01159   }
01160 
01161   void operator|=(const valarray<value_type>& __x) const {
01162     size_t __index = _M_slice.start();
01163     for (size_t __i = 0;
01164          __i < _M_slice.size();
01165          ++__i, __index += _M_slice.stride())
01166       _M_array[__index] |= __x[__i];
01167   }
01168 
01169   void operator<<=(const valarray<value_type>& __x) const {
01170     size_t __index = _M_slice.start();
01171     for (size_t __i = 0;
01172          __i < _M_slice.size();
01173          ++__i, __index += _M_slice.stride())
01174       _M_array[__index] <<= __x[__i];
01175   }
01176 
01177   void operator>>=(const valarray<value_type>& __x) const {
01178     size_t __index = _M_slice.start();
01179     for (size_t __i = 0;
01180          __i < _M_slice.size();
01181          ++__i, __index += _M_slice.stride())
01182       _M_array[__index] >>= __x[__i];
01183   }
01184 
01185   void operator=(const value_type& __c) const {
01186     size_t __index = _M_slice.start();
01187     for (size_t __i = 0;
01188          __i < _M_slice.size();
01189          ++__i, __index += _M_slice.stride())
01190       _M_array[__index] = __c;
01191   }
01192 
01193   ~slice_array() {}
01194 
01195 private:
01196   slice_array(const slice& __slice, valarray<_Tp>& __array)
01197     : _M_slice(__slice), _M_array(__array)
01198     {}
01199 
01200   slice          _M_slice;
01201   valarray<_Tp>& _M_array;
01202 
01203 private:                        // Disable assignment and default constructor
01204   slice_array();
01205 };
01206 
01207 // valarray member functions dealing with slice and slice_array
01208 
01209 template <class _Tp>
01210 inline valarray<_Tp>::valarray(const slice_array<_Tp>& __x)
01211   : _Valarray_base<_Tp>(__x._M_slice.size())
01212 {
01213   typedef typename __type_traits<_Tp>::has_trivial_default_constructor
01214           _Is_Trivial;
01215   _M_initialize(_Is_Trivial());  
01216   *this = __x;
01217 }
01218 
01219 
01220 template <class _Tp>
01221 inline slice_array<_Tp> valarray<_Tp>::operator[](slice __slice) {
01222   return slice_array<_Tp>(__slice, *this);
01223 }
01224 
01225 //----------------------------------------------------------------------
01226 // gslice and gslice_array
01227 
01228 template <class _Size>
01229 struct _Gslice_Iter_tmpl;
01230 
01231 class gslice {
01232   friend struct _Gslice_Iter_tmpl<size_t>;
01233 public:
01234   gslice() : _M_start(0), _M_lengths(0), _M_strides(0) {}
01235   gslice(size_t __start,
01236          const _Valarray_size_t& __lengths, const _Valarray_size_t& __strides)
01237     : _M_start(__start), _M_lengths(__lengths), _M_strides(__strides)
01238     {}
01239   __TRIVIAL_DESTRUCTOR(gslice)
01240 
01241   size_t start()            const { return _M_start; }
01242   _Valarray_size_t size()   const { return _M_lengths; }
01243   _Valarray_size_t stride() const { return _M_strides; }
01244 
01245   // Extension: check for an empty gslice.
01246   bool _M_empty() const { return _M_lengths.size() == 0; }
01247 
01248   // Extension: number of indices this gslice represents.  (For a degenerate
01249   // gslice, they're not necessarily all distinct.)
01250   size_t _M_size() const {
01251     return !this->_M_empty()
01252       ? accumulate(_M_lengths._M_first + 1,
01253                    _M_lengths._M_first + _M_lengths._M_size,
01254                    _M_lengths[0],
01255                    multiplies<size_t>())
01256       : 0;
01257   }
01258 
01259 private:
01260   size_t _M_start;
01261   _Valarray_size_t _M_lengths;
01262   _Valarray_size_t _M_strides;
01263 };
01264 
01265 // This is not an STL iterator.  It is constructed from a gslice, and it
01266 // steps through the gslice indices in sequence.  See 23.3.6 of the C++
01267 // standard, paragraphs 2-3, for an explanation of the sequence.  At
01268 // each step we get two things: the ordinal (i.e. number of steps taken),
01269 // and the one-dimensional index.
01270 
01271 template <class _Size>
01272 struct _Gslice_Iter_tmpl {
01273   _Gslice_Iter_tmpl(const gslice& __gslice)
01274     : _M_step(0), _M_1d_idx(__gslice.start()),
01275       _M_indices(size_t(0), __gslice._M_lengths.size()),
01276       _M_gslice(__gslice)
01277     {}
01278     
01279   bool _M_done() const { return _M_indices[0] == _M_gslice._M_lengths[0]; }
01280 
01281   bool _M_incr();
01282 
01283   _Size _M_step;
01284   _Size _M_1d_idx;
01285 
01286   valarray<_Size> _M_indices;
01287   const gslice& _M_gslice;
01288 };
01289 
01290 typedef _Gslice_Iter_tmpl<size_t> _Gslice_Iter;
01291 
01292 template <class _Tp>
01293 class gslice_array {
01294   friend class valarray<_Tp>;
01295 public:
01296   typedef _Tp value_type;
01297 
01298   void operator= (const valarray<value_type>& __x) const {
01299     if (!_M_gslice._M_empty()) {
01300       _Gslice_Iter __i(_M_gslice);
01301       do _M_array[__i._M_1d_idx] = __x[__i._M_step]; while(__i._M_incr());
01302     }
01303   }
01304 
01305   void operator*= (const valarray<value_type>& __x) const {
01306     if (!_M_gslice._M_empty()) {
01307       _Gslice_Iter __i(_M_gslice);
01308       do _M_array[__i._M_1d_idx] *= __x[__i._M_step]; while(__i._M_incr());
01309     }
01310   }
01311 
01312   void operator/= (const valarray<value_type>& __x) const {
01313     if (!_M_gslice._M_empty()) {
01314       _Gslice_Iter __i(_M_gslice);
01315       do _M_array[__i._M_1d_idx] /= __x[__i._M_step]; while(__i._M_incr());
01316     }
01317   }
01318 
01319   void operator%= (const valarray<value_type>& __x) const {
01320     if (!_M_gslice._M_empty()) {
01321       _Gslice_Iter __i(_M_gslice);
01322       do _M_array[__i._M_1d_idx] %= __x[__i._M_step]; while(__i._M_incr());
01323     }
01324   }
01325 
01326   void operator+= (const valarray<value_type>& __x) const {
01327     if (!_M_gslice._M_empty()) {
01328       _Gslice_Iter __i(_M_gslice);
01329       do _M_array[__i._M_1d_idx] += __x[__i._M_step]; while(__i._M_incr());
01330     }
01331   }
01332 
01333   void operator-= (const valarray<value_type>& __x) const {
01334     if (!_M_gslice._M_empty()) {
01335       _Gslice_Iter __i(_M_gslice);
01336       do _M_array[__i._M_1d_idx] -= __x[__i._M_step]; while(__i._M_incr());
01337     }
01338   }
01339 
01340   void operator^= (const valarray<value_type>& __x) const {
01341     if (!_M_gslice._M_empty()) {
01342       _Gslice_Iter __i(_M_gslice);
01343       do _M_array[__i._M_1d_idx] ^= __x[__i._M_step]; while(__i._M_incr());
01344     }
01345   }
01346 
01347   void operator&= (const valarray<value_type>& __x) const {
01348     if (!_M_gslice._M_empty()) {
01349       _Gslice_Iter __i(_M_gslice);
01350       do _M_array[__i._M_1d_idx] &= __x[__i._M_step]; while(__i._M_incr());
01351     }
01352   }
01353 
01354   void operator|= (const valarray<value_type>& __x) const {
01355     if (!_M_gslice._M_empty()) {
01356       _Gslice_Iter __i(_M_gslice);
01357       do _M_array[__i._M_1d_idx] |= __x[__i._M_step]; while(__i._M_incr());
01358     }
01359   }
01360 
01361   void operator<<= (const valarray<value_type>& __x) const {
01362     if (!_M_gslice._M_empty()) {
01363       _Gslice_Iter __i(_M_gslice);
01364       do _M_array[__i._M_1d_idx] <<= __x[__i._M_step]; while(__i._M_incr());
01365     }
01366   }
01367 
01368   void operator>>= (const valarray<value_type>& __x) const {
01369     if (!_M_gslice._M_empty()) {
01370       _Gslice_Iter __i(_M_gslice);
01371       do _M_array[__i._M_1d_idx] >>= __x[__i._M_step]; while(__i._M_incr());
01372     }
01373   }
01374 
01375   void operator= (const value_type& __c) const {
01376     if (!_M_gslice._M_empty()) {
01377       _Gslice_Iter __i(_M_gslice);
01378       do _M_array[__i._M_1d_idx] = __c; while(__i._M_incr());
01379     }
01380   }
01381 
01382   ~gslice_array() {}
01383 
01384 private:                        
01385   gslice_array(gslice __gslice, valarray<_Tp>& __array)
01386     : _M_gslice(__gslice), _M_array(__array)
01387     {}
01388 
01389   gslice                _M_gslice;
01390   valarray<value_type>& _M_array;
01391 
01392 private:                        // Disable assignment
01393   void operator=(const gslice_array<_Tp>&);
01394 };
01395 
01396 // valarray member functions dealing with gslice and gslice_array.  Note
01397 // that it is illegal (behavior is undefined) to construct a gslice_array
01398 // from a degenerate gslice.
01399 
01400 template <class _Tp>
01401 inline valarray<_Tp>::valarray(const gslice_array<_Tp>& __x)
01402   : _Valarray_base<_Tp>(__x._M_gslice._M_size())
01403 {
01404   typedef typename __type_traits<_Tp>::has_trivial_default_constructor
01405           _Is_Trivial;
01406   _M_initialize(_Is_Trivial());  
01407   *this = __x;
01408 }
01409 
01410 template <class _Tp>
01411 inline gslice_array<_Tp> valarray<_Tp>::operator[](gslice __slice) {
01412   return gslice_array<_Tp>(__slice, *this);
01413 }
01414 
01415 
01416 //----------------------------------------------------------------------
01417 // mask_array
01418 
01419 template <class _Tp>
01420 class mask_array {
01421   friend class valarray<_Tp>;
01422 public:
01423   typedef _Tp value_type;
01424 
01425   void operator=(const valarray<value_type>& __x) const {
01426     size_t __idx = 0;
01427     for (size_t __i = 0; __i < _M_array.size(); ++__i)
01428       if (_M_mask[__i]) _M_array[__i] = __x[__idx++];
01429   }
01430 
01431   void operator*=(const valarray<value_type>& __x) const {
01432     size_t __idx = 0;
01433     for (size_t __i = 0; __i < _M_array.size(); ++__i)
01434       if (_M_mask[__i]) _M_array[__i] *= __x[__idx++];
01435   }
01436 
01437   void operator/=(const valarray<value_type>& __x) const {
01438     size_t __idx = 0;
01439     for (size_t __i = 0; __i < _M_array.size(); ++__i)
01440       if (_M_mask[__i]) _M_array[__i] /= __x[__idx++];
01441   }
01442 
01443   void operator%=(const valarray<value_type>& __x) const {
01444     size_t __idx = 0;
01445     for (size_t __i = 0; __i < _M_array.size(); ++__i)
01446       if (_M_mask[__i]) _M_array[__i] %= __x[__idx++];
01447   }
01448 
01449   void operator+=(const valarray<value_type>& __x) const {
01450     size_t __idx = 0;
01451     for (size_t __i = 0; __i < _M_array.size(); ++__i)
01452       if (_M_mask[__i]) _M_array[__i] += __x[__idx++];
01453   }
01454 
01455   void operator-=(const valarray<value_type>& __x) const {
01456     size_t __idx = 0;
01457     for (size_t __i = 0; __i < _M_array.size(); ++__i)
01458       if (_M_mask[__i]) _M_array[__i] -= __x[__idx++];
01459   }
01460   
01461   void operator^=(const valarray<value_type>& __x) const {
01462     size_t __idx = 0;
01463     for (size_t __i = 0; __i < _M_array.size(); ++__i)
01464       if (_M_mask[__i]) _M_array[__i] ^= __x[__idx++];
01465   }
01466 
01467   void operator&=(const valarray<value_type>& __x) const {
01468     size_t __idx = 0;
01469     for (size_t __i = 0; __i < _M_array.size(); ++__i)
01470       if (_M_mask[__i]) _M_array[__i] &= __x[__idx++];
01471   }
01472 
01473   void operator|=(const valarray<value_type>& __x) const {
01474     size_t __idx = 0;
01475     for (size_t __i = 0; __i < _M_array.size(); ++__i)
01476       if (_M_mask[__i]) _M_array[__i] |= __x[__idx++];
01477   }
01478 
01479   void operator<<=(const valarray<value_type>& __x) const {
01480     size_t __idx = 0;
01481     for (size_t __i = 0; __i < _M_array.size(); ++__i)
01482       if (_M_mask[__i]) _M_array[__i] <<= __x[__idx++];
01483   }
01484 
01485   void operator>>=(const valarray<value_type>& __x) const {
01486     size_t __idx = 0;
01487     for (size_t __i = 0; __i < _M_array.size(); ++__i)
01488       if (_M_mask[__i]) _M_array[__i] >>= __x[__idx++];
01489   }
01490 
01491   void operator=(const value_type& __c) const {
01492     for (size_t __i = 0; __i < _M_array.size(); ++__i)
01493       if (_M_mask[__i]) _M_array[__i] = __c;
01494   }
01495 
01496   ~mask_array() {}
01497 
01498   // Extension: number of true values in the mask
01499   size_t _M_num_true() const {
01500     size_t __result = 0;
01501     for (size_t __i = 0; __i < _M_mask.size(); ++__i)
01502       if (_M_mask[__i]) ++__result;
01503     return __result;
01504   }
01505 
01506 private:
01507   mask_array(const _Valarray_bool& __mask, valarray<_Tp>& __array)
01508     : _M_mask(__mask), _M_array(__array)
01509     {}
01510 
01511   _Valarray_bool _M_mask;
01512   valarray<_Tp>& _M_array;
01513 
01514 private:                        // Disable assignment
01515   void operator=(const mask_array<_Tp>&);
01516 };
01517 
01518 // valarray member functions dealing with mask_array
01519 
01520 template <class _Tp>
01521 inline valarray<_Tp>::valarray(const mask_array<_Tp>& __x)
01522   : _Valarray_base<_Tp>(__x._M_num_true())
01523 {
01524   typedef typename __type_traits<_Tp>::has_trivial_default_constructor
01525           _Is_Trivial;
01526   _M_initialize(_Is_Trivial());  
01527   *this = __x;
01528 }
01529 
01530 // Behavior is undefined if __x._M_num_true() != this->size()
01531 template <class _Tp>
01532 inline valarray<_Tp>& valarray<_Tp>::operator=(const mask_array<_Tp>& __x) {
01533   size_t __idx = 0;
01534   for (size_t __i = 0; __i < __x._M_array.size(); ++__i)
01535     if (__x._M_mask[__i]) (*this)[__idx++] = __x._M_array[__i];
01536   return *this;
01537 }
01538 
01539 template <class _Tp>
01540 inline mask_array<_Tp> valarray<_Tp>::operator[](const _Valarray_bool& __mask)
01541 {
01542   return mask_array<_Tp>(__mask, *this);
01543 }
01544 
01545 
01546 //----------------------------------------------------------------------
01547 // indirect_array
01548 
01549 template <class _Tp>
01550 class indirect_array {
01551   friend class valarray<_Tp>;
01552 public:
01553   typedef _Tp value_type;
01554 
01555   void operator=(const valarray<value_type>& __x) const {
01556     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
01557       _M_array[_M_addr[__i]] = __x[__i];
01558   }
01559 
01560   void operator*=(const valarray<value_type>& __x) const {
01561     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
01562       _M_array[_M_addr[__i]] *= __x[__i];
01563   }
01564 
01565   void operator/=(const valarray<value_type>& __x) const {
01566     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
01567       _M_array[_M_addr[__i]] /= __x[__i];
01568   }
01569 
01570   void operator%=(const valarray<value_type>& __x) const {
01571     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
01572       _M_array[_M_addr[__i]] %= __x[__i];
01573   }
01574 
01575   void operator+=(const valarray<value_type>& __x) const {
01576     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
01577       _M_array[_M_addr[__i]] += __x[__i];
01578   }
01579 
01580   void operator-=(const valarray<value_type>& __x) const {
01581     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
01582       _M_array[_M_addr[__i]] -= __x[__i];
01583   }
01584 
01585   void operator^=(const valarray<value_type>& __x) const {
01586     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
01587       _M_array[_M_addr[__i]] ^= __x[__i];
01588   }
01589 
01590   void operator&=(const valarray<value_type>& __x) const {
01591     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
01592       _M_array[_M_addr[__i]] &= __x[__i];
01593   }
01594 
01595   void operator|=(const valarray<value_type>& __x) const {
01596     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
01597       _M_array[_M_addr[__i]] |= __x[__i];
01598   }
01599 
01600   void operator<<=(const valarray<value_type>& __x) const {
01601     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
01602       _M_array[_M_addr[__i]] <<= __x[__i];
01603   }
01604 
01605   void operator>>=(const valarray<value_type>& __x) const {
01606     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
01607       _M_array[_M_addr[__i]] >>= __x[__i];
01608   }
01609 
01610   void operator=(const value_type& __c) const {
01611     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
01612       _M_array[_M_addr[__i]] = __c;
01613   }
01614 
01615   ~indirect_array() {}
01616 
01617 private:
01618   indirect_array(const _Valarray_size_t& __addr, valarray<_Tp>& __array)
01619     : _M_addr(__addr), _M_array(__array)
01620     {}
01621 
01622   _Valarray_size_t _M_addr;
01623   valarray<_Tp>&   _M_array;
01624 
01625 private:                        // Disable assignment
01626   void operator=(const indirect_array<_Tp>&);
01627 };
01628 
01629 // valarray member functions dealing with indirect_array
01630 
01631 template <class _Tp>
01632 inline valarray<_Tp>::valarray(const indirect_array<_Tp>& __x)
01633   : _Valarray_base<_Tp>(__x._M_addr.size())
01634 {
01635   typedef typename __type_traits<_Tp>::has_trivial_default_constructor
01636           _Is_Trivial;
01637   _M_initialize(_Is_Trivial());  
01638   *this = __x;
01639 }
01640 
01641 
01642 template <class _Tp>
01643 inline indirect_array<_Tp>
01644 valarray<_Tp>::operator[](const _Valarray_size_t& __addr)
01645 {
01646   return indirect_array<_Tp>(__addr, *this);
01647 }
01648 
01649 _STLP_END_NAMESPACE
01650 
01651 # if !defined (_STLP_LINK_TIME_INSTANTIATION)
01652 #  include <stl/_valarray.c>
01653 # endif
01654 
01655 #endif /* _STLP_VALARRAY */
01656 
01657 
01658 // Local Variables:
01659 // mode:C++
01660 // End:

Generated on Mon Jun 5 10:20:47 2006 for Intelligence.kdevelop by  doxygen 1.4.6