86 lines
3.2 KiB
C++
86 lines
3.2 KiB
C++
|
|
// 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 <boost/function_types/is_function.hpp>
|
|
#include <boost/function_types/is_function_pointer.hpp>
|
|
#include <boost/function_types/is_function_reference.hpp>
|
|
#include <boost/function_types/function_type.hpp>
|
|
#include <boost/function_types/parameter_types.hpp>
|
|
#include <boost/function_types/result_type.hpp>
|
|
#include <boost/type_traits/remove_pointer.hpp>
|
|
#include <boost/type_traits/remove_reference.hpp>
|
|
#include <boost/function.hpp>
|
|
#include <boost/mpl/if.hpp>
|
|
#include <boost/mpl/identity.hpp>
|
|
#include <boost/mpl/pop_front.hpp>
|
|
#include <boost/mpl/push_front.hpp>
|
|
#include <boost/typeof/typeof.hpp>
|
|
|
|
// 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<typename F>
|
|
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<call_ptr>::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<typename F>
|
|
struct functor_type< boost::function<F> > {
|
|
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<typename F>
|
|
struct function_type {
|
|
typedef
|
|
typename boost::mpl::if_<boost::function_types::is_function<F>,
|
|
boost::mpl::identity<F>
|
|
,
|
|
typename boost::mpl::if_<boost::function_types::
|
|
is_function_pointer<F>,
|
|
boost::remove_pointer<F>
|
|
,
|
|
typename boost::mpl::if_<boost::function_types::
|
|
is_function_reference<F>,
|
|
boost::remove_reference<F>
|
|
, // Else, requires that F is a functor.
|
|
functor_type<F>
|
|
>::type
|
|
>::type
|
|
>::type
|
|
::type type;
|
|
};
|
|
|
|
} } // namespace
|
|
|
|
#endif // #include guard
|
|
|