home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / stlpt453.zip / STLport-4.5.3 / stlport / stl / _valarray.h < prev    next >
C/C++ Source or Header  |  2001-12-05  |  51KB  |  1,658 lines

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