Allow more flexibility when performing operations on Vectors of
different types.
This commit is contained in:
parent
727345fbe9
commit
c70d2ad423
2 changed files with 77 additions and 16 deletions
|
@ -73,13 +73,13 @@ namespace cloonel {
|
|||
};
|
||||
|
||||
template <typename T, typename U, uint32_t S>
|
||||
Vector<typename std::common_type<T, U>::type, S> operator+ ( Vector<T, S> parA, const Vector<U, S>& parB ) __attribute__((pure));
|
||||
Vector<typename std::common_type<T, U>::type, S> operator+ ( const Vector<T, S>& parA, const Vector<U, S>& parB ) __attribute__((pure));
|
||||
template <typename T, typename U, uint32_t S>
|
||||
Vector<typename std::common_type<T, U>::type, S> operator- ( Vector<T, S> parA, const Vector<U, S>& parB ) __attribute__((pure));
|
||||
Vector<typename std::common_type<T, U>::type, S> operator- ( const Vector<T, S>& parA, const Vector<U, S>& parB ) __attribute__((pure));
|
||||
template <typename T, typename U, uint32_t S>
|
||||
Vector<typename std::common_type<T, U>::type, S> operator* ( Vector<T, S> parA, const Vector<U, S>& parB ) __attribute__((pure));
|
||||
Vector<typename std::common_type<T, U>::type, S> operator* ( const Vector<T, S>& parA, const Vector<U, S>& parB ) __attribute__((pure));
|
||||
template <typename T, typename U, uint32_t S>
|
||||
Vector<typename std::common_type<T, U>::type, S> operator/ ( Vector<T, S> parA, const Vector<U, S>& parB ) __attribute__((pure));
|
||||
Vector<typename std::common_type<T, U>::type, S> operator/ ( const Vector<T, S>& parA, const Vector<U, S>& parB ) __attribute__((pure));
|
||||
template <typename T, typename U, uint32_t S, typename=typename std::enable_if<std::is_fundamental<U>::value>::type>
|
||||
Vector<typename std::common_type<T, U>::type, S> operator+ ( U parA, const Vector<T, S>& parB ) __attribute__((pure));
|
||||
template <typename T, typename U, uint32_t S, typename=typename std::enable_if<std::is_fundamental<U>::value>::type>
|
||||
|
@ -129,6 +129,71 @@ namespace cloonel {
|
|||
}
|
||||
#endif
|
||||
|
||||
namespace implem {
|
||||
template <typename T, typename U>
|
||||
struct CategorizeTypes {
|
||||
typedef typename std::common_type<T, U>::type CommonType;
|
||||
typedef typename std::conditional<std::is_same<CommonType, T>::value, U, T>::type OtherType;
|
||||
};
|
||||
template <typename Cat, uint32_t S, bool Straightforward=std::is_same<typename Cat::CommonType, typename Cat::OtherType>::value>
|
||||
struct DoOperation {
|
||||
static Vector<typename Cat::CommonType, S> do_mul ( Vector<typename Cat::CommonType, S> parLho, const Vector<typename Cat::CommonType, S>& parRho ) {
|
||||
parLho *= parRho;
|
||||
return parLho;
|
||||
}
|
||||
static Vector<typename Cat::CommonType, S> do_div ( Vector<typename Cat::CommonType, S> parLho, const Vector<typename Cat::CommonType, S>& parRho ) {
|
||||
parLho /= parRho;
|
||||
return parLho;
|
||||
}
|
||||
static Vector<typename Cat::CommonType, S> do_sum ( Vector<typename Cat::CommonType, S> parLho, const Vector<typename Cat::CommonType, S>& parRho ) {
|
||||
parLho += parRho;
|
||||
return parLho;
|
||||
}
|
||||
static Vector<typename Cat::CommonType, S> do_sub ( Vector<typename Cat::CommonType, S> parLho, const Vector<typename Cat::CommonType, S>& parRho ) {
|
||||
parLho -= parRho;
|
||||
return parLho;
|
||||
}
|
||||
};
|
||||
template <typename Cat, uint32_t S>
|
||||
struct DoOperation<Cat, S, false> {
|
||||
static Vector<typename Cat::CommonType, S> do_mul ( Vector<typename Cat::CommonType, S> parLho, const Vector<typename Cat::OtherType, S>& parRho ) {
|
||||
parLho *= parRho;
|
||||
return parLho;
|
||||
}
|
||||
static Vector<typename Cat::CommonType, S> do_mul ( const Vector<typename Cat::OtherType, S>& parLho, const Vector<typename Cat::CommonType, S>& parRho ) {
|
||||
Vector<typename Cat::CommonType, S> ret(parLho);
|
||||
ret *= parRho;
|
||||
return ret;
|
||||
}
|
||||
static Vector<typename Cat::CommonType, S> do_div ( Vector<typename Cat::CommonType, S> parLho, const Vector<typename Cat::OtherType, S>& parRho ) {
|
||||
parLho /= parRho;
|
||||
return parLho;
|
||||
}
|
||||
static Vector<typename Cat::CommonType, S> do_div ( const Vector<typename Cat::OtherType, S>& parLho, const Vector<typename Cat::CommonType, S>& parRho ) {
|
||||
Vector<typename Cat::CommonType, S> ret(parLho);
|
||||
ret /= parRho;
|
||||
return ret;
|
||||
}
|
||||
static Vector<typename Cat::CommonType, S> do_sum ( Vector<typename Cat::CommonType, S> parLho, const Vector<typename Cat::OtherType, S>& parRho ) {
|
||||
parLho += parRho;
|
||||
return parLho;
|
||||
}
|
||||
static Vector<typename Cat::CommonType, S> do_sum ( const Vector<typename Cat::OtherType, S>& parLho, const Vector<typename Cat::CommonType, S>& parRho ) {
|
||||
Vector<typename Cat::CommonType, S> ret(parLho);
|
||||
ret += parRho;
|
||||
return ret;
|
||||
}
|
||||
static Vector<typename Cat::CommonType, S> do_sub ( Vector<typename Cat::CommonType, S> parLho, const Vector<typename Cat::OtherType, S>& parRho ) {
|
||||
parLho -= parRho;
|
||||
return parLho;
|
||||
}
|
||||
static Vector<typename Cat::CommonType, S> do_sub ( const Vector<typename Cat::OtherType, S>& parLho, const Vector<typename Cat::CommonType, S>& parRho ) {
|
||||
Vector<typename Cat::CommonType, S> ret(parLho);
|
||||
ret -= parRho;
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
} //namespace implem
|
||||
} //namespace cloonel
|
||||
#include "vector.inl"
|
||||
#endif
|
||||
|
|
|
@ -113,27 +113,23 @@ namespace cloonel {
|
|||
///-------------------------------------------------------------------------
|
||||
template <typename T, typename U, uint32_t S>
|
||||
inline
|
||||
Vector<typename std::common_type<T, U>::type, S> operator+ (Vector<T, S> parA, const Vector<U, S>& parB) {
|
||||
parA += parB;
|
||||
return parA;
|
||||
Vector<typename std::common_type<T, U>::type, S> operator+ (const Vector<T, S>& parA, const Vector<U, S>& parB) {
|
||||
return implem::DoOperation<implem::CategorizeTypes<T, U>, S>::do_sum(parA, parB);
|
||||
}
|
||||
template <typename T, typename U, uint32_t S>
|
||||
inline
|
||||
Vector<typename std::common_type<T, U>::type, S> operator- (Vector<T, S> parA, const Vector<U, S>& parB) {
|
||||
parA -= parB;
|
||||
return parA;
|
||||
Vector<typename std::common_type<T, U>::type, S> operator- (const Vector<T, S>& parA, const Vector<U, S>& parB) {
|
||||
return implem::DoOperation<implem::CategorizeTypes<T, U>, S>::do_sub(parA, parB);
|
||||
}
|
||||
template <typename T, typename U, uint32_t S>
|
||||
inline
|
||||
Vector<typename std::common_type<T, U>::type, S> operator* (Vector<T, S> parA, const Vector<U, S>& parB) {
|
||||
parA *= parB;
|
||||
return parA;
|
||||
Vector<typename std::common_type<T, U>::type, S> operator* (const Vector<T, S>& parA, const Vector<U, S>& parB) {
|
||||
return implem::DoOperation<implem::CategorizeTypes<T, U>, S>::do_mul(parA, parB);
|
||||
}
|
||||
template <typename T, typename U, uint32_t S>
|
||||
inline
|
||||
Vector<typename std::common_type<T, U>::type, S> operator/ (Vector<T, S> parA, const Vector<U, S>& parB) {
|
||||
parA /= parB;
|
||||
return parA;
|
||||
Vector<typename std::common_type<T, U>::type, S> operator/ (const Vector<T, S>& parA, const Vector<U, S>& parB) {
|
||||
return implem::DoOperation<implem::CategorizeTypes<T, U>, S>::do_div(parA, parB);
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue