#include <iostream>
#include <tuple>
template < class T, class F>
class predicate {
public :
explicit predicate( T const & t, F const & p = F( ) )
: value( t)
, pred( f) { }
bool match( T const & value2) {
return pred( value, value2) ;
}
private :
T value;
F pred;
} ;
template < class T>
struct __op_eq {
operator( ) ( T const & a, T const & b) {
return a == b;
}
} ;
template < class T>
struct __op_gt {
operator( ) ( T const & a, T const & b) {
return a > b;
}
} ;
template < class T> using eq_pred = predicate< T, op_eq< T>> ;
template < class T> using gt_pred = predicate< T, op_gt< T>> ;
template < class ... Ts >
class __match {
public :
template < class ... Us >
__match( Us&& ... argz ) : args( argz...) { }
template < class U, class Us...>
match& operator= ( std:: tuple < U, Us...> t) {
do_match< 0 > ( t) ;
do_assign< 0 > ( t) ;
return * this ;
}
private :
void do_match( std:: tuple <> const & ) { }
template < std:: size_t I, class U, class ... Us >
void do_match( std:: tuple < U, Us...> const & tup) {
do_match< I + 1 > ( std:: tail ( tup) ) ;
}
template < std:: size_t I, class U, class ... Us , class V, class W>
void do_match( std:: tuple < predicate< V, W> , Us...> const & tup) {
if ( ! std:: get < 0 > ( tup) .match ( std:: get < I> ( args) ) ) {
throw match_error{ } ;
}
do_match< I + 1 > ( std:: tail ( tup) ) ;
}
void do_assign( std:: tuple <> const & ) { }
template < std:: size_t I, class U, class ... Us >
void do_assign( std:: tuple < U, Us...> tup) {
std:: get < 0 > ( tup) = std:: get < I> ( args) ;
do_assign< I + 1 > ( std:: tail ( tup) ) ;
}
template < std:: size_t I, class U, class ... Us , class V, class W>
void do_assign( std:: tuple < predicate< V, W> , Us...> const & tup) {
do_assign< I + 1 > ( std:: tail ( tup) ) ;
}
std:: tuple < Ts& ...> args;
} ;
template < class ... Ts >
__match< Ts...> match( Ts&& ... ts ) {
return __match< Ts...> { ts...} ;
}
int main( ) {
int a, b, c;
match( a, b, eq_pred{ 42 } , c) = std:: make_tuple ( 1 , 2 , 42 , 3 ) ;
std:: cout << a << ", " << b << ", " << c << '\n ' ;
match( a, b, eq_pred{ 43 } , c) = std:: make_tuple ( 1 , 2 , 42 , 3 ) ;
std:: cout << a << ", " << b << ", " << c << '\n ' ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHVwbGU+Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBGPgpjbGFzcyBwcmVkaWNhdGUgewpwdWJsaWM6CiAgICBleHBsaWNpdCBwcmVkaWNhdGUoVCBjb25zdCYgdCwgRiBjb25zdCYgcCA9IEYoKSkKICAgIDogdmFsdWUodCkKICAgICwgcHJlZChmKSB7fQoKICAgIGJvb2wgbWF0Y2goVCBjb25zdCYgdmFsdWUyKSB7CiAgICAgICAgcmV0dXJuIHByZWQodmFsdWUsIHZhbHVlMik7CiAgICB9Cgpwcml2YXRlOgogICAgVCB2YWx1ZTsKICAgIEYgcHJlZDsKfTsKCnRlbXBsYXRlPGNsYXNzIFQ+CnN0cnVjdCBfX29wX2VxIHsKICAgIG9wZXJhdG9yKCkoVCBjb25zdCYgYSwgVCBjb25zdCYgYikgewogICAgICAgIHJldHVybiBhID09IGI7CiAgICB9Cn07Cgp0ZW1wbGF0ZTxjbGFzcyBUPgpzdHJ1Y3QgX19vcF9ndCB7CiAgICBvcGVyYXRvcigpKFQgY29uc3QmIGEsIFQgY29uc3QmIGIpIHsKICAgICAgICByZXR1cm4gYSA+IGI7CiAgICB9Cn07Cgp0ZW1wbGF0ZTxjbGFzcyBUPiB1c2luZyBlcV9wcmVkID0gcHJlZGljYXRlPFQsIG9wX2VxPFQ+PjsKdGVtcGxhdGU8Y2xhc3MgVD4gdXNpbmcgZ3RfcHJlZCA9IHByZWRpY2F0ZTxULCBvcF9ndDxUPj47Cgp0ZW1wbGF0ZTxjbGFzcy4uLiBUcz4KY2xhc3MgX19tYXRjaCB7CnB1YmxpYzoKICAgIHRlbXBsYXRlPGNsYXNzLi4uIFVzPgogICAgX19tYXRjaChVcyYmLi4uIGFyZ3opIDogYXJncyhhcmd6Li4uKSB7fQoKICAgIHRlbXBsYXRlPGNsYXNzIFUsIGNsYXNzIFVzLi4uPgogICAgbWF0Y2gmIG9wZXJhdG9yPShzdGQ6OnR1cGxlPFUsIFVzLi4uPiB0KSB7CiAgICAgICAgZG9fbWF0Y2g8MD4odCk7CiAgICAgICAgZG9fYXNzaWduPDA+KHQpOwogICAgICAgIHJldHVybiAqdGhpczsKICAgIH0KCnByaXZhdGU6CiAgICB2b2lkIGRvX21hdGNoKHN0ZDo6dHVwbGU8PiBjb25zdCYpIHt9CgogICAgdGVtcGxhdGU8c3RkOjpzaXplX3QgSSwgY2xhc3MgVSwgY2xhc3MuLi4gVXM+CiAgICB2b2lkIGRvX21hdGNoKHN0ZDo6dHVwbGU8VSwgVXMuLi4+IGNvbnN0JiB0dXApIHsKICAgICAgICBkb19tYXRjaDxJICsgMT4oc3RkOjp0YWlsKHR1cCkpOwogICAgfQoKICAgIHRlbXBsYXRlPHN0ZDo6c2l6ZV90IEksIGNsYXNzIFUsIGNsYXNzLi4uIFVzLCBjbGFzcyBWLCBjbGFzcyBXPgogICAgdm9pZCBkb19tYXRjaChzdGQ6OnR1cGxlPHByZWRpY2F0ZTxWLCBXPiwgVXMuLi4+IGNvbnN0JiB0dXApIHsKICAgICAgICBpZiAoIXN0ZDo6Z2V0PDA+KHR1cCkubWF0Y2goc3RkOjpnZXQ8ST4oYXJncykpKSB7CiAgICAgICAgICAgIHRocm93IG1hdGNoX2Vycm9ye307CiAgICAgICAgfQoKICAgICAgICBkb19tYXRjaDxJICsgMT4oc3RkOjp0YWlsKHR1cCkpOwogICAgfQoKICAgIHZvaWQgZG9fYXNzaWduKHN0ZDo6dHVwbGU8PiBjb25zdCYpIHt9CgogICAgdGVtcGxhdGU8c3RkOjpzaXplX3QgSSwgY2xhc3MgVSwgY2xhc3MuLi4gVXM+CiAgICB2b2lkIGRvX2Fzc2lnbihzdGQ6OnR1cGxlPFUsIFVzLi4uPiB0dXApIHsKICAgICAgICBzdGQ6OmdldDwwPih0dXApID0gc3RkOjpnZXQ8ST4oYXJncyk7CiAgICAgICAgZG9fYXNzaWduPEkgKyAxPihzdGQ6OnRhaWwodHVwKSk7CiAgICB9CgogICAgdGVtcGxhdGU8c3RkOjpzaXplX3QgSSwgY2xhc3MgVSwgY2xhc3MuLi4gVXMsIGNsYXNzIFYsIGNsYXNzIFc+CiAgICB2b2lkIGRvX2Fzc2lnbihzdGQ6OnR1cGxlPHByZWRpY2F0ZTxWLCBXPiwgVXMuLi4+IGNvbnN0JiB0dXApIHsKICAgICAgICBkb19hc3NpZ248SSArIDE+KHN0ZDo6dGFpbCh0dXApKTsKICAgIH0KCiAgICBzdGQ6OnR1cGxlPFRzJi4uLj4gYXJnczsKfTsKCnRlbXBsYXRlPGNsYXNzLi4uIFRzPgpfX21hdGNoPFRzLi4uPiBtYXRjaChUcyYmLi4uIHRzKSB7CiAgICByZXR1cm4gX19tYXRjaDxUcy4uLj57dHMuLi59Owp9CgppbnQgbWFpbigpIHsKICAgIGludCBhLCBiLCBjOwogICAgbWF0Y2goYSwgYiwgZXFfcHJlZHs0Mn0sIGMpID0gc3RkOjptYWtlX3R1cGxlKDEsIDIsIDQyLCAzKTsKICAgIHN0ZDo6Y291dCA8PCBhIDw8ICIsICIgPDwgYiA8PCAiLCAiIDw8IGMgPDwgJ1xuJzsKCiAgICBtYXRjaChhLCBiLCBlcV9wcmVkezQzfSwgYykgPSBzdGQ6Om1ha2VfdHVwbGUoMSwgMiwgNDIsIDMpOwogICAgc3RkOjpjb3V0IDw8IGEgPDwgIiwgIiA8PCBiIDw8ICIsICIgPDwgYyA8PCAnXG4nOwp9Cg==
compilation info
prog.cpp: In constructor 'predicate<T, F>::predicate(const T&, const F&)':
prog.cpp:9:12: error: 'f' was not declared in this scope
prog.cpp: At global scope:
prog.cpp:22:38: error: ISO C++ forbids declaration of 'operator()' with no type
prog.cpp:29:38: error: ISO C++ forbids declaration of 'operator()' with no type
prog.cpp:34:19: error: expected unqualified-id before 'using'
prog.cpp:35:19: error: expected unqualified-id before 'using'
prog.cpp:43:31: error: 'struct Us' is not a valid type for a template constant parameter
prog.cpp:44:5: error: 'match' does not name a type
prog.cpp:50:1: error: expected unqualified-id before 'private'
prog.cpp: In member function 'void __match<Ts>::do_match(const std::tuple<U, Us ...>&)':
prog.cpp:55:25: error: 'tail' is not a member of 'std'
prog.cpp: In member function 'void __match<Ts>::do_match(const std::tuple<predicate<V, W>, Us ...>&)':
prog.cpp:61:19: error: 'match_error' was not declared in this scope
prog.cpp:61:30: error: expected ';' before '{' token
prog.cpp:64:25: error: 'tail' is not a member of 'std'
prog.cpp: In member function 'void __match<Ts>::do_assign(std::tuple<U, Us ...>)':
prog.cpp:72:26: error: 'tail' is not a member of 'std'
prog.cpp: In member function 'void __match<Ts>::do_assign(const std::tuple<predicate<V, W>, Us ...>&)':
prog.cpp:77:26: error: 'tail' is not a member of 'std'
prog.cpp: In function 'int main()':
prog.cpp:90:17: error: 'eq_pred' was not declared in this scope
prog.cpp:93:24: error: expected ')' before '{' token
stdout