]>
git.proxmox.com Git - ceph.git/blob - 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)
5 #include <boost/hana.hpp>
10 namespace hana
= boost::hana
;
13 struct yes
{ std::string
toString() const { return "yes"; } };
16 namespace has_toString_then
{
17 //! [has_toString.then]
18 template <typename T
, typename
= void>
24 struct has_toString
<T
, decltype((void)std::declval
<T
>().toString())>
27 //! [has_toString.then]
29 static_assert(has_toString
<yes
>::value
, "");
30 static_assert(!has_toString
<no
>::value
, "");
33 //! [has_toString.now]
34 auto has_toString
= hana::is_valid([](auto&& obj
) -> decltype(obj
.toString()) { });
35 //! [has_toString.now]
37 BOOST_HANA_CONSTANT_CHECK(has_toString(yes
{}));
38 BOOST_HANA_CONSTANT_CHECK(hana::not_(has_toString(no
{})));
40 namespace optionalToString_then
{
41 //! [optionalToString.then]
43 auto optionalToString(T
const& obj
)
44 -> std::enable_if_t
<decltype(has_toString(obj
))::value
, std::string
>
45 { return obj
.toString(); }
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]
53 // make sure they compile
54 template std::string
optionalToString(yes
const&);
55 template std::string
optionalToString(no
const&);
58 //! [optionalToString]
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"; }
66 //! [optionalToString]
70 BOOST_HANA_RUNTIME_CHECK(optionalToString(yes
{}) == "yes");
71 BOOST_HANA_RUNTIME_CHECK(optionalToString(no
{}) == "toString not defined");
76 //! [non_static_member_from_object]
77 auto has_member
= hana::is_valid([](auto&& x
) -> decltype((void)x
.member
) { });
79 struct Foo
{ int member
[4]; };
81 BOOST_HANA_CONSTANT_CHECK(has_member(Foo
{}));
82 BOOST_HANA_CONSTANT_CHECK(!has_member(Bar
{}));
83 //! [non_static_member_from_object]
87 //! [non_static_member_from_type]
88 auto has_member
= hana::is_valid([](auto t
) -> decltype(
89 (void)hana::traits::declval(t
).member
92 struct Foo
{ int member
[4]; };
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]
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
106 struct Foo
{ struct member
; /* not defined! */ };
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]
116 namespace static_member
{
118 auto has_member
= hana::is_valid([](auto t
) -> decltype(
119 (void)decltype(t
)::type::member
122 struct Foo
{ static int member
[4]; };
124 BOOST_HANA_CONSTANT_CHECK(has_member(hana::type_c
<Foo
>));
125 BOOST_HANA_CONSTANT_CHECK(!has_member(hana::type_c
<Bar
>));
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
136 struct Foo
{ template <typename
...> struct member
; };
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]