#include <type_traits>
#include <memory>
namespace TestFoo{
struct Tag {};
struct shift_left:Tag {};
struct shift_right:Tag {};
struct multiplies:Tag {};
struct divides:Tag {};
struct modulus:Tag {};
struct plus:Tag {};
struct minus:Tag {};
struct less:Tag {};
struct greater:Tag {};
struct less_equal:Tag {};
struct greater_equal:Tag {};
struct equal_to:Tag {};
struct not_equal_to:Tag {};
struct logical_or:Tag {};
struct logical_and:Tag {};
struct bitwise_and:Tag {};
struct bitwise_or:Tag {};
struct bitwise_xor:Tag {};
struct shift_left_assign:Tag {};
struct shift_right_assign:Tag {};
struct multiplies_assign:Tag {};
struct divides_assign:Tag {};
struct modulus_assign:Tag {};
struct plus_assign:Tag {};
struct minus_assign:Tag {};
struct bitwise_and_assign:Tag {};
struct bitwise_or_assign:Tag {};
struct bitwise_xor_assign:Tag {};
template<typename Tag, typename...ARGS>
class Expr
{
public:
template<typename...SRC>
Expr(SRC const&...){
}
private:
};
template<typename T>
struct is_expr{
static constexpr std::size_t value = 0;
};
template<typename Tag, typename...ARGS>
struct is_expr<Expr<Tag, ARGS...>>{
static constexpr std::size_t value = sizeof...(ARGS);
};
#define BinaryOp(op, name) \
template<typename L, typename R, typename = typename std::enable_if<is_expr<L>::value || is_expr<R>::value>::type> \
Expr<name, L, R> operator op(const L&l, const R&r) \
{ \
return {std::forward<const L&>(l), std::forward<const R&>(r)}; \
}
BinaryOp(<<, shift_left)
BinaryOp(>>, shift_right)
BinaryOp(*, multiplies)
BinaryOp(%, modulus)
BinaryOp(+, plus)
BinaryOp(-, minus)
BinaryOp(<, less)
BinaryOp(>, greater)
BinaryOp(<=, less_equal)
BinaryOp(>=, greater_equal)
BinaryOp(==, equal_to)
BinaryOp(!=, not_equal_to)
BinaryOp(||, logical_or)
BinaryOp(&&, logical_and)
}
using namespace TestFoo;//using namespace Appear bug
void test(){
Expr<int, int>{} && Expr<int, int>{};
Expr<int, int>{} || Expr<int, int>{};
}
int main()
{
return 0;
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8bWVtb3J5PgpuYW1lc3BhY2UgVGVzdEZvb3sKc3RydWN0IFRhZyB7fTsKc3RydWN0IHNoaWZ0X2xlZnQ6VGFnIHt9OwpzdHJ1Y3Qgc2hpZnRfcmlnaHQ6VGFnIHt9OwpzdHJ1Y3QgbXVsdGlwbGllczpUYWcge307CnN0cnVjdCBkaXZpZGVzOlRhZyB7fTsKc3RydWN0IG1vZHVsdXM6VGFnIHt9OwpzdHJ1Y3QgcGx1czpUYWcge307CnN0cnVjdCBtaW51czpUYWcge307CnN0cnVjdCBsZXNzOlRhZyB7fTsKc3RydWN0IGdyZWF0ZXI6VGFnIHt9OwpzdHJ1Y3QgbGVzc19lcXVhbDpUYWcge307CnN0cnVjdCBncmVhdGVyX2VxdWFsOlRhZyB7fTsKc3RydWN0IGVxdWFsX3RvOlRhZyB7fTsKc3RydWN0IG5vdF9lcXVhbF90bzpUYWcge307CnN0cnVjdCBsb2dpY2FsX29yOlRhZyB7fTsKc3RydWN0IGxvZ2ljYWxfYW5kOlRhZyB7fTsKc3RydWN0IGJpdHdpc2VfYW5kOlRhZyB7fTsKc3RydWN0IGJpdHdpc2Vfb3I6VGFnIHt9OwpzdHJ1Y3QgYml0d2lzZV94b3I6VGFnIHt9OwpzdHJ1Y3Qgc2hpZnRfbGVmdF9hc3NpZ246VGFnIHt9OwpzdHJ1Y3Qgc2hpZnRfcmlnaHRfYXNzaWduOlRhZyB7fTsKc3RydWN0IG11bHRpcGxpZXNfYXNzaWduOlRhZyB7fTsKc3RydWN0IGRpdmlkZXNfYXNzaWduOlRhZyB7fTsKc3RydWN0IG1vZHVsdXNfYXNzaWduOlRhZyB7fTsKc3RydWN0IHBsdXNfYXNzaWduOlRhZyB7fTsKc3RydWN0IG1pbnVzX2Fzc2lnbjpUYWcge307CnN0cnVjdCBiaXR3aXNlX2FuZF9hc3NpZ246VGFnIHt9OwpzdHJ1Y3QgYml0d2lzZV9vcl9hc3NpZ246VGFnIHt9OwpzdHJ1Y3QgYml0d2lzZV94b3JfYXNzaWduOlRhZyB7fTsKCnRlbXBsYXRlPHR5cGVuYW1lIFRhZywgdHlwZW5hbWUuLi5BUkdTPgpjbGFzcyBFeHByCnsKCnB1YmxpYzoKICAgIHRlbXBsYXRlPHR5cGVuYW1lLi4uU1JDPgogICAgRXhwcihTUkMgY29uc3QmLi4uKXsKCiAgICB9CnByaXZhdGU6Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpzdHJ1Y3QgaXNfZXhwcnsKICAgIHN0YXRpYyBjb25zdGV4cHIgc3RkOjpzaXplX3QgdmFsdWUgPSAwOwp9Owp0ZW1wbGF0ZTx0eXBlbmFtZSBUYWcsIHR5cGVuYW1lLi4uQVJHUz4Kc3RydWN0IGlzX2V4cHI8RXhwcjxUYWcsIEFSR1MuLi4+PnsKICAgIHN0YXRpYyBjb25zdGV4cHIgc3RkOjpzaXplX3QgdmFsdWUgPSBzaXplb2YuLi4oQVJHUyk7Cn07CgojZGVmaW5lIEJpbmFyeU9wKG9wLCBuYW1lKSAgIFwKdGVtcGxhdGU8dHlwZW5hbWUgTCwgdHlwZW5hbWUgUiwgdHlwZW5hbWUgPSB0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjxpc19leHByPEw+Ojp2YWx1ZSB8fCBpc19leHByPFI+Ojp2YWx1ZT46OnR5cGU+IFwKRXhwcjxuYW1lLCBMLCBSPiBvcGVyYXRvciBvcChjb25zdCBMJmwsIGNvbnN0IFImcikgXAp7IFwKICAgcmV0dXJuICB7c3RkOjpmb3J3YXJkPGNvbnN0IEwmPihsKSwgc3RkOjpmb3J3YXJkPGNvbnN0IFImPihyKX07IFwKfQoKQmluYXJ5T3AoPDwsIHNoaWZ0X2xlZnQpCkJpbmFyeU9wKD4+LCBzaGlmdF9yaWdodCkKQmluYXJ5T3AoKiwgbXVsdGlwbGllcykKQmluYXJ5T3AoJSwgbW9kdWx1cykKQmluYXJ5T3AoKywgcGx1cykKQmluYXJ5T3AoLSwgbWludXMpCkJpbmFyeU9wKDwsIGxlc3MpCkJpbmFyeU9wKD4sIGdyZWF0ZXIpCkJpbmFyeU9wKDw9LCBsZXNzX2VxdWFsKQpCaW5hcnlPcCg+PSwgZ3JlYXRlcl9lcXVhbCkKQmluYXJ5T3AoPT0sIGVxdWFsX3RvKQpCaW5hcnlPcCghPSwgbm90X2VxdWFsX3RvKQpCaW5hcnlPcCh8fCwgbG9naWNhbF9vcikKQmluYXJ5T3AoJiYsIGxvZ2ljYWxfYW5kKQoKfQoKdXNpbmcgbmFtZXNwYWNlIFRlc3RGb287Ly91c2luZyBuYW1lc3BhY2UgQXBwZWFyIGJ1Zwp2b2lkIHRlc3QoKXsKICAgIEV4cHI8aW50LCBpbnQ+e30gJiYgRXhwcjxpbnQsIGludD57fTsKICAgIEV4cHI8aW50LCBpbnQ+e30gfHwgRXhwcjxpbnQsIGludD57fTsKCn0KCmludCBtYWluKCkKewoJcmV0dXJuIDA7Cn0K