Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- template<class T, class R>
- class Matcher;
- template<class T, class R>
- class RevTuple
- {
- private:
- T value;
- R rest;
- public:
- template<typename N> struct RevType
- {
- typedef RevTuple<T, typename R::template RevType<N>::push_type> push_type;
- };
- typedef T data_type;
- typedef R pop_type;
- RevTuple(const T &val, const R &r):
- value(val), rest(r) {}
- T &GetValue() { return value; }
- R &GetRest() { return rest; }
- template<typename N>
- typename RevType<N>::push_type operator,(const N &val)
- {
- return typename RevType<N>::push_type(value, (rest, val));
- }
- Matcher<T, R> Match()
- {
- return Matcher<T, R>(*this);
- }
- };
- struct empty
- {
- template<typename N> struct RevType
- {
- typedef RevTuple<N, empty> push_type;
- };
- typedef empty data_type;
- typedef empty pop_type; //?
- template<typename N>
- typename RevType<N>::push_type operator,(const N &val)
- {
- return typename RevType<N>::push_type(val, *this);
- }
- };
- template<class T, class R>
- class Matcher
- {
- private:
- RevTuple<T, R> *data;
- bool match;
- public:
- Matcher(RevTuple<T, R> &tuple, bool m = true):
- data(&tuple), match(m) {}
- typedef Matcher<typename R::data_type, typename R::pop_type> match_type;
- match_type operator,(const T &val)
- {
- if (match && val == data->GetValue())
- return match_type(data->GetRest());
- else
- return match_type(data->GetRest(), false);
- }
- match_type operator,(T *var)
- {
- if (match)
- {
- *var = data->GetValue();
- return match_type(data->GetRest());
- }
- else
- return match_type(data->GetRest(), false);
- }
- };
- template<>
- class Matcher<empty, empty>
- {
- private:
- bool match;
- public:
- Matcher(empty &tuple, bool m = true):
- match(m) {}
- operator bool()
- {
- return match;
- }
- };
- #define Rule empty(),
- #define Match(x) x.Match()##,
- int main()
- {
- int a, b, c;
- auto rule = (Rule 1, 2, 3);
- if (Match(rule) 1, &a, 3)
- std::cout << "Passed 1: " << a << std::endl;
- if (!(Match(rule) 1, 1, 3))
- std::cout << "Passed 2\n";
- if (Match(rule) &a, 2, &b)
- std::cout << "Passed 3: " << a << ", " << b << std::endl;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement