Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-16 09:16:01

0001 /*!
0002 @file
0003 Defines `boost::hana::detail::CanonicalConstant`.
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_DETAIL_CANONICAL_CONSTANT_HPP
0011 #define BOOST_HANA_DETAIL_CANONICAL_CONSTANT_HPP
0012 
0013 #include <boost/hana/config.hpp>
0014 
0015 
0016 namespace boost { namespace hana { namespace detail {
0017     //! @ingroup group-details
0018     //! Tag representing a canonical `Constant`.
0019     //!
0020     //! This is an implementation detail used to provide many models for
0021     //! stuff like `Monoid`, `Group`, etc. To create a `CanonicalConstant`,
0022     //! simply create an object with a nested `hana_tag` equal to the proper
0023     //! specialization of `CanonicalConstant<T>`, and then also provide a
0024     //! `constexpr` static member `::%value` holding the value of the constant.
0025     template <typename T>
0026     struct CanonicalConstant {
0027         using value_type = T;
0028     };
0029 } }} // end namespace boost::hana
0030 
0031 
0032 #include <boost/hana/concept/constant.hpp>
0033 #include <boost/hana/concept/integral_constant.hpp>
0034 #include <boost/hana/core/to.hpp>
0035 #include <boost/hana/core/when.hpp>
0036 
0037 #include <type_traits>
0038 
0039 
0040 namespace boost { namespace hana {
0041     //////////////////////////////////////////////////////////////////////////
0042     // Constant
0043     //////////////////////////////////////////////////////////////////////////
0044     template <typename T>
0045     struct value_impl<detail::CanonicalConstant<T>> {
0046         template <typename X>
0047         static constexpr decltype(auto) apply()
0048         { return X::value; }
0049     };
0050 
0051     namespace detail {
0052         template <typename T, typename X>
0053         struct canonical_constant {
0054             static constexpr auto value = hana::to<T>(hana::value<X>());
0055             using hana_tag = detail::CanonicalConstant<T>;
0056         };
0057     }
0058 
0059     template <typename T, typename C>
0060     struct to_impl<detail::CanonicalConstant<T>, C, when<
0061         hana::Constant<C>::value &&
0062         is_convertible<typename C::value_type, T>::value
0063     >>
0064         : embedding<is_embedded<typename C::value_type, T>::value>
0065     {
0066         template <typename X>
0067         static constexpr detail::canonical_constant<T, X> apply(X const&)
0068         { return {}; }
0069     };
0070 
0071     //////////////////////////////////////////////////////////////////////////
0072     // IntegralConstant (when value_type is integral)
0073     //////////////////////////////////////////////////////////////////////////
0074     template <typename T>
0075     struct IntegralConstant<detail::CanonicalConstant<T>> {
0076         static constexpr bool value = std::is_integral<T>::value;
0077     };
0078 }} // end namespace boost::hana
0079 
0080 #endif // !BOOST_HANA_DETAIL_CANONICAL_CONSTANT_HPP