calc1.cpp 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. //[ Calc1
  2. // Copyright 2008 Eric Niebler. Distributed under the Boost
  3. // Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. //
  6. // This is a simple example of how to build an arithmetic expression
  7. // evaluator with placeholders.
  8. #include <iostream>
  9. #include <boost/proto/core.hpp>
  10. #include <boost/proto/context.hpp>
  11. namespace proto = boost::proto;
  12. using proto::_;
  13. template<int I> struct placeholder {};
  14. // Define some placeholders
  15. proto::terminal< placeholder< 1 > >::type const _1 = {{}};
  16. proto::terminal< placeholder< 2 > >::type const _2 = {{}};
  17. // Define a calculator context, for evaluating arithmetic expressions
  18. struct calculator_context
  19. : proto::callable_context< calculator_context const >
  20. {
  21. // The values bound to the placeholders
  22. double d[2];
  23. // The result of evaluating arithmetic expressions
  24. typedef double result_type;
  25. explicit calculator_context(double d1 = 0., double d2 = 0.)
  26. {
  27. d[0] = d1;
  28. d[1] = d2;
  29. }
  30. // Handle the evaluation of the placeholder terminals
  31. template<int I>
  32. double operator ()(proto::tag::terminal, placeholder<I>) const
  33. {
  34. return d[ I - 1 ];
  35. }
  36. };
  37. template<typename Expr>
  38. double evaluate( Expr const &expr, double d1 = 0., double d2 = 0. )
  39. {
  40. // Create a calculator context with d1 and d2 substituted for _1 and _2
  41. calculator_context const ctx(d1, d2);
  42. // Evaluate the calculator expression with the calculator_context
  43. return proto::eval(expr, ctx);
  44. }
  45. int main()
  46. {
  47. // Displays "5"
  48. std::cout << evaluate( _1 + 2.0, 3.0 ) << std::endl;
  49. // Displays "6"
  50. std::cout << evaluate( _1 * _2, 3.0, 2.0 ) << std::endl;
  51. // Displays "0.5"
  52. std::cout << evaluate( (_1 - _2) / _2, 3.0, 2.0 ) << std::endl;
  53. return 0;
  54. }
  55. //]