function_traits.hpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /*
  2. * Copyright Andrey Semashev 2007 - 2015.
  3. * Distributed under the Boost Software License, Version 1.0.
  4. * (See accompanying file LICENSE_1_0.txt or copy at
  5. * http://www.boost.org/LICENSE_1_0.txt)
  6. */
  7. /*!
  8. * \file function_traits.hpp
  9. * \author Andrey Semashev
  10. * \date 30.08.2009
  11. *
  12. * \brief This header is the Boost.Log library implementation, see the library documentation
  13. * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
  14. */
  15. #ifndef BOOST_LOG_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED_
  16. #define BOOST_LOG_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED_
  17. #include <boost/mpl/has_xxx.hpp>
  18. #include <boost/log/detail/config.hpp>
  19. #if defined(BOOST_NO_SFINAE) || defined(BOOST_MPL_CFG_NO_HAS_XXX)
  20. # if !defined(BOOST_LOG_NO_FUNCTION_TRAITS)
  21. # define BOOST_LOG_NO_FUNCTION_TRAITS
  22. # endif
  23. #else
  24. #include <boost/mpl/int.hpp>
  25. #include <boost/mpl/front.hpp>
  26. #include <boost/mpl/pop_front.hpp>
  27. #include <boost/type_traits/remove_cv.hpp>
  28. #include <boost/type_traits/remove_reference.hpp>
  29. #include <boost/function_types/function_arity.hpp>
  30. #include <boost/function_types/parameter_types.hpp>
  31. #include <boost/function_types/is_nonmember_callable_builtin.hpp>
  32. #include <boost/log/detail/header.hpp>
  33. #ifdef BOOST_HAS_PRAGMA_ONCE
  34. #pragma once
  35. #endif
  36. namespace boost {
  37. BOOST_LOG_OPEN_NAMESPACE
  38. namespace aux {
  39. // A number of traits to deal with functors
  40. BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_argument_type, argument_type, false)
  41. BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_first_argument_type, first_argument_type, false)
  42. BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_second_argument_type, second_argument_type, false)
  43. BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_arg1_type, arg1_type, false)
  44. BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_arg2_type, arg2_type, false)
  45. namespace has_arity_no_adl {
  46. typedef char yes_type;
  47. struct no_type
  48. {
  49. char dummy[2];
  50. };
  51. template< typename FunT, int ArityV = FunT::arity >
  52. struct checker
  53. {
  54. };
  55. template< typename FunT >
  56. yes_type has_arity_impl(FunT const&, checker< FunT >*);
  57. template< typename FunT >
  58. no_type has_arity_impl(FunT const&, ...);
  59. } // namespace has_arity_no_adl
  60. //! The metafunction detects if the type has an arity static constant member
  61. template< typename FunT >
  62. struct has_arity
  63. {
  64. static FunT const& get_FunT();
  65. enum value_t { value = (sizeof(has_arity_no_adl::has_arity_impl(get_FunT(), 0)) == sizeof(has_arity_no_adl::yes_type)) };
  66. typedef mpl::bool_< value > type;
  67. };
  68. //! The metafunction results in an unqualified type with removed reference
  69. template< typename T >
  70. struct root_type :
  71. public remove_cv<
  72. typename remove_reference<
  73. T
  74. >::type
  75. >
  76. {
  77. };
  78. template<
  79. typename FunT,
  80. bool = function_types::is_nonmember_callable_builtin< FunT >::value,
  81. bool = has_argument_type< FunT >::value,
  82. bool = has_first_argument_type< FunT >::value,
  83. bool = has_arg1_type< FunT >::value
  84. >
  85. struct first_argument_type_of_impl
  86. {
  87. };
  88. template< typename FunT >
  89. struct first_argument_type_of_impl< FunT, true, false, false, false >
  90. {
  91. typedef typename root_type<
  92. typename mpl::front<
  93. typename function_types::parameter_types< FunT >::type
  94. >::type
  95. >::type type;
  96. };
  97. template< typename FunT, bool HasFirstArgumentV, bool HasArg1V >
  98. struct first_argument_type_of_impl< FunT, false, true, HasFirstArgumentV, HasArg1V >
  99. {
  100. typedef typename root_type<
  101. typename FunT::argument_type
  102. >::type type;
  103. };
  104. template< typename FunT, bool HasArg1V >
  105. struct first_argument_type_of_impl< FunT, false, false, true, HasArg1V >
  106. {
  107. typedef typename root_type<
  108. typename FunT::first_argument_type
  109. >::type type;
  110. };
  111. template< typename FunT >
  112. struct first_argument_type_of_impl< FunT, false, false, false, true >
  113. {
  114. typedef typename root_type<
  115. typename FunT::arg1_type
  116. >::type type;
  117. };
  118. //! The metafunction returns the first argument type of a function
  119. template< typename FunT >
  120. struct first_argument_type_of :
  121. public first_argument_type_of_impl< FunT >
  122. {
  123. };
  124. template<
  125. typename FunT,
  126. bool = function_types::is_nonmember_callable_builtin< FunT >::value,
  127. bool = has_second_argument_type< FunT >::value,
  128. bool = has_arg2_type< FunT >::value
  129. >
  130. struct second_argument_type_of_impl
  131. {
  132. };
  133. template< typename FunT >
  134. struct second_argument_type_of_impl< FunT, true, false, false >
  135. {
  136. typedef typename root_type<
  137. typename mpl::front<
  138. typename mpl::pop_front<
  139. typename function_types::parameter_types< FunT >::type
  140. >::type
  141. >::type
  142. >::type type;
  143. };
  144. template< typename FunT, bool HasArg2V >
  145. struct second_argument_type_of_impl< FunT, false, true, HasArg2V >
  146. {
  147. typedef typename root_type<
  148. typename FunT::second_argument_type
  149. >::type type;
  150. };
  151. template< typename FunT >
  152. struct second_argument_type_of_impl< FunT, false, false, true >
  153. {
  154. typedef typename root_type<
  155. typename FunT::arg2_type
  156. >::type type;
  157. };
  158. //! The metafunction returns the second argument type of a function
  159. template< typename FunT >
  160. struct second_argument_type_of :
  161. public second_argument_type_of_impl< FunT >
  162. {
  163. };
  164. template<
  165. typename FunT,
  166. bool = function_types::is_nonmember_callable_builtin< FunT >::value,
  167. bool = has_arity< FunT >::value,
  168. bool = has_argument_type< FunT >::value,
  169. bool = has_second_argument_type< FunT >::value
  170. >
  171. struct arity_of_impl
  172. {
  173. };
  174. template< typename FunT >
  175. struct arity_of_impl< FunT, true, false, false, false > :
  176. public function_types::function_arity< FunT >
  177. {
  178. };
  179. template< typename FunT, bool HasArgumentTypeV, bool HasSecondArgumentTypeV >
  180. struct arity_of_impl< FunT, false, true, HasArgumentTypeV, HasSecondArgumentTypeV > :
  181. public mpl::int_< FunT::arity >
  182. {
  183. };
  184. template< typename FunT, bool HasArgumentTypeV >
  185. struct arity_of_impl< FunT, false, false, HasArgumentTypeV, true > :
  186. public mpl::int_< 2 >
  187. {
  188. };
  189. template< typename FunT >
  190. struct arity_of_impl< FunT, false, false, true, false > :
  191. public mpl::int_< 1 >
  192. {
  193. };
  194. //! The metafunction returns the arity of a function
  195. template< typename FunT >
  196. struct arity_of :
  197. public arity_of_impl< FunT >
  198. {
  199. };
  200. } // namespace aux
  201. BOOST_LOG_CLOSE_NAMESPACE // namespace log
  202. } // namespace boost
  203. #include <boost/log/detail/footer.hpp>
  204. #endif // defined(BOOST_NO_SFINAE) || defined(BOOST_MPL_CFG_NO_HAS_XXX)
  205. #endif // BOOST_LOG_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED_