• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
13 #include "boost/core/lightweight_test.hpp"
14 #include "boost/variant.hpp"
15 
16 #include <iostream>
17 #include <sstream>
18 #include <string>
19 
20 /////////////////////////////////////////////////////////////////////
21 
22 using boost::variant;
23 using boost::recursive_wrapper;
24 using std::cout;
25 using std::endl;
26 
27 /////////////////////////////////////////////////////////////////////
28 /////////////////////////////////////////////////////////////////////
29 
30 struct Add;
31 struct Sub;
32 
33 typedef variant<int, recursive_wrapper<Add>, recursive_wrapper<Sub> > Expr;
34 
35 struct Sub
36 {
37    Sub();
38    Sub(const Expr& l, const Expr& r);
39    Sub(const Sub& other);
40 
41    Expr lhs_;
42    Expr rhs_;
43 };
44 
45 struct Add
46 {
AddAdd47    Add() { }
AddAdd48    Add(const Expr& l, const Expr& r) : lhs_(l), rhs_(r) { }
AddAdd49    Add(const Add& other) : lhs_(other.lhs_), rhs_(other.rhs_) { }
50 
51    Expr lhs_;
52    Expr rhs_;
53 };
54 
Sub()55 Sub::Sub() { }
Sub(const Expr & l,const Expr & r)56 Sub::Sub(const Expr& l, const Expr& r) : lhs_(l), rhs_(r) { }
Sub(const Sub & other)57 Sub::Sub(const Sub& other) : lhs_(other.lhs_), rhs_(other.rhs_) { }
58 
59 
60 //
61 // insert-to operators
62 //
63 std::ostream& operator<<(std::ostream& out, const Sub& a);
64 
operator <<(std::ostream & out,const Add & a)65 std::ostream& operator<<(std::ostream& out, const Add& a)
66 {
67    out << '(' << a.lhs_ << '+' << a.rhs_ << ')';
68    return out;
69 }
70 
operator <<(std::ostream & out,const Sub & a)71 std::ostream& operator<<(std::ostream& out, const Sub& a)
72 {
73    out << '(' << a.lhs_ << '-' << a.rhs_ << ')';
74    return out;
75 }
76 
77 //
78 // Expression evaluation visitor
79 //
80 struct Calculator : boost::static_visitor<int>
81 {
CalculatorCalculator82    Calculator()  { }
83 
operator ()Calculator84    int operator()(Add& x) const
85    {
86       Calculator calc;
87       int n1 = boost::apply_visitor(calc, x.lhs_);
88       int n2 = boost::apply_visitor(calc, x.rhs_);
89 
90       return n1 + n2;
91    }
92 
operator ()Calculator93    int operator()(Sub& x) const
94    {
95       return boost::apply_visitor(Calculator(), x.lhs_)
96          - boost::apply_visitor(Calculator(), x.rhs_);
97    }
98 
operator ()Calculator99    int operator()(Expr& x) const
100    {
101       Calculator calc;
102       return boost::apply_visitor(calc, x);
103    }
104 
operator ()Calculator105    int operator()(int x) const
106    {
107       return x;
108    }
109 
110 }; // Calculator
111 
112 
113 /////////////////////////////////////////////////////////////////////
114 
115 
main()116 int main()
117 {
118 
119    int n = 13;
120    Expr e1( Add(n, Sub(Add(40,2),Add(10,4))) ); //n + (40+2)-(10+14) = n+28
121 
122    std::ostringstream e1_str;
123    e1_str << e1;
124 
125    BOOST_TEST(e1.type() == boost::typeindex::type_id<Add>());
126    BOOST_TEST(e1_str.str() == "(13+((40+2)-(10+4)))");
127 
128    //Evaluate expression
129    int res = boost::apply_visitor(Calculator(), e1);
130    BOOST_TEST(res == n + 28);
131 
132    return boost::report_errors();
133 }
134 
135