/*! @file Defines `boost::hana::detail::CanonicalConstant`. @copyright Louis Dionne 2013-2017 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_HANA_DETAIL_CANONICAL_CONSTANT_HPP #define BOOST_HANA_DETAIL_CANONICAL_CONSTANT_HPP #include BOOST_HANA_NAMESPACE_BEGIN namespace detail { //! @ingroup group-details //! Tag representing a canonical `Constant`. //! //! This is an implementation detail used to provide many models for //! stuff like `Monoid`, `Group`, etc. To create a `CanonicalConstant`, //! simply create an object with a nested `hana_tag` equal to the proper //! specialization of `CanonicalConstant`, and then also provide a //! `constexpr` static member `::%value` holding the value of the constant. template struct CanonicalConstant { using value_type = T; }; } BOOST_HANA_NAMESPACE_END #include #include #include #include #include BOOST_HANA_NAMESPACE_BEGIN ////////////////////////////////////////////////////////////////////////// // Constant ////////////////////////////////////////////////////////////////////////// template struct value_impl> { template static constexpr decltype(auto) apply() { return X::value; } }; namespace detail { template struct canonical_constant { static constexpr auto value = hana::to(hana::value()); using hana_tag = detail::CanonicalConstant; }; } template struct to_impl, C, when< hana::Constant::value && is_convertible::value >> : embedding::value> { template static constexpr detail::canonical_constant apply(X const&) { return {}; } }; ////////////////////////////////////////////////////////////////////////// // IntegralConstant (when value_type is integral) ////////////////////////////////////////////////////////////////////////// template struct IntegralConstant> { static constexpr bool value = std::is_integral::value; }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_DETAIL_CANONICAL_CONSTANT_HPP