Chris@16: // Boost Lambda Library - lambda_functors.hpp ------------------------------- Chris@16: Chris@16: // Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi) Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // For more information, see http://www.boost.org Chris@16: Chris@16: // ------------------------------------------------ Chris@16: Chris@16: #ifndef BOOST_LAMBDA_LAMBDA_FUNCTORS_HPP Chris@16: #define BOOST_LAMBDA_LAMBDA_FUNCTORS_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #if BOOST_WORKAROUND(BOOST_MSVC, == 1310) Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #define BOOST_LAMBDA_DISABLE_IF_ARRAY1(A1, R1)\ Chris@16: typename lazy_disable_if, typename R1 >::type Chris@16: #define BOOST_LAMBDA_DISABLE_IF_ARRAY2(A1, A2, R1, R2) \ Chris@16: typename lazy_disable_if, is_array >, typename R1, R2 >::type Chris@16: #define BOOST_LAMBDA_DISABLE_IF_ARRAY3(A1, A2, A3, R1, R2, R3) \ Chris@16: typename lazy_disable_if, is_array, is_array >, typename R1, R2, R3 >::type Chris@16: Chris@16: #else Chris@16: Chris@16: #define BOOST_LAMBDA_DISABLE_IF_ARRAY1(A1, R1) typename R1::type Chris@16: #define BOOST_LAMBDA_DISABLE_IF_ARRAY2(A1, A2, R1, R2) typename R1, R2::type Chris@16: #define BOOST_LAMBDA_DISABLE_IF_ARRAY3(A1, A2, A3, R1, R2, R3) typename R1, R2, R3::type Chris@16: Chris@16: #endif Chris@16: Chris@16: namespace boost { Chris@16: namespace lambda { Chris@16: Chris@16: // -- lambda_functor -------------------------------------------- Chris@16: // -------------------------------------------------------------- Chris@16: Chris@16: //inline const null_type const_null_type() { return null_type(); } Chris@16: Chris@16: namespace detail { Chris@16: namespace { Chris@16: Chris@16: static const null_type constant_null_type = null_type(); Chris@16: Chris@16: } // unnamed Chris@16: } // detail Chris@16: Chris@16: class unused {}; Chris@16: Chris@16: #define cnull_type() detail::constant_null_type Chris@16: Chris@16: // -- free variables types -------------------------------------------------- Chris@16: Chris@16: // helper to work around the case where the nullary return type deduction Chris@16: // is always performed, even though the functor is not nullary Chris@16: namespace detail { Chris@16: template struct get_element_or_null_type { Chris@16: typedef typename Chris@16: detail::tuple_element_as_reference::type type; Chris@16: }; Chris@16: template struct get_element_or_null_type { Chris@16: typedef null_type type; Chris@16: }; Chris@16: } Chris@16: Chris@16: template struct placeholder; Chris@16: Chris@16: template<> struct placeholder { Chris@16: Chris@16: template struct sig { Chris@16: typedef typename detail::get_element_or_null_type<0, SigArgs>::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: RET call(CALL_FORMAL_ARGS) const { Chris@16: BOOST_STATIC_ASSERT(boost::is_reference::value); Chris@16: CALL_USE_ARGS; // does nothing, prevents warnings for unused args Chris@16: return a; Chris@16: } Chris@16: }; Chris@16: Chris@16: template<> struct placeholder { Chris@16: Chris@16: template struct sig { Chris@16: typedef typename detail::get_element_or_null_type<1, SigArgs>::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return b; } Chris@16: }; Chris@16: Chris@16: template<> struct placeholder { Chris@16: Chris@16: template struct sig { Chris@16: typedef typename detail::get_element_or_null_type<2, SigArgs>::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return c; } Chris@16: }; Chris@16: Chris@16: template<> struct placeholder { Chris@16: Chris@16: template struct sig { Chris@16: typedef typename detail::get_element_or_null_type<3, SigArgs>::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return env; } Chris@16: }; Chris@16: Chris@16: typedef const lambda_functor > placeholder1_type; Chris@16: typedef const lambda_functor > placeholder2_type; Chris@16: typedef const lambda_functor > placeholder3_type; Chris@16: Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: Chris@16: // free variables are lambda_functors. This is to allow uniform handling with Chris@16: // other lambda_functors. Chris@16: // ------------------------------------------------------------------- Chris@16: Chris@16: #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) Chris@16: #pragma warning(push) Chris@16: #pragma warning(disable:4512) //assignment operator could not be generated Chris@16: #endif Chris@16: Chris@16: // -- lambda_functor NONE ------------------------------------------------ Chris@16: template Chris@16: class lambda_functor : public T Chris@16: { Chris@16: Chris@16: BOOST_STATIC_CONSTANT(int, arity_bits = get_arity::value); Chris@16: Chris@16: public: Chris@16: typedef T inherited; Chris@16: Chris@16: lambda_functor() {} Chris@16: lambda_functor(const lambda_functor& l) : inherited(l) {} Chris@16: Chris@16: lambda_functor(const T& t) : inherited(t) {} Chris@16: Chris@16: template struct sig { Chris@16: typedef typename inherited::template Chris@16: sig::type type; Chris@16: }; Chris@16: Chris@16: // Note that this return type deduction template is instantiated, even Chris@16: // if the nullary Chris@16: // operator() is not called at all. One must make sure that it does not fail. Chris@16: typedef typename Chris@16: inherited::template sig::type Chris@16: nullary_return_type; Chris@16: Chris@16: // Support for boost::result_of. Chris@16: template struct result; Chris@16: template Chris@16: struct result { Chris@16: typedef nullary_return_type type; Chris@16: }; Chris@16: template Chris@16: struct result { Chris@16: typedef typename sig >::type type; Chris@16: }; Chris@16: template Chris@16: struct result { Chris@16: typedef typename sig >::type type; Chris@16: }; Chris@16: template Chris@16: struct result { Chris@16: typedef typename sig >::type type; Chris@16: }; Chris@16: Chris@16: nullary_return_type operator()() const { Chris@16: return inherited::template Chris@16: call Chris@16: (cnull_type(), cnull_type(), cnull_type(), cnull_type()); Chris@16: } Chris@16: Chris@16: template Chris@16: typename inherited::template sig >::type Chris@16: operator()(A& a) const { Chris@16: return inherited::template call< Chris@16: typename inherited::template sig >::type Chris@16: >(a, cnull_type(), cnull_type(), cnull_type()); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_LAMBDA_DISABLE_IF_ARRAY1(A, inherited::template sig >) Chris@16: operator()(A const& a) const { Chris@16: return inherited::template call< Chris@16: typename inherited::template sig >::type Chris@16: >(a, cnull_type(), cnull_type(), cnull_type()); Chris@16: } Chris@16: Chris@16: template Chris@16: typename inherited::template sig >::type Chris@16: operator()(A& a, B& b) const { Chris@16: return inherited::template call< Chris@16: typename inherited::template sig >::type Chris@16: >(a, b, cnull_type(), cnull_type()); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_LAMBDA_DISABLE_IF_ARRAY2(A, B, inherited::template sig >) Chris@16: operator()(A const& a, B& b) const { Chris@16: return inherited::template call< Chris@16: typename inherited::template sig >::type Chris@16: >(a, b, cnull_type(), cnull_type()); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_LAMBDA_DISABLE_IF_ARRAY2(A, B, inherited::template sig >) Chris@16: operator()(A& a, B const& b) const { Chris@16: return inherited::template call< Chris@16: typename inherited::template sig >::type Chris@16: >(a, b, cnull_type(), cnull_type()); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_LAMBDA_DISABLE_IF_ARRAY2(A, B, inherited::template sig >) Chris@16: operator()(A const& a, B const& b) const { Chris@16: return inherited::template call< Chris@16: typename inherited::template sig >::type Chris@16: >(a, b, cnull_type(), cnull_type()); Chris@16: } Chris@16: Chris@16: template Chris@16: typename inherited::template sig >::type Chris@16: operator()(A& a, B& b, C& c) const Chris@16: { Chris@16: return inherited::template call< Chris@16: typename inherited::template sig >::type Chris@16: >(a, b, c, cnull_type()); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_LAMBDA_DISABLE_IF_ARRAY3(A, B, C, inherited::template sig >) Chris@16: operator()(A const& a, B const& b, C const& c) const Chris@16: { Chris@16: return inherited::template call< Chris@16: typename inherited::template sig >::type Chris@16: >(a, b, c, cnull_type()); Chris@16: } Chris@16: Chris@16: // for internal calls with env Chris@16: template Chris@16: typename inherited::template sig >::type Chris@16: internal_call(CALL_FORMAL_ARGS) const { Chris@16: return inherited::template Chris@16: call >::type>(CALL_ACTUAL_ARGS); Chris@16: } Chris@16: Chris@16: template Chris@16: const lambda_functor, Chris@16: boost::tuple::type> > > Chris@16: operator=(const A& a) const { Chris@16: return lambda_functor_base< Chris@16: other_action, Chris@16: boost::tuple::type> > Chris@16: ( boost::tuple::type>(*this, a) ); Chris@16: } Chris@16: Chris@16: template Chris@16: const lambda_functor, Chris@16: boost::tuple::type> > > Chris@16: operator[](const A& a) const { Chris@16: return lambda_functor_base< Chris@16: other_action, Chris@16: boost::tuple::type> > Chris@16: ( boost::tuple::type>(*this, a ) ); Chris@16: } Chris@16: }; Chris@16: Chris@16: #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) Chris@16: #pragma warning(pop) Chris@16: #endif Chris@16: Chris@16: } // namespace lambda Chris@16: } // namespace boost Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: #if !defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_NO_DECLTYPE) Chris@16: Chris@16: template Chris@16: struct result_of()> Chris@16: { Chris@16: typedef typename boost::lambda::lambda_functor::nullary_return_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct result_of()> Chris@16: { Chris@16: typedef typename boost::lambda::lambda_functor::nullary_return_type type; Chris@16: }; Chris@16: Chris@16: #endif Chris@16: Chris@16: template Chris@16: struct tr1_result_of()> Chris@16: { Chris@16: typedef typename boost::lambda::lambda_functor::nullary_return_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct tr1_result_of()> Chris@16: { Chris@16: typedef typename boost::lambda::lambda_functor::nullary_return_type type; Chris@16: }; Chris@16: Chris@16: } Chris@16: Chris@16: // is_placeholder Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: Chris@16: template<> struct is_placeholder< lambda::lambda_functor< lambda::placeholder > > Chris@16: { Chris@16: enum _vt { value = 1 }; Chris@16: }; Chris@16: Chris@16: template<> struct is_placeholder< lambda::lambda_functor< lambda::placeholder > > Chris@16: { Chris@16: enum _vt { value = 2 }; Chris@16: }; Chris@16: Chris@16: template<> struct is_placeholder< lambda::lambda_functor< lambda::placeholder > > Chris@16: { Chris@16: enum _vt { value = 3 }; Chris@16: }; Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #endif