You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1542 lines
40 KiB
1542 lines
40 KiB
// valarray standard header
|
|
#pragma once
|
|
#ifndef _VALARRAY_
|
|
#define _VALARRAY_
|
|
#include <cmath>
|
|
#include <xstddef>
|
|
|
|
#pragma pack(push,8)
|
|
#pragma warning(push,3)
|
|
|
|
#pragma warning(disable: 4244 4700)
|
|
_STD_BEGIN
|
|
|
|
// FORWARD REFERENCES
|
|
class gslice;
|
|
class slice;
|
|
|
|
template<class _Ty>
|
|
class gslice_array;
|
|
template<class _Ty>
|
|
class indirect_array;
|
|
template<class _Ty>
|
|
class mask_array;
|
|
template<class _Ty>
|
|
class slice_array;
|
|
template<class _Ty>
|
|
class valarray;
|
|
|
|
typedef valarray<_Bool> _Boolarray;
|
|
typedef valarray<size_t> _Sizarray;
|
|
|
|
// MACROS FOR valarray
|
|
#define _VALOP(TYPE, LENGTH, RHS) /* assign RHS(_Idx) to new valarray */ \
|
|
valarray<TYPE> _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 _Ty>
|
|
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<class _Ty> inline
|
|
valarray<_Ty> operator*(const valarray<_Ty>& _Left,
|
|
const _Ty& _Right)
|
|
{ // return valarray * scalar
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] * _Right);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator*(const _Ty& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return scalar * valarray
|
|
_VALOP(_Ty, _Right.size(), _Left * _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator/(const valarray<_Ty>& _Left,
|
|
const _Ty& _Right)
|
|
{ // return valarray / scalar
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] / _Right);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator/(const _Ty& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return scalar / valarray
|
|
_VALOP(_Ty, _Right.size(), _Left / _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator%(const valarray<_Ty>& _Left,
|
|
const _Ty& _Right)
|
|
{ // return valarray % scalar
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] % _Right);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator%(const _Ty& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return scalar % valarray
|
|
_VALOP(_Ty, _Right.size(), _Left % _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator+(const valarray<_Ty>& _Left,
|
|
const _Ty& _Right)
|
|
{ // return valarray + scalar
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] + _Right);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator+(const _Ty& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return scalar + valarray
|
|
_VALOP(_Ty, _Right.size(), _Left + _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator-(const valarray<_Ty>& _Left,
|
|
const _Ty& _Right)
|
|
{ // return valarray - scalar
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] - _Right);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator-(const _Ty& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return scalar - valarray
|
|
_VALOP(_Ty, _Right.size(), _Left - _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator^(const valarray<_Ty>& _Left,
|
|
const _Ty& _Right)
|
|
{ // return valarray ^ scalar
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] ^ _Right);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator^(const _Ty& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return scalar ^ valarray
|
|
_VALOP(_Ty, _Right.size(), _Left ^ _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator&(const valarray<_Ty>& _Left,
|
|
const _Ty& _Right)
|
|
{ // return valarray & scalar
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] & _Right);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator&(const _Ty& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return scalar & valarray
|
|
_VALOP(_Ty, _Right.size(), _Left & _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator|(const valarray<_Ty>& _Left,
|
|
const _Ty& _Right)
|
|
{ // return valarray | scalar
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] | _Right);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator|(const _Ty& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return scalar | valarray
|
|
_VALOP(_Ty, _Right.size(), _Left | _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator<<(const valarray<_Ty>& _Left,
|
|
const _Ty& _Right)
|
|
{ // return valarray << scalar
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] << _Right);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator<<(const _Ty& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return scalar << valarray
|
|
_VALOP(_Ty, _Right.size(), _Left << _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator>>(const valarray<_Ty>& _Left,
|
|
const _Ty& _Right)
|
|
{ // return valarray >> scalar
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] >> _Right);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator>>(const _Ty& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return scalar >> valarray
|
|
_VALOP(_Ty, _Right.size(), _Left >> _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator&&(const valarray<_Ty>& _Left,
|
|
const _Ty& _Right)
|
|
{ // return valarray && scalar
|
|
_VALOP(_Bool, _Left.size(), _Left[_Idx] && _Right);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator&&(const _Ty& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return scalar && valarray
|
|
_VALOP(_Bool, _Right.size(), _Left && _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator||(const valarray<_Ty>& _Left,
|
|
const _Ty& _Right)
|
|
{ // return valarray || scalar
|
|
_VALOP(_Bool, _Left.size(), _Left[_Idx] || _Right);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator||(const _Ty& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return scalar || valarray
|
|
_VALOP(_Bool, _Right.size(), _Left || _Right[_Idx]);
|
|
}
|
|
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator*(const valarray<_Ty>& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return valarray * valarray
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] * _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator/(const valarray<_Ty>& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return valarray ? valarray
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] / _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator%(const valarray<_Ty>& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return valarray % valarray
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] % _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator+(const valarray<_Ty>& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return valarray + valarray
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] + _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator-(const valarray<_Ty>& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return valarray - valarray
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] - _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator^(const valarray<_Ty>& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return valarray ^ valarray
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] ^ _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator&(const valarray<_Ty>& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return valarray & valarray
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] & _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator|(const valarray<_Ty>& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return valarray | valarray
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] | _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator<<(const valarray<_Ty>& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return valarray << valarray
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] << _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> operator>>(const valarray<_Ty>& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return valarray >> valarray
|
|
_VALOP(_Ty, _Left.size(), _Left[_Idx] >> _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator&&(const valarray<_Ty>& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return valarray && valarray
|
|
_VALOP(_Bool, _Left.size(), _Left[_Idx] && _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator||(const valarray<_Ty>& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return valarray || valarray
|
|
_VALOP(_Bool, _Left.size(), _Left[_Idx] || _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator==(const valarray<_Ty>& _Left,
|
|
const _Ty& _Right)
|
|
{ // return valarray == scalar
|
|
_VALOP(_Bool, _Left.size(), _Left[_Idx] == _Right);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator==(const _Ty& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return scalar == valarray
|
|
_VALOP(_Bool, _Right.size(), _Left == _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator==(const valarray<_Ty>& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return valarray == valarray
|
|
_VALOP(_Bool, _Left.size(), _Left[_Idx] == _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator!=(const valarray<_Ty>& _Left,
|
|
const _Ty& _Right)
|
|
{ // return valarray != scalar
|
|
_VALOP(_Bool, _Left.size(), _Left[_Idx] != _Right);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator!=(const _Ty& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return scalar != valarray
|
|
_VALOP(_Bool, _Right.size(), _Left != _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator!=(const valarray<_Ty>& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return valarray != valarray
|
|
_VALOP(_Bool, _Left.size(), _Left[_Idx] != _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator<(const valarray<_Ty>& _Left,
|
|
const _Ty& _Right)
|
|
{ // return valarray < scalar
|
|
_VALOP(_Bool, _Left.size(), _Left[_Idx] < _Right);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator<(const _Ty& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return scalar < valarray
|
|
_VALOP(_Bool, _Right.size(), _Left < _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator<(const valarray<_Ty>& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return valarray < valarray
|
|
_VALOP(_Bool, _Left.size(), _Left[_Idx] < _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator>(const valarray<_Ty>& _Left,
|
|
const _Ty& _Right)
|
|
{ // return valarray > scalar
|
|
_VALOP(_Bool, _Left.size(), _Left[_Idx] > _Right);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator>(const _Ty& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return scalar > valarray
|
|
_VALOP(_Bool, _Right.size(), _Left > _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator>(const valarray<_Ty>& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return valarray > valarray
|
|
_VALOP(_Bool, _Left.size(), _Left[_Idx] > _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator<=(const valarray<_Ty>& _Left,
|
|
const _Ty& _Right)
|
|
{ // return valarray <= scalar
|
|
_VALOP(_Bool, _Left.size(), _Left[_Idx] <= _Right);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator<=(const _Ty& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return scalar <= valarray
|
|
_VALOP(_Bool, _Right.size(), _Left <= _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator<=(const valarray<_Ty>& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return valarray <= valarray
|
|
_VALOP(_Bool, _Left.size(), _Left[_Idx] <= _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator>=(const valarray<_Ty>& _Left,
|
|
const _Ty& _Right)
|
|
{ // return valarray >= scalar
|
|
_VALOP(_Bool, _Left.size(), _Left[_Idx] >= _Right);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator>=(const _Ty& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return scalar >= valarray
|
|
_VALOP(_Bool, _Right.size(), _Left >= _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Boolarray operator>=(const valarray<_Ty>& _Left,
|
|
const valarray<_Ty>& _Right)
|
|
{ // return valarray >= valarray
|
|
_VALOP(_Bool, _Left.size(), _Left[_Idx] >= _Right[_Idx]);
|
|
}
|
|
|
|
template<class _Ty> 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<class _Ty> inline
|
|
valarray<_Ty> acos(const valarray<_Ty>& _Left)
|
|
{ // apply acos to each element of valarray
|
|
_VALOP(_Ty, _Left.size(), ::acos(_Left[_Idx]));
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> asin(const valarray<_Ty>& _Left)
|
|
{ // apply asin to each element of valarray
|
|
_VALOP(_Ty, _Left.size(), ::asin(_Left[_Idx]));
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> atan(const valarray<_Ty>& _Left)
|
|
{ // apply atan to each element of valarray
|
|
_VALOP(_Ty, _Left.size(), ::atan(_Left[_Idx]));
|
|
}
|
|
|
|
template<class _Ty> 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<class _Ty> 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<class _Ty> 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<class _Ty> inline
|
|
valarray<_Ty> cos(const valarray<_Ty>& _Left)
|
|
{ // apply cos to each element of valarray
|
|
_VALOP(_Ty, _Left.size(), ::cos(_Left[_Idx]));
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> cosh(const valarray<_Ty>& _Left)
|
|
{ // apply cosh to each element of valarray
|
|
_VALOP(_Ty, _Left.size(), ::cosh(_Left[_Idx]));
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> exp(const valarray<_Ty>& _Left)
|
|
{ // apply exp to each element of valarray
|
|
_VALOP(_Ty, _Left.size(), ::exp(_Left[_Idx]));
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> log(const valarray<_Ty>& _Left)
|
|
{ // apply log to each element of valarray
|
|
_VALOP(_Ty, _Left.size(), ::log(_Left[_Idx]));
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> log10(const valarray<_Ty>& _Left)
|
|
{ // apply log10 to each element of valarray
|
|
_VALOP(_Ty, _Left.size(), ::log10(_Left[_Idx]));
|
|
}
|
|
|
|
template<class _Ty> 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<class _Ty> 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<class _Ty> 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<class _Ty> inline
|
|
valarray<_Ty> sin(const valarray<_Ty>& _Left)
|
|
{ // apply sin to each element of valarray
|
|
_VALOP(_Ty, _Left.size(), ::sin(_Left[_Idx]));
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> sinh(const valarray<_Ty>& _Left)
|
|
{ // apply sinh to each element of valarray
|
|
_VALOP(_Ty, _Left.size(), ::sinh(_Left[_Idx]));
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> sqrt(const valarray<_Ty>& _Left)
|
|
{ // apply sqrt to each element of valarray
|
|
_VALOP(_Ty, _Left.size(), ::sqrt(_Left[_Idx]));
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
valarray<_Ty> tan(const valarray<_Ty>& _Left)
|
|
{ // apply tan to each element of valarray
|
|
_VALOP(_Ty, _Left.size(), ::tan(_Left[_Idx]));
|
|
}
|
|
|
|
template<class _Ty> 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 _Ty>
|
|
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 _Ty>
|
|
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 _Ty>
|
|
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 _Ty>
|
|
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<class _Ty> 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<class _Ty> inline
|
|
valarray<_Ty> valarray<_Ty>::operator[](slice _Slice) const
|
|
{ // subscript nonmutable valarray by slice
|
|
return (valarray<_Ty>(slice_array<_Ty>(_Slice, _Myptr)));
|
|
}
|
|
|
|
template<class _Ty> 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<class _Ty> 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<class _Ty> 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<class _Ty> 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<class _Ty> 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<class _Ty> 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<class _Ty> 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<class _Ty> 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<class _Ty> 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<class _Ty> 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 */
|