pfor/src/pfor/expression/info.h

77 lines
2.0 KiB
C++

#ifndef PFOR_PFOR_EXPRESSION_INFO_H
#define PFOR_PFOR_EXPRESSION_INFO_H
#include "access.h"
#include "expression.h"
#include "operandtag.h"
#include "tagger.h"
#include "../mp/pack.h"
#include "../mp/meta.h"
namespace pfor {
namespace expr {
namespace impl {
/**
* @brief filters variables ids from an expression depending on access category
*/
template<typename, Access> struct RWListImpl;
template<typename Id, Access access, typename Index, typename... Ts, Access accessReq>
struct RWListImpl<Pack<OperandTag<Id, access, Index>, Ts...>, accessReq> {
using trail = typename RWListImpl<Pack<Ts...>, accessReq>::type;
using type = pfor::If<access == accessReq, PackPrepend<trail, Id>, trail>;
};
template<Access access, typename Index, typename... Ts, Access accessReq>
struct RWListImpl<Pack<OperandTag<IgnoredId, access, Index>, Ts...>, accessReq> {
using type = typename RWListImpl<Pack<Ts...>, accessReq>::type;
};
template<Access accessReq>
struct RWListImpl<Pack<>, accessReq> {
using type = Pack<>;
};
template<typename E, Access accessReq>
using RWList = typename RWListImpl<E, accessReq>::type;
}
template<typename T>
using ReadList = impl::RWList<T, Access::read>;
template<typename T>
using WriteList = impl::RWList<T, Access::write>;
/**
* @brief returns informations about the input expression
*/
template<std::size_t, typename> struct ExpressionInfoImpl;
template<std::size_t n, typename T, typename... Ts>
struct ExpressionInfoImpl<n, Pack<T, Ts...>> {
using trail = typename ExpressionInfoImpl<n+1, Pack<Ts...>>::type;
using exprtags = ExpressionTagger<T>;
using read = ReadList<exprtags>;
using write = WriteList<exprtags>;
using type = PackPrepend<trail, Pack<UIntToType<n>, write, read>>;
};
template<std::size_t n>
struct ExpressionInfoImpl<n, Pack<>> {
using type = Pack<>;
};
template<typename T>
using ExpressionInfo = typename ExpressionInfoImpl<0, T>::type;
// template<typename T>
// using SortedExpressionInfo = PackSort<ComparatorWritePack, typename ExpressionInfo<T>::type>;
}
}
#endif