williamr@2: /*
williamr@2:  *
williamr@2:  * © Portions copyright (c) 2006-2007 Nokia Corporation.  All rights reserved.
williamr@2:  *
williamr@2:  * Copyright (c) 1994
williamr@2:  * Hewlett-Packard Company
williamr@2:  *
williamr@2:  * Copyright (c) 1996,1997
williamr@2:  * Silicon Graphics Computer Systems, Inc.
williamr@2:  *
williamr@2:  * Copyright (c) 1997
williamr@2:  * Moscow Center for SPARC Technology
williamr@2:  *
williamr@2:  * Copyright (c) 1999 
williamr@2:  * Boris Fomitchev
williamr@2:  *
williamr@2:  * This material is provided "as is", with absolutely no warranty expressed
williamr@2:  * or implied. Any use is at your own risk.
williamr@2:  *
williamr@2:  * Permission to use or copy this software for any purpose is hereby granted 
williamr@2:  * without fee, provided the above notices are retained on all copies.
williamr@2:  * Permission to modify the code and to distribute modified code is granted,
williamr@2:  * provided the above notices are retained, and a notice that the code was
williamr@2:  * modified is included with the above copyright notice.
williamr@2:  *
williamr@2:  */
williamr@2: #ifndef _STLP_VALARRAY_C
williamr@2: #define _STLP_VALARRAY_C
williamr@2: 
williamr@2: #ifndef _STLP_VALARRAY_H
williamr@2: # include <stl/_valarray.h>
williamr@2: #endif
williamr@2: 
williamr@2: _STLP_BEGIN_NAMESPACE
williamr@2: 
williamr@2: template <class _Tp>
williamr@2: _Valarray_bool valarray<_Tp>:: operator!() const {
williamr@2:   _Valarray_bool __tmp(this->size(), _Valarray_bool::_NoInit());
williamr@2:   for (size_t __i = 0; __i < this->size(); ++__i)
williamr@2:     __tmp[__i] = !(*this)[__i];
williamr@2:   return __tmp;
williamr@2: }
williamr@2: 
williamr@2: // Behavior is undefined if __x and *this have different sizes
williamr@2: template <class _Tp>
williamr@2: valarray<_Tp>& valarray<_Tp>::operator=(const slice_array<_Tp>& __x)
williamr@2: {
williamr@2:   size_t __index = __x._M_slice.start();
williamr@2:   for (size_t __i = 0;
williamr@2:        __i < __x._M_slice.size();
williamr@2:        ++__i, __index += __x._M_slice.stride())
williamr@2:     (*this)[__i] = (*(__x._M_array))[__index];
williamr@2:   return *this;
williamr@2: }
williamr@2: 
williamr@2: template <class _Tp>
williamr@2: valarray<_Tp> valarray<_Tp>::operator[](slice __slice) const {
williamr@2:   valarray<_Tp> __tmp(__slice.size(), _NoInit());
williamr@2:   size_t __index = __slice.start();
williamr@2:   for (size_t __i = 0;
williamr@2:        __i < __slice.size();
williamr@2:        ++__i, __index += __slice.stride())
williamr@2:     __tmp[__i] = (*this)[__index];
williamr@2:   return __tmp;
williamr@2: }
williamr@2: 
williamr@2: template <class _Size>
williamr@2: bool _Gslice_Iter_tmpl<_Size>::_M_incr() {
williamr@2:   size_t __dim = _M_indices.size() - 1;
williamr@2:   ++_M_step;
williamr@2:   while (true) {
williamr@2:     _M_1d_idx += _M_gslice._M_strides[__dim];
williamr@2:     if (++_M_indices[__dim] != _M_gslice._M_lengths[__dim])
williamr@2:       return true;
williamr@2:     else if (__dim != 0) {
williamr@2:       _M_1d_idx -=
williamr@2: 	_M_gslice._M_strides[__dim] * _M_gslice._M_lengths[__dim];
williamr@2:       _M_indices[__dim] = 0;
williamr@2:       --__dim;
williamr@2:     }
williamr@2:     else
williamr@2:       return false;
williamr@2:   }
williamr@2: }
williamr@2: 
williamr@2: // Behavior is undefined if __x and *this have different sizes, or if
williamr@2: // __x was constructed from a degenerate gslice.
williamr@2: template <class _Tp>
williamr@2: valarray<_Tp>& valarray<_Tp>::operator=(const gslice_array<_Tp>& __x)
williamr@2: {
williamr@2:   if (this->size() != 0) {
williamr@2:     _Gslice_Iter __i(__x._M_gslice);
williamr@2:     do
williamr@2:       (*this)[__i._M_step] = __x._M_array[__i._M_1d_idx];
williamr@2:     while(__i._M_incr());
williamr@2:   }
williamr@2:   return *this;
williamr@2: }
williamr@2: 
williamr@2: template <class _Tp>
williamr@2: valarray<_Tp> valarray<_Tp>::operator[](gslice __slice) const
williamr@2: {
williamr@2:   valarray<_Tp> __tmp(__slice._M_size(), _NoInit());
williamr@2:   if (__tmp.size() != 0) {
williamr@2:     _Gslice_Iter __i(__slice);
williamr@2:     do __tmp[__i._M_step] = (*this)[__i._M_1d_idx]; while(__i._M_incr());
williamr@2:   }
williamr@2:   return __tmp;
williamr@2: }
williamr@2: 
williamr@2: template <class _Tp>
williamr@2: valarray<_Tp> valarray<_Tp>::operator[](const _Valarray_bool& __mask) const
williamr@2: {
williamr@2:   size_t _p_size = 0;
williamr@2:   {
williamr@2:     for (size_t __i = 0; __i < __mask.size(); ++__i)
williamr@2:       if (__mask[__i]) ++_p_size;
williamr@2:   }
williamr@2: 
williamr@2:   valarray<_Tp> __tmp(_p_size, _NoInit());
williamr@2:   size_t __idx = 0;
williamr@2:   {
williamr@2:     for (size_t __i = 0; __i < __mask.size(); ++__i)
williamr@2:       if (__mask[__i]) __tmp[__idx++] = (*this)[__i];
williamr@2:   }
williamr@2: 
williamr@2:   return __tmp;
williamr@2: }
williamr@2: 
williamr@2: template <class _Tp>
williamr@2: valarray<_Tp>& valarray<_Tp>::operator=(const indirect_array<_Tp>& __x) {
williamr@2:   for (size_t __i = 0; __i < __x._M_addr.size(); ++__i)
williamr@2:     (*this)[__i] = __x._M_array[__x._M_addr[__i]];
williamr@2:   return *this;
williamr@2: }
williamr@2: 
williamr@2: template <class _Tp>
williamr@2: valarray<_Tp>
williamr@2: valarray<_Tp>::operator[](const _Valarray_size_t& __addr) const
williamr@2: {
williamr@2:   valarray<_Tp> __tmp(__addr.size(), _NoInit());
williamr@2:   for (size_t __i = 0; __i < __addr.size(); ++__i)
williamr@2:     __tmp[__i] = (*this)[__addr[__i]];
williamr@2:   return __tmp;
williamr@2: }
williamr@2: 
williamr@2: //----------------------------------------------------------------------
williamr@2: // Other valarray noninline member functions
williamr@2: 
williamr@2: // Shift and cshift
williamr@2: 
williamr@2: template <class _Tp>
williamr@2: valarray<_Tp> valarray<_Tp>::shift(int __n) const
williamr@2: {
williamr@2:   valarray<_Tp> __tmp(this->size());
williamr@2: 
williamr@2:   if (__n >= 0) {
williamr@2:     if (__n < this->size())
williamr@2:       copy(this->_M_first + __n, this->_M_first + this->size(),
williamr@2:            __tmp._M_first);
williamr@2:   }
williamr@2:   else {
williamr@2:     if (-__n < this->size())
williamr@2:       copy(this->_M_first, this->_M_first + this->size() + __n,
williamr@2:            __tmp._M_first - __n);
williamr@2:   }
williamr@2:   return __tmp;
williamr@2: }
williamr@2: 
williamr@2: template <class _Tp>
williamr@2: valarray<_Tp> valarray<_Tp>::cshift(int __m) const
williamr@2: {
williamr@2:   valarray<_Tp> __tmp(this->size());
williamr@2:   
williamr@2: #ifdef __SYMBIAN32__
williamr@2: 	if (!this->size())
williamr@2: 		return __tmp;
williamr@2: #endif	
williamr@2: 	
williamr@2:   // Reduce __m to an equivalent number in the range [0, size()).  We
williamr@2:   // have to be careful with negative numbers, since the sign of a % b
williamr@2:   // is unspecified when a < 0.
williamr@2:   long __n = __m;
williamr@2:   if (this->size() < (numeric_limits<long>::max)())
williamr@2:     __n %= long(this->size());
williamr@2:   if (__n < 0)
williamr@2:     __n += this->size();
williamr@2: 
williamr@2:   copy(this->_M_first,       this->_M_first + __n,
williamr@2:        __tmp._M_first + (this->size() - __n));
williamr@2:   copy(this->_M_first + __n, this->_M_first + this->size(),
williamr@2:        __tmp._M_first);
williamr@2: 
williamr@2:   return __tmp;
williamr@2: }
williamr@2: 
williamr@2: _STLP_END_NAMESPACE
williamr@2: 
williamr@2: #endif /*  _STLP_VALARRAY_C */
williamr@2: 
williamr@2: // Local Variables:
williamr@2: // mode:C++
williamr@2: // End: