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/test/minimal.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 | { |
---|
47 | Add() { } |
---|
48 | Add(const Expr& l, const Expr& r) : lhs_(l), rhs_(r) { } |
---|
49 | Add(const Add& other) : lhs_(other.lhs_), rhs_(other.rhs_) { } |
---|
50 | |
---|
51 | Expr lhs_; |
---|
52 | Expr rhs_; |
---|
53 | }; |
---|
54 | |
---|
55 | Sub::Sub() { } |
---|
56 | Sub::Sub(const Expr& l, const Expr& r) : lhs_(l), rhs_(r) { } |
---|
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 | |
---|
65 | std::ostream& operator<<(std::ostream& out, const Add& a) |
---|
66 | { |
---|
67 | out << '(' << a.lhs_ << '+' << a.rhs_ << ')'; |
---|
68 | return out; |
---|
69 | } |
---|
70 | |
---|
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 | { |
---|
82 | Calculator() { } |
---|
83 | |
---|
84 | 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 | |
---|
93 | int operator()(Sub& x) const |
---|
94 | { |
---|
95 | return boost::apply_visitor(Calculator(), x.lhs_) |
---|
96 | - boost::apply_visitor(Calculator(), x.rhs_); |
---|
97 | } |
---|
98 | |
---|
99 | int operator()(Expr& x) const |
---|
100 | { |
---|
101 | Calculator calc; |
---|
102 | return boost::apply_visitor(calc, x); |
---|
103 | } |
---|
104 | |
---|
105 | int operator()(int x) const |
---|
106 | { |
---|
107 | return x; |
---|
108 | } |
---|
109 | |
---|
110 | }; // Calculator |
---|
111 | |
---|
112 | |
---|
113 | ///////////////////////////////////////////////////////////////////// |
---|
114 | |
---|
115 | |
---|
116 | int test_main(int, char* []) |
---|
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_CHECK(e1.type() == typeid(Add)); |
---|
126 | BOOST_CHECK(e1_str.str() == "(13+((40+2)-(10+4)))"); |
---|
127 | |
---|
128 | //Evaluate expression |
---|
129 | int res = boost::apply_visitor(Calculator(), e1); |
---|
130 | BOOST_CHECK(res == n + 28); |
---|
131 | |
---|
132 | return 0; |
---|
133 | } |
---|
134 | |
---|