]>
Commit | Line | Data |
---|---|---|
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 | ||
b32b8144 | 5 | #include <boost/hana/assert.hpp> |
7c673cae FG |
6 | #include <boost/hana/equal.hpp> |
7 | #include <boost/hana/monadic_fold_left.hpp> | |
8 | #include <boost/hana/optional.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 | namespace hana = boost::hana; | |
15 | ||
16 | ||
b32b8144 | 17 | auto builtin_common_t = hana::sfinae([](auto&& t, auto&& u) -> hana::type< |
7c673cae | 18 | std::decay_t<decltype(true ? hana::traits::declval(t) : hana::traits::declval(u))> |
b32b8144 | 19 | > { return {}; }); |
7c673cae FG |
20 | |
21 | template <typename ...T> | |
22 | struct common_type { }; | |
23 | ||
24 | template <typename T, typename U> | |
25 | struct common_type<T, U> | |
26 | : std::conditional_t<std::is_same<std::decay_t<T>, T>{} && | |
27 | std::is_same<std::decay_t<U>, U>{}, | |
28 | decltype(builtin_common_t(hana::type_c<T>, hana::type_c<U>)), | |
29 | common_type<std::decay_t<T>, std::decay_t<U>> | |
30 | > | |
31 | { }; | |
32 | ||
33 | template <typename T1, typename ...Tn> | |
34 | struct common_type<T1, Tn...> | |
35 | : decltype(hana::monadic_fold_left<hana::optional_tag>( | |
36 | hana::tuple_t<Tn...>, | |
37 | hana::type_c<std::decay_t<T1>>, | |
38 | hana::sfinae(hana::metafunction<common_type>) | |
39 | )) | |
40 | { }; | |
41 | ||
42 | template <typename ...Ts> | |
43 | using common_type_t = typename common_type<Ts...>::type; | |
44 | ||
b32b8144 FG |
45 | BOOST_HANA_CONSTANT_CHECK( |
46 | builtin_common_t(hana::type_c<int>, hana::type_c<float>) | |
47 | == | |
48 | hana::just(hana::type_c<float>) | |
49 | ); | |
50 | ||
7c673cae FG |
51 | static_assert(std::is_same< |
52 | common_type_t<char, short, char, short>, | |
53 | int | |
54 | >{}, ""); | |
55 | ||
56 | static_assert(std::is_same< | |
57 | common_type_t<char, double, short, char, short, double>, | |
58 | double | |
59 | >{}, ""); | |
60 | ||
61 | static_assert(std::is_same< | |
62 | common_type_t<char, short, float, short>, | |
63 | float | |
64 | >{}, ""); | |
65 | ||
66 | static_assert( | |
67 | hana::sfinae(hana::metafunction<common_type>)( | |
68 | hana::type_c<int>, hana::type_c<int>, hana::type_c<int*> | |
69 | ) == hana::nothing | |
70 | , ""); | |
71 | ||
72 | int main() { } |