]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/phoenix/example/invert.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / phoenix / example / invert.cpp
1 /*==============================================================================
2 Copyright (c) 2005-2010 Joel de Guzman
3 Copyright (c) 2010 Thomas Heller
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 ==============================================================================*/
8
9 #include <boost/phoenix/phoenix.hpp>
10 #include <boost/proto/proto.hpp>
11 #include <boost/proto/debug.hpp>
12
13 namespace phoenix = boost::phoenix;
14 namespace proto = boost::proto;
15
16 struct invert_actions
17 {
18 template <typename Rule>
19 struct when
20 : proto::_
21 {};
22 };
23
24 using phoenix::evaluator;
25
26 #ifdef _MSC_VER
27 // redifining evaluator, this is because MSVC chokes on function types like:
28 // F(G(...))
29 #define evaluator(A0, A1) proto::call<phoenix::evaluator(A0, A1)>
30 #endif
31
32 template <>
33 struct invert_actions::when<phoenix::rule::plus>
34 : proto::call<
35 phoenix::functional::make_minus(
36 evaluator(proto::_left, phoenix::_context)
37 , evaluator(proto::_right, phoenix::_context)
38 )
39 >
40 {};
41
42 template <>
43 struct invert_actions::when<phoenix::rule::minus>
44 : proto::call<
45 phoenix::functional::make_plus(
46 evaluator(proto::_left, phoenix::_context)
47 , evaluator(proto::_right, phoenix::_context)
48 )
49 >
50 {};
51
52 template <>
53 struct invert_actions::when<phoenix::rule::multiplies>
54 : proto::call<
55 phoenix::functional::make_divides(
56 evaluator(proto::_left, phoenix::_context)
57 , evaluator(proto::_right, phoenix::_context)
58 )
59 >
60 {};
61
62 template <>
63 struct invert_actions::when<phoenix::rule::divides>
64 : proto::call<
65 phoenix::functional::make_multiplies(
66 evaluator(proto::_left, phoenix::_context)
67 , evaluator(proto::_right, phoenix::_context)
68 )
69 >
70 {};
71
72 #ifdef _MSC_VER
73 #undef evaluator
74 #endif
75
76 template <typename Expr>
77 void print_expr(Expr const & expr)
78 {
79 std::cout << "before inversion:\n";
80 proto::display_expr(expr);
81 std::cout << "after inversion:\n";
82 proto::display_expr(
83 phoenix::eval(
84 expr
85 , phoenix::context(
86 phoenix::nothing
87 , invert_actions()
88 )
89 )
90 );
91 std::cout << "\n";
92 }
93
94 template <typename Expr>
95 typename
96 boost::phoenix::result_of::eval<
97 Expr const&
98 , phoenix::result_of::make_context<
99 phoenix::result_of::make_env<>::type
100 , invert_actions
101 >::type
102 >::type
103 invert(Expr const & expr)
104 {
105 return
106 phoenix::eval(
107 expr
108 , phoenix::make_context(
109 phoenix::make_env()
110 , invert_actions()
111 )
112 );
113 }
114
115 int main()
116 {
117 using phoenix::placeholders::_1;
118 using phoenix::placeholders::_2;
119 using phoenix::placeholders::_3;
120 using phoenix::placeholders::_4;
121
122 print_expr(_1);
123 print_expr(_1 + _2);
124 print_expr(_1 + _2 - _3);
125 print_expr(_1 * _2);
126 print_expr(_1 * _2 / _3);
127 print_expr(_1 * _2 + _3);
128 print_expr(_1 * _2 - _3);
129 print_expr(if_(_1 * _4)[_2 - _3]);
130
131 print_expr(_1 * invert(_2 - _3));
132 }
133