// valarray standard header #pragma once #ifndef _VALARRAY_ #define _VALARRAY_ #include #include #pragma pack(push,8) #pragma warning(push,3) #pragma warning(disable: 4244 4700) _STD_BEGIN // FORWARD REFERENCES class gslice; class slice; template class gslice_array; template class indirect_array; template class mask_array; template class slice_array; template class valarray; typedef valarray<_Bool> _Boolarray; typedef valarray _Sizarray; // MACROS FOR valarray #define _VALOP(TYPE, LENGTH, RHS) /* assign RHS(_Idx) to new valarray */ \ valarray _Ans(LENGTH); \ for (size_t _Idx = 0; _Idx < _Ans.size(); ++_Idx) \ _Ans[_Idx] = RHS; \ return _Ans #define _VALGOP(RHS) /* apply RHS(_Idx) to valarray */ \ for (size_t _Idx = 0; _Idx < size(); ++_Idx) \ _Myptr[_Idx] RHS; \ return *this // TEMPLATE CLASS valarray template class valarray { // store array with various indexing options public: typedef _Ty value_type; explicit valarray(size_t _Count = 0) { // construct with _Count * _Ty() _Tidy(); _Myres = _Count; _Grow(_Count); } valarray(const _Ty& _Val, size_t _Count) { // construct with _Count * _Val _Tidy(); _Grow(_Count, &_Val); } valarray(const _Ty *_Ptr, size_t _Count) { // construct with [_Ptr, _Ptr + _Count) _Tidy(); _Grow(_Count, _Ptr, 1); } valarray(const valarray<_Ty>& _Right) { // construct from valarray _Tidy(); _Grow(_Right.size(), _Right._Myptr, 1); } valarray(const slice_array<_Ty>& _Slicearr) { // construct from slice_array _Tidy(); *this = _Slicearr; } valarray(const gslice_array<_Ty>& _Gslicearr) { // construct from gslice_array _Tidy(); *this = _Gslicearr; } valarray(const mask_array<_Ty>& _Maskarr) { // construct from mask_array _Tidy(); *this = _Maskarr; } valarray(const indirect_array<_Ty>& _Indarr) { // construct from indirect_array _Tidy(); *this = _Indarr; } ~valarray() { // destroy the object _Tidy(true); } valarray<_Ty>& operator=(const valarray<_Ty>& _Right) { // assign valarray _Right if (this != &_Right) { // worth doing _Tidy(true); _Grow(_Right.size(), _Right._Myptr, 1); } return (*this); } valarray<_Ty>& operator=(const _Ty& _Val) { // assign _Val to each element _VALGOP(= _Val); } void resize(size_t _Newsize) { // determine new length, padding with _Ty() elements as needed resize(_Newsize, _Ty()); } void resize(size_t _Newsize, const _Ty _Val) { // determine new length, padding with _Val elements as needed _Grow(_Newsize, &_Val, 0, true); } valarray<_Ty>& operator=( const slice_array<_Ty>& _Slicearr); // defined below valarray<_Ty>& operator=( const gslice_array<_Ty>& _Gslicearr); // defined below valarray<_Ty>& operator=( const mask_array<_Ty>& _Maskarr); // defined below valarray<_Ty>& operator=( const indirect_array<_Ty>& _Indarr); // defined below valarray<_Ty> operator+() const { // return +valarray _VALOP(_Ty, size(), +_Myptr[_Idx]); } valarray<_Ty> operator-() const { // return -valarray _VALOP(_Ty, size(), -_Myptr[_Idx]); } valarray<_Ty> operator~() const { // return ~valarray _VALOP(_Ty, size(), ~_Myptr[_Idx]); } _Boolarray operator!() const { // return !valarray _VALOP(_Bool, size(), !_Myptr[_Idx]); } valarray<_Ty>& operator*=(const _Ty& _Right) { // multiply valarray elements by _Right _VALGOP(*= _Right); } valarray<_Ty>& operator/=(const _Ty& _Right) { // divide valarray elements by _Right _VALGOP(/= _Right); } valarray<_Ty>& operator%=(const _Ty& _Right) { // remainder valarray elements by _Right _VALGOP(%= _Right); } valarray<_Ty>& operator+=(const _Ty& _Right) { // add _Right to valarray elements _VALGOP(+= _Right); } valarray<_Ty>& operator-=(const _Ty& _Right) { // subtract _Right from valarray elements _VALGOP(-= _Right); } valarray<_Ty>& operator^=(const _Ty& _Right) { // XOR _Right into valarray elements _VALGOP(^= _Right); } valarray<_Ty>& operator&=(const _Ty& _Right) { // AND _Right into valarray elements _VALGOP(&= _Right); } valarray<_Ty>& operator|=(const _Ty& _Right) { // OR _Right into valarray elements _VALGOP(|= _Right); } valarray<_Ty>& operator<<=(const _Ty& _Right) { // left shift valarray elements by _Right _VALGOP(<<= _Right); } valarray<_Ty>& operator>>=(const _Ty& _Right) { // right shift valarray elements by _Right _VALGOP(>>= _Right); } valarray<_Ty>& operator*=(const valarray<_Ty>& _Right) { // multiply valarray elements by valarray _Right elements _VALGOP(*= _Right[_Idx]); } valarray<_Ty>& operator/=(const valarray<_Ty>& _Right) { // divide valarray elements by valarray _Right elements _VALGOP(/= _Right[_Idx]); } valarray<_Ty>& operator%=(const valarray<_Ty>& _Right) { // remainder valarray elements by valarray _Right elements _VALGOP(%= _Right[_Idx]); } valarray<_Ty>& operator+=(const valarray<_Ty>& _Right) { // add valarray _Right elements to valarray elements _VALGOP(+= _Right[_Idx]); } valarray<_Ty>& operator-=(const valarray<_Ty>& _Right) { // subtract valarray _Right elements from valarray elements _VALGOP(-= _Right[_Idx]); } valarray<_Ty>& operator^=(const valarray<_Ty>& _Right) { // XOR valarray _Right elements into valarray elements _VALGOP(^= _Right[_Idx]); } valarray<_Ty>& operator|=(const valarray<_Ty>& _Right) { // OR valarray _Right elements into valarray elements _VALGOP(|= _Right[_Idx]); } valarray<_Ty>& operator&=(const valarray<_Ty>& _Right) { // AND valarray _Right elements into valarray elements _VALGOP(&= _Right[_Idx]); } valarray<_Ty>& operator<<=(const valarray<_Ty>& _Right) { // left shift valarray elements by valarray _Right elements _VALGOP(<<= _Right[_Idx]); } valarray<_Ty>& operator>>=(const valarray<_Ty>& _Right) { // right shift valarray elements by valarray _Right elements _VALGOP(>>= _Right[_Idx]); } size_t size() const { // return length of sequence return (_Mysize); } _Ty operator[](size_t _Off) const { // subscript nonmutable sequence return (_Myptr[_Off]); } _Ty& operator[](size_t _Off) { // subscript mutable sequence return (_Myptr[_Off]); } valarray<_Ty> operator[]( slice _Slicearr) const; // defined below slice_array<_Ty> operator[]( slice _Slicearr); // defined below valarray<_Ty> operator[]( const gslice& _Gslicearr) const; // defined below gslice_array<_Ty> operator[]( const gslice& _Gslicearr); // defined below valarray<_Ty> operator[]( const _Boolarray& _Boolarr) const; // defined below mask_array<_Ty> operator[]( const _Boolarray& _Boolarr); // defined below valarray<_Ty> operator[]( const _Sizarray& _Indarr) const; // defined below indirect_array<_Ty> operator[]( const _Sizarray& _Indarr); // defined below _Ty sum() const { // return sum all elements _Ty _Sum = _Myptr[0]; for (size_t _Idx = 0; ++_Idx < size(); ) _Sum += _Myptr[_Idx]; return (_Sum); } _Ty min() const { // return smallest of all elements _Ty _Min = _Myptr[0]; for (size_t _Idx = 0; ++_Idx < size(); ) if (_Myptr[_Idx] < _Min) _Min = _Myptr[_Idx]; return (_Min); } _Ty max() const { // return largest of all elements _Ty _Max = _Myptr[0]; for (size_t _Idx = 0; ++_Idx < size(); ) if (_Max < _Myptr[_Idx]) _Max = _Myptr[_Idx]; return (_Max); } valarray<_Ty> shift(int _Count) const { // return valarray left shifted static _Ty _Dflt; _VALOP(_Ty, size(), 0 < _Count && size() - _Idx <= (size_t)_Count || _Count < 0 && _Idx < (size_t)-_Count ? _Dflt : _Myptr[_Idx + _Count]); } valarray<_Ty> cshift(int _Count) const { // return valarray left rotated if (size() == 0) ; // no shift else if (_Count < 0) { // right shift if ((_Count += size()) < 0) _Count = size() - (-_Count) % size(); } else if (size() <= (size_t)_Count) _Count %= size(); _VALOP(_Ty, size(), size() - _Idx <= (size_t)_Count ? _Myptr[_Idx - size() + _Count] : _Myptr[_Idx + _Count]); } valarray<_Ty> apply(_Ty _Func(_Ty)) const { // return valarray transformed by _Func, value argument _VALOP(_Ty, size(), _Func(_Myptr[_Idx])); } valarray<_Ty> apply(_Ty _Func(const _Ty&)) const { // return valarray transformed by _Func, nonmutable argument _VALOP(_Ty, size(), _Func(_Myptr[_Idx])); } void free() // retained { // erase all elements _Tidy(true); } private: void _Grow(size_t _Count, const _Ty *_Ptr = 0, size_t _Inc = 0, bool _Trim = false) { // grow to _Count elements and pad, trim if _Trim is true size_t _Oldsize = _Myptr == 0 ? 0 : _Myres; if (_Count == 0) { // new sequence empty if (_Trim) _Tidy(true); } else if (_Count == _Oldsize || _Count < _Oldsize && !_Trim) ; // big enough, no need to pad or trim else { // allocate new array, copy and pad size_t _Idx; size_t _Newsize = _Myptr == 0 && _Count < _Myres ? _Myres : _Count; _Ty *_Newptr = 0; size_t _Nm = _Count < _Mysize ? _Count : _Mysize; _TRY_BEGIN _Newptr = new _Ty[_Newsize]; _CATCH_ALL _Tidy(true); // allocation failed, discard storage and reraise _RERAISE; _CATCH_END for (_Idx = 0; _Idx < _Nm; ++_Idx) _Newptr[_Idx] = _Myptr[_Idx]; if (_Ptr != 0) for (; _Idx < _Newsize; ++_Idx, _Ptr += _Inc) _Newptr[_Idx] = *_Ptr; _Tidy(true); _Myptr = _Newptr; _Myres = _Newsize; } _Mysize = _Count; } void _Tidy(bool _Constructed = false) { // initialize the object, freeing any allocated storage if (_Constructed && _Myptr != 0) delete[] _Myptr; _Mysize = 0; _Myptr = 0; _Myres = 0; } _Ty *_Myptr; // current storage reserved for array size_t _Mysize; // current length of sequence size_t _Myres; // length of array }; // valarray TEMPLATE FUNCTIONS template inline valarray<_Ty> operator*(const valarray<_Ty>& _Left, const _Ty& _Right) { // return valarray * scalar _VALOP(_Ty, _Left.size(), _Left[_Idx] * _Right); } template inline valarray<_Ty> operator*(const _Ty& _Left, const valarray<_Ty>& _Right) { // return scalar * valarray _VALOP(_Ty, _Right.size(), _Left * _Right[_Idx]); } template inline valarray<_Ty> operator/(const valarray<_Ty>& _Left, const _Ty& _Right) { // return valarray / scalar _VALOP(_Ty, _Left.size(), _Left[_Idx] / _Right); } template inline valarray<_Ty> operator/(const _Ty& _Left, const valarray<_Ty>& _Right) { // return scalar / valarray _VALOP(_Ty, _Right.size(), _Left / _Right[_Idx]); } template inline valarray<_Ty> operator%(const valarray<_Ty>& _Left, const _Ty& _Right) { // return valarray % scalar _VALOP(_Ty, _Left.size(), _Left[_Idx] % _Right); } template inline valarray<_Ty> operator%(const _Ty& _Left, const valarray<_Ty>& _Right) { // return scalar % valarray _VALOP(_Ty, _Right.size(), _Left % _Right[_Idx]); } template inline valarray<_Ty> operator+(const valarray<_Ty>& _Left, const _Ty& _Right) { // return valarray + scalar _VALOP(_Ty, _Left.size(), _Left[_Idx] + _Right); } template inline valarray<_Ty> operator+(const _Ty& _Left, const valarray<_Ty>& _Right) { // return scalar + valarray _VALOP(_Ty, _Right.size(), _Left + _Right[_Idx]); } template inline valarray<_Ty> operator-(const valarray<_Ty>& _Left, const _Ty& _Right) { // return valarray - scalar _VALOP(_Ty, _Left.size(), _Left[_Idx] - _Right); } template inline valarray<_Ty> operator-(const _Ty& _Left, const valarray<_Ty>& _Right) { // return scalar - valarray _VALOP(_Ty, _Right.size(), _Left - _Right[_Idx]); } template inline valarray<_Ty> operator^(const valarray<_Ty>& _Left, const _Ty& _Right) { // return valarray ^ scalar _VALOP(_Ty, _Left.size(), _Left[_Idx] ^ _Right); } template inline valarray<_Ty> operator^(const _Ty& _Left, const valarray<_Ty>& _Right) { // return scalar ^ valarray _VALOP(_Ty, _Right.size(), _Left ^ _Right[_Idx]); } template inline valarray<_Ty> operator&(const valarray<_Ty>& _Left, const _Ty& _Right) { // return valarray & scalar _VALOP(_Ty, _Left.size(), _Left[_Idx] & _Right); } template inline valarray<_Ty> operator&(const _Ty& _Left, const valarray<_Ty>& _Right) { // return scalar & valarray _VALOP(_Ty, _Right.size(), _Left & _Right[_Idx]); } template inline valarray<_Ty> operator|(const valarray<_Ty>& _Left, const _Ty& _Right) { // return valarray | scalar _VALOP(_Ty, _Left.size(), _Left[_Idx] | _Right); } template inline valarray<_Ty> operator|(const _Ty& _Left, const valarray<_Ty>& _Right) { // return scalar | valarray _VALOP(_Ty, _Right.size(), _Left | _Right[_Idx]); } template inline valarray<_Ty> operator<<(const valarray<_Ty>& _Left, const _Ty& _Right) { // return valarray << scalar _VALOP(_Ty, _Left.size(), _Left[_Idx] << _Right); } template inline valarray<_Ty> operator<<(const _Ty& _Left, const valarray<_Ty>& _Right) { // return scalar << valarray _VALOP(_Ty, _Right.size(), _Left << _Right[_Idx]); } template inline valarray<_Ty> operator>>(const valarray<_Ty>& _Left, const _Ty& _Right) { // return valarray >> scalar _VALOP(_Ty, _Left.size(), _Left[_Idx] >> _Right); } template inline valarray<_Ty> operator>>(const _Ty& _Left, const valarray<_Ty>& _Right) { // return scalar >> valarray _VALOP(_Ty, _Right.size(), _Left >> _Right[_Idx]); } template inline _Boolarray operator&&(const valarray<_Ty>& _Left, const _Ty& _Right) { // return valarray && scalar _VALOP(_Bool, _Left.size(), _Left[_Idx] && _Right); } template inline _Boolarray operator&&(const _Ty& _Left, const valarray<_Ty>& _Right) { // return scalar && valarray _VALOP(_Bool, _Right.size(), _Left && _Right[_Idx]); } template inline _Boolarray operator||(const valarray<_Ty>& _Left, const _Ty& _Right) { // return valarray || scalar _VALOP(_Bool, _Left.size(), _Left[_Idx] || _Right); } template inline _Boolarray operator||(const _Ty& _Left, const valarray<_Ty>& _Right) { // return scalar || valarray _VALOP(_Bool, _Right.size(), _Left || _Right[_Idx]); } template inline valarray<_Ty> operator*(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // return valarray * valarray _VALOP(_Ty, _Left.size(), _Left[_Idx] * _Right[_Idx]); } template inline valarray<_Ty> operator/(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // return valarray ? valarray _VALOP(_Ty, _Left.size(), _Left[_Idx] / _Right[_Idx]); } template inline valarray<_Ty> operator%(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // return valarray % valarray _VALOP(_Ty, _Left.size(), _Left[_Idx] % _Right[_Idx]); } template inline valarray<_Ty> operator+(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // return valarray + valarray _VALOP(_Ty, _Left.size(), _Left[_Idx] + _Right[_Idx]); } template inline valarray<_Ty> operator-(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // return valarray - valarray _VALOP(_Ty, _Left.size(), _Left[_Idx] - _Right[_Idx]); } template inline valarray<_Ty> operator^(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // return valarray ^ valarray _VALOP(_Ty, _Left.size(), _Left[_Idx] ^ _Right[_Idx]); } template inline valarray<_Ty> operator&(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // return valarray & valarray _VALOP(_Ty, _Left.size(), _Left[_Idx] & _Right[_Idx]); } template inline valarray<_Ty> operator|(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // return valarray | valarray _VALOP(_Ty, _Left.size(), _Left[_Idx] | _Right[_Idx]); } template inline valarray<_Ty> operator<<(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // return valarray << valarray _VALOP(_Ty, _Left.size(), _Left[_Idx] << _Right[_Idx]); } template inline valarray<_Ty> operator>>(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // return valarray >> valarray _VALOP(_Ty, _Left.size(), _Left[_Idx] >> _Right[_Idx]); } template inline _Boolarray operator&&(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // return valarray && valarray _VALOP(_Bool, _Left.size(), _Left[_Idx] && _Right[_Idx]); } template inline _Boolarray operator||(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // return valarray || valarray _VALOP(_Bool, _Left.size(), _Left[_Idx] || _Right[_Idx]); } template inline _Boolarray operator==(const valarray<_Ty>& _Left, const _Ty& _Right) { // return valarray == scalar _VALOP(_Bool, _Left.size(), _Left[_Idx] == _Right); } template inline _Boolarray operator==(const _Ty& _Left, const valarray<_Ty>& _Right) { // return scalar == valarray _VALOP(_Bool, _Right.size(), _Left == _Right[_Idx]); } template inline _Boolarray operator==(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // return valarray == valarray _VALOP(_Bool, _Left.size(), _Left[_Idx] == _Right[_Idx]); } template inline _Boolarray operator!=(const valarray<_Ty>& _Left, const _Ty& _Right) { // return valarray != scalar _VALOP(_Bool, _Left.size(), _Left[_Idx] != _Right); } template inline _Boolarray operator!=(const _Ty& _Left, const valarray<_Ty>& _Right) { // return scalar != valarray _VALOP(_Bool, _Right.size(), _Left != _Right[_Idx]); } template inline _Boolarray operator!=(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // return valarray != valarray _VALOP(_Bool, _Left.size(), _Left[_Idx] != _Right[_Idx]); } template inline _Boolarray operator<(const valarray<_Ty>& _Left, const _Ty& _Right) { // return valarray < scalar _VALOP(_Bool, _Left.size(), _Left[_Idx] < _Right); } template inline _Boolarray operator<(const _Ty& _Left, const valarray<_Ty>& _Right) { // return scalar < valarray _VALOP(_Bool, _Right.size(), _Left < _Right[_Idx]); } template inline _Boolarray operator<(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // return valarray < valarray _VALOP(_Bool, _Left.size(), _Left[_Idx] < _Right[_Idx]); } template inline _Boolarray operator>(const valarray<_Ty>& _Left, const _Ty& _Right) { // return valarray > scalar _VALOP(_Bool, _Left.size(), _Left[_Idx] > _Right); } template inline _Boolarray operator>(const _Ty& _Left, const valarray<_Ty>& _Right) { // return scalar > valarray _VALOP(_Bool, _Right.size(), _Left > _Right[_Idx]); } template inline _Boolarray operator>(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // return valarray > valarray _VALOP(_Bool, _Left.size(), _Left[_Idx] > _Right[_Idx]); } template inline _Boolarray operator<=(const valarray<_Ty>& _Left, const _Ty& _Right) { // return valarray <= scalar _VALOP(_Bool, _Left.size(), _Left[_Idx] <= _Right); } template inline _Boolarray operator<=(const _Ty& _Left, const valarray<_Ty>& _Right) { // return scalar <= valarray _VALOP(_Bool, _Right.size(), _Left <= _Right[_Idx]); } template inline _Boolarray operator<=(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // return valarray <= valarray _VALOP(_Bool, _Left.size(), _Left[_Idx] <= _Right[_Idx]); } template inline _Boolarray operator>=(const valarray<_Ty>& _Left, const _Ty& _Right) { // return valarray >= scalar _VALOP(_Bool, _Left.size(), _Left[_Idx] >= _Right); } template inline _Boolarray operator>=(const _Ty& _Left, const valarray<_Ty>& _Right) { // return scalar >= valarray _VALOP(_Bool, _Right.size(), _Left >= _Right[_Idx]); } template inline _Boolarray operator>=(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // return valarray >= valarray _VALOP(_Bool, _Left.size(), _Left[_Idx] >= _Right[_Idx]); } template inline valarray<_Ty> abs(const valarray<_Ty>& _Left) { // apply abs to each element of valarray _VALOP(_Ty, _Left.size(), _Left[_Idx] < 0 ? -_Left[_Idx] : _Left[_Idx]); } template inline valarray<_Ty> acos(const valarray<_Ty>& _Left) { // apply acos to each element of valarray _VALOP(_Ty, _Left.size(), ::acos(_Left[_Idx])); } template inline valarray<_Ty> asin(const valarray<_Ty>& _Left) { // apply asin to each element of valarray _VALOP(_Ty, _Left.size(), ::asin(_Left[_Idx])); } template inline valarray<_Ty> atan(const valarray<_Ty>& _Left) { // apply atan to each element of valarray _VALOP(_Ty, _Left.size(), ::atan(_Left[_Idx])); } template inline valarray<_Ty> atan2(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // apply atan2 to pairs of valarray elements _VALOP(_Ty, _Left.size(), ::atan2(_Left[_Idx], _Right[_Idx])); } template inline valarray<_Ty> atan2(const valarray<_Ty>& _Left, const _Ty& _Right) { // apply atan2 to each valarray element and scalar _VALOP(_Ty, _Left.size(), ::atan2(_Left[_Idx], _Right)); } template inline valarray<_Ty> atan2(const _Ty& _Left, const valarray<_Ty>& _Right) { // apply atan2 to scalar and each valarray element _VALOP(_Ty, _Right.size(), ::atan2(_Left, _Right[_Idx])); } template inline valarray<_Ty> cos(const valarray<_Ty>& _Left) { // apply cos to each element of valarray _VALOP(_Ty, _Left.size(), ::cos(_Left[_Idx])); } template inline valarray<_Ty> cosh(const valarray<_Ty>& _Left) { // apply cosh to each element of valarray _VALOP(_Ty, _Left.size(), ::cosh(_Left[_Idx])); } template inline valarray<_Ty> exp(const valarray<_Ty>& _Left) { // apply exp to each element of valarray _VALOP(_Ty, _Left.size(), ::exp(_Left[_Idx])); } template inline valarray<_Ty> log(const valarray<_Ty>& _Left) { // apply log to each element of valarray _VALOP(_Ty, _Left.size(), ::log(_Left[_Idx])); } template inline valarray<_Ty> log10(const valarray<_Ty>& _Left) { // apply log10 to each element of valarray _VALOP(_Ty, _Left.size(), ::log10(_Left[_Idx])); } template inline valarray<_Ty> pow(const valarray<_Ty>& _Left, const valarray<_Ty>& _Right) { // apply pow to pairs of valarray elements _VALOP(_Ty, _Left.size(), ::pow(_Left[_Idx], _Right[_Idx])); } template inline valarray<_Ty> pow(const valarray<_Ty>& _Left, const _Ty& _Right) { // apply pow to each valarray element and scalar _VALOP(_Ty, _Left.size(), ::pow(_Left[_Idx], _Right)); } template inline valarray<_Ty> pow(const _Ty& _Left, const valarray<_Ty>& _Right) { // apply pow to scalar and each valarray element _VALOP(_Ty, _Right.size(), ::pow(_Left, _Right[_Idx])); } template inline valarray<_Ty> sin(const valarray<_Ty>& _Left) { // apply sin to each element of valarray _VALOP(_Ty, _Left.size(), ::sin(_Left[_Idx])); } template inline valarray<_Ty> sinh(const valarray<_Ty>& _Left) { // apply sinh to each element of valarray _VALOP(_Ty, _Left.size(), ::sinh(_Left[_Idx])); } template inline valarray<_Ty> sqrt(const valarray<_Ty>& _Left) { // apply sqrt to each element of valarray _VALOP(_Ty, _Left.size(), ::sqrt(_Left[_Idx])); } template inline valarray<_Ty> tan(const valarray<_Ty>& _Left) { // apply tan to each element of valarray _VALOP(_Ty, _Left.size(), ::tan(_Left[_Idx])); } template inline valarray<_Ty> tanh(const valarray<_Ty>& _Left) { // apply tanh to each element of valarray _VALOP(_Ty, _Left.size(), ::tanh(_Left[_Idx])); } // CLASS slice class slice { // define a slice of a valarray public: slice() : _Start(0), _Len(0), _Stride(0) { // construct with all zeros } slice(size_t _Off, size_t _Count, size_t _Inc) : _Start(_Off), _Len(_Count), _Stride(_Inc) { // construct slice from starting offset, length, and stride } size_t start() const { // return starting offset of slice return (_Start); } size_t size() const { // return number of elements specified by slice return (_Len); } size_t stride() const { // return distance between elements specified by slice return (_Stride); } protected: size_t _Start; // the starting offset size_t _Len; // the number of elements size_t _Stride; // the distance between elements }; // MACROS FOR slice_array #define _SLOP(RHS) /* apply RHS(_Idx) to slice_array */ \ size_t _Off = _Start; \ for (size_t _Idx = 0; _Idx < _Len; ++_Idx, _Off += _Stride) \ _Myptr[_Off] RHS; // TEMPLATE CLASS slice_array template class slice_array : public slice { // define a slice of a valarray public: typedef _Ty value_type; void operator=(const valarray<_Ty>& _Right) const { // assign a valarray to a slice _SLOP(= _Right[_Idx]); } void operator=(const _Ty& _Right) const { // assign a scalar to elements of a slice _SLOP(= _Right); } void operator*=(const valarray<_Ty>& _Right) const { // multiply slice by valarray _SLOP(*= _Right[_Idx]); } void operator/=(const valarray<_Ty>& _Right) const { // divide slice by valarray _SLOP(/= _Right[_Idx]); } void operator%=(const valarray<_Ty>& _Right) const { // remainder slice by valarray _SLOP(%= _Right[_Idx]); } void operator+=(const valarray<_Ty>& _Right) const { // add slice to valarray _SLOP(+= _Right[_Idx]); } void operator-=(const valarray<_Ty>& _Right) const { // subtract valarray from slice _SLOP(-= _Right[_Idx]); } void operator^=(const valarray<_Ty>& _Right) const { // XOR valarray into slice _SLOP(^= _Right[_Idx]); } void operator&=(const valarray<_Ty>& _Right) const { // AND valarray into slice _SLOP(&= _Right[_Idx]); } void operator|=(const valarray<_Ty>& _Right) const { // OR valarray into slice _SLOP(|= _Right[_Idx]); } void operator<<=(const valarray<_Ty>& _Right) const { // left shift slice by valarray _SLOP(<<= _Right[_Idx]); } void operator>>=(const valarray<_Ty>& _Right) const { // right shift slice by valarray _SLOP(>>= _Right[_Idx]); } _Ty& _Data(size_t _Idx) const { // return reference to underlying array element return (_Myptr[_Idx]); } private: friend class valarray<_Ty>; slice_array(const slice& _Slice, _Ty *_Pdata) : slice(_Slice), _Myptr(_Pdata) { // construct from slice and pointer to valarray contents } // slice_array(); // not defined // slice_array(const slice_array&); // not defined // slice_array& operator=(const slice_array&); // not defined _Ty *_Myptr; // pointer to valarray contents }; // CLASS gslice class gslice { // define a generalized (multidimensional) slice of a valarray public: gslice() : _Start(0) { // construct with all zeros } gslice(size_t _Off, const _Sizarray& _Lenarr, const _Sizarray& _Incarr) : _Start(_Off), _Len(_Lenarr), _Stride(_Incarr) { // construct from starting offset, arrays of lengths and strides } size_t start() const { // return starting offset of generalized slice return (_Start); } _Sizarray size() const { // return array of lengths of slices return (_Len); } _Sizarray stride() const { // return array of strides of slices return (_Stride); } size_t _Nslice() const { // return number of slices return (_Len.size()); } size_t _Off(_Sizarray& _Indexarr) const { // return offset for an array of indexes, then increment size_t _Idx, _Ans = _Start; for (_Idx = 0; _Idx < _Indexarr.size(); ++_Idx) _Ans += _Indexarr[_Idx] * _Stride[_Idx]; // compute offset while (0 < _Idx--) if (++_Indexarr[_Idx] < _Len[_Idx]) break; // increment done, quit else _Indexarr[_Idx] = 0; // carry to more-significant index return (_Ans); } size_t _Totlen() const { // return total length of generalized slice if (_Len.size() == 0) return (0); size_t _Count = _Len[0]; for (size_t _Idx = 0; ++_Idx < _Len.size(); ) _Count *= _Len[_Idx]; return (_Count); } private: size_t _Start; // the starting offset _Sizarray _Len; // array of numbers of elements _Sizarray _Stride; // array of distances between elements }; // MACROS FOR gslice_array #define _GSLOP(RHS) /* apply RHS(_Idx) to gslice_array */ \ _Sizarray _Indexarray((size_t)0, _Nslice()); \ size_t _Size = _Totlen(); \ for (size_t _Idx = 0; _Idx < _Size; ++_Idx) \ _Myptr[_Off(_Indexarray)] RHS; // TEMPLATE CLASS gslice_array template class gslice_array : public gslice { // define a generalized slice of a valarray public: typedef _Ty value_type; void operator=(const valarray<_Ty>& _Right) const { // assign a valarray to a generalized slice _GSLOP(= _Right[_Idx]); } void operator=(const _Ty& _Right) const { // assign a scalar to elements of a generalized slice _GSLOP(= _Right); } void operator*=(const valarray<_Ty>& _Right) const { // multiply generalized slice by valarray _GSLOP(*= _Right[_Idx]); } void operator/=(const valarray<_Ty>& _Right) const { // divide generalized slice by valarray _GSLOP(/= _Right[_Idx]); } void operator%=(const valarray<_Ty>& _Right) const { // remainder generalized slice by valarray _GSLOP(%= _Right[_Idx]); } void operator+=(const valarray<_Ty>& _Right) const { // add valarray to generalized slice _GSLOP(+= _Right[_Idx]); } void operator-=(const valarray<_Ty>& _Right) const { // subtract valarray from generalized slice _GSLOP(-= _Right[_Idx]); } void operator^=(const valarray<_Ty>& _Right) const { // XOR valarray into generalized slice _GSLOP(^= _Right[_Idx]); } void operator&=(const valarray<_Ty>& _Right) const { // AND valarray into generalized slice _GSLOP(&= _Right[_Idx]); } void operator|=(const valarray<_Ty>& _Right) const { // OR valarray into generalized slice _GSLOP(|= _Right[_Idx]); } void operator<<=(const valarray<_Ty>& _Right) const { // left shift generalized slice by valarray _GSLOP(<<= _Right[_Idx]); } void operator>>=(const valarray<_Ty>& _Right) const { // right shift generalized slice by valarray _GSLOP(>>= _Right[_Idx]); } _Ty& _Data(size_t _Idx) const { // return reference to underlying array element return (_Myptr[_Idx]); } private: friend class valarray<_Ty>; gslice_array(const gslice& _Gslice, _Ty *_Ptr) : gslice(_Gslice), _Myptr(_Ptr) { // construct from gslice and pointer to valarray contents } // gslice_array(); // not defined // gslice_array(const gslice_array&); // not defined // gslice_array& operator=( const gslice_array&); // not defined _Ty *_Myptr; // pointer to valarray contents }; // MACROS FOR mask_array #define _MOP(RHS) /* apply RHS(_Idx) to mask_array */ \ size_t _Off = 0; \ size_t _Size = _Totlen(); \ for (size_t _Idx = 0; _Idx < _Size; ++_Off) \ if (_Mask(_Off)) \ _Myptr[_Off] RHS, ++_Idx; // TEMPLATE CLASS mask_array template class mask_array { // define a subset of a valarray with an array of mask bits public: typedef _Ty value_type; void operator=(const valarray<_Ty>& _Right) const { // assign a valarray to a masked array _MOP(= _Right[_Idx]); } void operator=(const _Ty& _Right) const { // assign a scalar to elements of a masked array _MOP(= _Right); } void operator*=(const valarray<_Ty>& _Right) const { // multiply masked array by valarray _MOP(*= _Right[_Idx]); } void operator/=(const valarray<_Ty>& _Right) const { // divide masked array by valarray _MOP(/= _Right[_Idx]); } void operator%=(const valarray<_Ty>& _Right) const { // remainder masked array by valarray _MOP(%= _Right[_Idx]); } void operator+=(const valarray<_Ty>& _Right) const { // add valarray to masked array _MOP(+= _Right[_Idx]); } void operator-=(const valarray<_Ty>& _Right) const { // subtract valarray from masked array _MOP(-= _Right[_Idx]); } void operator^=(const valarray<_Ty>& _Right) const { // XOR valarray into masked array _MOP(^= _Right[_Idx]); } void operator&=(const valarray<_Ty>& _Right) const { // OR valarray into masked array _MOP(&= _Right[_Idx]); } void operator|=(const valarray<_Ty>& _Right) const { // OR valarray into masked array _MOP(|= _Right[_Idx]); } void operator<<=(const valarray<_Ty>& _Right) const { // left shift masked array by valarray _MOP(<<= _Right[_Idx]); } void operator>>=(const valarray<_Ty>& _Right) const { // right shift masked array by valarray _MOP(>>= _Right[_Idx]); } _Ty& _Data(size_t _Idx) const { // return reference to underlying array element return (_Myptr[_Idx]); } bool _Mask(size_t _Idx) const { // return mask element for a given index return (_Mybool[_Idx]); } size_t _Totlen() const { // return total length of masked array size_t _Count = 0; for (size_t _Idx = 0; _Idx < _Mybool.size(); ++_Idx) if (_Mybool[_Idx]) ++_Count; return (_Count); } private: friend class valarray<_Ty>; mask_array(const _Boolarray& _Maskarr, _Ty *_Pdata) : _Mybool(_Maskarr), _Myptr(_Pdata) { // construct from mask array and pointer to valarray contents } // mask_array(); // not defined // mask_array(const mask_array&); // not defined // mask_array& operator=(const mask_array&); // not defined _Boolarray _Mybool; // array of mask bits _Ty *_Myptr; // pointer to valarray contents }; // MACROS FOR indirect_array #define _IOP(RHS) /* apply RHS(_Idx) to indirect_array */ \ size_t _Size = _Totlen(); \ for (size_t _Idx = 0; _Idx < _Size; ++_Idx) \ _Myptr[_Indir(_Idx)] RHS; // TEMPLATE CLASS indirect_array template class indirect_array { // define a subset of a valarray with an array of indexes public: typedef _Ty value_type; void operator=(const valarray<_Ty>& _Right) const { // assign a valarray to an indirect array _IOP(= _Right[_Idx]); } void operator=(const _Ty& _Right) const { // assign a scalar to elements of an indirect array _IOP(= _Right); } void operator*=(const valarray<_Ty>& _Right) const { // multiply indirect array by valarray _IOP(*= _Right[_Idx]); } void operator/=(const valarray<_Ty>& _Right) const { // divide indirect array by valarray _IOP(/= _Right[_Idx]); } void operator%=(const valarray<_Ty>& _Right) const { // remainder indirect array by valarray _IOP(%= _Right[_Idx]); } void operator+=(const valarray<_Ty>& _Right) const { // add valarray to indirect array _IOP(+= _Right[_Idx]); } void operator-=(const valarray<_Ty>& _Right) const { // subtract valarray from indirect array _IOP(-= _Right[_Idx]); } void operator^=(const valarray<_Ty>& _Right) const { // XOR valarray into indirect array _IOP(^= _Right[_Idx]); } void operator&=(const valarray<_Ty>& _Right) const { // AND valarray into indirect array _IOP(&= _Right[_Idx]); } void operator|=(const valarray<_Ty>& _Right) const { // OR valarray into indirect array _IOP(|= _Right[_Idx]); } void operator<<=(const valarray<_Ty>& _Right) const { // left shift indirect array by valarray _IOP(<<= _Right[_Idx]); } void operator>>=(const valarray<_Ty>& _Right) const { // right shift indirect array by valarray _IOP(>>= _Right[_Idx]); } _Ty& _Data(size_t _Idx) const { // return reference to underlying array element return (_Myptr[_Idx]); } size_t _Indir(size_t _Idx) const { // return mapped index for a given index return (_Myindarr[_Idx]); } size_t _Totlen() const { // return total length of indirect array return (_Myindarr.size()); } private: friend class valarray<_Ty>; indirect_array(const _Sizarray& _Indarr, _Ty *_Ptr) : _Myindarr(_Indarr), _Myptr(_Ptr) { // construct from indirect array and pointer to valarray contents } // indirect_array(); // not defined // indirect_array(const indirect_array&); // not defined // indirect_array& operator=(const indirect_array&); // not defined _Sizarray _Myindarr; // array of indirect indexes _Ty *_Myptr; // pointer to valarray contents }; // slice_array TEMPLATE FUNCTIONS template inline valarray<_Ty>& valarray<_Ty>::operator=( const slice_array<_Ty>& _Slicearr) { // assign slice array to valarray _Tidy(true); _Grow(_Slicearr.size(), &_Slicearr._Data(_Slicearr.start()), _Slicearr.stride()); return (*this); } template inline valarray<_Ty> valarray<_Ty>::operator[](slice _Slice) const { // subscript nonmutable valarray by slice return (valarray<_Ty>(slice_array<_Ty>(_Slice, _Myptr))); } template inline slice_array<_Ty> valarray<_Ty>::operator[](slice _Slice) { // subscript mutable valarray by slice return (slice_array<_Ty>(_Slice, _Myptr)); } // gslice_array TEMPLATE FUNCTIONS template inline valarray<_Ty>& valarray<_Ty>::operator=( const gslice_array<_Ty>& _Gslicearr) { // assign generalized slice array to valarray _Tidy(true); _Grow(_Gslicearr._Totlen()); _Sizarray _Indexarray((size_t)0, _Gslicearr._Nslice()); _VALGOP(= _Gslicearr._Data(_Gslicearr._Off(_Indexarray))); } template inline valarray<_Ty> valarray<_Ty>::operator[](const gslice& _Gslice) const { // subscript nonmutable valarray by generalized slice return (valarray<_Ty>(gslice_array<_Ty>(_Gslice, _Myptr))); } template inline gslice_array<_Ty> valarray<_Ty>::operator[](const gslice& _Gslicearr) { // subscript mutable valarray by generalized slice return (gslice_array<_Ty>(_Gslicearr, _Myptr)); } // mask_array TEMPLATE FUNCTIONS template inline valarray<_Ty>& valarray<_Ty>::operator=(const mask_array<_Ty>& _Maskarr) { // assign masked array to valarray _Tidy(true); _Grow(_Maskarr._Totlen()); size_t _Count = 0; for (size_t _Idx = 0; _Idx < size(); ++_Count) if (_Maskarr._Mask(_Count)) _Myptr[_Idx++] = _Maskarr._Data(_Count); return (*this); } template inline valarray<_Ty> valarray<_Ty>::operator[](const _Boolarray& _Boolarr) const { // subscript nonmutable valarray by boolean (mask) array return (valarray<_Ty>(mask_array<_Ty>(_Boolarr, _Myptr))); } template inline mask_array<_Ty> valarray<_Ty>::operator[](const _Boolarray& _Boolarr) { // subscript nonmutable valarray by boolean (mask) array return (mask_array<_Ty>(_Boolarr, _Myptr)); } // indirect_array TEMPLATE FUNCTIONS template inline valarray<_Ty>& valarray<_Ty>::operator=( const indirect_array<_Ty>& _Indarr) { // assign indirect array to valarray _Tidy(true); _Grow(_Indarr._Totlen()); _VALGOP(= _Indarr._Data(_Indarr._Indir(_Idx))); } template inline valarray<_Ty> valarray<_Ty>::operator[](const _Sizarray& _Indarr) const { // subscript nonmutable valarray by indirect (mapping) array return (valarray<_Ty>(indirect_array<_Ty>(_Indarr, _Myptr))); } template inline indirect_array<_Ty> valarray<_Ty>::operator[](const _Sizarray& _Indarr) { // subscript mutable valarray by indirect (mapping) array return (indirect_array<_Ty>(_Indarr, _Myptr)); } _STD_END #pragma warning(default: 4244) #pragma warning(default: 4700) #pragma warning(pop) #pragma pack(pop) #endif /* _VALARRAY_ */ /* * Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V3.10:0009 */