#ifndef PFOR_PFOR_EXPRESSION_ALGORITHM_H #define PFOR_PFOR_EXPRESSION_ALGORITHM_H #include "access.h" #include "expression.h" #include "operandtag.h" #include "../mp/pack.h" #include "../mp/meta.h" namespace pfor { namespace expr { /** * @brief returns a pack of sub expressions */ template struct SplitCommaImpl; template struct SplitCommaImpl> { using type = Pack; }; template struct SplitCommaImpl> { using type = Pack>; }; template using SplitComma = typename SplitCommaImpl::type; /** * @brief returns a comma separated expression from pack */ template struct MergeCommaImpl; template struct MergeCommaImpl> { using type = Expression; }; template struct MergeCommaImpl> { using type = T; }; template using MergeComma = typename MergeCommaImpl

::type; /** * @brief returns the worst access (write being worse than read) */ template struct WorstAccess; template struct WorstAccess { static constexpr Access value = (access == Access::write? Access::write:WorstAccess::value); }; template struct WorstAccess { static constexpr Access value = access; }; /** */ template struct IncludeTagsImpl; template struct IncludeTagsImpl, Ts...>> { using trail = typename IncludeTagsImpl>::type; using trailit = typename IncludeTagsImpl>::indices; using type = pfor::If{}, PackPrepend>, trail>; using indices = pfor::If{}, PackPrepend, trailit>; }; template struct IncludeTagsImpl> { using type = Pack<>; using indices = Pack<>; }; template using IncludeTags = typename IncludeTagsImpl::type; /** */ template struct ExcludeTagsImpl; template struct ExcludeTagsImpl, Ts...>> { using trail = typename ExcludeTagsImpl>::type; using type = pfor::If{}, PackPrepend>, trail>; }; template struct ExcludeTagsImpl> { using type = Pack<>; }; template using ExcludeTags = typename ExcludeTagsImpl::type; /** */ template struct CountWrite; template struct CountWrite, Ts...>> { static constexpr std::size_t value = (access == Access::write? 1:0) + CountWrite>::value; }; template<> struct CountWrite> { static constexpr std::size_t value = 0; }; template constexpr std::size_t countWrite = CountWrite

::value; /** */ template struct FilterOperandTagsImpl; template struct FilterOperandTagsImpl, Ts...>, accessReq> { using trail = typename FilterOperandTagsImpl, accessReq>::type; using type = pfor::If>, trail>; }; template struct FilterOperandTagsImpl, Ts...>, accessReq> { using type = typename FilterOperandTagsImpl, accessReq>::type; }; template struct FilterOperandTagsImpl, access> { using type = Pack<>; }; template using FilterOperandTags = typename FilterOperandTagsImpl::type; /** */ template struct IndicesFromOperandTagsImpl; template struct IndicesFromOperandTagsImpl, Ts...>> { using type = PackPrepend>::type, Index>; }; template<> struct IndicesFromOperandTagsImpl> { using type = Pack<>; }; template using IndicesFromOperandTags = typename IndicesFromOperandTagsImpl

::type; } } #endif