fork download
  1. #include <type_traits>
  2. #include <memory>
  3. namespace TestFoo{
  4. struct Tag {};
  5. struct shift_left:Tag {};
  6. struct shift_right:Tag {};
  7. struct multiplies:Tag {};
  8. struct divides:Tag {};
  9. struct modulus:Tag {};
  10. struct plus:Tag {};
  11. struct minus:Tag {};
  12. struct less:Tag {};
  13. struct greater:Tag {};
  14. struct less_equal:Tag {};
  15. struct greater_equal:Tag {};
  16. struct equal_to:Tag {};
  17. struct not_equal_to:Tag {};
  18. struct logical_or:Tag {};
  19. struct logical_and:Tag {};
  20. struct bitwise_and:Tag {};
  21. struct bitwise_or:Tag {};
  22. struct bitwise_xor:Tag {};
  23. struct shift_left_assign:Tag {};
  24. struct shift_right_assign:Tag {};
  25. struct multiplies_assign:Tag {};
  26. struct divides_assign:Tag {};
  27. struct modulus_assign:Tag {};
  28. struct plus_assign:Tag {};
  29. struct minus_assign:Tag {};
  30. struct bitwise_and_assign:Tag {};
  31. struct bitwise_or_assign:Tag {};
  32. struct bitwise_xor_assign:Tag {};
  33.  
  34. template<typename Tag, typename...ARGS>
  35. class Expr
  36. {
  37.  
  38. public:
  39. template<typename...SRC>
  40. Expr(SRC const&...){
  41.  
  42. }
  43. private:
  44. };
  45.  
  46. template<typename T>
  47. struct is_expr{
  48. static constexpr std::size_t value = 0;
  49. };
  50. template<typename Tag, typename...ARGS>
  51. struct is_expr<Expr<Tag, ARGS...>>{
  52. static constexpr std::size_t value = sizeof...(ARGS);
  53. };
  54.  
  55. #define BinaryOp(op, name) \
  56. template<typename L, typename R, typename = typename std::enable_if<is_expr<L>::value || is_expr<R>::value>::type> \
  57. Expr<name, L, R> operator op(const L&l, const R&r) \
  58. { \
  59.   return {std::forward<const L&>(l), std::forward<const R&>(r)}; \
  60. }
  61.  
  62. BinaryOp(<<, shift_left)
  63. BinaryOp(>>, shift_right)
  64. BinaryOp(*, multiplies)
  65. BinaryOp(%, modulus)
  66. BinaryOp(+, plus)
  67. BinaryOp(-, minus)
  68. BinaryOp(<, less)
  69. BinaryOp(>, greater)
  70. BinaryOp(<=, less_equal)
  71. BinaryOp(>=, greater_equal)
  72. BinaryOp(==, equal_to)
  73. BinaryOp(!=, not_equal_to)
  74. BinaryOp(||, logical_or)
  75. BinaryOp(&&, logical_and)
  76.  
  77. }
  78.  
  79. using namespace TestFoo;//using namespace Appear bug
  80. void test(){
  81. Expr<int, int>{} && Expr<int, int>{};
  82. Expr<int, int>{} || Expr<int, int>{};
  83.  
  84. }
  85.  
  86. int main()
  87. {
  88. return 0;
  89. }
  90.  
Success #stdin #stdout 0s 3336KB
stdin
Standard input is empty
stdout
Standard output is empty