上一片文章我们构造了一个简单的varray类,对这个用户定义的具体类型来说,还不够功能完善,有很多的运算符操作都没有放进去。这是特的为了表述清楚而没有加入的。
这类操作包括:
1。取+/-/~/!等操作
2。与标量的数学运算:+,-,*,/,%,|,&,
3。与varray对象间的数学运算
4. bit运算
5。逻辑运算
首先需要考虑的问题便是:我们要把这些操作当作成员函数还是当作非成员函数。 我们注意到,有些运算符只能用作成员函数,比如赋值运算符。
成员函数优点:有一个操作数是隐含的,可以简化程序。缺点:在某些操作如果第一个操作数不是类对象时,就会出现无法使用的情况。这样就必须在外面加入若干的全局函数。如果这些函数要存取类的成员变量,还有必要将其设置为友元函数。
作为全局函数的优点是:类的接口比较简单。一般比较喜欢这种方式。
这里我实现了一部分运算符重载,类似的工作多为重复性的劳动,只要掌握了其中的原理即可。
valarray还实现了大部分的数学函数,如sin, cos, tan, ......
值得一提的是,我们有必要定义几种类型,包括 barray, ind_array, 用来表示真值数组和下标数组类型。(分别对应valarray中的mask_array和indirect_array)
template <class T> class varray;
typedef varray<bool> barray;
typedef varray<int> ind_array;
//operators
//unary: +, -, !(not), ~(bit complement)
varray<T> operator+()
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=+data[i];return tmp;}
varray<T> operator-()
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=-data[i];return tmp;}
varray<T> operator~()
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=~data[i];return tmp;}
varray<T> operator!()
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=!data[i];return tmp;}
varray<T>& operator+=(const T& x)
{for(int i=0;i<size();i++) data[i]+=x;return *this;}
varray<T>& operator-=(const T& x)
{for(int i=0;i<size();i++) data[i]-=x;return *this;}
varray<T>& operator*=(const T& x)
{for(int i=0;i<size();i++) data[i]*=x;return *this;}
varray<T>& operator/=(const T& x)
{for(int i=0;i<size();i++) data[i]/=x;return *this;}
varray<T>& operator%=(const T& x)
{for(int i=0;i<size();i++) data[i]%=x;return *this;}
varray<T>& operator^=(const T& x)
{for(int i=0;i<size();i++) data[i]^=x;return *this;}
varray<T>& operator&=(const T& x)
{for(int i=0;i<size();i++) data[i]&=x;return *this;}
varray<T>& operator|=(const T& x)
{for(int i=0;i<size();i++) data[i]|=x;return *this;}
varray<T>& operator>>=(const T& x)
{for(int i=0;i<size();i++) data[i]>>=x;return *this;}
varray<T>& operator<<=(const T& x)
{for(int i=0;i<size();i++) data[i]<<=x;return *this;}
varray<T>& operator+=(const varray<T>& v)
{for(int i=0;i<size();i++) data[i]+=v[i];return *this;}
varray<T>& operator-=(const varray<T>& v)
{for(int i=0;i<size();i++) data[i]-=v[i];return *this;}
varray<T>& operator*=(const varray<T>& v)
{for(int i=0;i<size();i++) data[i]*=v[i];return *this;}
varray<T>& operator/=(const varray<T>& v)
{for(int i=0;i<size();i++) data[i]/=v[i];return *this;}
varray<T>& operator%=(const varray<T>& v)
{for(int i=0;i<size();i++) data[i]%=v[i];return *this;}
varray<T>& operator^=(const varray<T>& v)
{for(int i=0;i<size();i++) data[i]^=v[i];return *this;}
varray<T>& operator&=(const varray<T>& v)
{for(int i=0;i<size();i++) data[i]&=v[i];return *this;}
varray<T>& operator|=(const varray<T>& v)
{for(int i=0;i<size();i++) data[i]|=v[i];return *this;}
varray<T>& operator>>=(const varray<T>& v)
{for(int i=0;i<size();i++) data[i]>>=v[i];return *this;}
varray<T>& operator<<=(const varray<T>& v)
{for(int i=0;i<size();i++) data[i]<<=v[i];return *this;}
varray<T> operator+(const T& x)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]+x;return tmp;}
varray<T> operator-(const T& x)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]-x;return tmp;}
varray<T> operator*(const T& x)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]*x;return tmp;}
varray<T> operator/(const T& x)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]/x;return tmp;}
varray<T> operator%(const T& x)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]%x;return tmp;}
varray<T> operator^(const T& x)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]^x;return tmp;}
varray<T> operator&(const T& x)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]&x;return tmp;}
varray<T> operator|(const T& x)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]|x;return tmp;}
varray<T> operator<<(const T& x)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]<<x;return tmp;}
varray<T> operator>>(const T& x)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]>>x;return tmp;}
varray<T> operator+(const varray<T>& v)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]+v[i];return tmp;}
varray<T> operator-(const varray<T>& v)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]-v[i];return tmp;}
varray<T> operator*(const varray<T>& v)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]*v[i];return tmp;}
varray<T> operator/(const varray<T>& v)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]/v[i];return tmp;}
varray<T> operator%(const varray<T>& v)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]%v[i];return tmp;}
varray<T> operator^(const varray<T>& v)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]^v[i];return tmp;}
varray<T> operator&(const varray<T>& v)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]&v[i];return tmp;}
varray<T> operator|(const varray<T>& v)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]|v[i];return tmp;}
varray<T> operator<<(const varray<T>& v)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]<<v[i];return tmp;}
varray<T> operator>>(const varray<T>& v)
{varray<T> tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]>>v[i];return tmp;}
barray operator&&(const T& x)
{barray tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]&&x;return tmp;}
barray operator||(const T& x)
{barray tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]||x;return tmp;}
barray operator&&(const varray<T>& v)
{barray tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]&&v[i];return tmp;}
barray operator||(const varray<T>& v)
{barray tmp(size());for(int i=0;i<size();i++) tmp[i]=data[i]||v[i];return tmp;}
//global functions
//some operators which has a scalar as the first
//some functions
template <class T> varray<T> sin(const varray<T>& v)
{varray<T> tmp(v.size());for(int i=0;i<v.size();i++) tmp[i]=::sin(v[i]);return tmp;}
template <class T> varray<T> cos(const varray<T>& v)
{varray<T> tmp(v.size());for(int i=0;i<v.size();i++) tmp[i]=::cos(v[i]);return tmp;}
template <class T> varray<T> tan(const varray<T>& v)
{varray<T> tmp(v.size());for(int i=0;i<v.size();i++) tmp[i]=::tan(v[i]);return tmp;}
template <class T> varray<T> sinh(const varray<T>& v)
{varray<T> tmp(v.size());for(int i=0;i<v.size();i++) tmp[i]=::sinh(v[i]);return tmp;}
template <class T> varray<T> cosh(const varray<T>& v)
{varray<T> tmp(v.size());for(int i=0;i<v.size();i++) tmp[i]=::cosh(v[i]);return tmp;}
template <class T> varray<T> exp(const varray<T>& v)
{varray<T> tmp(v.size());for(int i=0;i<v.size();i++) tmp[i]=::exp(v[i]);return tmp;}