#ifndef OPERATOR_HPP #define OPERATOR_HPP #include template struct Operator { virtual ~Operator() { } virtual Domain eval(const std::vector&) const = 0; virtual void print(std::ostream&) const = 0; }; template struct Maximum : public Operator { virtual Domain eval(const std::vector& arguments) const { Domain result = -infinity(); for (typename std::vector::const_iterator it = arguments.begin(); it != arguments.end(); ++it) { result = (result < *it ? *it : result); } return result; } void print(std::ostream& cout) const { cout << "max"; } }; template struct Minimum : public Operator { virtual Domain eval(const std::vector& arguments) const { Domain result = infinity(); for (typename std::vector::const_iterator it = arguments.begin(); it != arguments.end(); ++it) { result = (*it < result ? *it : result); } return result; } void print(std::ostream& cout) const { cout << "min"; } }; template struct Negation : public Operator { virtual Domain eval(const std::vector& arguments) const { if (arguments.size() > 1) throw "Too many arguments to a negation."; return -arguments[0]; } void print(std::ostream& cout) const { cout << "-"; } }; template struct Addition : public Operator { virtual Domain eval(const std::vector& arguments) const { Domain result = 0; for (typename std::vector::const_iterator it = arguments.begin(); it != arguments.end(); ++it) { result += *it; } return result; } void print(std::ostream& cout) const { cout << "add"; } }; template struct Subtraction : public Operator { virtual Domain eval(const std::vector& arguments) const { Domain result = 0; for (typename std::vector::const_iterator it = arguments.begin(); it != arguments.end(); ++it) { if (it == arguments.begin()) result = *it; else result -= *it; } return result; } void print(std::ostream& cout) const { cout << "sub"; } }; template struct Multiplication : public Operator { virtual Domain eval(const std::vector& arguments) const { Domain result = 1; for (auto it = arguments.begin(), end = arguments.end(); it != end; ++it) { result *= *it; } return result; } void print(std::ostream& cout) const { cout << "mult"; } }; template struct Comma : public Operator { virtual Domain eval(const std::vector& arguments) const { if (arguments[0] == -infinity()) { return -infinity(); } return arguments[1]; } void print(std::ostream& cout) const { cout << "comma"; } }; template struct Guard : public Operator { virtual Domain eval(const std::vector& arguments) const { if (arguments[0] < arguments[1]) { return -infinity(); } return arguments[2]; } void print(std::ostream& cout) const { cout << "guard"; } }; template std::ostream& operator<<(std::ostream& cout, const Operator& op) { op.print(cout); return cout; } #endif