]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/hana/example/tutorial/quickstart.switchAny.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / hana / example / tutorial / quickstart.switchAny.cpp
CommitLineData
b32b8144 1// Copyright Louis Dionne 2013-2017
7c673cae
FG
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)
4
5// Make sure `assert` always triggers an assertion
6#ifdef NDEBUG
7# undef NDEBUG
8#endif
9
10//! [full]
11#include <boost/hana.hpp>
12
13#include <boost/any.hpp>
14#include <cassert>
15#include <string>
16#include <typeindex>
17#include <typeinfo>
18#include <utility>
19namespace hana = boost::hana;
20
21//! [cases]
22template <typename T>
23auto case_ = [](auto f) {
24 return hana::make_pair(hana::type_c<T>, f);
25};
26
27struct default_t;
28auto default_ = case_<default_t>;
29//! [cases]
30
31//! [process]
32template <typename Any, typename Default>
33auto process(Any&, std::type_index const&, Default& default_) {
34 return default_();
35}
36
37template <typename Any, typename Default, typename Case, typename ...Rest>
38auto process(Any& a, std::type_index const& t, Default& default_,
39 Case& case_, Rest& ...rest)
40{
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...);
44}
45//! [process]
46
47//! [switch_]
48template <typename Any>
49auto switch_(Any& a) {
50 return [&a](auto ...cases_) {
51 auto cases = hana::make_tuple(cases_...);
52
53 auto default_ = hana::find_if(cases, [](auto const& c) {
54 return hana::first(c) == hana::type_c<default_t>;
55 });
56 static_assert(default_ != hana::nothing,
57 "switch is missing a default_ case");
58
59 auto rest = hana::filter(cases, [](auto const& c) {
60 return hana::first(c) != hana::type_c<default_t>;
61 });
62
63 return hana::unpack(rest, [&](auto& ...rest) {
64 return process(a, a.type(), hana::second(*default_), rest...);
65 });
66 };
67}
68//! [switch_]
69//! [full]
70
71
72int main() {
73using namespace std::literals;
74
75{
76
77//! [usage]
78boost::any a = 'x';
79std::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; })
83);
84
85assert(r == "char: x"s);
86//! [usage]
87
88}{
89
90//! [result_inference]
91boost::any a = 'x';
92auto r = switch_(a)(
93 case_<int>([](auto) -> int { return 1; }),
94 case_<char>([](auto) -> long { return 2l; }),
95 default_([]() -> long long { return 3ll; })
96);
97
98// r is inferred to be a long long
99static_assert(std::is_same<decltype(r), long long>{}, "");
100assert(r == 2ll);
101//! [result_inference]
102
103}
104
105}