sl@0: //-----------------------------------------------------------------------------
sl@0: // boost-libs variant/test/test3.cpp source file
sl@0: // See http://www.boost.org for updates, documentation, and revision history.
sl@0: //-----------------------------------------------------------------------------
sl@0: //
sl@0: // Copyright (c) 2003
sl@0: // Eric Friedman, Itay Maman
sl@0: //
sl@0: // Distributed under the Boost Software License, Version 1.0. (See
sl@0: // accompanying file LICENSE_1_0.txt or copy at
sl@0: // http://www.boost.org/LICENSE_1_0.txt)
sl@0: /*
sl@0:  * © Portions copyright (c) 2006-2007 Nokia Corporation.  All rights reserved.
sl@0: */
sl@0: 
sl@0: #include "boost/test/minimal.hpp"
sl@0: #include "boost/variant.hpp"
sl@0: 
sl@0: #include <iostream>
sl@0: #include <sstream>
sl@0: #include <string>
sl@0: #ifdef __SYMBIAN32__
sl@0: #include "std_log_result.h"
sl@0: #define LOG_FILENAME_LINE __FILE__, __LINE__
sl@0: #endif
sl@0: /////////////////////////////////////////////////////////////////////
sl@0: 
sl@0: using boost::variant;
sl@0: using boost::recursive_wrapper;
sl@0: #ifndef __SYMBIAN32__
sl@0: using std::cout;
sl@0: #endif
sl@0: using std::endl;
sl@0: 
sl@0: /////////////////////////////////////////////////////////////////////
sl@0: /////////////////////////////////////////////////////////////////////
sl@0: 
sl@0: struct Add;
sl@0: struct Sub;
sl@0: 
sl@0: typedef variant<int, recursive_wrapper<Add>, recursive_wrapper<Sub> > Expr;
sl@0: 
sl@0: struct Sub
sl@0: {
sl@0:    Sub();
sl@0:    Sub(const Expr& l, const Expr& r);
sl@0:    Sub(const Sub& other);
sl@0: 
sl@0:    Expr lhs_;
sl@0:    Expr rhs_;
sl@0: };
sl@0: 
sl@0: struct Add
sl@0: {
sl@0:    Add() { }
sl@0:    Add(const Expr& l, const Expr& r) : lhs_(l), rhs_(r) { }
sl@0:    Add(const Add& other) : lhs_(other.lhs_), rhs_(other.rhs_) { }
sl@0: 
sl@0:    Expr lhs_;
sl@0:    Expr rhs_;
sl@0: };
sl@0: 
sl@0: Sub::Sub() { }
sl@0: Sub::Sub(const Expr& l, const Expr& r) : lhs_(l), rhs_(r) { }
sl@0: Sub::Sub(const Sub& other) : lhs_(other.lhs_), rhs_(other.rhs_) { }
sl@0: 
sl@0: 
sl@0: //
sl@0: // insert-to operators
sl@0: //
sl@0: std::ostream& operator<<(std::ostream& out, const Sub& a);
sl@0: 
sl@0: std::ostream& operator<<(std::ostream& out, const Add& a)
sl@0: {
sl@0:    out << '(' << a.lhs_ << '+' << a.rhs_ << ')';
sl@0:    return out;
sl@0: }
sl@0: 
sl@0: std::ostream& operator<<(std::ostream& out, const Sub& a)
sl@0: {
sl@0:    out << '(' << a.lhs_ << '-' << a.rhs_ << ')';
sl@0:    return out;
sl@0: }
sl@0: 
sl@0: //
sl@0: // Expression evaluation visitor
sl@0: //
sl@0: struct Calculator : boost::static_visitor<int>
sl@0: {
sl@0:    Calculator()  { }
sl@0: 
sl@0:    int operator()(Add& x) const
sl@0:    {
sl@0:       Calculator calc;
sl@0:       int n1 = boost::apply_visitor(calc, x.lhs_);
sl@0:       int n2 = boost::apply_visitor(calc, x.rhs_);
sl@0:       
sl@0:       return n1 + n2;
sl@0:    }
sl@0: 
sl@0:    int operator()(Sub& x) const
sl@0:    {
sl@0:       return boost::apply_visitor(Calculator(), x.lhs_) 
sl@0:          - boost::apply_visitor(Calculator(), x.rhs_);
sl@0:    }
sl@0: 
sl@0:    int operator()(Expr& x) const
sl@0:    {
sl@0:       Calculator calc;
sl@0:       return boost::apply_visitor(calc, x);
sl@0:    }
sl@0: 
sl@0:    int operator()(int x) const
sl@0:    {
sl@0:       return x;
sl@0:    }
sl@0: 
sl@0: }; // Calculator
sl@0: 
sl@0: 
sl@0: /////////////////////////////////////////////////////////////////////
sl@0: 
sl@0: 
sl@0: int test_main(int, char* [])
sl@0: {
sl@0: std_log(LOG_FILENAME_LINE,"[Test Case for test3]");
sl@0:    int n = 13;
sl@0:    Expr e1( Add(n, Sub(Add(40,2),Add(10,4))) ); //n + (40+2)-(10+14) = n+28
sl@0: 
sl@0:    std::ostringstream e1_str;
sl@0:    e1_str << e1;
sl@0: 
sl@0:    BOOST_CHECK(e1.type() == typeid(Add));
sl@0:    BOOST_CHECK(e1_str.str() == "(13+((40+2)-(10+4)))");
sl@0: 
sl@0:    //Evaluate expression
sl@0:    int res = boost::apply_visitor(Calculator(), e1);
sl@0:    BOOST_CHECK(res == n + 28);
sl@0: 
sl@0: #ifdef __SYMBIAN32__
sl@0:    	testResultXml("test3");
sl@0: 	close_log_file();
sl@0: #endif
sl@0:    return 0;
sl@0: }
sl@0: