/home/ntakagi/work/STLport-5.1.5/stlport/stl/_valarray.h

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



Generated on Mon Mar 10 15:32:44 2008 by  doxygen 1.5.1