#ifndef BOOST_MP11_UTILITY_HPP_INCLUDED #define BOOST_MP11_UTILITY_HPP_INCLUDED // Copyright 2015, 2017, 2019 Peter Dimov. // // Distributed under the Boost Software License, Version 1.0. // // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt #include #include namespace boost { namespace mp11 { // mp_identity template struct mp_identity { using type = T; }; // mp_identity_t template using mp_identity_t = typename mp_identity::type; // mp_inherit template struct mp_inherit: T... {}; // mp_if, mp_if_c namespace detail { template struct mp_if_c_impl { }; template struct mp_if_c_impl { using type = T; }; template struct mp_if_c_impl { using type = E; }; } // namespace detail template using mp_if_c = typename detail::mp_if_c_impl::type; template using mp_if = typename detail::mp_if_c_impl(C::value), T, E...>::type; // mp_valid #if BOOST_MP11_WORKAROUND( BOOST_MP11_INTEL, != 0 ) // tested at 1800 // contributed by Roland Schulz in https://github.com/boostorg/mp11/issues/17 namespace detail { template using void_t = void; template class F, class... T> struct mp_valid_impl: mp_false {}; template class F, class... T> struct mp_valid_impl>, F, T...>: mp_true {}; } // namespace detail template class F, class... T> using mp_valid = typename detail::mp_valid_impl; #else // implementation by Bruno Dutra (by the name is_evaluable) namespace detail { template class F, class... T> struct mp_valid_impl { template class G, class = G> static mp_true check(int); template class> static mp_false check(...); using type = decltype(check(0)); }; } // namespace detail template class F, class... T> using mp_valid = typename detail::mp_valid_impl::type; #endif template using mp_valid_q = mp_valid; // mp_defer namespace detail { template class F, class... T> struct mp_defer_impl { using type = F; }; struct mp_no_type { }; #if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) template class F, class... T> struct mp_defer_cuda_workaround { using type = mp_if, detail::mp_defer_impl, detail::mp_no_type>; }; #endif } // namespace detail #if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) template class F, class... T> using mp_defer = typename detail::mp_defer_cuda_workaround< F, T...>::type; #else template class F, class... T> using mp_defer = mp_if, detail::mp_defer_impl, detail::mp_no_type>; #endif // mp_eval_if, mp_eval_if_c namespace detail { template class F, class... U> struct mp_eval_if_c_impl; template class F, class... U> struct mp_eval_if_c_impl { using type = T; }; template class F, class... U> struct mp_eval_if_c_impl: mp_defer { }; } // namespace detail template class F, class... U> using mp_eval_if_c = typename detail::mp_eval_if_c_impl::type; template class F, class... U> using mp_eval_if = typename detail::mp_eval_if_c_impl(C::value), T, F, U...>::type; template using mp_eval_if_q = typename detail::mp_eval_if_c_impl(C::value), T, Q::template fn, U...>::type; // mp_eval_if_not template class F, class... U> using mp_eval_if_not = mp_eval_if, T, F, U...>; template using mp_eval_if_not_q = mp_eval_if, T, Q::template fn, U...>; // mp_eval_or template class F, class... U> using mp_eval_or = mp_eval_if_not, T, F, U...>; template using mp_eval_or_q = mp_eval_or; // mp_cond // so elegant; so doesn't work // template using mp_cond = mp_eval_if; namespace detail { template struct mp_cond_impl; } // namespace detail template using mp_cond = typename detail::mp_cond_impl::type; namespace detail { template using mp_cond_ = mp_eval_if; template struct mp_cond_impl: mp_defer { }; } // namespace detail // mp_quote template class F> struct mp_quote { // the indirection through mp_defer works around the language inability // to expand T... into a fixed parameter list of an alias template template using fn = typename mp_defer::type; }; // mp_quote_trait template class F> struct mp_quote_trait { template using fn = typename F::type; }; // mp_invoke_q #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) namespace detail { template struct mp_invoke_q_impl: mp_defer {}; } // namespace detail template using mp_invoke_q = typename detail::mp_invoke_q_impl::type; #elif BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 50000 ) template using mp_invoke_q = typename mp_defer::type; #else template using mp_invoke_q = typename Q::template fn; #endif // old name for mp_invoke_q retained for compatibility, but deprecated template using mp_invoke BOOST_MP11_DEPRECATED("please use mp_invoke_q") = mp_invoke_q; // mp_not_fn

template class P> struct mp_not_fn { template using fn = mp_not< mp_invoke_q, T...> >; }; template using mp_not_fn_q = mp_not_fn; } // namespace mp11 } // namespace boost #endif // #ifndef BOOST_MP11_UTILITY_HPP_INCLUDED