123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- //-----------------------------------------------------------------------------
- // boost-libs variant/test/test3.cpp source file
- // See http://www.boost.org for updates, documentation, and revision history.
- //-----------------------------------------------------------------------------
- //
- // Copyright (c) 2003
- // Eric Friedman, Itay Maman
- //
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- #include "boost/core/lightweight_test.hpp"
- #include "boost/variant.hpp"
- #include <iostream>
- #include <sstream>
- #include <string>
- /////////////////////////////////////////////////////////////////////
- using boost::variant;
- using boost::recursive_wrapper;
- using std::cout;
- using std::endl;
- /////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////
- struct Add;
- struct Sub;
- typedef variant<int, recursive_wrapper<Add>, recursive_wrapper<Sub> > Expr;
- struct Sub
- {
- Sub();
- Sub(const Expr& l, const Expr& r);
- Sub(const Sub& other);
- Expr lhs_;
- Expr rhs_;
- };
- struct Add
- {
- Add() { }
- Add(const Expr& l, const Expr& r) : lhs_(l), rhs_(r) { }
- Add(const Add& other) : lhs_(other.lhs_), rhs_(other.rhs_) { }
- Expr lhs_;
- Expr rhs_;
- };
- Sub::Sub() { }
- Sub::Sub(const Expr& l, const Expr& r) : lhs_(l), rhs_(r) { }
- Sub::Sub(const Sub& other) : lhs_(other.lhs_), rhs_(other.rhs_) { }
- //
- // insert-to operators
- //
- std::ostream& operator<<(std::ostream& out, const Sub& a);
- std::ostream& operator<<(std::ostream& out, const Add& a)
- {
- out << '(' << a.lhs_ << '+' << a.rhs_ << ')';
- return out;
- }
- std::ostream& operator<<(std::ostream& out, const Sub& a)
- {
- out << '(' << a.lhs_ << '-' << a.rhs_ << ')';
- return out;
- }
- //
- // Expression evaluation visitor
- //
- struct Calculator : boost::static_visitor<int>
- {
- Calculator() { }
- int operator()(Add& x) const
- {
- Calculator calc;
- int n1 = boost::apply_visitor(calc, x.lhs_);
- int n2 = boost::apply_visitor(calc, x.rhs_);
-
- return n1 + n2;
- }
- int operator()(Sub& x) const
- {
- return boost::apply_visitor(Calculator(), x.lhs_)
- - boost::apply_visitor(Calculator(), x.rhs_);
- }
- int operator()(Expr& x) const
- {
- Calculator calc;
- return boost::apply_visitor(calc, x);
- }
- int operator()(int x) const
- {
- return x;
- }
- }; // Calculator
- /////////////////////////////////////////////////////////////////////
- int main()
- {
- int n = 13;
- Expr e1( Add(n, Sub(Add(40,2),Add(10,4))) ); //n + (40+2)-(10+14) = n+28
- std::ostringstream e1_str;
- e1_str << e1;
- BOOST_TEST(e1.type() == boost::typeindex::type_id<Add>());
- BOOST_TEST(e1_str.str() == "(13+((40+2)-(10+4)))");
- //Evaluate expression
- int res = boost::apply_visitor(Calculator(), e1);
- BOOST_TEST(res == n + 28);
- return boost::report_errors();
- }
|