Chris@16: /* Chris@101: * Copyright Andrey Semashev 2007 - 2015. Chris@16: * Distributed under the Boost Software License, Version 1.0. Chris@16: * (See accompanying file LICENSE_1_0.txt or copy at Chris@16: * http://www.boost.org/LICENSE_1_0.txt) Chris@16: */ Chris@16: /*! Chris@16: * \file function_traits.hpp Chris@16: * \author Andrey Semashev Chris@16: * \date 30.08.2009 Chris@16: * Chris@16: * \brief This header is the Boost.Log library implementation, see the library documentation Chris@16: * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html. Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_LOG_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED_ Chris@16: #define BOOST_LOG_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED_ Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #if defined(BOOST_NO_SFINAE) || defined(BOOST_MPL_CFG_NO_HAS_XXX) Chris@16: # if !defined(BOOST_LOG_NO_FUNCTION_TRAITS) Chris@16: # define BOOST_LOG_NO_FUNCTION_TRAITS Chris@16: # endif Chris@16: #else Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #ifdef BOOST_HAS_PRAGMA_ONCE Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: BOOST_LOG_OPEN_NAMESPACE Chris@16: Chris@16: namespace aux { Chris@16: Chris@16: // A number of traits to deal with functors Chris@16: BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_argument_type, argument_type, false) Chris@16: BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_first_argument_type, first_argument_type, false) Chris@16: BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_second_argument_type, second_argument_type, false) Chris@16: BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_arg1_type, arg1_type, false) Chris@16: BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_arg2_type, arg2_type, false) Chris@16: Chris@16: namespace has_arity_no_adl { Chris@16: Chris@16: typedef char yes_type; Chris@16: struct no_type Chris@16: { Chris@16: char dummy[2]; Chris@16: }; Chris@16: Chris@16: template< typename FunT, int ArityV = FunT::arity > Chris@16: struct checker Chris@16: { Chris@16: }; Chris@16: Chris@16: template< typename FunT > Chris@16: yes_type has_arity_impl(FunT const&, checker< FunT >*); Chris@16: template< typename FunT > Chris@16: no_type has_arity_impl(FunT const&, ...); Chris@16: Chris@16: } // namespace has_arity_no_adl Chris@16: Chris@16: //! The metafunction detects if the type has an arity static constant member Chris@16: template< typename FunT > Chris@16: struct has_arity Chris@16: { Chris@16: static FunT const& get_FunT(); Chris@16: Chris@16: enum value_t { value = (sizeof(has_arity_no_adl::has_arity_impl(get_FunT(), 0)) == sizeof(has_arity_no_adl::yes_type)) }; Chris@16: typedef mpl::bool_< value > type; Chris@16: }; Chris@16: Chris@16: //! The metafunction results in an unqualified type with removed reference Chris@16: template< typename T > Chris@16: struct root_type : Chris@16: public remove_cv< Chris@16: typename remove_reference< Chris@16: T Chris@16: >::type Chris@16: > Chris@16: { Chris@16: }; Chris@16: Chris@16: template< Chris@16: typename FunT, Chris@16: bool = function_types::is_nonmember_callable_builtin< FunT >::value, Chris@16: bool = has_argument_type< FunT >::value, Chris@16: bool = has_first_argument_type< FunT >::value, Chris@16: bool = has_arg1_type< FunT >::value Chris@16: > Chris@16: struct first_argument_type_of_impl Chris@16: { Chris@16: }; Chris@16: template< typename FunT > Chris@16: struct first_argument_type_of_impl< FunT, true, false, false, false > Chris@16: { Chris@16: typedef typename root_type< Chris@16: typename mpl::front< Chris@16: typename function_types::parameter_types< FunT >::type Chris@16: >::type Chris@16: >::type type; Chris@16: }; Chris@16: template< typename FunT, bool HasFirstArgumentV, bool HasArg1V > Chris@16: struct first_argument_type_of_impl< FunT, false, true, HasFirstArgumentV, HasArg1V > Chris@16: { Chris@16: typedef typename root_type< Chris@16: typename FunT::argument_type Chris@16: >::type type; Chris@16: }; Chris@16: template< typename FunT, bool HasArg1V > Chris@16: struct first_argument_type_of_impl< FunT, false, false, true, HasArg1V > Chris@16: { Chris@16: typedef typename root_type< Chris@16: typename FunT::first_argument_type Chris@16: >::type type; Chris@16: }; Chris@16: template< typename FunT > Chris@16: struct first_argument_type_of_impl< FunT, false, false, false, true > Chris@16: { Chris@16: typedef typename root_type< Chris@16: typename FunT::arg1_type Chris@16: >::type type; Chris@16: }; Chris@16: Chris@16: //! The metafunction returns the first argument type of a function Chris@16: template< typename FunT > Chris@16: struct first_argument_type_of : Chris@16: public first_argument_type_of_impl< FunT > Chris@16: { Chris@16: }; Chris@16: Chris@16: Chris@16: template< Chris@16: typename FunT, Chris@16: bool = function_types::is_nonmember_callable_builtin< FunT >::value, Chris@16: bool = has_second_argument_type< FunT >::value, Chris@16: bool = has_arg2_type< FunT >::value Chris@16: > Chris@16: struct second_argument_type_of_impl Chris@16: { Chris@16: }; Chris@16: template< typename FunT > Chris@16: struct second_argument_type_of_impl< FunT, true, false, false > Chris@16: { Chris@16: typedef typename root_type< Chris@16: typename mpl::front< Chris@16: typename mpl::pop_front< Chris@16: typename function_types::parameter_types< FunT >::type Chris@16: >::type Chris@16: >::type Chris@16: >::type type; Chris@16: }; Chris@16: template< typename FunT, bool HasArg2V > Chris@16: struct second_argument_type_of_impl< FunT, false, true, HasArg2V > Chris@16: { Chris@16: typedef typename root_type< Chris@16: typename FunT::second_argument_type Chris@16: >::type type; Chris@16: }; Chris@16: template< typename FunT > Chris@16: struct second_argument_type_of_impl< FunT, false, false, true > Chris@16: { Chris@16: typedef typename root_type< Chris@16: typename FunT::arg2_type Chris@16: >::type type; Chris@16: }; Chris@16: Chris@16: //! The metafunction returns the second argument type of a function Chris@16: template< typename FunT > Chris@16: struct second_argument_type_of : Chris@16: public second_argument_type_of_impl< FunT > Chris@16: { Chris@16: }; Chris@16: Chris@16: Chris@16: template< Chris@16: typename FunT, Chris@16: bool = function_types::is_nonmember_callable_builtin< FunT >::value, Chris@16: bool = has_arity< FunT >::value, Chris@16: bool = has_argument_type< FunT >::value, Chris@16: bool = has_second_argument_type< FunT >::value Chris@16: > Chris@16: struct arity_of_impl Chris@16: { Chris@16: }; Chris@16: template< typename FunT > Chris@16: struct arity_of_impl< FunT, true, false, false, false > : Chris@16: public function_types::function_arity< FunT > Chris@16: { Chris@16: }; Chris@16: template< typename FunT, bool HasArgumentTypeV, bool HasSecondArgumentTypeV > Chris@16: struct arity_of_impl< FunT, false, true, HasArgumentTypeV, HasSecondArgumentTypeV > : Chris@16: public mpl::int_< FunT::arity > Chris@16: { Chris@16: }; Chris@16: template< typename FunT, bool HasArgumentTypeV > Chris@16: struct arity_of_impl< FunT, false, false, HasArgumentTypeV, true > : Chris@16: public mpl::int_< 2 > Chris@16: { Chris@16: }; Chris@16: template< typename FunT > Chris@16: struct arity_of_impl< FunT, false, false, true, false > : Chris@16: public mpl::int_< 1 > Chris@16: { Chris@16: }; Chris@16: Chris@16: //! The metafunction returns the arity of a function Chris@16: template< typename FunT > Chris@16: struct arity_of : Chris@16: public arity_of_impl< FunT > Chris@16: { Chris@16: }; Chris@16: Chris@16: } // namespace aux Chris@16: Chris@16: BOOST_LOG_CLOSE_NAMESPACE // namespace log Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // defined(BOOST_NO_SFINAE) || defined(BOOST_MPL_CFG_NO_HAS_XXX) Chris@16: Chris@16: #endif // BOOST_LOG_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED_