📄 valarray
字号:
// valarray standard header
#pragma once
#ifndef _VALARRAY_
#define _VALARRAY_
#ifndef RC_INVOKED
#include <cmath>
#include <memory>
#pragma pack(push,_CRT_PACKING)
#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 valarray<_Ty> _Myt;
typedef _Ty value_type;
valarray()
{ // construct empty valarray
_Tidy();
}
explicit valarray(size_t _Count)
{ // construct with _Count * _Ty()
_Tidy();
_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 _Myt& _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(_Myt&& _Right)
{ // construct by moving _Right
_Tidy();
_Assign_rv(_STD forward<_Myt>(_Right));
}
_Myt& operator=(_Myt&& _Right)
{ // assign by moving _Right
_Assign_rv(_STD forward<_Myt>(_Right));
return (*this);
}
void _Assign_rv(_Myt&& _Right)
{ // assign by moving _Right
if (this != &_Right)
{ // clear this and steal from _Right
_Tidy(true);
_Myptr = _Right._Myptr;
_Mysize = _Right._Mysize;
_Right._Tidy();
}
}
void swap(_Myt&& _Right)
{ // exchange contents with movable _Right
_Assign_rv(_STD forward<_Myt>(_Right));
}
void swap(_Myt& _Right)
{ // exchange contents with _Right
if (this != &_Right)
{ // swap with emptied container
_STD swap(_Myptr, _Right._Myptr);
_STD swap(_Mysize, _Right._Mysize);
}
}
~valarray()
{ // destroy the object
_Tidy(true);
}
_Myt& operator=(const _Myt& _Right)
{ // assign valarray _Right
if (this == &_Right)
; // do nothing
else if (size() == _Right.size())
for (size_t _Idx = 0; _Idx < size(); ++_Idx)
_Myptr[_Idx] = _Right[_Idx];
else
{ // resize and copy
_Tidy(true);
_Grow(_Right.size(), _Right._Myptr, 1);
}
return (*this);
}
_Myt& operator=(const _Ty& _Val)
{ // assign _Val to each element
_VALGOP(= _Val);
}
void resize(size_t _Newsize)
{ // determine new length, filling with _Ty() elements
_Tidy(true);
_Grow(_Newsize);
}
void resize(size_t _Newsize, const _Ty _Val)
{ // determine new length, filling with _Val elements
_Tidy(true);
_Grow(_Newsize, &_Val, 0);
}
_Myt& operator=(
const slice_array<_Ty>& _Slicearr); // defined below
_Myt& operator=(
const gslice_array<_Ty>& _Gslicearr); // defined below
_Myt& operator=(
const mask_array<_Ty>& _Maskarr); // defined below
_Myt& operator=(
const indirect_array<_Ty>& _Indarr); // defined below
_Myt operator+() const
{ // return +valarray
_VALOP(_Ty, size(), +_Myptr[_Idx]);
}
_Myt operator-() const
{ // return -valarray
_VALOP(_Ty, size(), -_Myptr[_Idx]);
}
_Myt operator~() const
{ // return ~valarray
_VALOP(_Ty, size(), ~_Myptr[_Idx]);
}
_Boolarray operator!() const
{ // return !valarray
_VALOP(_Bool, size(), !_Myptr[_Idx]);
}
_Myt& operator*=(const _Ty& _Right)
{ // multiply valarray elements by _Right
_VALGOP(*= _Right);
}
_Myt& operator/=(const _Ty& _Right)
{ // divide valarray elements by _Right
_VALGOP(/= _Right);
}
_Myt& operator%=(const _Ty& _Right)
{ // remainder valarray elements by _Right
_VALGOP(%= _Right);
}
_Myt& operator+=(const _Ty& _Right)
{ // add _Right to valarray elements
_VALGOP(+= _Right);
}
_Myt& operator-=(const _Ty& _Right)
{ // subtract _Right from valarray elements
_VALGOP(-= _Right);
}
_Myt& operator^=(const _Ty& _Right)
{ // XOR _Right into valarray elements
_VALGOP(^= _Right);
}
_Myt& operator&=(const _Ty& _Right)
{ // AND _Right into valarray elements
_VALGOP(&= _Right);
}
_Myt& operator|=(const _Ty& _Right)
{ // OR _Right into valarray elements
_VALGOP(|= _Right);
}
_Myt& operator<<=(const _Ty& _Right)
{ // left shift valarray elements by _Right
_VALGOP(<<= _Right);
}
_Myt& operator>>=(const _Ty& _Right)
{ // right shift valarray elements by _Right
_VALGOP(>>= _Right);
}
_Myt& operator*=(const _Myt& _Right)
{ // multiply valarray elements by valarray _Right elements
_VALGOP(*= _Right[_Idx]);
}
_Myt& operator/=(const _Myt& _Right)
{ // divide valarray elements by valarray _Right elements
_VALGOP(/= _Right[_Idx]);
}
_Myt& operator%=(const _Myt& _Right)
{ // remainder valarray elements by valarray _Right elements
_VALGOP(%= _Right[_Idx]);
}
_Myt& operator+=(const _Myt& _Right)
{ // add valarray _Right elements to valarray elements
_VALGOP(+= _Right[_Idx]);
}
_Myt& operator-=(const _Myt& _Right)
{ // subtract valarray _Right elements from valarray elements
_VALGOP(-= _Right[_Idx]);
}
_Myt& operator^=(const _Myt& _Right)
{ // XOR valarray _Right elements into valarray elements
_VALGOP(^= _Right[_Idx]);
}
_Myt& operator|=(const _Myt& _Right)
{ // OR valarray _Right elements into valarray elements
_VALGOP(|= _Right[_Idx]);
}
_Myt& operator&=(const _Myt& _Right)
{ // AND valarray _Right elements into valarray elements
_VALGOP(&= _Right[_Idx]);
}
_Myt& operator<<=(const _Myt& _Right)
{ // left shift valarray elements by valarray _Right elements
_VALGOP(<<= _Right[_Idx]);
}
_Myt& operator>>=(const _Myt& _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]);
}
_Myt operator[](
slice _Slicearr) const; // defined below
slice_array<_Ty> operator[](
slice _Slicearr); // defined below
_Myt operator[](
const gslice& _Gslicearr) const; // defined below
gslice_array<_Ty> operator[](
const gslice& _Gslicearr); // defined below
_Myt operator[](
const _Boolarray& _Boolarr) const; // defined below
mask_array<_Ty> operator[](
const _Boolarray& _Boolarr); // defined below
_Myt 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);
}
_Myt shift(int _Count) const
{ // return valarray left shifted
__PURE_APPDOMAIN_GLOBAL static _Ty _Dflt;
_VALOP(_Ty, size(),
0 < _Count && size() - _Idx <= (size_t)_Count
|| _Count < 0 && _Idx < (size_t)-_Count
? _Dflt : _Myptr[_Idx + _Count]);
}
_Myt cshift(int _Count) const
{ // return valarray left rotated
if (size() == 0)
; // no shift
else if (_Count < 0)
{ // right shift
if (size() < (size_t)0 - _Count)
_Count = (int)(size() - ((size_t)0 - _Count - size())
% size());
else
_Count = (int)(size() + _Count);
}
else if (size() <= (size_t)_Count)
_Count %= size();
_VALOP(_Ty, size(), size() - _Idx <= (size_t)_Count
? _Myptr[_Idx - size() + _Count] : _Myptr[_Idx + _Count]);
}
_Myt apply(_Ty _Func(_Ty)) const
{ // return valarray transformed by _Func, value argument
_VALOP(_Ty, size(), _Func(_Myptr[_Idx]));
}
_Myt 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 _Newsize)
{ // grow to _Count elements and pad with default values
if (0 < _Newsize)
{ // worth doing, allocate
_Myptr = _Allocate(_Newsize, (_Ty *)0);
_TRY_BEGIN
for (size_t _Idx = 0; _Idx < _Newsize; ++_Idx)
_Construct(&_Myptr[_Idx]);
_CATCH_ALL
_Tidy(true); // construction failed, clean up and reraise
_RERAISE;
_CATCH_END
_Mysize = _Newsize;
}
}
void _Grow(size_t _Newsize,
const _Ty *_Ptr,
size_t _Inc = 0)
{ // grow to _Count elements and fill
if (0 < _Newsize)
{ // worth doing, allocate
_Myptr = _Allocate(_Newsize, (_Ty *)0);
_TRY_BEGIN
for (size_t _Idx = 0; _Idx < _Newsize; ++_Idx, _Ptr += _Inc)
_Construct(&_Myptr[_Idx], *_Ptr);
_CATCH_ALL
_Tidy(true); // construction failed, clean up and reraise
_RERAISE;
_CATCH_END
_Mysize = _Newsize;
}
}
void _Tidy(bool _Constructed = false)
{ // initialize the object, freeing any allocated storage
if (_Constructed && _Myptr != 0)
{ // destroy elements
for (size_t _Idx = 1; _Idx < _Mysize; ++_Idx)
_Destroy(&_Myptr[_Idx]);
delete _Myptr;
}
_Mysize = 0;
_Myptr = 0;
}
_Ty *_Myptr; // current storage reserved for array
size_t _Mysize; // current length of sequence
};
// valarray TEMPLATE FUNCTIONS
template<class _Ty> inline
void swap(valarray<_Ty>& _Left,
valarray<_Ty>& _Right)
{ // swap _Left and _Right valarrays
_Left.swap(_Right);
}
template<class _Ty> inline
void swap(valarray<_Ty>& _Left,
valarray<_Ty>&& _Right)
{ // swap _Left and _Right valarrays
typedef valarray<_Ty> _Myt;
_Left.swap(_STD forward<_Myt>(_Right));
}
template<class _Ty> inline
void swap(valarray<_Ty>&& _Left,
valarray<_Ty>& _Right)
{ // swap _Left and _Right valarrays
typedef valarray<_Ty> _Myt;
_Right.swap(_STD forward<_Myt>(_Left));
}
#if _HAS_CPP0X
template<class _Ty> inline
_Ty *begin(valarray<_Ty>& _Array)
{ // get beginning of valarray
return (&_Array[0]);
}
template<class _Ty> inline
const _Ty *begin(const valarray<_Ty>& _Array)
{ // get beginning of valarray
return (&_Array[0]);
}
template<class _Ty> inline
_Ty *end(valarray<_Ty>& _Array)
{ // get end of valarray
return (&_Array[0] + _Array.size());
}
template<class _Ty> inline
const _Ty *end(const valarray<_Ty>& _Array)
{ // get end of valarray
return (&_Array[0] + _Array.size());
}
#endif /* _HAS_CPP0X */
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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -