test3.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. //-----------------------------------------------------------------------------
  2. // boost-libs variant/test/test3.cpp source file
  3. // See http://www.boost.org for updates, documentation, and revision history.
  4. //-----------------------------------------------------------------------------
  5. //
  6. // Copyright (c) 2003
  7. // Eric Friedman, Itay Maman
  8. //
  9. // Distributed under the Boost Software License, Version 1.0. (See
  10. // accompanying file LICENSE_1_0.txt or copy at
  11. // http://www.boost.org/LICENSE_1_0.txt)
  12. #include "boost/core/lightweight_test.hpp"
  13. #include "boost/variant.hpp"
  14. #include <iostream>
  15. #include <sstream>
  16. #include <string>
  17. /////////////////////////////////////////////////////////////////////
  18. using boost::variant;
  19. using boost::recursive_wrapper;
  20. using std::cout;
  21. using std::endl;
  22. /////////////////////////////////////////////////////////////////////
  23. /////////////////////////////////////////////////////////////////////
  24. struct Add;
  25. struct Sub;
  26. typedef variant<int, recursive_wrapper<Add>, recursive_wrapper<Sub> > Expr;
  27. struct Sub
  28. {
  29. Sub();
  30. Sub(const Expr& l, const Expr& r);
  31. Sub(const Sub& other);
  32. Expr lhs_;
  33. Expr rhs_;
  34. };
  35. struct Add
  36. {
  37. Add() { }
  38. Add(const Expr& l, const Expr& r) : lhs_(l), rhs_(r) { }
  39. Add(const Add& other) : lhs_(other.lhs_), rhs_(other.rhs_) { }
  40. Expr lhs_;
  41. Expr rhs_;
  42. };
  43. Sub::Sub() { }
  44. Sub::Sub(const Expr& l, const Expr& r) : lhs_(l), rhs_(r) { }
  45. Sub::Sub(const Sub& other) : lhs_(other.lhs_), rhs_(other.rhs_) { }
  46. //
  47. // insert-to operators
  48. //
  49. std::ostream& operator<<(std::ostream& out, const Sub& a);
  50. std::ostream& operator<<(std::ostream& out, const Add& a)
  51. {
  52. out << '(' << a.lhs_ << '+' << a.rhs_ << ')';
  53. return out;
  54. }
  55. std::ostream& operator<<(std::ostream& out, const Sub& a)
  56. {
  57. out << '(' << a.lhs_ << '-' << a.rhs_ << ')';
  58. return out;
  59. }
  60. //
  61. // Expression evaluation visitor
  62. //
  63. struct Calculator : boost::static_visitor<int>
  64. {
  65. Calculator() { }
  66. int operator()(Add& x) const
  67. {
  68. Calculator calc;
  69. int n1 = boost::apply_visitor(calc, x.lhs_);
  70. int n2 = boost::apply_visitor(calc, x.rhs_);
  71. return n1 + n2;
  72. }
  73. int operator()(Sub& x) const
  74. {
  75. return boost::apply_visitor(Calculator(), x.lhs_)
  76. - boost::apply_visitor(Calculator(), x.rhs_);
  77. }
  78. int operator()(Expr& x) const
  79. {
  80. Calculator calc;
  81. return boost::apply_visitor(calc, x);
  82. }
  83. int operator()(int x) const
  84. {
  85. return x;
  86. }
  87. }; // Calculator
  88. /////////////////////////////////////////////////////////////////////
  89. int main()
  90. {
  91. int n = 13;
  92. Expr e1( Add(n, Sub(Add(40,2),Add(10,4))) ); //n + (40+2)-(10+14) = n+28
  93. std::ostringstream e1_str;
  94. e1_str << e1;
  95. BOOST_TEST(e1.type() == boost::typeindex::type_id<Add>());
  96. BOOST_TEST(e1_str.str() == "(13+((40+2)-(10+4)))");
  97. //Evaluate expression
  98. int res = boost::apply_visitor(Calculator(), e1);
  99. BOOST_TEST(res == n + 28);
  100. return boost::report_errors();
  101. }