| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- #ifndef BOOST_MP11_LAMBDA_HPP_INCLUDED
- #define BOOST_MP11_LAMBDA_HPP_INCLUDED
- // Copyright 2024 Joaquin M Lopez Munoz.
- //
- // 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 <boost/mp11/detail/config.hpp>
- #if BOOST_MP11_WORKAROUND(BOOST_MP11_MSVC, <= 1800)
- // mp_lambda not supported due to compiler limitations
- #else
- #include <boost/mp11/bind.hpp>
- #include <cstddef>
- #include <type_traits>
- #if defined(_MSC_VER) || defined(__GNUC__)
- # pragma push_macro( "I" )
- # undef I
- #endif
- namespace boost
- {
- namespace mp11
- {
- namespace detail
- {
- template<class T> struct lambda_impl;
- } // namespace detail
- // mp_lambda
- template<class T> using mp_lambda = typename detail::lambda_impl<T>::type;
- namespace detail
- {
- // base case (no placeholder replacement)
- template<class T> struct lambda_impl
- {
- template<class... U> using make = T;
- using type = mp_bind<make>;
- };
- // placeholders (behave directly as mp_bind expressions)
- template<std::size_t I> struct lambda_impl<mp_arg<I>>
- {
- using type = mp_arg<I>;
- };
- #define BOOST_MP11_SPECIALIZE_LAMBDA_IMPL(name, compound_type) \
- template<class T> using lambda_make_##name = compound_type; \
- \
- template<class T> struct lambda_impl<compound_type> \
- { \
- using type = mp_bind<lambda_make_##name, mp_lambda<T>>; \
- };
- // [basic.type.qualifier]
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL(const, const T)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL(volatile, volatile T)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL(const_volatile, const volatile T)
- // [dcl.ptr]
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL(pointer, T*)
- // [dcl.ref]
- // GCC < 7 fails with template<class U> using make = U&;
- template<class T> struct lambda_impl<T&>
- {
- template<class U> using make = typename std::add_lvalue_reference<U>::type;
- using type = mp_bind<make, mp_lambda<T>>;
- };
- template<class T> struct lambda_impl<T&&>
- {
- template<class U> using make = typename std::add_rvalue_reference<U>::type;
- using type = mp_bind<make, mp_lambda<T>>;
- };
- // [dcl.array]
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL(array, T[])
- #undef BOOST_MP11_SPECIALIZE_LAMBDA_IMPL
- template<class T, std::size_t N> struct lambda_impl<T[N]>
- {
- template<class Q> using make = Q[N];
- using type = mp_bind<make, mp_lambda<T>>;
- };
- // [dcl.fct], [dcl.mptr] (member functions)
- #define BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(name, qualifier) \
- template<class R, class... T> using lambda_make_fct_##name = R(T...) qualifier; \
- \
- template<class R, class... T> struct lambda_impl<R(T...) qualifier> \
- { \
- using type = mp_bind< \
- lambda_make_fct_##name, \
- mp_lambda<R>, mp_lambda<T>...>; \
- }; \
- \
- template<class R, class... T> using lambda_make_fct_##name##_ellipsis = \
- R(T..., ...) qualifier; \
- \
- template<class R, class... T> struct lambda_impl<R(T..., ...) qualifier> \
- { \
- using type = mp_bind< \
- lambda_make_fct_##name##_ellipsis, \
- mp_lambda<R>, mp_lambda<T>...>; \
- }; \
- \
- template<class R, class C, class... T> using lambda_make_mfptr_##name = \
- R (C::*)(T...) qualifier; \
- \
- template<class R, class C, class... T> struct lambda_impl<R (C::*)(T...) qualifier> \
- { \
- using type = mp_bind< \
- lambda_make_mfptr_##name, \
- mp_lambda<R>, mp_lambda<C>, mp_lambda<T>...>; \
- }; \
- \
- template<class R, class C, class... T> using lambda_make_mfptr_##name##_ellipsis = \
- R (C::*)(T..., ...) qualifier; \
- \
- template<class R, class C, class... T> struct lambda_impl<R (C::*)(T..., ...) qualifier> \
- { \
- using type = mp_bind< \
- lambda_make_mfptr_##name##_ellipsis, \
- mp_lambda<R>, mp_lambda<C>, mp_lambda<T>...>; \
- };
- #define BOOST_MP11_LAMBDA_EMPTY()
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(no_qualifier, BOOST_MP11_LAMBDA_EMPTY())
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const, const)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(volatile, volatile)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_volatile, const volatile)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(ref, &)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_ref, const&)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(volatile_ref, volatile&)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_volatile_ref, const volatile&)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(rvalue_ref, &&)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_rvalue_ref, const&&)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(volatile_rvalue_ref, volatile&&)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_volatile_rvalue_ref, const volatile&&)
- #if (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L
- // P0012R1: exception specification as part of the type system
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(noexcept, noexcept)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_noexcept, const noexcept)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(volatile_noexcept, volatile noexcept)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_volatile_noexcept, const volatile noexcept)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(ref_noexcept, & noexcept)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_ref_noexcept, const& noexcept)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(volatile_ref_noexcept, volatile& noexcept)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_volatile_ref_noexcept, const volatile& noexcept)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(rvalue_ref_noexcept, && noexcept)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_rvalue_ref_noexcept, const&& noexcept)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(volatile_rvalue_ref_noexcept, volatile&& noexcept)
- BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_volatile_rvalue_ref_noexcept, const volatile&& noexcept)
- #endif // P0012R1
- #undef BOOST_MP11_LAMBDA_EMPTY
- #undef BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR
- // [dcl.mptr] (data members)
- template<class T, class C> struct lambda_impl<T C::*>
- {
- template<class U, class D> using make = U D::*;
- using type = mp_bind<make, mp_lambda<T>, mp_lambda<C>>;
- };
- // template class instantiation
- template<template <class...> class C, class... Ts> struct lambda_impl<C<Ts...>>
- {
- using type = mp_bind<C, mp_lambda<Ts>...>;
- };
- } // namespace detail
- } // namespace mp11
- } // namespace boost
- #if defined(_MSC_VER) || defined(__GNUC__)
- # pragma pop_macro( "I" )
- #endif
- #endif // mp_lambda supported
- #endif // #ifndef BOOST_MP11_LAMBDA_HPP_INCLUDED
|