/*
 *
 *
 * Copyright (c) 1994
 * Hewlett-Packard Company
 *
 * Copyright (c) 1996,1997
 * Silicon Graphics Computer Systems, Inc.
 *
 * Copyright (c) 1997
 * Moscow Center for SPARC Technology
 *
 * Copyright (c) 1999
 * Boris Fomitchev
 *
 * This material is provided "as is", with absolutely no warranty expressed
 * or implied. Any use is at your own risk.
 *
 * Permission to use or copy this software for any purpose is hereby granted
 * without fee, provided the above notices are retained on all copies.
 * Permission to modify the code and to distribute modified code is granted,
 * provided the above notices are retained, and a notice that the code was
 * modified is included with the above copyright notice.
 *
 */
#ifndef _STLP_VALARRAY_C
#define _STLP_VALARRAY_C

#ifndef _STLP_VALARRAY_H
# include <stl/_valarray.h>
#endif

_STLP_BEGIN_NAMESPACE

template <class _Tp>
_Valarray_bool valarray<_Tp>:: operator!() const {
  _Valarray_bool __tmp(this->size(), _Valarray_bool::_NoInit());
  for (size_t __i = 0; __i < this->size(); ++__i)
    __tmp[__i] = !(*this)[__i];
  return __tmp;
}

// Behavior is undefined if __x and *this have different sizes
template <class _Tp>
valarray<_Tp>& valarray<_Tp>::operator=(const slice_array<_Tp>& __x)
{
  size_t __index = __x._M_slice.start();
  for (size_t __i = 0;
       __i < __x._M_slice.size();
       ++__i, __index += __x._M_slice.stride())
    (*this)[__i] = __x._M_array[__index];
  return *this;
}

template <class _Tp>
valarray<_Tp> valarray<_Tp>::operator[](slice __slice) const {
  valarray<_Tp> __tmp(__slice.size(), _NoInit());
  size_t __index = __slice.start();
  for (size_t __i = 0;
       __i < __slice.size();
       ++__i, __index += __slice.stride())
    __tmp[__i] = (*this)[__index];
  return __tmp;
}

template <class _Size>
bool _Gslice_Iter_tmpl<_Size>::_M_incr() {
  size_t __dim = _M_indices.size() - 1;
  ++_M_step;
  for (;;) {
    _M_1d_idx += _M_gslice._M_strides[__dim];
    if (++_M_indices[__dim] != _M_gslice._M_lengths[__dim])
      return true;
    else if (__dim != 0) {
      _M_1d_idx -= _M_gslice._M_strides[__dim] * _M_gslice._M_lengths[__dim];
      _M_indices[__dim] = 0;
      --__dim;
    }
    else
      return false;
  }
}

// Behavior is undefined if __x and *this have different sizes, or if
// __x was constructed from a degenerate gslice.
template <class _Tp>
valarray<_Tp>& valarray<_Tp>::operator=(const gslice_array<_Tp>& __x)
{
  if (this->size() != 0) {
    _Gslice_Iter __i(__x._M_gslice);
    do
      (*this)[__i._M_step] = __x._M_array[__i._M_1d_idx];
    while(__i._M_incr());
  }
  return *this;
}

template <class _Tp>
valarray<_Tp> valarray<_Tp>::operator[](const gslice& __slice) const
{
  valarray<_Tp> __tmp(__slice._M_size(), _NoInit());
  if (__tmp.size() != 0) {
    _Gslice_Iter __i(__slice);
    do __tmp[__i._M_step] = (*this)[__i._M_1d_idx]; while(__i._M_incr());
  }
  return __tmp;
}

template <class _Tp>
valarray<_Tp> valarray<_Tp>::operator[](const _Valarray_bool& __mask) const
{
  size_t _p_size = 0;
  {
    for (size_t __i = 0; __i < __mask.size(); ++__i)
      if (__mask[__i]) ++_p_size;
  }

  valarray<_Tp> __tmp(_p_size, _NoInit());
  size_t __idx = 0;
  {
    for (size_t __i = 0; __i < __mask.size(); ++__i)
      if (__mask[__i]) __tmp[__idx++] = (*this)[__i];
  }

  return __tmp;
}

template <class _Tp>
valarray<_Tp>& valarray<_Tp>::operator=(const indirect_array<_Tp>& __x) {
  for (size_t __i = 0; __i < __x._M_addr.size(); ++__i)
    (*this)[__i] = __x._M_array[__x._M_addr[__i]];
  return *this;
}

template <class _Tp>
valarray<_Tp>
valarray<_Tp>::operator[](const _Valarray_size_t& __addr) const
{
  valarray<_Tp> __tmp(__addr.size(), _NoInit());
  for (size_t __i = 0; __i < __addr.size(); ++__i)
    __tmp[__i] = (*this)[__addr[__i]];
  return __tmp;
}

//----------------------------------------------------------------------
// Other valarray noninline member functions

// Shift and cshift

template <class _Tp>
valarray<_Tp> valarray<_Tp>::shift(int __n) const
{
  valarray<_Tp> __tmp(this->size());

  if (__n >= 0) {
    if (__n < this->size())
      copy(this->_M_first + __n, this->_M_first + this->size(),
           __tmp._M_first);
  }
  else {
    if (-__n < this->size())
      copy(this->_M_first, this->_M_first + this->size() + __n,
           __tmp._M_first - __n);
  }
  return __tmp;
}

template <class _Tp>
valarray<_Tp> valarray<_Tp>::cshift(int __m) const
{
  valarray<_Tp> __tmp(this->size());

  // Reduce __m to an equivalent number in the range [0, size()).  We
  // have to be careful with negative numbers, since the sign of a % b
  // is unspecified when a < 0.
  long __n = __m;
  if (this->size() < (numeric_limits<long>::max)())
    __n %= long(this->size());
  if (__n < 0)
    __n += this->size();

  copy(this->_M_first,       this->_M_first + __n,
       __tmp._M_first + (this->size() - __n));
  copy(this->_M_first + __n, this->_M_first + this->size(),
       __tmp._M_first);

  return __tmp;
}

_STLP_END_NAMESPACE

#endif /*  _STLP_VALARRAY_C */

// Local Variables:
// mode:C++
// End:
