File indexing completed on 2025-01-18 09:39:11
0001 #ifndef BOOST_LAMBDA2_LAMBDA2_HPP_INCLUDED
0002 #define BOOST_LAMBDA2_LAMBDA2_HPP_INCLUDED
0003
0004
0005
0006
0007
0008 #include <functional>
0009 #include <type_traits>
0010 #include <utility>
0011 #include <tuple>
0012 #include <cstddef>
0013 #include <iosfwd>
0014
0015
0016
0017 #define BOOST_LAMBDA2_VERSION 108400
0018
0019 namespace boost
0020 {
0021 namespace lambda2
0022 {
0023
0024 namespace lambda2_detail
0025 {
0026
0027 struct subscript
0028 {
0029 template<class T1, class T2> decltype(auto) operator()(T1&& t1, T2&& t2) const
0030 {
0031 return std::forward<T1>(t1)[ std::forward<T2>(t2) ];
0032 }
0033 };
0034
0035 template<int I> struct get
0036 {
0037 template<class T> decltype(auto) operator()( T&& t ) const
0038 {
0039 return std::get<I>( std::forward<T>(t) );
0040 }
0041 };
0042
0043 }
0044
0045
0046
0047 template<int I> struct lambda2_arg
0048 {
0049 template<class... A> decltype(auto) operator()( A&&... a ) const noexcept
0050 {
0051 return std::get<std::size_t{I-1}>( std::tuple<A&&...>( std::forward<A>(a)... ) );
0052 }
0053
0054 template<class T> auto operator[]( T&& t ) const
0055 {
0056 return std::bind( lambda2_detail::subscript(), *this, std::forward<T>( t ) );
0057 }
0058 };
0059
0060 #if defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L
0061 # define BOOST_LAMBDA2_INLINE_VAR inline
0062 #else
0063 # define BOOST_LAMBDA2_INLINE_VAR
0064 #endif
0065
0066 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<1> _1{};
0067 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<2> _2{};
0068 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<3> _3{};
0069 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<4> _4{};
0070 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<5> _5{};
0071 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<6> _6{};
0072 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<7> _7{};
0073 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<8> _8{};
0074 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<9> _9{};
0075
0076
0077
0078 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_detail::get<0> first{};
0079 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_detail::get<1> second{};
0080
0081 #undef BOOST_LAMBDA2_INLINE_VAR
0082
0083 }
0084 }
0085
0086 namespace std
0087 {
0088
0089 template<int I> struct is_placeholder< boost::lambda2::lambda2_arg<I> >: integral_constant<int, I>
0090 {
0091 };
0092
0093 }
0094
0095 namespace boost
0096 {
0097 namespace lambda2
0098 {
0099
0100 namespace lambda2_detail
0101 {
0102
0103
0104
0105 #define BOOST_LAMBDA2_UNARY_FN(op, fn) \
0106 struct fn \
0107 { \
0108 template<class T> decltype(auto) operator()(T&& t) const \
0109 { \
0110 return op std::forward<T>(t); \
0111 } \
0112 };
0113
0114 #define BOOST_LAMBDA2_POSTFIX_FN(op, fn) \
0115 struct fn \
0116 { \
0117 template<class T> decltype(auto) operator()(T&& t) const \
0118 { \
0119 return std::forward<T>(t) op; \
0120 } \
0121 };
0122
0123 #define BOOST_LAMBDA2_BINARY_FN(op, fn) \
0124 struct fn \
0125 { \
0126 template<class T1, class T2> decltype(auto) operator()(T1&& t1, T2&& t2) const \
0127 { \
0128 return std::forward<T1>(t1) op std::forward<T2>(t2); \
0129 } \
0130 };
0131
0132 BOOST_LAMBDA2_BINARY_FN(<<, left_shift)
0133 BOOST_LAMBDA2_BINARY_FN(>>, right_shift)
0134
0135 BOOST_LAMBDA2_UNARY_FN(+, unary_plus)
0136 BOOST_LAMBDA2_UNARY_FN(*, dereference)
0137
0138 BOOST_LAMBDA2_UNARY_FN(++, increment)
0139 BOOST_LAMBDA2_UNARY_FN(--, decrement)
0140
0141 BOOST_LAMBDA2_POSTFIX_FN(++, postfix_increment)
0142 BOOST_LAMBDA2_POSTFIX_FN(--, postfix_decrement)
0143
0144 BOOST_LAMBDA2_BINARY_FN(+=, plus_equal)
0145 BOOST_LAMBDA2_BINARY_FN(-=, minus_equal)
0146 BOOST_LAMBDA2_BINARY_FN(*=, multiplies_equal)
0147 BOOST_LAMBDA2_BINARY_FN(/=, divides_equal)
0148 BOOST_LAMBDA2_BINARY_FN(%=, modulus_equal)
0149 BOOST_LAMBDA2_BINARY_FN(&=, bit_and_equal)
0150 BOOST_LAMBDA2_BINARY_FN(|=, bit_or_equal)
0151 BOOST_LAMBDA2_BINARY_FN(^=, bit_xor_equal)
0152 BOOST_LAMBDA2_BINARY_FN(<<=, left_shift_equal)
0153 BOOST_LAMBDA2_BINARY_FN(>>=, right_shift_equal)
0154
0155
0156
0157 template<class T> using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
0158
0159 template<class T, class T2 = remove_cvref_t<T>> using is_lambda_expression =
0160 std::integral_constant<bool, std::is_placeholder<T2>::value || std::is_bind_expression<T2>::value>;
0161
0162 template<class A> using enable_unary_lambda =
0163 std::enable_if_t<is_lambda_expression<A>::value>;
0164
0165 template<class A, class B> using enable_binary_lambda =
0166 std::enable_if_t<is_lambda_expression<A>::value || is_lambda_expression<B>::value>;
0167
0168 template<class T> using is_stream = std::is_base_of<std::ios_base, remove_cvref_t<T>>;
0169
0170 }
0171
0172 #define BOOST_LAMBDA2_UNARY_LAMBDA(op, fn) \
0173 template<class A, class = lambda2_detail::enable_unary_lambda<A>> \
0174 auto operator op( A&& a ) \
0175 { \
0176 return std::bind( fn(), std::forward<A>(a) ); \
0177 }
0178
0179 #define BOOST_LAMBDA2_POSTFIX_LAMBDA(op, fn) \
0180 template<class A, class = lambda2_detail::enable_unary_lambda<A>> \
0181 auto operator op( A&& a, int ) \
0182 { \
0183 return std::bind( fn(), std::forward<A>(a) ); \
0184 }
0185
0186 #define BOOST_LAMBDA2_BINARY_LAMBDA(op, fn) \
0187 template<class A, class B, class = lambda2_detail::enable_binary_lambda<A, B>> \
0188 auto operator op( A&& a, B&& b ) \
0189 { \
0190 return std::bind( fn(), std::forward<A>(a), std::forward<B>(b) ); \
0191 }
0192
0193
0194
0195 BOOST_LAMBDA2_BINARY_LAMBDA(+, std::plus<>)
0196 BOOST_LAMBDA2_BINARY_LAMBDA(-, std::minus<>)
0197 BOOST_LAMBDA2_BINARY_LAMBDA(*, std::multiplies<>)
0198 BOOST_LAMBDA2_BINARY_LAMBDA(/, std::divides<>)
0199 BOOST_LAMBDA2_BINARY_LAMBDA(%, std::modulus<>)
0200 BOOST_LAMBDA2_UNARY_LAMBDA(-, std::negate<>)
0201
0202 BOOST_LAMBDA2_BINARY_LAMBDA(==, std::equal_to<>)
0203 BOOST_LAMBDA2_BINARY_LAMBDA(!=, std::not_equal_to<>)
0204 BOOST_LAMBDA2_BINARY_LAMBDA(>, std::greater<>)
0205 BOOST_LAMBDA2_BINARY_LAMBDA(<, std::less<>)
0206 BOOST_LAMBDA2_BINARY_LAMBDA(>=, std::greater_equal<>)
0207 BOOST_LAMBDA2_BINARY_LAMBDA(<=, std::less_equal<>)
0208
0209 BOOST_LAMBDA2_BINARY_LAMBDA(&&, std::logical_and<>)
0210 BOOST_LAMBDA2_BINARY_LAMBDA(||, std::logical_or<>)
0211 BOOST_LAMBDA2_UNARY_LAMBDA(!, std::logical_not<>)
0212
0213 BOOST_LAMBDA2_BINARY_LAMBDA(&, std::bit_and<>)
0214 BOOST_LAMBDA2_BINARY_LAMBDA(|, std::bit_or<>)
0215 BOOST_LAMBDA2_BINARY_LAMBDA(^, std::bit_xor<>)
0216 BOOST_LAMBDA2_UNARY_LAMBDA(~, std::bit_not<>)
0217
0218
0219
0220 BOOST_LAMBDA2_UNARY_LAMBDA(+, lambda2_detail::unary_plus)
0221 BOOST_LAMBDA2_UNARY_LAMBDA(*, lambda2_detail::dereference)
0222
0223 BOOST_LAMBDA2_UNARY_LAMBDA(++, lambda2_detail::increment)
0224 BOOST_LAMBDA2_UNARY_LAMBDA(--, lambda2_detail::decrement)
0225
0226 BOOST_LAMBDA2_POSTFIX_LAMBDA(++, lambda2_detail::postfix_increment)
0227 BOOST_LAMBDA2_POSTFIX_LAMBDA(--, lambda2_detail::postfix_decrement)
0228
0229
0230
0231 BOOST_LAMBDA2_BINARY_LAMBDA(+=, lambda2_detail::plus_equal)
0232 BOOST_LAMBDA2_BINARY_LAMBDA(-=, lambda2_detail::minus_equal)
0233 BOOST_LAMBDA2_BINARY_LAMBDA(*=, lambda2_detail::multiplies_equal)
0234 BOOST_LAMBDA2_BINARY_LAMBDA(/=, lambda2_detail::divides_equal)
0235 BOOST_LAMBDA2_BINARY_LAMBDA(%=, lambda2_detail::modulus_equal)
0236 BOOST_LAMBDA2_BINARY_LAMBDA(&=, lambda2_detail::bit_and_equal)
0237 BOOST_LAMBDA2_BINARY_LAMBDA(|=, lambda2_detail::bit_or_equal)
0238 BOOST_LAMBDA2_BINARY_LAMBDA(^=, lambda2_detail::bit_xor_equal)
0239 BOOST_LAMBDA2_BINARY_LAMBDA(<<=, lambda2_detail::left_shift_equal)
0240 BOOST_LAMBDA2_BINARY_LAMBDA(>>=, lambda2_detail::right_shift_equal)
0241
0242
0243
0244 template<class A, class = std::enable_if_t<!lambda2_detail::is_stream<A>::value>,
0245 class B, class = lambda2_detail::enable_binary_lambda<A, B>>
0246 auto operator<<( A&& a, B&& b )
0247 {
0248 return std::bind( lambda2_detail::left_shift(), std::forward<A>(a), std::forward<B>(b) );
0249 }
0250
0251 template<class A, class = std::enable_if_t<lambda2_detail::is_stream<A>::value>,
0252 class B, class = lambda2_detail::enable_unary_lambda<B>>
0253 auto operator<<( A& a, B&& b )
0254 {
0255 return std::bind( lambda2_detail::left_shift(), std::ref(a), std::forward<B>(b) );
0256 }
0257
0258
0259
0260 template<class A, class = std::enable_if_t<!lambda2_detail::is_stream<A>::value>,
0261 class B, class = lambda2_detail::enable_binary_lambda<A, B>>
0262 auto operator>>( A&& a, B&& b )
0263 {
0264 return std::bind( lambda2_detail::right_shift(), std::forward<A>(a), std::forward<B>(b) );
0265 }
0266
0267 template<class A, class = std::enable_if_t<lambda2_detail::is_stream<A>::value>,
0268 class B, class = lambda2_detail::enable_unary_lambda<B>>
0269 auto operator>>( A& a, B&& b )
0270 {
0271 return std::bind( lambda2_detail::right_shift(), std::ref(a), std::forward<B>(b) );
0272 }
0273
0274
0275
0276 template<class A, class B, class = lambda2_detail::enable_unary_lambda<A>>
0277 auto operator->*( A&& a, B&& b )
0278 {
0279 return std::bind( std::forward<B>(b), std::forward<A>(a) );
0280 }
0281
0282 }
0283 }
0284
0285 #endif