integral_constant.hpp 2.9 KB

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