|
| 1 | +#pragma once |
| 2 | + |
| 3 | +#include <tuple> |
| 4 | + |
| 5 | +#include "CheckOperation.h" |
| 6 | + |
| 7 | +namespace Viatra { |
| 8 | +namespace Query { |
| 9 | +namespace Operations { |
| 10 | +namespace Check { |
| 11 | + |
| 12 | +/** |
| 13 | + * @brief InstanceOf check. |
| 14 | + * |
| 15 | + * This type of check examines whether an instance is of the specified type. |
| 16 | + * |
| 17 | + * @tparam MatchingFrame Describes the structure of the *MatchingFrame* the operation is executed on. |
| 18 | + * @tparam TequiredMatcher The matcher the nac call has to call. |
| 19 | + * @tparam Mp The arbitrary list of member pointers to access the proper field of the frame (to pass them to the matcher). |
| 20 | +*/ |
| 21 | +template<class MatchingFrame, class RequiredMatcher, class ...Mp> |
| 22 | +class NACOperation : public CheckOperation<MatchingFrame> { |
| 23 | +public: |
| 24 | + NACOperation(const RequiredMatcher& matcher, Mp... memberPointers); |
| 25 | + |
| 26 | +protected: |
| 27 | + bool check(MatchingFrame& frame, const Matcher::ISearchContext& context); |
| 28 | + |
| 29 | +private: |
| 30 | + |
| 31 | + template<unsigned int... index> |
| 32 | + bool invoke_helper(MatchingFrame& frame, std::index_sequence<index...>); |
| 33 | + |
| 34 | + const RequiredMatcher _matcher; |
| 35 | + std::tuple<Mp...> _memberPointers; |
| 36 | +}; |
| 37 | + |
| 38 | +template<class MatchingFrame, class RequiredMatcher, class ...Mp> |
| 39 | +inline NACOperation<MatchingFrame, RequiredMatcher, Mp...>::NACOperation(const RequiredMatcher& matcher, Mp ...memberPointers) : |
| 40 | + _matcher(matcher), _memberPointers(memberPointers...) { |
| 41 | +} |
| 42 | + |
| 43 | +template<class MatchingFrame, class RequiredMatcher, class ...Mp> |
| 44 | +inline bool NACOperation<MatchingFrame, RequiredMatcher, Mp...>::check(MatchingFrame & frame, const Matcher::ISearchContext & context) { |
| 45 | + constexpr auto Size = std::tuple_size<typename std::decay<std::tuple<Mp...>>::type>::value; |
| 46 | + return invoke_helper(frame, std::make_index_sequence<Size>{}); |
| 47 | +} |
| 48 | + |
| 49 | +template<class MatchingFrame, class RequiredMatcher, class ...Mp> |
| 50 | +NACOperation<MatchingFrame, RequiredMatcher, Mp...>* create_NACOperation(const RequiredMatcher& matcher, Mp... memberPointers) { |
| 51 | + return new NACOperation<MatchingFrame, RequiredMatcher, Mp...>(matcher, memberPointers...); |
| 52 | +} |
| 53 | + |
| 54 | +template<class MatchingFrame, class RequiredMatcher, class ...Mp> |
| 55 | +template<unsigned int ...index> |
| 56 | +inline bool NACOperation<MatchingFrame, RequiredMatcher, Mp...>::invoke_helper(MatchingFrame& frame, std::index_sequence<index...>) { |
| 57 | + auto matches = _matcher.matches((frame.*std::get<index>(std::forward<std::tuple<Mp...>>(_memberPointers)))...); |
| 58 | + return matches.size() == 0; |
| 59 | +} |
| 60 | + |
| 61 | +} /* namespace Check */ |
| 62 | +} /* namespace Util */ |
| 63 | +} /* namespace Query */ |
| 64 | +} /* namespace Viatra */ |
0 commit comments