fork download
  1. #include <vector>
  2. #include <iterator>
  3. #include <algorithm>
  4. #include <memory>
  5. #include <iostream>
  6. #include <stdexcept>
  7.  
  8. class expression {
  9. //addition and constants are unused, and merely shown for extendibility
  10. enum exprtype{parameter_type, constant_type, multiplication_type, addition_type} type;
  11. long long value; //for value types, and parameter number
  12. std::unique_ptr<expression> left; //for unary and binary functions
  13. std::unique_ptr<expression> right; //for binary functions
  14.  
  15. public:
  16. //constructors
  17. expression(long long val, bool is_variable=false)
  18. :type(is_variable?parameter_type:constant_type), value(val)
  19. {}
  20. expression(const expression& rhs)
  21. : type(rhs.type)
  22. , value(rhs.value)
  23. , left(rhs.left.get() ? std::unique_ptr<expression>(new expression(*rhs.left)) : std::unique_ptr<expression>(NULL))
  24. , right(rhs.right.get() ? std::unique_ptr<expression>(new expression(*rhs.right)) : std::unique_ptr<expression>(NULL))
  25. {}
  26. expression(expression&& rhs)
  27. :type(rhs.type), value(rhs.value), left(std::move(rhs.left)), right(std::move(rhs.right))
  28. {}
  29. //assignment operator
  30. expression& operator=(expression rhs) {
  31. type = rhs.type;
  32. value = rhs.value;
  33. left = std::move(rhs.left);
  34. right = std::move(rhs.right);
  35. return *this;
  36. }
  37.  
  38. //operators
  39. friend expression operator*(expression lhs, expression rhs) {
  40. expression ret(0);
  41. ret.type = multiplication_type;
  42. ret.left = std::unique_ptr<expression>(new expression(std::move(lhs)));
  43. ret.right = std::unique_ptr<expression>(new expression(std::move(rhs)));
  44. return ret;
  45. }
  46. friend expression operator+(expression lhs, expression rhs) {
  47. expression ret(0);
  48. ret.type = addition_type;
  49. ret.left = std::unique_ptr<expression>(new expression(std::move(lhs)));
  50. ret.right = std::unique_ptr<expression>(new expression(std::move(rhs)));
  51. return ret;
  52. }
  53.  
  54. //skip the parameter list, don't care. Ignore it entirely
  55. expression& operator<<(const expression&) {return *this;}
  56. expression& operator,(const expression&) {return *this;}
  57.  
  58. template<class container>
  59. void operator>>(container& rhs) {
  60. for(auto it=rhs.begin(); it!=rhs.end(); ++it)
  61. *it = execute(*it);
  62. }
  63.  
  64. private:
  65. //execution
  66. template<class T>
  67. T execute(const T& p0) {
  68. switch(type) {
  69. case parameter_type :
  70. switch(value) {
  71. case 0: return p0; //only one variable
  72. default: throw std::runtime_error("Invalid parameter ID");
  73. }
  74. case constant_type:
  75. return ((T)(value));
  76. case multiplication_type:
  77. return left->execute(p0) * right->execute(p0);
  78. case addition_type:
  79. return left->execute(p0) + right->execute(p0);
  80. default:
  81. throw std::runtime_error("Invalid expression type");
  82. }
  83. }
  84. //This is also unused, and merely shown as extrapolation
  85. template<class T>
  86. T execute(const T& p0, const T& p1) {
  87. switch(type) {
  88. case parameter_type :
  89. switch(value) {
  90. case 0: return p0;
  91. case 1: return p1; //this version has two variables
  92. default: throw std::runtime_error("Invalid parameter ID");
  93. }
  94. case constant_type:
  95. return value;
  96. case multiplication_type:
  97. return left->execute(p0, p1) * right->execute(p0, p1);
  98. case addition_type:
  99. return left->execute(p0, p1) + right->execute(p0, p1);
  100. default:
  101. throw std::runtime_error("Invalid expression type");
  102. }
  103. }
  104. };
  105. #define take
  106. #define with <<
  107. #define in >>
  108. expression x(0, true); //x will be used as a parameter. Sorry: required :(
  109.  
  110. int main() {
  111. std::vector<int> container;
  112. container.push_back(-3);
  113. container.push_back(0);
  114. container.push_back(7);
  115. take x*x with x in container;
  116. for(unsigned i=0; i<container.size(); ++i)
  117. std::cout << container[i] << ' ';
  118.  
  119. std::cout << '\n';
  120. std::vector<float> container2;
  121. container2.push_back(-2.3);
  122. container2.push_back(0);
  123. container2.push_back(7.1);
  124. take 1+x with x in container2;
  125. for(unsigned i=0; i<container2.size(); ++i)
  126. std::cout << container2[i] << ' ';
  127.  
  128. return 0;
  129. }
  130.  
Success #stdin #stdout 0s 3076KB
stdin
Standard input is empty
stdout
9 0 49 
-1.3 1 8.1