#include <iostream>
using namespace std;
struct shr {
template <typename A, typename B>
constexpr auto operator()(A&& a, B&& b) {
return std::forward<A>(a) >> std::forward<B>(b);
}
};
struct shl {
template <typename A, typename B>
constexpr void operator()(A&& a, B&& b) {
std::forward<A>(a) << std::forward<B>(b);
}
};
template <typename F, typename A, typename B = A>
auto Apply(A&& a, B&& b) {
return F{}(std::forward<A>(a), std::forward<B>(b));
}
int main() {
// std::cout << (2 >> 1); but uglier
Apply<shl>(std::cout, Apply<shr>(2, 1));
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKc3RydWN0IHNociB7CiAgdGVtcGxhdGUgPHR5cGVuYW1lIEEsIHR5cGVuYW1lIEI+CiAgY29uc3RleHByIGF1dG8gb3BlcmF0b3IoKShBJiYgYSwgQiYmIGIpIHsKICAgIHJldHVybiBzdGQ6OmZvcndhcmQ8QT4oYSkgPj4gc3RkOjpmb3J3YXJkPEI+KGIpOwogIH0KfTsKCnN0cnVjdCBzaGwgewogIHRlbXBsYXRlIDx0eXBlbmFtZSBBLCB0eXBlbmFtZSBCPgogIGNvbnN0ZXhwciB2b2lkIG9wZXJhdG9yKCkoQSYmIGEsIEImJiBiKSB7CiAgICBzdGQ6OmZvcndhcmQ8QT4oYSkgPDwgc3RkOjpmb3J3YXJkPEI+KGIpOwogIH0KfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBGLCB0eXBlbmFtZSBBLCB0eXBlbmFtZSBCID0gQT4KYXV0byBBcHBseShBJiYgYSwgQiYmIGIpIHsKICByZXR1cm4gRnt9KHN0ZDo6Zm9yd2FyZDxBPihhKSwgc3RkOjpmb3J3YXJkPEI+KGIpKTsKfQoKCmludCBtYWluKCkgewogIC8vIHN0ZDo6Y291dCA8PCAoMiA+PiAxKTsgYnV0IHVnbGllcgogIEFwcGx5PHNobD4oc3RkOjpjb3V0LCBBcHBseTxzaHI+KDIsIDEpKTsKfQ==