File indexing completed on 2025-01-18 09:37:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_HANA_CORE_COMMON_HPP
0011 #define BOOST_HANA_CORE_COMMON_HPP
0012
0013 #include <boost/hana/fwd/core/common.hpp>
0014
0015 #include <boost/hana/concept/constant.hpp>
0016 #include <boost/hana/config.hpp>
0017 #include <boost/hana/core/when.hpp>
0018 #include <boost/hana/detail/canonical_constant.hpp>
0019 #include <boost/hana/detail/std_common_type.hpp>
0020 #include <boost/hana/detail/void_t.hpp>
0021
0022 #include <type_traits>
0023
0024
0025 namespace boost { namespace hana {
0026
0027
0028
0029
0030 template <typename T, typename U, typename>
0031 struct common : common<T, U, when<true>> { };
0032
0033
0034 template <typename T, typename U, bool condition>
0035 struct common<T, U, when<condition>>
0036 : detail::std_common_type<T, U>
0037 { };
0038
0039 template <typename T>
0040 struct common<T, T> {
0041 using type = T;
0042 };
0043
0044
0045
0046
0047 template <typename T, typename U, typename>
0048 struct has_common : std::false_type { };
0049
0050 template <typename T, typename U>
0051 struct has_common<T, U, detail::void_t<typename common<T, U>::type>>
0052 : std::true_type
0053 { };
0054
0055
0056
0057
0058 namespace constant_detail {
0059
0060
0061
0062
0063
0064
0065
0066 template <typename A, typename B, typename C>
0067 struct which {
0068 using type = detail::CanonicalConstant<C>;
0069 };
0070
0071 template <template <typename ...> class A, typename T, typename U, typename C>
0072 struct which<A<T>, A<U>, C> {
0073 using type = A<C>;
0074 };
0075 }
0076
0077 template <typename A, typename B>
0078 struct common<A, B, when<
0079 hana::Constant<A>::value &&
0080 hana::Constant<B>::value &&
0081 has_common<typename A::value_type, typename B::value_type>::value
0082 >> {
0083 using type = typename constant_detail::which<
0084 A, B,
0085 typename common<typename A::value_type,
0086 typename B::value_type>::type
0087 >::type;
0088 };
0089
0090 template <typename A, typename B>
0091 struct common<A, B, when<
0092 hana::Constant<A>::value &&
0093 !hana::Constant<B>::value &&
0094 has_common<typename A::value_type, B>::value
0095 >> {
0096 using type = typename common<typename A::value_type, B>::type;
0097 };
0098
0099 template <typename A, typename B>
0100 struct common<A, B, when<
0101 !hana::Constant<A>::value &&
0102 hana::Constant<B>::value &&
0103 has_common<A, typename B::value_type>::value
0104 >> {
0105 using type = typename common<A, typename B::value_type>::type;
0106 };
0107 }}
0108
0109 #endif