]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/yap/example/future_group.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/algorithm.hpp>
9 #include <boost/hana/concat.hpp>
12 // A custom expression template for future groups. It supports operators ||
14 template <boost::yap::expr_kind Kind
, typename Tuple
>
17 static boost::yap::expr_kind
const kind
= Kind
;
19 future_expr (Tuple
&& tuple
) :
20 elements (std::forward
<Tuple
&&>(tuple
))
25 // Returns the transformed/flattened expression.
29 BOOST_YAP_USER_BINARY_OPERATOR(logical_or
, future_expr
, future_expr
)
30 BOOST_YAP_USER_BINARY_OPERATOR(logical_and
, future_expr
, future_expr
)
32 // A special-cased future terminal that matches the semantics from the
33 // original Proto example.
36 future_expr
<boost::yap::expr_kind::terminal
, boost::hana::tuple
<T
>>
38 future (T
const & t
= T()) :
39 future_expr
<boost::yap::expr_kind::terminal
, boost::hana::tuple
<T
>> (boost::hana::tuple
<T
>{t
})
43 { return boost::yap::value(*this); }
47 using remove_cv_ref_t
= std::remove_cv_t
<std::remove_reference_t
<T
>>;
49 // A transform that flattens future expressions into a tuple.
50 struct future_transform
52 // Transform a terminal into its contained tuple.
56 boost::yap::expr_kind::terminal
,
64 // Transform left || right -> transform(left).
65 template <typename T
, typename U
>
68 boost::yap::expr_kind::logical_or
,
69 boost::hana::tuple
<T
, U
>
72 // Recursively transform the left side, and return the result.
73 // Without the recursion, we might return a terminal expression here
75 return boost::yap::transform(boost::yap::left(or_expr
), *this);
79 // Transform left && right -> concat(transform(left), transform(right)).
80 template <typename T
, typename U
>
83 boost::yap::expr_kind::logical_and
,
84 boost::hana::tuple
<T
, U
>
87 // Recursively transform each side, then combine the resulting tuples
88 // into a single tuple result.
89 return boost::hana::concat(
90 boost::yap::transform(boost::yap::left(and_expr
), *this),
91 boost::yap::transform(boost::yap::right(and_expr
), *this)
97 template <boost::yap::expr_kind Kind
, typename Tuple
>
98 auto future_expr
<Kind
, Tuple
>::get () const
99 { return boost::yap::transform(*this, future_transform
{}); }
107 // Called "vector" just so the code in main() will match the original Proto
109 template <typename
...T
>
110 using vector
= boost::hana::tuple
<T
...>;
117 future
<vector
<A
,B
> > ab
;
119 // Verify that various future groups have the
120 // correct return types.
122 vector
<A
, B
, C
> t1
= (a
&& b
&& c
).get();
123 vector
<A
, C
> t2
= ((a
|| a
) && c
).get();
124 vector
<A
, B
, C
> t3
= ((a
&& b
|| a
&& b
) && c
).get();
125 vector
<vector
<A
, B
>, C
> t4
= ((ab
|| ab
) && c
).get();