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