struct op {\
template <typename T, typename U>\
using expression = decltype(std::op(std::declval<T &>(), std::declval<U &>()));\
constexpr op() = default;\
template <typename T, typename U>\
inline constexpr auto operator()(T const &t, U const &u) const { return std::op(t, u); }\
};\
template <typename T>\
struct op##_st {\
template <typename U>\
using expression = typename op::template expression<T, U>;\
T const t;\
constexpr op##_st() = default;\
constexpr op##_st(T const &t) : t(t) { }\
template <typename U>\
inline constexpr auto operator()(U const &u) const { return std::op(t, u); }\
};\
template <typename T>\
struct op##_ts {\
template <typename U>\
using expression = typename op::template expression<U, T>;\
T const t;\
constexpr op##_ts() = default;\
constexpr op##_ts(T const &t) : t(t) { }\
template <typename U>\
inline constexpr auto operator()(U const &u) const { return std::op(u, t); }\
}