File indexing completed on 2025-12-16 09:52:34
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_HANA_CORE_TO_HPP
0011 #define BOOST_HANA_CORE_TO_HPP
0012
0013 #include <boost/hana/fwd/core/to.hpp>
0014
0015 #include <boost/hana/concept/constant.hpp>
0016 #include <boost/hana/concept/foldable.hpp>
0017 #include <boost/hana/concept/sequence.hpp>
0018 #include <boost/hana/config.hpp>
0019 #include <boost/hana/core/common.hpp>
0020 #include <boost/hana/core/dispatch.hpp>
0021 #include <boost/hana/core/make.hpp>
0022 #include <boost/hana/detail/wrong.hpp>
0023 #include <boost/hana/unpack.hpp>
0024 #include <boost/hana/value.hpp>
0025
0026 #include <type_traits>
0027 #include <utility>
0028
0029
0030 namespace boost { namespace hana {
0031
0032
0033
0034
0035 template <typename To, typename From, typename>
0036 struct to_impl : to_impl<To, From, when<true>> { };
0037
0038
0039 namespace convert_detail {
0040 struct no_conversion { };
0041
0042 template <typename To, typename From, typename = void>
0043 struct maybe_static_cast : no_conversion {
0044 template <typename X>
0045 static constexpr auto apply(X const&) {
0046 static_assert(detail::wrong<to_impl<To, From>, X>{},
0047 "no conversion is available between the provided types");
0048 }
0049 };
0050
0051 template <typename To, typename From>
0052 struct maybe_static_cast<To, From, decltype((void)
0053 static_cast<To>(std::declval<From>())
0054 )> {
0055 template <typename X>
0056 static constexpr To apply(X&& x)
0057 { return static_cast<To>(static_cast<X&&>(x)); }
0058 };
0059 }
0060
0061 template <typename To, typename From, bool condition>
0062 struct to_impl<To, From, when<condition>>
0063 : convert_detail::maybe_static_cast<To, From>
0064 { };
0065
0066 template <typename To>
0067 struct to_impl<To, To> : embedding<> {
0068 template <typename X>
0069 static constexpr X apply(X&& x)
0070 { return static_cast<X&&>(x); }
0071 };
0072
0073
0074 template <typename To>
0075 template <typename X>
0076 constexpr decltype(auto) to_t<To>::operator()(X&& x) const {
0077 using From = typename hana::tag_of<X>::type;
0078 return to_impl<To, From>::apply(static_cast<X&&>(x));
0079 }
0080
0081
0082 #define BOOST_HANA_DEFINE_EMBEDDING_IMPL(TO, FROM) \
0083 template <> \
0084 struct to_impl<TO, FROM> : embedding<> \
0085 { static constexpr TO apply(FROM x) { return x; } } \
0086
0087 BOOST_HANA_DEFINE_EMBEDDING_IMPL(long double, double);
0088 BOOST_HANA_DEFINE_EMBEDDING_IMPL(long double, float);
0089 BOOST_HANA_DEFINE_EMBEDDING_IMPL(double , float);
0090
0091 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed long long, signed long);
0092 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed long long, signed int);
0093 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed long long, signed short);
0094 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed long long, signed char);
0095 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed long , signed int);
0096 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed long , signed short);
0097 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed long , signed char);
0098 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed int , signed short);
0099 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed int , signed char);
0100 BOOST_HANA_DEFINE_EMBEDDING_IMPL(signed short , signed char);
0101
0102 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned long long, unsigned long);
0103 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned long long, unsigned int);
0104 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned long long, unsigned short);
0105 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned long long, unsigned char);
0106 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned long , unsigned int);
0107 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned long , unsigned short);
0108 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned long , unsigned char);
0109 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned int , unsigned short);
0110 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned int , unsigned char);
0111 BOOST_HANA_DEFINE_EMBEDDING_IMPL(unsigned short , unsigned char);
0112 #undef BOOST_HANA_DEFINE_EMBEDDING_IMPL
0113
0114 namespace detail {
0115 template <typename T>
0116 struct copy_char_signedness {
0117 using type = typename std::conditional<std::is_signed<char>::value,
0118 std::make_signed<T>, std::make_unsigned<T>
0119 >::type::type;
0120 };
0121 }
0122
0123
0124
0125
0126 #define BOOST_HANA_DEFINE_CHAR_EMBEDDING_IMPL(TO) \
0127 template <> \
0128 struct to_impl<detail::copy_char_signedness<TO>::type, char> \
0129 : embedding<> \
0130 { \
0131 static constexpr detail::copy_char_signedness<TO>::type \
0132 apply(char x) \
0133 { return x; } \
0134 } \
0135
0136 BOOST_HANA_DEFINE_CHAR_EMBEDDING_IMPL(long long);
0137 BOOST_HANA_DEFINE_CHAR_EMBEDDING_IMPL(long);
0138 BOOST_HANA_DEFINE_CHAR_EMBEDDING_IMPL(int);
0139 BOOST_HANA_DEFINE_CHAR_EMBEDDING_IMPL(short);
0140 #undef BOOST_HANA_DEFINE_CHAR_EMBEDDING_IMPL
0141
0142 template <typename T>
0143 struct to_impl<T*, decltype(nullptr)> : embedding<> {
0144 static constexpr T* apply(decltype(nullptr)) { return nullptr; }
0145 };
0146
0147
0148
0149
0150 template <typename From, typename To, typename>
0151 struct is_convertible : std::true_type { };
0152
0153 template <typename From, typename To>
0154 struct is_convertible<From, To, decltype((void)
0155 static_cast<convert_detail::no_conversion>(*(to_impl<To, From>*)0)
0156 )> : std::false_type { };
0157
0158
0159
0160
0161 template <typename From, typename To, typename>
0162 struct is_embedded : std::false_type { };
0163
0164 template <typename From, typename To>
0165 struct is_embedded<From, To, decltype((void)
0166 static_cast<embedding<true>>(*(to_impl<To, From>*)0)
0167 )> : std::true_type { };
0168
0169
0170
0171
0172 template <typename To, typename From>
0173 struct to_impl<To, From, when<
0174 hana::Constant<From>::value &&
0175 is_convertible<typename From::value_type, To>::value
0176 >> : embedding<is_embedded<typename From::value_type, To>::value> {
0177 template <typename X>
0178 static constexpr decltype(auto) apply(X const&)
0179 { return hana::to<To>(hana::value<X>()); }
0180 };
0181
0182
0183
0184
0185 template <typename S, typename F>
0186 struct to_impl<S, F, when<
0187 hana::Sequence<S>::value &&
0188 hana::Foldable<F>::value
0189 >> : embedding<Sequence<F>::value> {
0190 template <typename Xs>
0191 static constexpr decltype(auto) apply(Xs&& xs)
0192 { return hana::unpack(static_cast<Xs&&>(xs), hana::make<S>); }
0193 };
0194 }}
0195
0196 #endif