generalize element return values in operation classes

This commit is contained in:
Christian Zimmermann 2019-07-24 18:49:53 +02:00
parent 867c6e13e9
commit ba8655896b
3 changed files with 100 additions and 29 deletions

View file

@ -75,7 +75,86 @@ namespace MultiArrayTools
return a;
}
};
template <typename T, typename U>
using plusv = decltype(std::declval<T>()+std::declval<U>());
template <typename T, typename U>
using minusv = decltype(std::declval<T>()-std::declval<U>());
template <typename T, typename U>
using multipliesv = decltype(std::declval<T>()*std::declval<U>());
template <typename T, typename U>
using dividesv = decltype(std::declval<T>()/std::declval<U>());
template <typename T, typename U>
struct plusx : public StaticFunctionBase<plusv<T,U>, plusx<T,U>, T, U>
{
static constexpr bool FISSTATIC = true;
using StaticFunctionBase<plusv<T,U>, plusx<T,U>, T, U>::apply;
static inline plusv<T,U> apply(T a1, U a2)
{
return a1 + a2;
}
static inline T& selfApply(T& a1, const T& a2)
{
return a1 += a2;
}
};
template <typename T, typename U>
struct minusx : public StaticFunctionBase<minusv<T,U>, minusx<T,U>, T, U>
{
static constexpr bool FISSTATIC = true;
using StaticFunctionBase<minusv<T,U>, minusx<T,U>, T, U>::apply;
static inline plusv<T,U> apply(T a1, U a2)
{
return a1 - a2;
}
};
template <typename T, typename U>
struct multipliesx : public StaticFunctionBase<multipliesv<T,U>, multipliesx<T,U>, T, U>
{
static constexpr bool FISSTATIC = true;
using StaticFunctionBase<multipliesv<T,U>, multipliesx<T,U>, T, U>::apply;
static inline multipliesv<T,U> apply(T a1, U a2)
{
return a1 * a2;
}
};
template <typename T, typename U>
struct dividesx : public StaticFunctionBase<dividesv<T,U>, dividesx<T,U>, T, U>
{
static constexpr bool FISSTATIC = true;
using StaticFunctionBase<dividesv<T,U>, dividesx<T,U>, T, U>::apply;
static inline dividesv<T,U> apply(T a1, U a2)
{
return a1 / a2;
}
};
template <typename T>
using plus = plusx<T,T>;
template <typename T>
using minus = minusx<T,T>;
template <typename T>
using multiplies = multipliesx<T,T>;
template <typename T>
using divides = dividesx<T,T>;
/*
template <typename T>
struct plus : public StaticFunctionBase<T, plus<T>, T, T>
{
@ -128,7 +207,7 @@ namespace MultiArrayTools
return a1 / a2;
}
};
*/
// OPERATIONS (STATIC)
template <typename R, typename... Args>
class function

View file

@ -18,35 +18,31 @@ namespace MultiArrayTools
template <typename T, class OperationClass>
template <class Second>
auto OperationBase<T,OperationClass>::operator+(const OperationBase<T,Second>& in) const
-> Operation<T,plus<T>,OperationClass,Second>
template <typename U, class Second>
auto OperationBase<T,OperationClass>::operator+(const OperationBase<U,Second>& in) const
{
return Operation<T,plus<T>,OperationClass,Second>(THIS(), in.THIS());
return Operation<plusv<T,U>,plusx<T,U>,OperationClass,Second>(THIS(), in.THIS());
}
template <typename T, class OperationClass>
template <class Second>
auto OperationBase<T,OperationClass>::operator-(const OperationBase<T,Second>& in) const
-> Operation<T,minus<T>,OperationClass,Second>
template <typename U, class Second>
auto OperationBase<T,OperationClass>::operator-(const OperationBase<U,Second>& in) const
{
return Operation<T,minus<T>,OperationClass,Second>(THIS(), in.THIS());
return Operation<minusv<T,U>,minusx<T,U>,OperationClass,Second>(THIS(), in.THIS());
}
template <typename T, class OperationClass>
template <class Second>
auto OperationBase<T,OperationClass>::operator*(const OperationBase<T,Second>& in) const
-> Operation<T,multiplies<T>,OperationClass,Second>
template <typename U, class Second>
auto OperationBase<T,OperationClass>::operator*(const OperationBase<U,Second>& in) const
{
return Operation<T,multiplies<T>,OperationClass,Second>(THIS(), in.THIS());
return Operation<multipliesv<T,U>,multipliesx<T,U>,OperationClass,Second>(THIS(), in.THIS());
}
template <typename T, class OperationClass>
template <class Second>
auto OperationBase<T,OperationClass>::operator/(const OperationBase<T,Second>& in) const
-> Operation<T,divides<T>,OperationClass,Second>
template <typename U, class Second>
auto OperationBase<T,OperationClass>::operator/(const OperationBase<U,Second>& in) const
{
return Operation<T,divides<T>,OperationClass,Second>(THIS(), in.THIS());
return Operation<dividesv<T,U>,dividesx<T,U>,OperationClass,Second>(THIS(), in.THIS());
}
template <typename T, class OperationClass>

View file

@ -33,21 +33,17 @@ namespace MultiArrayTools
OperationClass& THIS() { return static_cast<OperationClass&>(*this); }
const OperationClass& THIS() const { return static_cast<OperationClass const&>(*this); }
template <class Second>
auto operator+(const OperationBase<T,Second>& in) const
-> Operation<T,plus<T>,OperationClass,Second>;
template <typename U, class Second>
auto operator+(const OperationBase<U,Second>& in) const;
template <class Second>
auto operator-(const OperationBase<T,Second>& in) const
-> Operation<T,minus<T>,OperationClass,Second>;
template <typename U, class Second>
auto operator-(const OperationBase<U,Second>& in) const;
template <class Second>
auto operator*(const OperationBase<T,Second>& in) const
-> Operation<T,multiplies<T>,OperationClass,Second>;
template <typename U, class Second>
auto operator*(const OperationBase<U,Second>& in) const;
template <class Second>
auto operator/(const OperationBase<T,Second>& in) const
-> Operation<T,divides<T>,OperationClass,Second>;
template <typename U, class Second>
auto operator/(const OperationBase<U,Second>& in) const;
template <class IndexType>
auto c(const std::shared_ptr<IndexType>& ind) const