135 lines
4.1 KiB
C++
135 lines
4.1 KiB
C++
#ifndef PFOR_PFOR_INDEX_OPERATORS_H
|
|
#define PFOR_PFOR_INDEX_OPERATORS_H
|
|
|
|
#include "index.h"
|
|
#include "op.h"
|
|
#include "traits.h"
|
|
|
|
#include "properties.h"
|
|
|
|
namespace pfor {
|
|
namespace index {
|
|
|
|
/**
|
|
* @brief operator+
|
|
*/
|
|
template<typename Rhs, std::enable_if_t<isIndex<Rhs>>* = nullptr>
|
|
inline decltype(auto) operator+(Rhs&& rhs) {
|
|
return std::forward<Rhs>(rhs);
|
|
}
|
|
|
|
/**
|
|
* @brief operator-
|
|
*/
|
|
template<typename Rhs, std::enable_if_t<isIndex<Rhs> and not isLinear<std::decay_t<Rhs>>>* = nullptr>
|
|
inline decltype(auto) operator-(Rhs&&) {
|
|
using RhsT = std::decay_t<Rhs>;
|
|
using RProp = typename RhsT::Properties;
|
|
using Properties = ComputeProperties<op::Minus, RProp, RProp>;
|
|
return IndexImpl<Pack<op::Minus, RhsT>, Properties>{};
|
|
}
|
|
|
|
template<typename Rhs, std::enable_if_t<isIndex<Rhs> and isLinear<std::decay_t<Rhs>>>* = nullptr>
|
|
inline decltype(auto) operator-(Rhs&&) {
|
|
using RhsT = std::decay_t<Rhs>;
|
|
return LinearIndex<-linearSlope<RhsT>, -linearOffset<RhsT>>{};
|
|
}
|
|
|
|
/**
|
|
* @brief operator+
|
|
*/
|
|
template<
|
|
typename Lhs, typename Rhs, std::enable_if_t<
|
|
allIndex<Lhs, Rhs> and (not isLinear<std::decay_t<Lhs>> or not isLinear<std::decay_t<Rhs>>)
|
|
>* = nullptr
|
|
>
|
|
inline decltype(auto) operator+(Lhs&&, Rhs&&) {
|
|
using LhsT = std::decay_t<Lhs>;
|
|
using RhsT = std::decay_t<Rhs>;
|
|
using LProp = typename LhsT::Properties;
|
|
using RProp = typename RhsT::Properties;
|
|
using Properties = ComputeProperties<op::Addition, LProp, RProp>;
|
|
return IndexImpl<Pack<op::Addition, LhsT, RhsT>, Properties>{};
|
|
}
|
|
|
|
template<
|
|
typename Lhs, typename Rhs, std::enable_if_t<
|
|
allIndex<Lhs, Rhs> and (isLinear<std::decay_t<Lhs>> and isLinear<std::decay_t<Rhs>>)
|
|
>* = nullptr
|
|
>
|
|
inline decltype(auto) operator+(Lhs&&, Rhs&&) {
|
|
using LhsT = std::decay_t<Lhs>;
|
|
using RhsT = std::decay_t<Rhs>;
|
|
return LinearIndex<linearSlope<LhsT> + linearSlope<RhsT>, linearOffset<LhsT> + linearOffset<RhsT>>{};
|
|
}
|
|
|
|
/**
|
|
* @brief operator-
|
|
*/
|
|
template<
|
|
typename Lhs, typename Rhs, std::enable_if_t<
|
|
allIndex<Lhs, Rhs> and (not isLinear<std::decay_t<Lhs>> or not isLinear<std::decay_t<Rhs>>)
|
|
>* = nullptr
|
|
>
|
|
inline decltype(auto) operator-(Lhs&&, Rhs&&) {
|
|
using LhsT = std::decay_t<Lhs>;
|
|
using RhsT = std::decay_t<Rhs>;
|
|
using LProp = typename LhsT::Properties;
|
|
using RProp = typename RhsT::Properties;
|
|
using Properties = ComputeProperties<op::Subtraction, LProp, RProp>;
|
|
return IndexImpl<Pack<op::Subtraction, LhsT, RhsT>, Properties>{};
|
|
}
|
|
|
|
template<
|
|
typename Lhs, typename Rhs, std::enable_if_t<
|
|
allIndex<Lhs, Rhs> and (isLinear<std::decay_t<Lhs>> and isLinear<std::decay_t<Rhs>>)
|
|
>* = nullptr
|
|
>
|
|
inline decltype(auto) operator-(Lhs&&, Rhs&&) {
|
|
using LhsT = std::decay_t<Lhs>;
|
|
using RhsT = std::decay_t<Rhs>;
|
|
return LinearIndex<linearSlope<LhsT> - linearSlope<RhsT>, linearOffset<LhsT> - linearOffset<RhsT>>{};
|
|
}
|
|
|
|
/**
|
|
* @brief operator*
|
|
*/
|
|
template<
|
|
typename Lhs, typename Rhs, std::enable_if_t<
|
|
allIndex<Lhs, Rhs> and (
|
|
not isLinear<std::decay_t<Lhs>> or not isLinear<std::decay_t<Rhs>> or
|
|
(not isConstant<std::decay_t<Lhs>> and not isConstant<std::decay_t<Rhs>>)
|
|
)
|
|
>* = nullptr
|
|
>
|
|
inline decltype(auto) operator*(Lhs&&, Rhs&&) {
|
|
using LhsT = std::decay_t<Lhs>;
|
|
using RhsT = std::decay_t<Rhs>;
|
|
using LProp = typename LhsT::Properties;
|
|
using RProp = typename RhsT::Properties;
|
|
using Properties = ComputeProperties<op::Multiplication, LProp, RProp>;
|
|
return IndexImpl<Pack<op::Multiplication, LhsT, RhsT>, Properties>{};
|
|
}
|
|
|
|
template<
|
|
typename Lhs, typename Rhs, std::enable_if_t<
|
|
allIndex<Lhs, Rhs> and (
|
|
isLinear<std::decay_t<Lhs>> and isLinear<std::decay_t<Rhs>> and
|
|
(isConstant<std::decay_t<Lhs>> or isConstant<std::decay_t<Rhs>>)
|
|
)
|
|
>* = nullptr
|
|
>
|
|
inline decltype(auto) operator*(Lhs&&, Rhs&&) {
|
|
using LhsT = std::decay_t<Lhs>;
|
|
using RhsT = std::decay_t<Rhs>;
|
|
constexpr auto slope = linearSlope<LhsT> + linearSlope<RhsT>; // because one is null
|
|
constexpr auto scalar = linearSlope<LhsT>? linearOffset<RhsT>:linearOffset<LhsT>;
|
|
constexpr auto offset = linearOffset<LhsT> * linearOffset<RhsT>;
|
|
return LinearIndex<scalar * slope, offset>{};
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
#endif
|