]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/proto/example/calc2.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / proto / example / calc2.cpp
1 //[ Calc2
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 example enhances the simple arithmetic expression evaluator
7 // in calc1.cpp by using proto::extends to make arithmetic
8 // expressions immediately evaluable with operator (), a-la a
9 // function object
10
11 #include <iostream>
12 #include <boost/proto/core.hpp>
13 #include <boost/proto/context.hpp>
14 namespace proto = boost::proto;
15 using proto::_;
16
17 template<typename Expr>
18 struct calculator_expression;
19
20 // Tell proto how to generate expressions in the calculator_domain
21 struct calculator_domain
22 : proto::domain<proto::generator<calculator_expression> >
23 {};
24
25 // Will be used to define the placeholders _1 and _2
26 template<int I> struct placeholder {};
27
28 // Define a calculator context, for evaluating arithmetic expressions
29 // (This is as before, in calc1.cpp)
30 struct calculator_context
31 : proto::callable_context< calculator_context const >
32 {
33 // The values bound to the placeholders
34 double d[2];
35
36 // The result of evaluating arithmetic expressions
37 typedef double result_type;
38
39 explicit calculator_context(double d1 = 0., double d2 = 0.)
40 {
41 d[0] = d1;
42 d[1] = d2;
43 }
44
45 // Handle the evaluation of the placeholder terminals
46 template<int I>
47 double operator ()(proto::tag::terminal, placeholder<I>) const
48 {
49 return d[ I - 1 ];
50 }
51 };
52
53 // Wrap all calculator expressions in this type, which defines
54 // operator () to evaluate the expression.
55 template<typename Expr>
56 struct calculator_expression
57 : proto::extends<Expr, calculator_expression<Expr>, calculator_domain>
58 {
59 explicit calculator_expression(Expr const &expr = Expr())
60 : calculator_expression::proto_extends(expr)
61 {}
62
63 BOOST_PROTO_EXTENDS_USING_ASSIGN(calculator_expression<Expr>)
64
65 // Override operator () to evaluate the expression
66 double operator ()() const
67 {
68 calculator_context const ctx;
69 return proto::eval(*this, ctx);
70 }
71
72 double operator ()(double d1) const
73 {
74 calculator_context const ctx(d1);
75 return proto::eval(*this, ctx);
76 }
77
78 double operator ()(double d1, double d2) const
79 {
80 calculator_context const ctx(d1, d2);
81 return proto::eval(*this, ctx);
82 }
83 };
84
85 // Define some placeholders (notice they're wrapped in calculator_expression<>)
86 calculator_expression<proto::terminal< placeholder< 1 > >::type> const _1;
87 calculator_expression<proto::terminal< placeholder< 2 > >::type> const _2;
88
89 // Now, our arithmetic expressions are immediately executable function objects:
90 int main()
91 {
92 // Displays "5"
93 std::cout << (_1 + 2.0)( 3.0 ) << std::endl;
94
95 // Displays "6"
96 std::cout << ( _1 * _2 )( 3.0, 2.0 ) << std::endl;
97
98 // Displays "0.5"
99 std::cout << ( (_1 - _2) / _2 )( 3.0, 2.0 ) << std::endl;
100
101 return 0;
102 }
103 //]