]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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/assert.hpp> | |
6 | #include <boost/hana/chain.hpp> | |
7 | #include <boost/hana/equal.hpp> | |
8 | #include <boost/hana/for_each.hpp> | |
9 | #include <boost/hana/traits.hpp> | |
10 | #include <boost/hana/tuple.hpp> | |
11 | #include <boost/hana/type.hpp> | |
12 | ||
13 | #include <type_traits> | |
14 | #include <utility> | |
15 | namespace hana = boost::hana; | |
16 | ||
17 | ||
18 | // Using the `tuple` Monad, we generate all the possible combinations of | |
19 | // cv-qualifiers and reference qualifiers. Then, we use the `optional` | |
20 | // Monad to make sure that our generic function can be called with | |
21 | // arguments of any of those types. | |
22 | ||
23 | // cv_qualifiers : type -> tuple(type) | |
24 | auto cv_qualifiers = [](auto t) { | |
25 | return hana::make_tuple( | |
26 | t, | |
27 | hana::traits::add_const(t), | |
28 | hana::traits::add_volatile(t), | |
29 | hana::traits::add_volatile(hana::traits::add_const(t)) | |
30 | ); | |
31 | }; | |
32 | ||
33 | // ref_qualifiers : type -> tuple(type) | |
34 | auto ref_qualifiers = [](auto t) { | |
35 | return hana::make_tuple( | |
36 | hana::traits::add_lvalue_reference(t), | |
37 | hana::traits::add_rvalue_reference(t) | |
38 | ); | |
39 | }; | |
40 | ||
41 | auto possible_args = cv_qualifiers(hana::type_c<int>) | ref_qualifiers; | |
42 | ||
43 | BOOST_HANA_CONSTANT_CHECK( | |
44 | possible_args == hana::make_tuple( | |
45 | hana::type_c<int&>, | |
46 | hana::type_c<int&&>, | |
47 | hana::type_c<int const&>, | |
48 | hana::type_c<int const&&>, | |
49 | hana::type_c<int volatile&>, | |
50 | hana::type_c<int volatile&&>, | |
51 | hana::type_c<int const volatile&>, | |
52 | hana::type_c<int const volatile&&> | |
53 | ) | |
54 | ); | |
55 | ||
56 | struct some_function { | |
57 | template <typename T> | |
58 | void operator()(T&&) const { } | |
59 | }; | |
60 | ||
61 | int main() { | |
62 | hana::for_each(possible_args, [](auto t) { | |
63 | using T = typename decltype(t)::type; | |
64 | static_assert(decltype(hana::is_valid(some_function{})(std::declval<T>())){}, | |
65 | "some_function should be callable with any type of argument"); | |
66 | }); | |
67 | } |