1 /*!
2 @file
3 Adapts Boost.MPL IntegralConstants 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_BOOST_MPL_INTEGRAL_C_HPP
11 #define BOOST_HANA_EXT_BOOST_MPL_INTEGRAL_C_HPP
12 
13 #include <boost/hana/concept/integral_constant.hpp>
14 #include <boost/hana/config.hpp>
15 #include <boost/hana/core/tag_of.hpp>
16 #include <boost/hana/core/when.hpp>
17 #include <boost/hana/fwd/core/to.hpp>
18 
19 #include <boost/mpl/integral_c.hpp>
20 #include <boost/mpl/integral_c_tag.hpp>
21 
22 #include <type_traits>
23 
24 
25 #ifdef BOOST_HANA_DOXYGEN_INVOKED
26 namespace boost { namespace mpl {
27     //! @ingroup group-ext-mpl
28     //! Adapter for IntegralConstants from the Boost.MPL.
29     //!
30     //! Provided models
31     //! ---------------
32     //! 1. `Constant` and `IntegralConstant`\n
33     //! A Boost.MPL IntegralConstant is a model of the `IntegralConstant`
34     //! and `Constant` concepts just like `hana::integral_constant`s are.
35     //! As a consequence, they are also implicitly a model of the concepts
36     //! provided for all models of `Constant`.
37     //! @include example/ext/boost/mpl/integral_c/integral_constant.cpp
38     template <typename T, T v>
39     struct integral_c { };
40 }}
41 #endif
42 
43 
44 BOOST_HANA_NAMESPACE_BEGIN
45     namespace ext { namespace boost { namespace mpl {
46         template <typename T>
47         struct integral_c_tag { using value_type = T; };
48     }}}
49 
50     template <typename T>
51     struct tag_of<T, when<
52         std::is_same<
53             typename T::tag,
54             ::boost::mpl::integral_c_tag
55         >::value
56     >> {
57         using type = ext::boost::mpl::integral_c_tag<
58             typename hana::tag_of<typename T::value_type>::type
59         >;
60     };
61 
62     //////////////////////////////////////////////////////////////////////////
63     // IntegralConstant/Constant
64     //////////////////////////////////////////////////////////////////////////
65     template <typename T>
66     struct IntegralConstant<ext::boost::mpl::integral_c_tag<T>> {
67         static constexpr bool value = true;
68     };
69 
70     template <typename T, typename C>
71     struct to_impl<ext::boost::mpl::integral_c_tag<T>, C,
72         when<hana::IntegralConstant<C>::value>
73     > : embedding<is_embedded<typename C::value_type, T>::value> {
74         template <typename N>
applyto_impl75         static constexpr auto apply(N const&) {
76             return ::boost::mpl::integral_c<T, N::value>{};
77         }
78     };
79 BOOST_HANA_NAMESPACE_END
80 
81 #endif // !BOOST_HANA_EXT_BOOST_MPL_INTEGRAL_C_HPP
82