Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:52:34

0001 /*!
0002 @file
0003 Defines `boost::hana::to` and related utilities.
0004 
0005 Copyright Louis Dionne 2013-2022
0006 Distributed under the Boost Software License, Version 1.0.
0007 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
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     // to
0033     //////////////////////////////////////////////////////////////////////////
0034     //! @cond
0035     template <typename To, typename From, typename>
0036     struct to_impl : to_impl<To, From, when<true>> { };
0037     //! @endcond
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     } // end namespace convert_detail
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     //! @cond
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     //! @endcond
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     // If `char` is signed, we define an embedding from `char` to any signed
0124     // integral type. Otherwise, we define one from `char` to any unsigned
0125     // integral type.
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     // is_convertible
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     // is_embedded
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     // Conversion for Constants
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     // Foldable -> Sequence
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 }} // end namespace boost::hana
0195 
0196 #endif // !BOOST_HANA_CORE_TO_HPP