File indexing completed on 2025-01-30 09:46:50
0001 #ifndef BOOST_MP11_DETAIL_MP_DEFER_HPP_INCLUDED
0002 #define BOOST_MP11_DETAIL_MP_DEFER_HPP_INCLUDED
0003
0004
0005
0006
0007
0008 #include <boost/mp11/integral.hpp>
0009 #include <boost/mp11/detail/config.hpp>
0010
0011 namespace boost
0012 {
0013 namespace mp11
0014 {
0015
0016
0017 namespace detail
0018 {
0019
0020 template<bool C, class T, class... E> struct mp_if_c_impl
0021 {
0022 };
0023
0024 template<class T, class... E> struct mp_if_c_impl<true, T, E...>
0025 {
0026 using type = T;
0027 };
0028
0029 template<class T, class E> struct mp_if_c_impl<false, T, E>
0030 {
0031 using type = E;
0032 };
0033
0034 }
0035
0036 template<bool C, class T, class... E> using mp_if_c = typename detail::mp_if_c_impl<C, T, E...>::type;
0037 template<class C, class T, class... E> using mp_if = typename detail::mp_if_c_impl<static_cast<bool>(C::value), T, E...>::type;
0038
0039
0040
0041 #if BOOST_MP11_WORKAROUND( BOOST_MP11_INTEL, != 0 )
0042
0043
0044
0045 namespace detail
0046 {
0047
0048 template<class...> using void_t = void;
0049
0050 template<class, template<class...> class F, class... T>
0051 struct mp_valid_impl: mp_false {};
0052
0053 template<template<class...> class F, class... T>
0054 struct mp_valid_impl<void_t<F<T...>>, F, T...>: mp_true {};
0055
0056 }
0057
0058 template<template<class...> class F, class... T> using mp_valid = typename detail::mp_valid_impl<void, F, T...>;
0059
0060 #else
0061
0062
0063 namespace detail
0064 {
0065
0066 template<template<class...> class F, class... T> struct mp_valid_impl
0067 {
0068 template<template<class...> class G, class = G<T...>> static mp_true check(int);
0069 template<template<class...> class> static mp_false check(...);
0070
0071 using type = decltype(check<F>(0));
0072 };
0073
0074 }
0075
0076 template<template<class...> class F, class... T> using mp_valid = typename detail::mp_valid_impl<F, T...>::type;
0077
0078 #endif
0079
0080 template<class Q, class... T> using mp_valid_q = mp_valid<Q::template fn, T...>;
0081
0082
0083 namespace detail
0084 {
0085
0086 template<template<class...> class F, class... T> struct mp_defer_impl
0087 {
0088 using type = F<T...>;
0089 };
0090
0091 struct mp_no_type
0092 {
0093 };
0094
0095 #if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
0096
0097 template<template<class...> class F, class... T> struct mp_defer_cuda_workaround
0098 {
0099 using type = mp_if<mp_valid<F, T...>, detail::mp_defer_impl<F, T...>, detail::mp_no_type>;
0100 };
0101
0102 #endif
0103
0104 }
0105
0106 #if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
0107
0108 template<template<class...> class F, class... T> using mp_defer = typename detail::mp_defer_cuda_workaround< F, T...>::type;
0109
0110 #else
0111
0112 template<template<class...> class F, class... T> using mp_defer = mp_if<mp_valid<F, T...>, detail::mp_defer_impl<F, T...>, detail::mp_no_type>;
0113
0114 #endif
0115
0116 }
0117 }
0118
0119 #endif