diff options
Diffstat (limited to 'boost/functional/overloaded_function/detail/function_type.hpp')
-rw-r--r-- | boost/functional/overloaded_function/detail/function_type.hpp | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/boost/functional/overloaded_function/detail/function_type.hpp b/boost/functional/overloaded_function/detail/function_type.hpp new file mode 100644 index 0000000000..0c28607b88 --- /dev/null +++ b/boost/functional/overloaded_function/detail/function_type.hpp @@ -0,0 +1,85 @@ + +// 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 + |