// (C) Copyright Jonathan Turkanis 2004. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) // Disclaimer: Not a Boost library. #ifndef BOOST_IDL_INVOKER_HPP_INCLUDED #define BOOST_IDL_INVOKER_HPP_INCLUDED #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #include // BOOST_MSVC. #include #if BOOST_WORKAROUND(BOOST_MSVC, == 1310) # pragma warning(push) # pragma warning(disable:4224) // parameter previouisly defined as type #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace interfaces { namespace detail { //------------------Declations of helper templates----------------------------// template< typename Interface, typename Offset, typename Signature, int Arity = function_arity::value > struct null_invoker; template< typename Interface, typename Offset, typename Signature, typename Names, typename Advice, int Arity > struct basic_invoker; template< typename Interface, typename Offset, typename Signature, typename Names, typename Advice, int Arity > struct transforming_invoker; //------------------Derfintion of invoker-------------------------------------// // // Template Parameters: // Interface - The interface whose member function is to be invoked. // Offset - The offset within the function table of the function to be // invoked. // Signature - The signature of the function to be invoked, represented as a // function type. // Names - A type with static member functions funtion_name and param_names() // returning const char* and const char**. // Advice - A Model of the concept Advice. // template< typename Interface, typename Offset, typename Signature, typename Names, typename Category = typename advice_category< typename Interface::interface_advice >::type > struct invoker; template< typename Interface, typename Offset, typename Signature, typename Names > struct invoker : null_invoker< Interface, Offset, Signature, function_arity::value > { }; template< typename Interface, typename Offset, typename Signature, typename Names > struct invoker : basic_invoker< Interface, Offset, Signature, Names, typename Interface::interface_advice, function_arity::value > { }; template< typename Interface, typename Offset, typename Signature, typename Names > struct invoker : transforming_invoker< Interface, Offset, Signature, Names, typename Interface::interface_advice, function_arity::value > { }; //----------------------------------------------------------------------------// // // Macro: BOOST_IDL_INVOKER_ARGS(arity) // Expands to: x0, ..., xm, with m = arity - 1. // #define BOOST_IDL_INVOKER_ARGS(arity) BOOST_PP_ENUM_PARAMS(arity, x) // // Macro: BOOST_IDL_INVOKER_PARAMS(signature, arity) // Parameters: // signature - an identifier denoting a function type // arity - the arity of the function type // Expands to: An argument list of the form // // , typename nth_function_argument::type x0 // , ... // , typename nth_function_argument::type xm // // where m is arity - 1. // #define BOOST_IDL_INVOKER_PARAMS_IMPL(z, n, signature) \ , typename nth_function_argument< signature, mpl::long_ >::type \ BOOST_PP_CAT(x, n) \ /**/ #define BOOST_IDL_INVOKER_PARAMS(signature, arity) \ BOOST_PP_REPEAT(arity, BOOST_IDL_INVOKER_PARAMS_IMPL, signature) \ /**/ //------Local iteration defining specializations of null_invoker--------------// #define BOOST_PP_LOCAL_MACRO(n) \ template \ struct null_invoker { \ typedef typename add_void_pointer::type function_type; \ static typename function_result::type \ execute( const void* pv \ BOOST_IDL_INVOKER_PARAMS(Signature, n) ) \ { \ const Interface* self = \ static_cast(const_cast(pv)); \ const void* pointer = \ access::get_interface_pointer(*self); \ const function_type* f = \ reinterpret_cast( \ access::get_interface_table(*self) + Offset::value \ ); \ return (*f)( const_cast(pointer) BOOST_PP_COMMA_IF(n) \ BOOST_IDL_INVOKER_ARGS(n) ); \ } \ }; \ /**/ #define BOOST_PP_LOCAL_LIMITS (0, BOOST_IDL_FUNCTION_TRAITS_MAX_ARITY) #include BOOST_PP_LOCAL_ITERATE() //------Local iteration defining specializations of basic_invoker-------------// #define BOOST_PP_LOCAL_MACRO(n) \ template< typename Interface, typename Offset, typename Signature, \ typename Names, typename Advice > \ struct basic_invoker { \ typedef typename add_void_pointer::type function_type; \ typedef typename function_result::type result_type; \ typedef typename argument_tuple::type tuple_type; \ typedef ::boost::interfaces::detail::finalizer finalizer_type; \ typedef typename finalizer_type::after_type after_type; \ typedef typename finalizer_type::finally_type finally_type; \ static const char* function_name() { return Names::function_name(); } \ static const char** param_names() { return Names::param_names(); } \ static result_type execute( const void* pv \ BOOST_IDL_INVOKER_PARAMS(Signature, n) ) \ { \ const Interface* self = \ static_cast(const_cast(pv)); \ const Advice* advice = static_cast(self); \ after_type after = &Advice::after; \ finally_type finally = &Advice::finally; \ tuple_type tuple = tuple_type(BOOST_IDL_INVOKER_ARGS(n)); \ finalizer_type finalizer( advice, after, finally, tuple, \ function_name(), n, param_names() ); \ const void* pointer = \ access::get_interface_pointer(*self); \ const function_type* f = \ reinterpret_cast( \ access::get_interface_table(*self) + Offset::value \ ); \ advice->before(tuple, function_name(), n, param_names()); \ if ( is_void::value && \ advice->cancel(tuple, function_name(), n, param_names()) ) \ { return return_void(); } \ try { \ return (*f)( const_cast(pointer) \ BOOST_PP_COMMA_IF(n) \ BOOST_IDL_INVOKER_ARGS(n) ); \ } catch (std::exception& e) { \ finalizer.set_error(); \ advice->error(e, tuple, function_name(), n, param_names()); \ throw e; \ } \ } \ }; \ /**/ #define BOOST_PP_LOCAL_LIMITS (0, BOOST_IDL_FUNCTION_TRAITS_MAX_ARITY) #include BOOST_PP_LOCAL_ITERATE() //------Local iteration defining specializations of transforming_invoker------// #define BOOST_PP_LOCAL_MACRO(n) \ template< typename Interface, typename Offset, typename Signature, \ typename Names, typename Advice > \ struct transforming_invoker { \ typedef typename add_void_pointer::type function_type; \ typedef typename function_result::type result_type; \ typedef typename argument_tuple::type tuple_type; \ typedef ::boost::interfaces::detail::finalizer finalizer_type; \ typedef typename finalizer_type::after_type after_type; \ typedef typename finalizer_type::finally_type finally_type; \ static const char* function_name() { return Names::function_name(); } \ static const char** param_names() { return Names::param_names(); } \ static result_type execute( const void* pv \ BOOST_IDL_INVOKER_PARAMS(Signature, n) ) \ { \ const Interface* self = \ static_cast(const_cast(pv)); \ const Advice* advice = static_cast(self); \ after_type after = &Advice::after; \ finally_type finally = &Advice::finally; \ tuple_type tuple = tuple_type(BOOST_IDL_INVOKER_ARGS(n)); \ finalizer_type finalizer( advice, after, finally, tuple, \ function_name(), n, param_names() ); \ const void* pointer = \ access::get_interface_pointer(*self); \ const function_type* f = \ reinterpret_cast( \ access::get_interface_table(*self) + Offset::value \ ); \ advice->before(tuple, function_name(), n, param_names()); \ if ( is_void::value && \ advice->cancel(tuple, function_name(), n, param_names()) ) \ { return return_void(); } \ try { \ return advice->transform( \ (*f)( const_cast(pointer) \ BOOST_PP_COMMA_IF(n) \ BOOST_IDL_INVOKER_ARGS(n) ), \ tuple, function_name(), n, param_names() ); \ } catch (std::exception& e) { \ finalizer.set_error(); \ advice->error(e, tuple, function_name(), n, param_names()); \ throw e; \ } \ } \ }; \ /**/ #define BOOST_PP_LOCAL_LIMITS (0, BOOST_IDL_FUNCTION_TRAITS_MAX_ARITY) #include BOOST_PP_LOCAL_ITERATE() } } } // End namespaces detail, interfaces, boost. #endif // #ifndef BOOST_IDL_INVOKER_HPP_INCLUDED