File indexing completed on 2025-01-30 09:43:51
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_HOF_GUARD_FUNCTION_LAMBDA_H
0009 #define BOOST_HOF_GUARD_FUNCTION_LAMBDA_H
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068 #include <boost/hof/config.hpp>
0069
0070
0071 #if !BOOST_HOF_HAS_CONSTEXPR_LAMBDA || !BOOST_HOF_HAS_INLINE_LAMBDAS
0072
0073 #include <type_traits>
0074 #include <utility>
0075 #include <boost/hof/detail/result_of.hpp>
0076 #include <boost/hof/reveal.hpp>
0077 #include <boost/hof/detail/constexpr_deduce.hpp>
0078 #include <boost/hof/function.hpp>
0079
0080
0081 #ifndef BOOST_HOF_REWRITE_STATIC_LAMBDA
0082 #ifdef _MSC_VER
0083 #define BOOST_HOF_REWRITE_STATIC_LAMBDA 1
0084 #else
0085 #define BOOST_HOF_REWRITE_STATIC_LAMBDA 0
0086 #endif
0087 #endif
0088
0089 namespace boost { namespace hof {
0090
0091 namespace detail {
0092
0093 template<class F>
0094 struct static_function_wrapper
0095 {
0096
0097 constexpr static_function_wrapper()
0098 {}
0099
0100 static_assert(BOOST_HOF_IS_EMPTY(F), "Function or lambda expression must be empty");
0101
0102 struct failure
0103 : failure_for<F>
0104 {};
0105
0106 template<class... Ts>
0107 const F& base_function(Ts&&...) const
0108 {
0109 return reinterpret_cast<const F&>(*this);
0110 }
0111
0112 BOOST_HOF_RETURNS_CLASS(static_function_wrapper);
0113
0114 template<class... Ts>
0115 BOOST_HOF_SFINAE_RESULT(const F&, id_<Ts>...)
0116 operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
0117 (
0118 BOOST_HOF_RETURNS_REINTERPRET_CAST(const F&)(*BOOST_HOF_CONST_THIS)(BOOST_HOF_FORWARD(Ts)(xs)...)
0119 );
0120 };
0121
0122 struct static_function_wrapper_factor
0123 {
0124 constexpr static_function_wrapper_factor()
0125 {}
0126 template<class F>
0127 constexpr static_function_wrapper<F> operator= (const F&) const
0128 {
0129
0130 return {};
0131 }
0132 };
0133
0134 #if BOOST_HOF_REWRITE_STATIC_LAMBDA
0135 template<class T, class=void>
0136 struct is_rewritable
0137 : std::false_type
0138 {};
0139
0140 template<class T>
0141 struct is_rewritable<T, typename detail::holder<
0142 typename T::fit_rewritable_tag
0143 >::type>
0144 : std::is_same<typename T::fit_rewritable_tag, T>
0145 {};
0146
0147 template<class T, class=void>
0148 struct is_rewritable1
0149 : std::false_type
0150 {};
0151
0152 template<class T>
0153 struct is_rewritable1<T, typename detail::holder<
0154 typename T::fit_rewritable1_tag
0155 >::type>
0156 : std::is_same<typename T::fit_rewritable1_tag, T>
0157 {};
0158
0159
0160 template<class T, class=void>
0161 struct rewrite_lambda;
0162
0163 template<template<class...> class Adaptor, class... Ts>
0164 struct rewrite_lambda<Adaptor<Ts...>, typename std::enable_if<
0165 is_rewritable<Adaptor<Ts...>>::value
0166 >::type>
0167 {
0168 typedef Adaptor<typename rewrite_lambda<Ts>::type...> type;
0169 };
0170
0171 template<template<class...> class Adaptor, class T, class... Ts>
0172 struct rewrite_lambda<Adaptor<T, Ts...>, typename std::enable_if<
0173 is_rewritable1<Adaptor<T, Ts...>>::value
0174 >::type>
0175 {
0176 typedef Adaptor<typename rewrite_lambda<T>::type, Ts...> type;
0177 };
0178
0179 template<class T>
0180 struct rewrite_lambda<T, typename std::enable_if<
0181 std::is_empty<T>::value &&
0182 !is_rewritable<T>::value &&
0183 !is_rewritable1<T>::value
0184 >::type>
0185 {
0186 typedef static_function_wrapper<T> type;
0187 };
0188
0189 template<class T>
0190 struct rewrite_lambda<T, typename std::enable_if<
0191 !std::is_empty<T>::value &&
0192 !is_rewritable<T>::value &&
0193 !is_rewritable1<T>::value
0194 >::type>
0195 {
0196 typedef T type;
0197 };
0198
0199 #endif
0200
0201 template<class T>
0202 struct reveal_static_lambda_function_wrapper_factor
0203 {
0204 constexpr reveal_static_lambda_function_wrapper_factor()
0205 {}
0206 #if BOOST_HOF_REWRITE_STATIC_LAMBDA
0207 template<class F>
0208 constexpr reveal_adaptor<typename rewrite_lambda<F>::type>
0209 operator=(const F&) const
0210 {
0211 return reveal_adaptor<typename rewrite_lambda<F>::type>();
0212 }
0213 #elif BOOST_HOF_HAS_CONST_FOLD
0214 template<class F>
0215 constexpr const reveal_adaptor<F>& operator=(const F&) const
0216 {
0217 return reinterpret_cast<const reveal_adaptor<F>&>(static_const_var<T>());
0218 }
0219 #else
0220 template<class F>
0221 constexpr reveal_adaptor<static_function_wrapper<F>> operator=(const F&) const
0222 {
0223 return {};
0224 }
0225 #endif
0226 };
0227
0228 }}}
0229
0230 #endif
0231
0232 #if BOOST_HOF_HAS_CONSTEXPR_LAMBDA
0233 #define BOOST_HOF_STATIC_LAMBDA []
0234 #else
0235 #define BOOST_HOF_DETAIL_MAKE_STATIC BOOST_HOF_DETAIL_CONSTEXPR_DEDUCE boost::hof::detail::static_function_wrapper_factor()
0236 #define BOOST_HOF_STATIC_LAMBDA BOOST_HOF_DETAIL_MAKE_STATIC = []
0237 #endif
0238
0239 #if BOOST_HOF_HAS_INLINE_LAMBDAS
0240 #define BOOST_HOF_STATIC_LAMBDA_FUNCTION BOOST_HOF_STATIC_FUNCTION
0241 #else
0242 #define BOOST_HOF_DETAIL_MAKE_REVEAL_STATIC(T) BOOST_HOF_DETAIL_CONSTEXPR_DEDUCE_UNIQUE(T) boost::hof::detail::reveal_static_lambda_function_wrapper_factor<T>()
0243 #define BOOST_HOF_STATIC_LAMBDA_FUNCTION(name) \
0244 struct fit_private_static_function_ ## name {}; \
0245 BOOST_HOF_STATIC_AUTO_REF name = BOOST_HOF_DETAIL_MAKE_REVEAL_STATIC(fit_private_static_function_ ## name)
0246 #endif
0247
0248 #endif