]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/example/tutorial/introspection.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / hana / example / tutorial / introspection.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)
4
5 #include <boost/hana.hpp>
6
7 #include <string>
8 #include <type_traits>
9 #include <utility>
10 namespace hana = boost::hana;
11
12
13 struct yes { std::string toString() const { return "yes"; } };
14 struct no { };
15
16 namespace has_toString_then {
17 //! [has_toString.then]
18 template <typename T, typename = void>
19 struct has_toString
20 : std::false_type
21 { };
22
23 template <typename T>
24 struct has_toString<T, decltype((void)std::declval<T>().toString())>
25 : std::true_type
26 { };
27 //! [has_toString.then]
28
29 static_assert(has_toString<yes>::value, "");
30 static_assert(!has_toString<no>::value, "");
31 }
32
33 //! [has_toString.now]
34 auto has_toString = hana::is_valid([](auto&& obj) -> decltype(obj.toString()) { });
35 //! [has_toString.now]
36
37 BOOST_HANA_CONSTANT_CHECK(has_toString(yes{}));
38 BOOST_HANA_CONSTANT_CHECK(hana::not_(has_toString(no{})));
39
40 namespace optionalToString_then {
41 //! [optionalToString.then]
42 template <typename T>
43 auto optionalToString(T const& obj)
44 -> std::enable_if_t<decltype(has_toString(obj))::value, std::string>
45 { return obj.toString(); }
46
47 template <typename T>
48 auto optionalToString(T const& obj)
49 -> std::enable_if_t<decltype(!has_toString(obj))::value, std::string>
50 { return "toString not defined"; }
51 //! [optionalToString.then]
52
53 // make sure they compile
54 template std::string optionalToString(yes const&);
55 template std::string optionalToString(no const&);
56 }
57
58 //! [optionalToString]
59 template <typename T>
60 std::string optionalToString(T const& obj) {
61 return hana::if_(has_toString(obj),
62 [](auto& x) { return x.toString(); },
63 [](auto& x) { return "toString not defined"; }
64 )(obj);
65 }
66 //! [optionalToString]
67
68
69 int main() {
70 BOOST_HANA_RUNTIME_CHECK(optionalToString(yes{}) == "yes");
71 BOOST_HANA_RUNTIME_CHECK(optionalToString(no{}) == "toString not defined");
72
73
74 {
75
76 //! [non_static_member_from_object]
77 auto has_member = hana::is_valid([](auto&& x) -> decltype((void)x.member) { });
78
79 struct Foo { int member[4]; };
80 struct Bar { };
81 BOOST_HANA_CONSTANT_CHECK(has_member(Foo{}));
82 BOOST_HANA_CONSTANT_CHECK(!has_member(Bar{}));
83 //! [non_static_member_from_object]
84
85 }{
86
87 //! [non_static_member_from_type]
88 auto has_member = hana::is_valid([](auto t) -> decltype(
89 (void)hana::traits::declval(t).member
90 ) { });
91
92 struct Foo { int member[4]; };
93 struct Bar { };
94 BOOST_HANA_CONSTANT_CHECK(has_member(hana::type_c<Foo>));
95 BOOST_HANA_CONSTANT_CHECK(!has_member(hana::type_c<Bar>));
96 //! [non_static_member_from_type]
97
98 }{
99
100 //! [nested_type_name]
101 auto has_member = hana::is_valid([](auto t) -> hana::type<
102 typename decltype(t)::type::member
103 //^^^^^^^^ needed because of the dependent context
104 > { });
105
106 struct Foo { struct member; /* not defined! */ };
107 struct Bar { };
108 BOOST_HANA_CONSTANT_CHECK(has_member(hana::type_c<Foo>));
109 BOOST_HANA_CONSTANT_CHECK(!has_member(hana::type_c<Bar>));
110 //! [nested_type_name]
111
112 }
113
114 }
115
116 namespace static_member {
117 //! [static_member]
118 auto has_member = hana::is_valid([](auto t) -> decltype(
119 (void)decltype(t)::type::member
120 ) { });
121
122 struct Foo { static int member[4]; };
123 struct Bar { };
124 BOOST_HANA_CONSTANT_CHECK(has_member(hana::type_c<Foo>));
125 BOOST_HANA_CONSTANT_CHECK(!has_member(hana::type_c<Bar>));
126 //! [static_member]
127 }
128
129 namespace nested_template {
130 //! [nested_template]
131 auto has_member = hana::is_valid([](auto t) -> decltype(hana::template_<
132 decltype(t)::type::template member
133 // ^^^^^^^^ needed because of the dependent context
134 >) { });
135
136 struct Foo { template <typename ...> struct member; };
137 struct Bar { };
138 BOOST_HANA_CONSTANT_CHECK(has_member(hana::type_c<Foo>));
139 BOOST_HANA_CONSTANT_CHECK(!has_member(hana::type_c<Bar>));
140 //! [nested_template]
141 }