fork download
  1. #include <type_traits>
  2. #include <tuple>
  3.  
  4. namespace mplex {
  5.  
  6. template <std::size_t N> struct placeholder {
  7. static constexpr std::size_t value = N;
  8.  
  9. template <typename T>
  10. friend auto constexpr eval(placeholder, T&& tuple) { return std::get<N>(std::forward<T>(tuple)); }
  11. };
  12. using p1 = placeholder<0>;
  13. using p2 = placeholder<1>;
  14. using p3 = placeholder<2>;
  15.  
  16. template <typename T> struct expression_template { using type = T; };
  17.  
  18. auto _1 = expression_template<p1>{};
  19. auto _2 = expression_template<p2>{};
  20. auto _3 = expression_template<p3>{};
  21.  
  22. template <int Value>
  23. expression_template<std::integral_constant<int, Value> > int_();
  24.  
  25. template <typename T, T Value, typename X>
  26. auto constexpr eval(std::integral_constant<T, Value>, X&&) { return Value; }
  27.  
  28. template <typename L, typename R>
  29. struct mul {
  30. template <typename T>
  31. friend auto constexpr eval(mul, T&& tuple) { return eval(L{}, tuple)*eval(R{}, tuple); }
  32. };
  33. template <typename A, typename B>
  34. auto operator*(expression_template<A>, expression_template<B>) -> expression_template<mul<A, B>>;
  35.  
  36. template <typename L, typename R>
  37. struct add {
  38. template <typename T>
  39. friend auto constexpr eval(add, T&& tuple) { return eval(L{}, tuple)+eval(R{}, tuple); }
  40. };
  41. template <typename A, typename B>
  42. auto operator+(expression_template<A>, expression_template<B>) -> expression_template<add<A, B>>;
  43.  
  44. template <typename L, typename R>
  45. struct div {
  46. template <typename T>
  47. friend constexpr auto eval(div, T&& tuple) { return eval(L{}, tuple)/eval(R{}, tuple); }
  48. };
  49. template <typename A, typename B>
  50. auto operator/(expression_template<A>, expression_template<B>) -> expression_template<div<A, B>>;
  51.  
  52. } // namespace mplex
  53.  
  54. int main()
  55. {
  56. using namespace mplex;
  57. using newFunctor = decltype((_1 + int_<7>())*(_2/_3))::type;
  58. auto constexpr result = eval(newFunctor{}, std::make_tuple(1, 6, 3));
  59. static_assert(result == (1+7)*(6/3), "");
  60. }
  61.  
Success #stdin #stdout 0s 3452KB
stdin
Standard input is empty
stdout
Standard output is empty