]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/example/tutorial/type.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / hana / example / tutorial / type.cpp
1 // Copyright Louis Dionne 2013-2016
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 #include <boost/hana/ext/std/integral_constant.hpp>
7
8 #include <boost/mpl/copy_if.hpp>
9 #include <boost/mpl/equal.hpp>
10 #include <boost/mpl/less.hpp>
11 #include <boost/mpl/min_element.hpp>
12 #include <boost/mpl/or.hpp>
13 #include <boost/mpl/placeholders.hpp>
14 #include <boost/mpl/sizeof.hpp>
15 #include <boost/mpl/vector.hpp>
16
17 #include <boost/fusion/include/at_key.hpp>
18 #include <boost/fusion/include/equal_to.hpp>
19 #include <boost/fusion/include/filter_if.hpp>
20 #include <boost/fusion/include/make_map.hpp>
21 #include <boost/fusion/include/make_vector.hpp>
22
23 #include <string>
24 #include <type_traits>
25 #include <vector>
26 namespace fusion = boost::fusion;
27 namespace mpl = boost::mpl;
28 namespace hana = boost::hana;
29 using namespace hana::literals;
30
31
32 template <int n>
33 struct storage { char weight[n]; };
34
35 int main() {
36
37 {
38
39 //! [tuple]
40 auto types = hana::make_tuple(hana::type_c<int*>, hana::type_c<char&>, hana::type_c<void>);
41 auto char_ref = types[1_c];
42
43 BOOST_HANA_CONSTANT_CHECK(char_ref == hana::type_c<char&>);
44 //! [tuple]
45
46 }{
47
48 //! [filter.MPL]
49 using types = mpl::vector<int, char&, void*>;
50 using ts = mpl::copy_if<types, mpl::or_<std::is_pointer<mpl::_1>,
51 std::is_reference<mpl::_1>>>::type;
52 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
53 // placeholder expression
54
55 static_assert(mpl::equal<ts, mpl::vector<char&, void*>>::value, "");
56 //! [filter.MPL]
57
58 }{
59
60 using hana::traits::is_pointer; // the traits namespace was not introduced
61 using hana::traits::is_reference; // yet, so we use unqualified names for now
62
63 //! [filter.Hana]
64 auto types = hana::tuple_t<int*, char&, void>;
65
66 auto ts = hana::filter(types, [](auto t) {
67 return is_pointer(t) || is_reference(t);
68 });
69
70 BOOST_HANA_CONSTANT_CHECK(ts == hana::tuple_t<int*, char&>);
71 //! [filter.Hana]
72
73 }{
74
75 //! [single_library.then]
76 // types (MPL)
77 using types = mpl::vector<int*, char&, void>;
78 using ts = mpl::copy_if<types, mpl::or_<std::is_pointer<mpl::_1>,
79 std::is_reference<mpl::_1>>>::type;
80
81 // values (Fusion)
82 auto values = fusion::make_vector(1, 'c', nullptr, 3.5);
83 auto vs = fusion::filter_if<std::is_integral<mpl::_1>>(values);
84 //! [single_library.then]
85
86 static_assert(mpl::equal<ts, mpl::vector<int*, char&>>::value, "");
87 BOOST_HANA_RUNTIME_CHECK(vs == fusion::make_vector(1, 'c'));
88
89 }{
90
91 using hana::traits::is_pointer;
92 using hana::traits::is_reference;
93 using hana::traits::is_integral;
94
95 //! [single_library.Hana]
96 // types
97 auto types = hana::tuple_t<int*, char&, void>;
98 auto ts = hana::filter(types, [](auto t) {
99 return is_pointer(t) || is_reference(t);
100 });
101
102 // values
103 auto values = hana::make_tuple(1, 'c', nullptr, 3.5);
104 auto vs = hana::filter(values, [](auto const& t) {
105 return is_integral(hana::typeid_(t));
106 });
107 //! [single_library.Hana]
108
109 BOOST_HANA_CONSTANT_CHECK(ts == hana::tuple_t<int*, char&>);
110 BOOST_HANA_RUNTIME_CHECK(vs == hana::make_tuple(1, 'c'));
111
112 }{
113
114 //! [make_map.Fusion]
115 auto map = fusion::make_map<char, int, long, float, double, void>(
116 "char", "int", "long", "float", "double", "void"
117 );
118
119 std::string Int = fusion::at_key<int>(map);
120 BOOST_HANA_RUNTIME_CHECK(Int == "int");
121 //! [make_map.Fusion]
122
123 }{
124
125 //! [make_map.Hana]
126 auto map = hana::make_map(
127 hana::make_pair(hana::type_c<char>, "char"),
128 hana::make_pair(hana::type_c<int>, "int"),
129 hana::make_pair(hana::type_c<long>, "long"),
130 hana::make_pair(hana::type_c<float>, "float"),
131 hana::make_pair(hana::type_c<double>, "double")
132 );
133
134 std::string Int = map[hana::type_c<int>];
135 BOOST_HANA_RUNTIME_CHECK(Int == "int");
136 //! [make_map.Hana]
137
138 }{
139
140 using hana::traits::add_pointer;
141
142 //! [skip_first_step]
143 auto types = hana::tuple_t<int*, char&, void>; // first step skipped
144
145 auto pointers = hana::transform(types, [](auto t) {
146 return add_pointer(t);
147 });
148 //! [skip_first_step]
149
150 BOOST_HANA_CONSTANT_CHECK(pointers == hana::tuple_t<int**, char*, void*>);
151
152 }{
153
154 //! [traits]
155 BOOST_HANA_CONSTANT_CHECK(hana::traits::add_pointer(hana::type_c<int>) == hana::type_c<int*>);
156 BOOST_HANA_CONSTANT_CHECK(hana::traits::common_type(hana::type_c<int>, hana::type_c<long>) == hana::type_c<long>);
157 BOOST_HANA_CONSTANT_CHECK(hana::traits::is_integral(hana::type_c<int>));
158
159 auto types = hana::tuple_t<int, char, long>;
160 BOOST_HANA_CONSTANT_CHECK(hana::all_of(types, hana::traits::is_integral));
161 //! [traits]
162
163 }{
164
165 //! [extent]
166 auto extent = [](auto t, auto n) {
167 return std::extent<typename decltype(t)::type, hana::value(n)>{};
168 };
169
170 BOOST_HANA_CONSTANT_CHECK(extent(hana::type_c<char>, hana::int_c<1>) == hana::size_c<0>);
171 BOOST_HANA_CONSTANT_CHECK(extent(hana::type_c<char[1][2]>, hana::int_c<1>) == hana::size_c<2>);
172 //! [extent]
173
174 }
175
176 }
177
178 namespace mpl_based {
179 //! [smallest.MPL]
180 template <typename ...T>
181 struct smallest
182 : mpl::deref<
183 typename mpl::min_element<
184 mpl::vector<T...>,
185 mpl::less<mpl::sizeof_<mpl::_1>, mpl::sizeof_<mpl::_2>>
186 >::type
187 >
188 { };
189
190 template <typename ...T>
191 using smallest_t = typename smallest<T...>::type;
192
193 static_assert(std::is_same<
194 smallest_t<char, long, long double>,
195 char
196 >::value, "");
197 //! [smallest.MPL]
198
199 static_assert(std::is_same<
200 smallest_t<storage<3>, storage<1>, storage<2>>,
201 storage<1>
202 >::value, "");
203 } // end namespace mpl_based
204
205 namespace hana_based {
206 //! [smallest.Hana]
207 template <typename ...T>
208 auto smallest = hana::minimum(hana::make_tuple(hana::type_c<T>...), [](auto t, auto u) {
209 return hana::sizeof_(t) < hana::sizeof_(u);
210 });
211
212 template <typename ...T>
213 using smallest_t = typename decltype(smallest<T...>)::type;
214
215 static_assert(std::is_same<
216 smallest_t<char, long, long double>, char
217 >::value, "");
218 //! [smallest.Hana]
219
220 static_assert(std::is_same<
221 smallest_t<storage<3>, storage<1>, storage<2>>,
222 storage<1>
223 >::value, "");
224 } // end namespace hana_based
225
226
227 namespace metafunction1 {
228 //! [metafunction1]
229 template <template <typename> class F, typename T>
230 constexpr auto metafunction(hana::basic_type<T> const&)
231 { return hana::type_c<typename F<T>::type>; }
232
233 auto t = hana::type_c<int>;
234 BOOST_HANA_CONSTANT_CHECK(metafunction<std::add_pointer>(t) == hana::type_c<int*>);
235 //! [metafunction1]
236 }
237
238 namespace metafunction2 {
239 //! [metafunction2]
240 template <template <typename ...> class F, typename ...T>
241 constexpr auto metafunction(hana::basic_type<T> const& ...)
242 { return hana::type_c<typename F<T...>::type>; }
243
244 BOOST_HANA_CONSTANT_CHECK(
245 metafunction<std::common_type>(hana::type_c<int>, hana::type_c<long>) == hana::type_c<long>
246 );
247 //! [metafunction2]
248 }
249
250 namespace _template {
251 //! [template_]
252 template <template <typename ...> class F, typename ...T>
253 constexpr auto template_(hana::basic_type<T> const& ...)
254 { return hana::type_c<F<T...>>; }
255
256 BOOST_HANA_CONSTANT_CHECK(
257 template_<std::vector>(hana::type_c<int>) == hana::type_c<std::vector<int>>
258 );
259 //! [template_]
260 }