File indexing completed on 2025-01-18 09:39:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef BOOST_LAMBDA_LAMBDA_FUNCTORS_HPP
0014 #define BOOST_LAMBDA_LAMBDA_FUNCTORS_HPP
0015
0016 #include <boost/config.hpp>
0017 #include <boost/detail/workaround.hpp>
0018 #include <boost/utility/result_of.hpp>
0019
0020 #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
0021
0022 #include <boost/mpl/or.hpp>
0023 #include <boost/utility/enable_if.hpp>
0024 #include <boost/type_traits/is_array.hpp>
0025
0026 #define BOOST_LAMBDA_DISABLE_IF_ARRAY1(A1, R1)\
0027 typename lazy_disable_if<is_array<A1>, typename R1 >::type
0028 #define BOOST_LAMBDA_DISABLE_IF_ARRAY2(A1, A2, R1, R2) \
0029 typename lazy_disable_if<mpl::or_<is_array<A1>, is_array<A2> >, typename R1, R2 >::type
0030 #define BOOST_LAMBDA_DISABLE_IF_ARRAY3(A1, A2, A3, R1, R2, R3) \
0031 typename lazy_disable_if<mpl::or_<is_array<A1>, is_array<A2>, is_array<A3> >, typename R1, R2, R3 >::type
0032
0033 #else
0034
0035 #define BOOST_LAMBDA_DISABLE_IF_ARRAY1(A1, R1) typename R1::type
0036 #define BOOST_LAMBDA_DISABLE_IF_ARRAY2(A1, A2, R1, R2) typename R1, R2::type
0037 #define BOOST_LAMBDA_DISABLE_IF_ARRAY3(A1, A2, A3, R1, R2, R3) typename R1, R2, R3::type
0038
0039 #endif
0040
0041 namespace boost {
0042 namespace lambda {
0043
0044
0045
0046
0047
0048
0049 namespace detail {
0050 namespace {
0051
0052 static const null_type constant_null_type = null_type();
0053
0054 }
0055 }
0056
0057 class unused {};
0058
0059 #define cnull_type() detail::constant_null_type
0060
0061
0062
0063
0064
0065 namespace detail {
0066 template<int N, class Tuple> struct get_element_or_null_type {
0067 typedef typename
0068 detail::tuple_element_as_reference<N, Tuple>::type type;
0069 };
0070 template<int N> struct get_element_or_null_type<N, null_type> {
0071 typedef null_type type;
0072 };
0073 }
0074
0075 template <int I> struct placeholder;
0076
0077 template<> struct placeholder<FIRST> {
0078
0079 template<class SigArgs> struct sig {
0080 typedef typename detail::get_element_or_null_type<0, SigArgs>::type type;
0081 };
0082
0083 template<class RET, CALL_TEMPLATE_ARGS>
0084 RET call(CALL_FORMAL_ARGS) const {
0085 BOOST_STATIC_ASSERT(boost::is_reference<RET>::value);
0086 CALL_USE_ARGS;
0087 return a;
0088 }
0089 };
0090
0091 template<> struct placeholder<SECOND> {
0092
0093 template<class SigArgs> struct sig {
0094 typedef typename detail::get_element_or_null_type<1, SigArgs>::type type;
0095 };
0096
0097 template<class RET, CALL_TEMPLATE_ARGS>
0098 RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return b; }
0099 };
0100
0101 template<> struct placeholder<THIRD> {
0102
0103 template<class SigArgs> struct sig {
0104 typedef typename detail::get_element_or_null_type<2, SigArgs>::type type;
0105 };
0106
0107 template<class RET, CALL_TEMPLATE_ARGS>
0108 RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return c; }
0109 };
0110
0111 template<> struct placeholder<EXCEPTION> {
0112
0113 template<class SigArgs> struct sig {
0114 typedef typename detail::get_element_or_null_type<3, SigArgs>::type type;
0115 };
0116
0117 template<class RET, CALL_TEMPLATE_ARGS>
0118 RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return env; }
0119 };
0120
0121 typedef const lambda_functor<placeholder<FIRST> > placeholder1_type;
0122 typedef const lambda_functor<placeholder<SECOND> > placeholder2_type;
0123 typedef const lambda_functor<placeholder<THIRD> > placeholder3_type;
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0134 #pragma warning(push)
0135 #pragma warning(disable:4512)
0136 #endif
0137
0138
0139 template <class T>
0140 class lambda_functor : public T
0141 {
0142
0143 BOOST_STATIC_CONSTANT(int, arity_bits = get_arity<T>::value);
0144
0145 public:
0146 typedef T inherited;
0147
0148 lambda_functor() {}
0149 lambda_functor(const lambda_functor& l) : inherited(l) {}
0150
0151 lambda_functor(const T& t) : inherited(t) {}
0152
0153 template <class SigArgs> struct sig {
0154 typedef typename inherited::template
0155 sig<typename SigArgs::tail_type>::type type;
0156 };
0157
0158
0159
0160
0161 typedef typename
0162 inherited::template sig<null_type>::type
0163 nullary_return_type;
0164
0165
0166 template <class Sig> struct result;
0167 template <class F>
0168 struct result<F()> {
0169 typedef nullary_return_type type;
0170 };
0171 template <class F, class A>
0172 struct result<F(A)> {
0173 typedef typename sig<tuple<F, A> >::type type;
0174 };
0175 template <class F, class A, class B>
0176 struct result<F(A, B)> {
0177 typedef typename sig<tuple<F, A, B> >::type type;
0178 };
0179 template <class F, class A, class B, class C>
0180 struct result<F(A, B, C)> {
0181 typedef typename sig<tuple<F, A, B, C> >::type type;
0182 };
0183
0184 nullary_return_type operator()() const {
0185 return inherited::template
0186 call<nullary_return_type>
0187 (cnull_type(), cnull_type(), cnull_type(), cnull_type());
0188 }
0189
0190 template<class A>
0191 typename inherited::template sig<tuple<A&> >::type
0192 operator()(A& a) const {
0193 return inherited::template call<
0194 typename inherited::template sig<tuple<A&> >::type
0195 >(a, cnull_type(), cnull_type(), cnull_type());
0196 }
0197
0198 template<class A>
0199 BOOST_LAMBDA_DISABLE_IF_ARRAY1(A, inherited::template sig<tuple<A const&> >)
0200 operator()(A const& a) const {
0201 return inherited::template call<
0202 typename inherited::template sig<tuple<A const&> >::type
0203 >(a, cnull_type(), cnull_type(), cnull_type());
0204 }
0205
0206 template<class A, class B>
0207 typename inherited::template sig<tuple<A&, B&> >::type
0208 operator()(A& a, B& b) const {
0209 return inherited::template call<
0210 typename inherited::template sig<tuple<A&, B&> >::type
0211 >(a, b, cnull_type(), cnull_type());
0212 }
0213
0214 template<class A, class B>
0215 BOOST_LAMBDA_DISABLE_IF_ARRAY2(A, B, inherited::template sig<tuple<A const&, B&> >)
0216 operator()(A const& a, B& b) const {
0217 return inherited::template call<
0218 typename inherited::template sig<tuple<A const&, B&> >::type
0219 >(a, b, cnull_type(), cnull_type());
0220 }
0221
0222 template<class A, class B>
0223 BOOST_LAMBDA_DISABLE_IF_ARRAY2(A, B, inherited::template sig<tuple<A&, B const&> >)
0224 operator()(A& a, B const& b) const {
0225 return inherited::template call<
0226 typename inherited::template sig<tuple<A&, B const&> >::type
0227 >(a, b, cnull_type(), cnull_type());
0228 }
0229
0230 template<class A, class B>
0231 BOOST_LAMBDA_DISABLE_IF_ARRAY2(A, B, inherited::template sig<tuple<A const&, B const&> >)
0232 operator()(A const& a, B const& b) const {
0233 return inherited::template call<
0234 typename inherited::template sig<tuple<A const&, B const&> >::type
0235 >(a, b, cnull_type(), cnull_type());
0236 }
0237
0238 template<class A, class B, class C>
0239 typename inherited::template sig<tuple<A&, B&, C&> >::type
0240 operator()(A& a, B& b, C& c) const
0241 {
0242 return inherited::template call<
0243 typename inherited::template sig<tuple<A&, B&, C&> >::type
0244 >(a, b, c, cnull_type());
0245 }
0246
0247 template<class A, class B, class C>
0248 BOOST_LAMBDA_DISABLE_IF_ARRAY3(A, B, C, inherited::template sig<tuple<A const&, B const&, C const&> >)
0249 operator()(A const& a, B const& b, C const& c) const
0250 {
0251 return inherited::template call<
0252 typename inherited::template sig<tuple<A const&, B const&, C const&> >::type
0253 >(a, b, c, cnull_type());
0254 }
0255
0256
0257 template<CALL_TEMPLATE_ARGS>
0258 typename inherited::template sig<tuple<CALL_REFERENCE_TYPES> >::type
0259 internal_call(CALL_FORMAL_ARGS) const {
0260 return inherited::template
0261 call<typename inherited::template
0262 sig<tuple<CALL_REFERENCE_TYPES> >::type>(CALL_ACTUAL_ARGS);
0263 }
0264
0265 template<class A>
0266 const lambda_functor<lambda_functor_base<
0267 other_action<assignment_action>,
0268 boost::tuple<lambda_functor,
0269 typename const_copy_argument <const A>::type> > >
0270 operator=(const A& a) const {
0271 return lambda_functor_base<
0272 other_action<assignment_action>,
0273 boost::tuple<lambda_functor,
0274 typename const_copy_argument <const A>::type> >
0275 ( boost::tuple<lambda_functor,
0276 typename const_copy_argument <const A>::type>(*this, a) );
0277 }
0278
0279 template<class A>
0280 const lambda_functor<lambda_functor_base<
0281 other_action<subscript_action>,
0282 boost::tuple<lambda_functor,
0283 typename const_copy_argument <const A>::type> > >
0284 operator[](const A& a) const {
0285 return lambda_functor_base<
0286 other_action<subscript_action>,
0287 boost::tuple<lambda_functor,
0288 typename const_copy_argument <const A>::type> >
0289 ( boost::tuple<lambda_functor,
0290 typename const_copy_argument <const A>::type>(*this, a ) );
0291 }
0292 };
0293
0294 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0295 #pragma warning(pop)
0296 #endif
0297
0298 }
0299 }
0300
0301 namespace boost {
0302
0303 #if !defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_NO_CXX11_DECLTYPE)
0304
0305 template<class T>
0306 struct result_of<boost::lambda::lambda_functor<T>()>
0307 {
0308 typedef typename boost::lambda::lambda_functor<T>::nullary_return_type type;
0309 };
0310
0311 template<class T>
0312 struct result_of<const boost::lambda::lambda_functor<T>()>
0313 {
0314 typedef typename boost::lambda::lambda_functor<T>::nullary_return_type type;
0315 };
0316
0317 #endif
0318
0319 template<class T>
0320 struct tr1_result_of<boost::lambda::lambda_functor<T>()>
0321 {
0322 typedef typename boost::lambda::lambda_functor<T>::nullary_return_type type;
0323 };
0324
0325 template<class T>
0326 struct tr1_result_of<const boost::lambda::lambda_functor<T>()>
0327 {
0328 typedef typename boost::lambda::lambda_functor<T>::nullary_return_type type;
0329 };
0330
0331 }
0332
0333
0334
0335 #include <boost/is_placeholder.hpp>
0336
0337 namespace boost
0338 {
0339
0340 template<> struct is_placeholder< lambda::lambda_functor< lambda::placeholder<lambda::FIRST> > >
0341 {
0342 enum _vt { value = 1 };
0343 };
0344
0345 template<> struct is_placeholder< lambda::lambda_functor< lambda::placeholder<lambda::SECOND> > >
0346 {
0347 enum _vt { value = 2 };
0348 };
0349
0350 template<> struct is_placeholder< lambda::lambda_functor< lambda::placeholder<lambda::THIRD> > >
0351 {
0352 enum _vt { value = 3 };
0353 };
0354
0355 }
0356
0357 #endif