#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//macro overloading by number of arguments:
//http://stackoverflow.com/a/11763277/556899
#define GET_MACRO(_1, _2, _3, _4, _5, NAME, ...) NAME
#define _L(...) GET_MACRO(__VA_ARGS__, _L4, _L3, _L2, _L1, _L0)(__VA_ARGS__)
//separate macro per each number of arguments
#define _L0(res)\
[&]() { return res; }
#define _L1(a, res)\
[&](auto a) { return res; }
#define _L2(a, b, res)\
[&](auto a, auto b) { return res; }
#define _L3(a, b, c, res)\
[&](auto a, auto b, auto c) { return res; }
#define _L4(a, b, c, d, res)\
[&](auto a, auto b, auto c, auto d) { return res; }
//Swift-like version
#define _S0(res) _L0(res)
#define _S1(res) _L1(_0, res)
#define _S2(res) _L2(_0, _1, res)
#define _S3(res) _L3(_0, _1, _2, res)
#define _S4(res) _L4(_0, _1, _2, _3, res)
int main() {
auto f = [&](auto x, auto y) { return x + y; };
cout << f(1, 4) << endl;
auto g = _L(x, y, x + y);
cout << g(2, 5) << endl;
auto x = _L(g(123, 321));
cout << x() << endl;
auto avg = _L(x, y, z, (x+y+z)/3.0);
cout << avg(1, 2, 7) << endl;
vector<string> arr{"hello", "q", "any", "length", "gg", "omg"};
auto compByKey = _L(f, _L(x, y, f(x) < f(y)));
sort(arr.begin(), arr.end(), compByKey(_L(x, x.length())));
for_each(arr.begin(), arr.end(), _L(x, (void)(cout << x << endl)));
sort(arr.begin(), arr.end(), _S2(_0 > _1));
for_each(arr.begin(), arr.end(), _S1((void)(cout << _0 << endl)));
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8YWxnb3JpdGhtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKLy9tYWNybyBvdmVybG9hZGluZyBieSBudW1iZXIgb2YgYXJndW1lbnRzOgovL2h0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzExNzYzMjc3LzU1Njg5OQojZGVmaW5lIEdFVF9NQUNSTyhfMSwgXzIsIF8zLCBfNCwgXzUsIE5BTUUsIC4uLikgTkFNRQojZGVmaW5lIF9MKC4uLikgR0VUX01BQ1JPKF9fVkFfQVJHU19fLCBfTDQsIF9MMywgX0wyLCBfTDEsIF9MMCkoX19WQV9BUkdTX18pCgovL3NlcGFyYXRlIG1hY3JvIHBlciBlYWNoIG51bWJlciBvZiBhcmd1bWVudHMKI2RlZmluZSBfTDAocmVzKVwKICAgWyZdKCkgeyByZXR1cm4gcmVzOyB9CiNkZWZpbmUgX0wxKGEsIHJlcylcCiAgIFsmXShhdXRvIGEpIHsgcmV0dXJuIHJlczsgfQojZGVmaW5lIF9MMihhLCBiLCByZXMpXAogICBbJl0oYXV0byBhLCBhdXRvIGIpIHsgcmV0dXJuIHJlczsgfQojZGVmaW5lIF9MMyhhLCBiLCBjLCByZXMpXAogICBbJl0oYXV0byBhLCBhdXRvIGIsIGF1dG8gYykgeyByZXR1cm4gcmVzOyB9CiNkZWZpbmUgX0w0KGEsIGIsIGMsIGQsIHJlcylcCiAgIFsmXShhdXRvIGEsIGF1dG8gYiwgYXV0byBjLCBhdXRvIGQpIHsgcmV0dXJuIHJlczsgfQoKLy9Td2lmdC1saWtlIHZlcnNpb24KI2RlZmluZSBfUzAocmVzKSBfTDAocmVzKQojZGVmaW5lIF9TMShyZXMpIF9MMShfMCwgcmVzKQojZGVmaW5lIF9TMihyZXMpIF9MMihfMCwgXzEsIHJlcykKI2RlZmluZSBfUzMocmVzKSBfTDMoXzAsIF8xLCBfMiwgcmVzKQojZGVmaW5lIF9TNChyZXMpIF9MNChfMCwgXzEsIF8yLCBfMywgcmVzKQoKaW50IG1haW4oKSB7CglhdXRvIGYgPSBbJl0oYXV0byB4LCBhdXRvIHkpIHsgcmV0dXJuIHggKyB5OyB9OwoJY291dCA8PCBmKDEsIDQpIDw8IGVuZGw7CgkKCWF1dG8gZyA9IF9MKHgsIHksIHggKyB5KTsKCWNvdXQgPDwgZygyLCA1KSA8PCBlbmRsOwoJYXV0byB4ID0gX0woZygxMjMsIDMyMSkpOwoJY291dCA8PCB4KCkgPDwgZW5kbDsKCWF1dG8gYXZnID0gX0woeCwgeSwgeiwgKHgreSt6KS8zLjApOwoJY291dCA8PCBhdmcoMSwgMiwgNykgPDwgZW5kbDsKCQoJdmVjdG9yPHN0cmluZz4gYXJyeyJoZWxsbyIsICJxIiwgImFueSIsICJsZW5ndGgiLCAiZ2ciLCAib21nIn07CglhdXRvIGNvbXBCeUtleSA9IF9MKGYsIF9MKHgsIHksIGYoeCkgPCBmKHkpKSk7Cglzb3J0KGFyci5iZWdpbigpLCBhcnIuZW5kKCksIGNvbXBCeUtleShfTCh4LCB4Lmxlbmd0aCgpKSkpOwoJZm9yX2VhY2goYXJyLmJlZ2luKCksIGFyci5lbmQoKSwgX0woeCwgKHZvaWQpKGNvdXQgPDwgeCA8PCBlbmRsKSkpOwoJCglzb3J0KGFyci5iZWdpbigpLCBhcnIuZW5kKCksIF9TMihfMCA+IF8xKSk7Cglmb3JfZWFjaChhcnIuYmVnaW4oKSwgYXJyLmVuZCgpLCBfUzEoKHZvaWQpKGNvdXQgPDwgXzAgPDwgZW5kbCkpKTsKCQoJcmV0dXJuIDA7Cn0K