Back to home page

EIC code displayed by LXR

 
 

    


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 // Copyright 2020, 2021 Peter Dimov
0005 // Distributed under the Boost Software License, Version 1.0.
0006 // https://www.boost.org/LICENSE_1_0.txt
0007 
0008 #include <functional>
0009 #include <type_traits>
0010 #include <utility>
0011 #include <tuple>
0012 #include <cstddef>
0013 #include <iosfwd>
0014 
0015 // Same format as BOOST_VERSION:
0016 //   major * 100000 + minor * 100 + patch
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 } // namespace lambda2_detail
0044 
0045 // placeholders
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 // first, second
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 } // namespace lambda2
0084 } // namespace boost
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 } // namespace std
0094 
0095 namespace boost
0096 {
0097 namespace lambda2
0098 {
0099 
0100 namespace lambda2_detail
0101 {
0102 
0103 // additional function objects
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 // operators
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 } // namespace lambda2_detail
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 // standard
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 // additional
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 // compound assignment
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 // operator<<
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 // operator>>
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 // operator->*
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 } // namespace lambda2
0283 } // namespace boost
0284 
0285 #endif // #ifndef BOOST_LAMBDA2_LAMBDA2_HPP_INCLUDED