pfor/src/pfor/expression/tagger.h

73 lines
2.9 KiB
C++

#ifndef PFOR_PFOR_EXPRESSION_TAGGER_H
#define PFOR_PFOR_EXPRESSION_TAGGER_H
#include "access.h"
#include "algorithm.h"
#include "expression.h"
#include "operandtag.h"
#include "op.h"
#include "../mp/pack.h"
namespace pfor {
namespace expr {
namespace impl {
template<typename, Access, typename, std::size_t, typename...> struct ExpressionTagger;
template<typename Input, Access access, typename Op, std::size_t d, typename T, typename... Ts>
struct ExpressionTagger<Input, access, Op, d, T, Ts...> {
static constexpr Access faccess = WorstAccess<access, OperationTraits<Op, T, d>::access>::value;
static constexpr Access taccess = WorstAccess<access, OperationTraits<Op, T, d+1>::access>::value;
using first = typename ExpressionTagger<Input, faccess, Op, d, T>::type;
using type = typename ExpressionTagger<first, taccess, Op, d+1, Ts...>::type;
};
template<typename Input, Access access, typename Op, std::size_t d, typename NOp, typename... Ts>
struct ExpressionTagger<Input, access, Op, d, Expression<NOp, Ts...>> {
using type = typename ExpressionTagger<Input, access, NOp, 0, Ts...>::type;
};
template<typename Input, Access access, typename Op, std::size_t d, typename T, typename Id, typename Index>
struct ExpressionTagger<Input, access, Op, d, Expression<T*, Id, Index>> {
static constexpr Access waccess = WorstAccess<access, OperationTraits<Op, T, d>::access>::value;
using type = PackAppend<Input, OperandTag<Id, waccess, Index>>;
};
template<typename Input, Access access, typename Op, std::size_t d, typename T, std::size_t n, typename Id, typename Index>
struct ExpressionTagger<Input, access, Op, d, Expression<std::array<T, n>, Id, Index>> {
static constexpr Access waccess = WorstAccess<access, OperationTraits<Op, T, d>::access>::value;
using type = PackAppend<Input, OperandTag<Id, waccess, Index>>;
};
template<typename Input, Access access, typename Op, std::size_t d, typename T>
struct ExpressionTagger<Input, access, Op, d, Constant<T>> {
static constexpr Access waccess = WorstAccess<access, OperationTraits<Op, T, d>::access>::value;
using type = PackAppend<Input, OperandTag<IgnoredId, waccess, index::IndexImplExpr<>>>;
};
template<typename Input, Access access, std::size_t d, typename Cond, typename T, typename F>
struct ExpressionTagger<Input, access, op::If, d, Cond, T, F> {
using tagcond = typename ExpressionTagger<Input, Access::read, Cond, d, Cond>::type;
using tagtrue = typename ExpressionTagger<tagcond, access, op::If, d+1, T>::type;
using type = typename ExpressionTagger<tagtrue, access, op::If, d+2, F>::type;
};
}
template<typename...> struct ExpressionTaggerImpl;
template<typename Op, typename... Ts>
struct ExpressionTaggerImpl<Expression<Op, Ts...>> {
using type = typename impl::ExpressionTagger<Pack<>, Access::read, Op, 0, Ts...>::type;
};
template<typename... Ts>
using ExpressionTagger = typename ExpressionTaggerImpl<Ts...>::type;
}
}
#endif