// Copyright (C) 2009-2012 Lorenzo Caminiti // Distributed under the Boost Software License, Version 1.0 // (see accompanying file LICENSE_1_0.txt or a copy at // http://www.boost.org/LICENSE_1_0.txt) // Home at http://www.boost.org/libs/functional/overloaded_function #ifndef BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_DETAIL_FUNCTION_TYPE_HPP_ #define BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_DETAIL_FUNCTION_TYPE_HPP_ #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Do not use namespace ::detail because overloaded_function is already a class. namespace boost { namespace overloaded_function_detail { // Requires: F is a monomorphic functor (i.e., has non-template `operator()`). // Returns: F's function type `result_type (arg1_type, arg2_type, ...)`. // It does not assume F typedef result_type, arg1_type, ... but needs typeof. template class functor_type { // NOTE: clang does not accept extra parenthesis `&(...)`. typedef BOOST_TYPEOF_TPL(&F::operator()) call_ptr; public: typedef typename boost::function_types::function_type< typename boost::mpl::push_front< typename boost::mpl::pop_front< // Remove functor type (1st). typename boost::function_types::parameter_types< call_ptr>::type >::type , typename boost::function_types::result_type::type >::type >::type type; }; // NOTE: When using boost::function in Boost.Typeof emulation mode, the user // has to register boost::functionN instead of boost::function in oder to // do TYPEOF(F::operator()). That is confusing, so boost::function is handled // separately so it does not require any Boost.Typeof registration at all. template struct functor_type< boost::function > { typedef F type; }; // Requires: F is a function type, pointer, reference, or monomorphic functor. // Returns: F's function type `result_type (arg1_type, arg2_type, ...)`. template struct function_type { typedef typename boost::mpl::if_, boost::mpl::identity , typename boost::mpl::if_, boost::remove_pointer , typename boost::mpl::if_, boost::remove_reference , // Else, requires that F is a functor. functor_type >::type >::type >::type ::type type; }; } } // namespace #endif // #include guard