]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/hana/example/tutorial/introspection.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / hana / example / tutorial / introspection.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#include <boost/hana.hpp>
6
7#include <string>
8#include <type_traits>
9#include <utility>
10namespace hana = boost::hana;
11
12
13struct yes { std::string toString() const { return "yes"; } };
14struct no { };
15
16namespace has_toString_then {
17//! [has_toString.then]
18template <typename T, typename = void>
19struct has_toString
20 : std::false_type
21{ };
22
23template <typename T>
24struct has_toString<T, decltype((void)std::declval<T>().toString())>
25 : std::true_type
26{ };
27//! [has_toString.then]
28
29static_assert(has_toString<yes>::value, "");
30static_assert(!has_toString<no>::value, "");
31}
32
33//! [has_toString.now]
34auto has_toString = hana::is_valid([](auto&& obj) -> decltype(obj.toString()) { });
35//! [has_toString.now]
36
37BOOST_HANA_CONSTANT_CHECK(has_toString(yes{}));
38BOOST_HANA_CONSTANT_CHECK(hana::not_(has_toString(no{})));
39
40namespace optionalToString_then {
41//! [optionalToString.then]
42template <typename T>
43auto optionalToString(T const& obj)
44 -> std::enable_if_t<decltype(has_toString(obj))::value, std::string>
45{ return obj.toString(); }
46
47template <typename T>
48auto 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
54template std::string optionalToString(yes const&);
55template std::string optionalToString(no const&);
56}
57
58//! [optionalToString]
59template <typename T>
60std::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
69int main() {
70BOOST_HANA_RUNTIME_CHECK(optionalToString(yes{}) == "yes");
71BOOST_HANA_RUNTIME_CHECK(optionalToString(no{}) == "toString not defined");
72
73
74{
75
76//! [non_static_member_from_object]
77auto has_member = hana::is_valid([](auto&& x) -> decltype((void)x.member) { });
78
79struct Foo { int member[4]; };
80struct Bar { };
81BOOST_HANA_CONSTANT_CHECK(has_member(Foo{}));
82BOOST_HANA_CONSTANT_CHECK(!has_member(Bar{}));
83//! [non_static_member_from_object]
84
85}{
86
87//! [non_static_member_from_type]
88auto has_member = hana::is_valid([](auto t) -> decltype(
89 (void)hana::traits::declval(t).member
90) { });
91
92struct Foo { int member[4]; };
93struct Bar { };
94BOOST_HANA_CONSTANT_CHECK(has_member(hana::type_c<Foo>));
95BOOST_HANA_CONSTANT_CHECK(!has_member(hana::type_c<Bar>));
96//! [non_static_member_from_type]
97
98}{
99
100//! [nested_type_name]
101auto has_member = hana::is_valid([](auto t) -> hana::type<
102 typename decltype(t)::type::member
103//^^^^^^^^ needed because of the dependent context
104> { });
105
106struct Foo { struct member; /* not defined! */ };
107struct Bar { };
108BOOST_HANA_CONSTANT_CHECK(has_member(hana::type_c<Foo>));
109BOOST_HANA_CONSTANT_CHECK(!has_member(hana::type_c<Bar>));
110//! [nested_type_name]
111
112}
113
114}
115
116namespace static_member {
117//! [static_member]
118auto has_member = hana::is_valid([](auto t) -> decltype(
119 (void)decltype(t)::type::member
120) { });
121
122struct Foo { static int member[4]; };
123struct Bar { };
124BOOST_HANA_CONSTANT_CHECK(has_member(hana::type_c<Foo>));
125BOOST_HANA_CONSTANT_CHECK(!has_member(hana::type_c<Bar>));
126//! [static_member]
127}
128
129namespace nested_template {
130//! [nested_template]
131auto 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
136struct Foo { template <typename ...> struct member; };
137struct Bar { };
138BOOST_HANA_CONSTANT_CHECK(has_member(hana::type_c<Foo>));
139BOOST_HANA_CONSTANT_CHECK(!has_member(hana::type_c<Bar>));
140//! [nested_template]
141}
92f5a8d4
TL
142
143namespace template_specialization {
144//! [template_specialization]
145template <typename T, typename U>
146struct Foo;
147
148template <typename T>
149struct Bar;
150
151auto is_binary_template = hana::is_valid([](auto trait) -> decltype(
152 trait(hana::type_c<void>, hana::type_c<void>)
153) { });
154
155BOOST_HANA_CONSTANT_CHECK(is_binary_template(hana::template_<Foo>));
156BOOST_HANA_CONSTANT_CHECK(!is_binary_template(hana::template_<Bar>));
157//! [template_specialization]
158}