1 2 // Copyright (C) 2009-2012 Lorenzo Caminiti 3 // Distributed under the Boost Software License, Version 1.0 4 // (see accompanying file LICENSE_1_0.txt or a copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 // Home at http://www.boost.org/libs/functional/overloaded_function 7 8 #ifndef BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_DETAIL_FUNCTION_TYPE_HPP_ 9 #define BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_DETAIL_FUNCTION_TYPE_HPP_ 10 11 #include <boost/function_types/is_function.hpp> 12 #include <boost/function_types/is_function_pointer.hpp> 13 #include <boost/function_types/is_function_reference.hpp> 14 #include <boost/function_types/function_type.hpp> 15 #include <boost/function_types/parameter_types.hpp> 16 #include <boost/function_types/result_type.hpp> 17 #include <boost/type_traits/remove_pointer.hpp> 18 #include <boost/type_traits/remove_reference.hpp> 19 #include <boost/function.hpp> 20 #include <boost/mpl/if.hpp> 21 #include <boost/mpl/identity.hpp> 22 #include <boost/mpl/pop_front.hpp> 23 #include <boost/mpl/push_front.hpp> 24 #include <boost/typeof/typeof.hpp> 25 26 // Do not use namespace ::detail because overloaded_function is already a class. 27 namespace boost { namespace overloaded_function_detail { 28 29 // Requires: F is a monomorphic functor (i.e., has non-template `operator()`). 30 // Returns: F's function type `result_type (arg1_type, arg2_type, ...)`. 31 // It does not assume F typedef result_type, arg1_type, ... but needs typeof. 32 template<typename F> 33 class functor_type { 34 // NOTE: clang does not accept extra parenthesis `&(...)`. 35 typedef BOOST_TYPEOF_TPL(&F::operator()) call_ptr; 36 public: 37 typedef 38 typename boost::function_types::function_type< 39 typename boost::mpl::push_front< 40 typename boost::mpl::pop_front< // Remove functor type (1st). 41 typename boost::function_types::parameter_types< 42 call_ptr>::type 43 >::type 44 , typename boost::function_types::result_type<call_ptr>::type 45 >::type 46 >::type 47 type; 48 }; 49 50 // NOTE: When using boost::function in Boost.Typeof emulation mode, the user 51 // has to register boost::functionN instead of boost::function in oder to 52 // do TYPEOF(F::operator()). That is confusing, so boost::function is handled 53 // separately so it does not require any Boost.Typeof registration at all. 54 template<typename F> 55 struct functor_type< boost::function<F> > { 56 typedef F type; 57 }; 58 59 // Requires: F is a function type, pointer, reference, or monomorphic functor. 60 // Returns: F's function type `result_type (arg1_type, arg2_type, ...)`. 61 template<typename F> 62 struct function_type { 63 typedef 64 typename boost::mpl::if_<boost::function_types::is_function<F>, 65 boost::mpl::identity<F> 66 , 67 typename boost::mpl::if_<boost::function_types:: 68 is_function_pointer<F>, 69 boost::remove_pointer<F> 70 , 71 typename boost::mpl::if_<boost::function_types:: 72 is_function_reference<F>, 73 boost::remove_reference<F> 74 , // Else, requires that F is a functor. 75 functor_type<F> 76 >::type 77 >::type 78 >::type 79 ::type type; 80 }; 81 82 } } // namespace 83 84 #endif // #include guard 85 86