Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:37:06

0001 #ifndef BOOST_MP11_LAMBDA_HPP_INCLUDED
0002 #define BOOST_MP11_LAMBDA_HPP_INCLUDED
0003 
0004 //  Copyright 2024 Joaquin M Lopez Munoz.
0005 //
0006 //  Distributed under the Boost Software License, Version 1.0.
0007 //
0008 //  See accompanying file LICENSE_1_0.txt or copy at
0009 //  http://www.boost.org/LICENSE_1_0.txt
0010 
0011 #include <boost/mp11/detail/config.hpp>
0012 
0013 #if BOOST_MP11_WORKAROUND(BOOST_MP11_MSVC, <= 1800)
0014 
0015 // mp_lambda not supported due to compiler limitations
0016 
0017 #else
0018 
0019 #include <boost/mp11/bind.hpp>
0020 #include <cstddef>
0021 #include <type_traits>
0022 
0023 #if defined(_MSC_VER) || defined(__GNUC__)
0024 # pragma push_macro( "I" )
0025 # undef I
0026 #endif
0027 
0028 namespace boost
0029 {
0030 namespace mp11
0031 {
0032 namespace detail
0033 {
0034 
0035 template<class T> struct lambda_impl;
0036 
0037 } // namespace detail
0038 
0039 // mp_lambda
0040 template<class T> using mp_lambda = typename detail::lambda_impl<T>::type;
0041 
0042 namespace detail
0043 {
0044 
0045 // base case (no placeholder replacement)
0046 template<class T> struct lambda_impl
0047 {
0048     template<class... U> using make = T;
0049     using type = mp_bind<make>;
0050 };
0051 
0052 // placeholders (behave directly as mp_bind expressions)
0053 template<std::size_t I> struct lambda_impl<mp_arg<I>>
0054 {
0055     using type = mp_arg<I>;
0056 };
0057 
0058 #define BOOST_MP11_SPECIALIZE_LAMBDA_IMPL(name, compound_type) \
0059 template<class T> using lambda_make_##name = compound_type;    \
0060                                                                \
0061 template<class T> struct lambda_impl<compound_type>            \
0062 {                                                              \
0063     using type = mp_bind<lambda_make_##name, mp_lambda<T>>;    \
0064 };
0065 
0066 // [basic.type.qualifier]
0067 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL(const, const T)
0068 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL(volatile, volatile T)
0069 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL(const_volatile, const volatile T)
0070 
0071 // [dcl.ptr]
0072 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL(pointer, T*)
0073 
0074 // [dcl.ref]
0075 // GCC < 7 fails with template<class U> using make = U&;
0076 template<class T> struct lambda_impl<T&>
0077 {
0078     template<class U> using make = typename std::add_lvalue_reference<U>::type;
0079     using type = mp_bind<make, mp_lambda<T>>;
0080 };
0081 
0082 template<class T> struct lambda_impl<T&&>
0083 {
0084     template<class U> using make = typename std::add_rvalue_reference<U>::type;
0085     using type = mp_bind<make, mp_lambda<T>>;
0086 };
0087 
0088 // [dcl.array]
0089 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL(array, T[])
0090 
0091 #undef BOOST_MP11_SPECIALIZE_LAMBDA_IMPL
0092 
0093 template<class T, std::size_t N> struct lambda_impl<T[N]>
0094 {
0095     template<class Q> using make = Q[N];
0096     using type = mp_bind<make, mp_lambda<T>>;
0097 };
0098 
0099 // [dcl.fct], [dcl.mptr] (member functions)
0100 #define BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(name, qualifier)                 \
0101 template<class R, class... T> using lambda_make_fct_##name = R(T...) qualifier;          \
0102                                                                                          \
0103 template<class R, class... T> struct lambda_impl<R(T...) qualifier>                      \
0104 {                                                                                        \
0105     using type =  mp_bind<                                                               \
0106         lambda_make_fct_##name,                                                          \
0107         mp_lambda<R>, mp_lambda<T>...>;                                                  \
0108 };                                                                                       \
0109                                                                                          \
0110 template<class R, class... T> using lambda_make_fct_##name##_ellipsis =                  \
0111     R(T..., ...) qualifier;                                                              \
0112                                                                                          \
0113 template<class R, class... T> struct lambda_impl<R(T..., ...) qualifier>                 \
0114 {                                                                                        \
0115     using type = mp_bind<                                                                \
0116         lambda_make_fct_##name##_ellipsis,                                               \
0117         mp_lambda<R>, mp_lambda<T>...>;                                                  \
0118 };                                                                                       \
0119                                                                                          \
0120 template<class R, class C, class... T> using lambda_make_mfptr_##name =                  \
0121     R (C::*)(T...) qualifier;                                                            \
0122                                                                                          \
0123 template<class R, class C, class... T> struct lambda_impl<R (C::*)(T...) qualifier>      \
0124 {                                                                                        \
0125     using type = mp_bind<                                                                \
0126         lambda_make_mfptr_##name,                                                        \
0127         mp_lambda<R>, mp_lambda<C>, mp_lambda<T>...>;                                    \
0128 };                                                                                       \
0129                                                                                          \
0130 template<class R, class C, class... T> using lambda_make_mfptr_##name##_ellipsis =       \
0131     R (C::*)(T..., ...) qualifier;                                                       \
0132                                                                                          \
0133 template<class R, class C, class... T> struct lambda_impl<R (C::*)(T..., ...) qualifier> \
0134 {                                                                                        \
0135     using type = mp_bind<                                                                \
0136         lambda_make_mfptr_##name##_ellipsis,                                             \
0137         mp_lambda<R>, mp_lambda<C>, mp_lambda<T>...>;                                    \
0138 };
0139 
0140 #define BOOST_MP11_LAMBDA_EMPTY()
0141 
0142 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(no_qualifier, BOOST_MP11_LAMBDA_EMPTY())
0143 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const, const)
0144 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(volatile, volatile)
0145 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_volatile, const volatile)
0146 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(ref, &)
0147 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_ref, const&)
0148 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(volatile_ref, volatile&)
0149 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_volatile_ref, const volatile&)
0150 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(rvalue_ref, &&)
0151 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_rvalue_ref, const&&)
0152 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(volatile_rvalue_ref, volatile&&)
0153 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_volatile_rvalue_ref, const volatile&&)
0154 
0155 #if (defined(_MSVC_LANG) &&  _MSVC_LANG >= 201703L) || __cplusplus >= 201703L
0156 
0157 // P0012R1: exception specification as part of the type system
0158 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(noexcept, noexcept)
0159 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_noexcept, const noexcept)
0160 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(volatile_noexcept, volatile noexcept)
0161 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_volatile_noexcept, const volatile noexcept)
0162 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(ref_noexcept, & noexcept)
0163 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_ref_noexcept, const& noexcept)
0164 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(volatile_ref_noexcept, volatile& noexcept)
0165 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_volatile_ref_noexcept, const volatile& noexcept)
0166 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(rvalue_ref_noexcept, && noexcept)
0167 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_rvalue_ref_noexcept, const&& noexcept)
0168 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(volatile_rvalue_ref_noexcept, volatile&& noexcept)
0169 BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR(const_volatile_rvalue_ref_noexcept, const volatile&& noexcept)
0170 
0171 #endif // P0012R1
0172 
0173 #undef BOOST_MP11_LAMBDA_EMPTY
0174 #undef BOOST_MP11_SPECIALIZE_LAMBDA_IMPL_FCT_AND_MFPTR
0175 
0176 // [dcl.mptr] (data members)
0177 template<class T, class C> struct lambda_impl<T C::*>
0178 {
0179     template<class U, class D> using make = U D::*;
0180     using type = mp_bind<make, mp_lambda<T>, mp_lambda<C>>;
0181 };
0182 
0183 // template class instantiation
0184 template<template <class...> class C, class... Ts> struct lambda_impl<C<Ts...>>
0185 {
0186     using type = mp_bind<C, mp_lambda<Ts>...>;
0187 };
0188 
0189 } // namespace detail
0190 } // namespace mp11
0191 } // namespace boost
0192 
0193 #if defined(_MSC_VER) || defined(__GNUC__)
0194 # pragma pop_macro( "I" )
0195 #endif
0196 
0197 #endif // mp_lambda supported
0198 
0199 #endif // #ifndef BOOST_MP11_LAMBDA_HPP_INCLUDED