]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/yap/example/mixed.cpp
1 // Copyright (C) 2016-2018 T. Zachary Laine
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
7 #include <boost/yap/yap.hpp>
15 // This wrapper makes the pattern matching in transforms below (like deref and
16 // incr) a lot easier to write.
17 template <typename Iter
>
23 template <typename Iter
>
24 auto make_iter_wrapper (Iter it
)
25 { return iter_wrapper
<Iter
>{it
}; }
28 // A container -> wrapped-begin transform.
31 template <typename Cont
>
32 auto operator() (boost::yap::expr_tag
<boost::yap::expr_kind::terminal
>,
34 -> decltype(boost::yap::make_terminal(make_iter_wrapper(cont
.begin())))
35 { return boost::yap::make_terminal(make_iter_wrapper(cont
.begin())); }
38 // A wrapped-iterator -> dereferenced value transform.
41 template <typename Iter
>
42 auto operator() (boost::yap::expr_tag
<boost::yap::expr_kind::terminal
>,
43 iter_wrapper
<Iter
> wrapper
)
44 -> decltype(boost::yap::make_terminal(*wrapper
.it
))
45 { return boost::yap::make_terminal(*wrapper
.it
); }
48 // A wrapped-iterator increment transform, using side effects.
51 template <typename Iter
>
52 auto operator() (boost::yap::expr_tag
<boost::yap::expr_kind::terminal
>,
53 iter_wrapper
<Iter
> & wrapper
)
54 -> decltype(boost::yap::make_terminal(wrapper
.it
))
57 // Since this transform is valuable for its side effects, and thus the
58 // result of the transform is ignored, we could return anything here.
59 return boost::yap::make_terminal(wrapper
.it
);
64 // The implementation of elementwise evaluation of expressions of sequences;
65 // all the later operations use this one.
67 template <class, class> class Cont
,
73 Cont
<T
, A
> & op_assign (Cont
<T
, A
> & cont
, Expr
const & e
, Op
&& op
)
75 decltype(auto) expr
= boost::yap::as_expr(e
);
76 // Transform the expression of sequences into an expression of
78 auto expr2
= boost::yap::transform(boost::yap::as_expr(expr
), begin
{});
79 for (auto && x
: cont
) {
80 // Transform the expression of iterators into an expression of
81 // pointed-to-values, evaluate the resulting expression, and call op()
82 // with the result of the evaluation.
83 op(x
, boost::yap::evaluate(boost::yap::transform(expr2
, deref
{})));
84 // Transform the expression of iterators into an ignored value; as a
85 // side effect, increment the iterators in the expression.
86 boost::yap::transform(expr2
, incr
{});
92 template <class, class> class Cont
,
97 Cont
<T
, A
> & assign (Cont
<T
, A
> & cont
, Expr
const & expr
)
99 return op_assign(cont
, expr
, [](auto & cont_value
, auto && expr_value
) {
100 cont_value
= std::forward
<decltype(expr_value
)>(expr_value
);
105 template <class, class> class Cont
,
110 Cont
<T
, A
> & operator+= (Cont
<T
, A
> & cont
, Expr
const & expr
)
112 return op_assign(cont
, expr
, [](auto & cont_value
, auto && expr_value
) {
113 cont_value
+= std::forward
<decltype(expr_value
)>(expr_value
);
118 template <class, class> class Cont
,
123 Cont
<T
, A
> & operator-= (Cont
<T
, A
> & cont
, Expr
const & expr
)
125 return op_assign(cont
, expr
, [](auto & cont_value
, auto && expr_value
) {
126 cont_value
-= std::forward
<decltype(expr_value
)>(expr_value
);
130 // A type trait that identifies std::vectors and std::lists.
131 template <typename T
>
132 struct is_mixed
: std::false_type
{};
134 template <typename T
, typename A
>
135 struct is_mixed
<std::vector
<T
, A
>> : std::true_type
{};
137 template <typename T
, typename A
>
138 struct is_mixed
<std::list
<T
, A
>> : std::true_type
{};
140 // Define expression-producing operators over std::vectors and std::lists.
141 BOOST_YAP_USER_UDT_UNARY_OPERATOR(negate
, boost::yap::expression
, is_mixed
); // -
142 BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(multiplies
, boost::yap::expression
, is_mixed
); // *
143 BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(divides
, boost::yap::expression
, is_mixed
); // /
144 BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(modulus
, boost::yap::expression
, is_mixed
); // %
145 BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(plus
, boost::yap::expression
, is_mixed
); // +
146 BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(minus
, boost::yap::expression
, is_mixed
); // -
147 BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(less
, boost::yap::expression
, is_mixed
); // <
148 BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(greater
, boost::yap::expression
, is_mixed
); // >
149 BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(less_equal
, boost::yap::expression
, is_mixed
); // <=
150 BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(greater_equal
, boost::yap::expression
, is_mixed
); // >=
151 BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(equal_to
, boost::yap::expression
, is_mixed
); // ==
152 BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(not_equal_to
, boost::yap::expression
, is_mixed
); // !=
153 BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(logical_or
, boost::yap::expression
, is_mixed
); // ||
154 BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(logical_and
, boost::yap::expression
, is_mixed
); // &&
155 BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(bitwise_and
, boost::yap::expression
, is_mixed
); // &
156 BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(bitwise_or
, boost::yap::expression
, is_mixed
); // |
157 BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(bitwise_xor
, boost::yap::expression
, is_mixed
); // ^
159 // Define a type that can resolve to any overload of std::sin().
172 std::vector
<int> a
,b
,c
,d
;
174 std::list
<std::complex<double>> f
;
177 for(i
= 0;i
< n
; ++i
)
184 f
.push_back(std::complex<double>(1.0, 1.0));
188 assign(d
, a
+ b
* c
);
189 a
+= if_else(d
< 30, b
, c
);
192 e
+= e
- 4 / (c
+ 1);
194 auto sin
= boost::yap::make_terminal(sin_t
{});
195 f
-= sin(0.1 * e
* std::complex<double>(0.2, 1.2));
197 std::list
<double>::const_iterator ei
= e
.begin();
198 std::list
<std::complex<double>>::const_iterator fi
= f
.begin();
199 for (i
= 0; i
< n
; ++i
)
202 << "a(" << i
<< ") = " << a
[i
]
203 << " b(" << i
<< ") = " << b
[i
]
204 << " c(" << i
<< ") = " << c
[i
]
205 << " d(" << i
<< ") = " << d
[i
]
206 << " e(" << i
<< ") = " << *ei
++
207 << " f(" << i
<< ") = " << *fi
++