valarray
上传用户:nizebo
上传日期:2022-05-14
资源大小:882k
文件大小:52k
源码类别:

STL

开发平台:

Visual C++

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