SHOW:
|
|
- or go back to the newest paste.
| 1 | #include <iostream> | |
| 2 | - | class Matcher {}; //на будущее
|
| 2 | + | |
| 3 | template<class T, class R> | |
| 4 | class Matcher; | |
| 5 | ||
| 6 | template<class T, class R> | |
| 7 | class RevTuple | |
| 8 | {
| |
| 9 | private: | |
| 10 | T value; | |
| 11 | R rest; | |
| 12 | public: | |
| 13 | template<typename N> struct RevType | |
| 14 | {
| |
| 15 | typedef RevTuple<T, typename R::template RevType<N>::push_type> push_type; | |
| 16 | }; | |
| 17 | typedef T data_type; | |
| 18 | typedef R pop_type; | |
| 19 | RevTuple(const T &val, const R &r): | |
| 20 | value(val), rest(r) {}
| |
| 21 | T &GetValue() { return value; }
| |
| 22 | R &GetRest() { return rest; }
| |
| 23 | template<typename N> | |
| 24 | typename RevType<N>::push_type operator,(const N &val) | |
| 25 | {
| |
| 26 | return typename RevType<N>::push_type(value, (rest, val)); | |
| 27 | } | |
| 28 | Matcher<T, R> Match() | |
| 29 | {
| |
| 30 | return Matcher<T, R>(*this); | |
| 31 | } | |
| 32 | }; | |
| 33 | ||
| 34 | struct empty | |
| 35 | {
| |
| 36 | template<typename N> struct RevType | |
| 37 | {
| |
| 38 | typedef RevTuple<N, empty> push_type; | |
| 39 | }; | |
| 40 | typedef empty data_type; | |
| 41 | typedef empty pop_type; //? | |
| 42 | template<typename N> | |
| 43 | typename RevType<N>::push_type operator,(const N &val) | |
| 44 | {
| |
| 45 | return typename RevType<N>::push_type(val, *this); | |
| 46 | } | |
| 47 | - | empty Rule() |
| 47 | + | |
| 48 | ||
| 49 | - | return empty(); |
| 49 | + | |
| 50 | - | } |
| 50 | + | class Matcher |
| 51 | {
| |
| 52 | private: | |
| 53 | RevTuple<T, R> *data; | |
| 54 | - | //int a, b, c; |
| 54 | + | bool match; |
| 55 | - | (Rule(), 1, 2); |
| 55 | + | |
| 56 | - | /*if (r.Match(), 1, &a, 3) |
| 56 | + | Matcher(RevTuple<T, R> &tuple, bool m = true): |
| 57 | data(&tuple), match(m) {}
| |
| 58 | - | if (!(r.Match(), 1, 1, 3)) |
| 58 | + | typedef Matcher<typename R::data_type, typename R::pop_type> match_type; |
| 59 | match_type operator,(const T &val) | |
| 60 | - | if (r.Match(), a, 2, b) |
| 60 | + | |
| 61 | - | std::cout << "Passed 3: " << a << ", " << b << std::endl;*/ |
| 61 | + | if (match && val == data->GetValue()) |
| 62 | return match_type(data->GetRest()); | |
| 63 | else | |
| 64 | return match_type(data->GetRest(), false); | |
| 65 | } | |
| 66 | match_type operator,(T *var) | |
| 67 | {
| |
| 68 | if (match) | |
| 69 | {
| |
| 70 | *var = data->GetValue(); | |
| 71 | return match_type(data->GetRest()); | |
| 72 | } | |
| 73 | else | |
| 74 | return match_type(data->GetRest(), false); | |
| 75 | } | |
| 76 | }; | |
| 77 | ||
| 78 | template<> | |
| 79 | class Matcher<empty, empty> | |
| 80 | {
| |
| 81 | private: | |
| 82 | bool match; | |
| 83 | public: | |
| 84 | Matcher(empty &tuple, bool m = true): | |
| 85 | match(m) {}
| |
| 86 | operator bool() | |
| 87 | {
| |
| 88 | return match; | |
| 89 | } | |
| 90 | }; | |
| 91 | ||
| 92 | #define Rule empty(), | |
| 93 | #define Match(x) x.Match()##, | |
| 94 | ||
| 95 | int main() | |
| 96 | {
| |
| 97 | int a, b, c; | |
| 98 | auto rule = (Rule 1, 2, 3); | |
| 99 | ||
| 100 | if (Match(rule) 1, &a, 3) | |
| 101 | std::cout << "Passed 1: " << a << std::endl; | |
| 102 | if (!(Match(rule) 1, 1, 3)) | |
| 103 | std::cout << "Passed 2\n"; | |
| 104 | if (Match(rule) &a, 2, &b) | |
| 105 | std::cout << "Passed 3: " << a << ", " << b << std::endl; | |
| 106 | } |