]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/hana/type.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / hana / type.hpp
index 80a498753f1b2a81e48286421117c13ae67354f9..b1d3e2a308a661bf2841e81c3cf881b455c3908a 100644 (file)
@@ -14,6 +14,7 @@ Distributed under the Boost Software License, Version 1.0.
 
 #include <boost/hana/bool.hpp>
 #include <boost/hana/config.hpp>
+#include <boost/hana/core/when.hpp>
 #include <boost/hana/detail/operators/adl.hpp>
 #include <boost/hana/detail/operators/comparable.hpp>
 #include <boost/hana/fwd/concept/metafunction.hpp>
@@ -152,6 +153,24 @@ BOOST_HANA_NAMESPACE_BEGIN
     //////////////////////////////////////////////////////////////////////////
     // template_
     //////////////////////////////////////////////////////////////////////////
+    // Note: We have to use the very complicated trick below instead of just
+    // mentionning `F<T...>` in a SFINAE-able context because of CWG 1430
+    // (http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_active.html#1430).
+    namespace template_detail {
+        template <typename ...T> struct args;
+        template <typename ...> using always_void = void;
+
+        template <template <typename ...> class F, typename Args, typename = void>
+        struct specialization_is_valid
+            : std::false_type
+        { };
+
+        template <template <typename ...> class F, typename ...T>
+        struct specialization_is_valid<F, args<T...>, always_void<F<T...>>>
+            : std::true_type
+        { };
+    } // end namespace detail
+
     template <template <typename ...> class F>
     struct template_t {
         template <typename ...T>
@@ -159,7 +178,9 @@ BOOST_HANA_NAMESPACE_BEGIN
             using type = F<T...>;
         };
 
-        template <typename ...T>
+        template <typename ...T, typename = std::enable_if_t<
+            template_detail::specialization_is_valid<F, template_detail::args<typename T::type...>>::value
+        >>
         constexpr auto operator()(T const& ...) const
         { return hana::type<F<typename T::type...>>{}; }
     };
@@ -177,6 +198,23 @@ BOOST_HANA_NAMESPACE_BEGIN
         operator()(T const& ...) const { return {}; }
     };
 
+    //////////////////////////////////////////////////////////////////////////
+    // metafunction_class
+    //////////////////////////////////////////////////////////////////////////
+    namespace detail {
+        template <typename F, typename ...T>
+        struct always_first { using type = F; };
+    }
+    template <typename F>
+    struct metafunction_class_t {
+        template <typename ...T>
+        using apply = typename detail::always_first<F, T...>::type::template apply<T...>;
+
+        template <typename ...T>
+        constexpr hana::type<typename detail::always_first<F, T...>::type::template apply<typename T::type...>::type>
+        operator()(T const& ...) const { return {}; }
+    };
+
     //////////////////////////////////////////////////////////////////////////
     // Metafunction
     //////////////////////////////////////////////////////////////////////////
@@ -200,9 +238,10 @@ BOOST_HANA_NAMESPACE_BEGIN
     //////////////////////////////////////////////////////////////////////////
     template <typename F>
     struct integral_t {
-        template <typename ...T>
-        constexpr auto operator()(T const& ...) const {
-            using Result = typename F::template apply<typename T::type...>::type;
+        template <typename ...T, typename Result =
+            typename detail::always_first<F, T...>::type::template apply<typename T::type...>::type
+        >
+        constexpr Result operator()(T const& ...) const {
             return Result{};
         }
     };