1 /*! 2 @file 3 Adapts `std::integral_constant` for use with Hana. 4 5 @copyright Louis Dionne 2013-2017 6 Distributed under the Boost Software License, Version 1.0. 7 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) 8 */ 9 10 #ifndef BOOST_HANA_EXT_STD_INTEGRAL_CONSTANT_HPP 11 #define BOOST_HANA_EXT_STD_INTEGRAL_CONSTANT_HPP 12 13 #include <boost/hana/concept/integral_constant.hpp> 14 #include <boost/hana/config.hpp> 15 #include <boost/hana/core/when.hpp> 16 #include <boost/hana/fwd/core/to.hpp> 17 #include <boost/hana/fwd/core/tag_of.hpp> 18 #include <boost/hana/fwd/integral_constant.hpp> 19 20 #include <type_traits> 21 22 23 #ifdef BOOST_HANA_DOXYGEN_INVOKED 24 namespace std { 25 //! @ingroup group-ext-std 26 //! Adapter for `std::integral_constant`s. 27 //! 28 //! Provided models 29 //! --------------- 30 //! 1. `Constant` and `IntegralConstant`\n 31 //! A `std::integral_constant` is a model of the `IntegralConstant` and 32 //! `Constant` concepts, just like `hana::integral_constant`s are. As a 33 //! consequence, they are also implicitly a model of the concepts provided 34 //! for all models of `Constant`. 35 //! @include example/ext/std/integral_constant.cpp 36 template <typename T, T v> 37 struct integral_constant { }; 38 } 39 #endif 40 41 42 BOOST_HANA_NAMESPACE_BEGIN 43 namespace ext { namespace std { 44 template <typename T> 45 struct integral_constant_tag { using value_type = T; }; 46 }} 47 48 namespace detail { 49 template <typename T, T v> 50 constexpr bool is_std_integral_constant(std::integral_constant<T,v> *)51 is_std_integral_constant(std::integral_constant<T, v>*) 52 { return true; } 53 is_std_integral_constant(...)54 constexpr bool is_std_integral_constant(...) 55 { return false; } 56 57 58 template <typename T, T v> 59 constexpr bool is_hana_integral_constant(hana::integral_constant<T,v> *)60 is_hana_integral_constant(hana::integral_constant<T, v>*) 61 { return true; } 62 is_hana_integral_constant(...)63 constexpr bool is_hana_integral_constant(...) 64 { return false; } 65 } 66 67 template <typename T> 68 struct tag_of<T, when< 69 detail::is_std_integral_constant((T*)0) && 70 !detail::is_hana_integral_constant((T*)0) 71 >> { 72 using type = ext::std::integral_constant_tag< 73 typename hana::tag_of<typename T::value_type>::type 74 >; 75 }; 76 77 ////////////////////////////////////////////////////////////////////////// 78 // Constant/IntegralConstant 79 ////////////////////////////////////////////////////////////////////////// 80 template <typename T> 81 struct IntegralConstant<ext::std::integral_constant_tag<T>> { 82 static constexpr bool value = true; 83 }; 84 85 template <typename T, typename C> 86 struct to_impl<ext::std::integral_constant_tag<T>, C, when< 87 hana::IntegralConstant<C>::value 88 >> : embedding<is_embedded<typename C::value_type, T>::value> { 89 template <typename N> applyto_impl90 static constexpr auto apply(N const&) { 91 return std::integral_constant<T, N::value>{}; 92 } 93 }; 94 BOOST_HANA_NAMESPACE_END 95 96 #endif // !BOOST_HANA_EXT_STD_INTEGRAL_CONSTANT_HPP 97