]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/example/tutorial/quickstart.switchAny.cpp
1 // Copyright Louis Dionne 2013-2017
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
5 // Make sure `assert` always triggers an assertion
11 #include <boost/hana.hpp>
13 #include <boost/any.hpp>
19 namespace hana
= boost::hana
;
23 auto case_
= [](auto f
) {
24 return hana::make_pair(hana::type_c
<T
>, f
);
28 auto default_
= case_
<default_t
>;
32 template <typename Any
, typename Default
>
33 auto process(Any
&, std::type_index
const&, Default
& default_
) {
37 template <typename Any
, typename Default
, typename Case
, typename
...Rest
>
38 auto process(Any
& a
, std::type_index
const& t
, Default
& default_
,
39 Case
& case_
, Rest
& ...rest
)
41 using T
= typename
decltype(+hana::first(case_
))::type
;
42 return t
== typeid(T
) ? hana::second(case_
)(*boost::unsafe_any_cast
<T
>(&a
))
43 : process(a
, t
, default_
, rest
...);
48 template <typename Any
>
49 auto switch_(Any
& a
) {
50 return [&a
](auto ...cases_
) {
51 auto cases
= hana::make_tuple(cases_
...);
53 auto default_
= hana::find_if(cases
, [](auto const& c
) {
54 return hana::first(c
) == hana::type_c
<default_t
>;
56 static_assert(default_
!= hana::nothing
,
57 "switch is missing a default_ case");
59 auto rest
= hana::filter(cases
, [](auto const& c
) {
60 return hana::first(c
) != hana::type_c
<default_t
>;
63 return hana::unpack(rest
, [&](auto& ...rest
) {
64 return process(a
, a
.type(), hana::second(*default_
), rest
...);
73 using namespace std::literals
;
79 std::string r
= switch_(a
)(
80 case_
<int>([](auto i
) { return "int: "s
+ std::to_string(i
); }),
81 case_
<char>([](auto c
) { return "char: "s
+ std::string
{c
}; }),
82 default_([] { return "unknown"s
; })
85 assert(r
== "char: x"s
);
90 //! [result_inference]
93 case_
<int>([](auto) -> int { return 1; }),
94 case_
<char>([](auto) -> long { return 2l; }),
95 default_([]() -> long long { return 3ll; })
98 // r is inferred to be a long long
99 static_assert(std::is_same
<decltype(r
), long long>{}, "");
101 //! [result_inference]