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 16 #ifndef BOOST_LOG_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED_ 17 #define BOOST_LOG_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED_ 18 19 #include <boost/mpl/has_xxx.hpp> 20 #include <boost/log/detail/config.hpp> 21 22 #if defined(BOOST_NO_SFINAE) || defined(BOOST_MPL_CFG_NO_HAS_XXX) 23 # if !defined(BOOST_LOG_NO_FUNCTION_TRAITS) 24 # define BOOST_LOG_NO_FUNCTION_TRAITS 25 # endif 26 #else 27 28 #include <boost/mpl/int.hpp> 29 #include <boost/mpl/front.hpp> 30 #include <boost/mpl/pop_front.hpp> 31 #include <boost/type_traits/remove_cv.hpp> 32 #include <boost/type_traits/remove_reference.hpp> 33 #include <boost/function_types/function_arity.hpp> 34 #include <boost/function_types/parameter_types.hpp> 35 #include <boost/function_types/is_nonmember_callable_builtin.hpp> 36 #include <boost/log/detail/header.hpp> 37 38 #ifdef BOOST_HAS_PRAGMA_ONCE 39 #pragma once 40 #endif 41 42 namespace boost { 43 44 BOOST_LOG_OPEN_NAMESPACE 45 46 namespace aux { 47 48 // A number of traits to deal with functors 49 BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_argument_type, argument_type, false) 50 BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_first_argument_type, first_argument_type, false) 51 BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_second_argument_type, second_argument_type, false) 52 BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_arg1_type, arg1_type, false) 53 BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_arg2_type, arg2_type, false) 54 55 namespace has_arity_no_adl { 56 57 typedef char yes_type; 58 struct no_type 59 { 60 char dummy[2]; 61 }; 62 63 template< typename FunT, int ArityV = FunT::arity > 64 struct checker 65 { 66 }; 67 68 template< typename FunT > 69 yes_type has_arity_impl(FunT const&, checker< FunT >*); 70 template< typename FunT > 71 no_type has_arity_impl(FunT const&, ...); 72 73 } // namespace has_arity_no_adl 74 75 //! The metafunction detects if the type has an arity static constant member 76 template< typename FunT > 77 struct has_arity 78 { 79 static FunT const& get_FunT(); 80 81 enum value_t { value = (sizeof(has_arity_no_adl::has_arity_impl(get_FunT(), 0)) == sizeof(has_arity_no_adl::yes_type)) }; 82 typedef mpl::bool_< value > type; 83 }; 84 85 //! The metafunction results in an unqualified type with removed reference 86 template< typename T > 87 struct root_type : 88 public remove_cv< 89 typename remove_reference< 90 T 91 >::type 92 > 93 { 94 }; 95 96 template< 97 typename FunT, 98 bool = function_types::is_nonmember_callable_builtin< FunT >::value, 99 bool = has_argument_type< FunT >::value, 100 bool = has_first_argument_type< FunT >::value, 101 bool = has_arg1_type< FunT >::value 102 > 103 struct first_argument_type_of_impl 104 { 105 }; 106 template< typename FunT > 107 struct first_argument_type_of_impl< FunT, true, false, false, false > 108 { 109 typedef typename root_type< 110 typename mpl::front< 111 typename function_types::parameter_types< FunT >::type 112 >::type 113 >::type type; 114 }; 115 template< typename FunT, bool HasFirstArgumentV, bool HasArg1V > 116 struct first_argument_type_of_impl< FunT, false, true, HasFirstArgumentV, HasArg1V > 117 { 118 typedef typename root_type< 119 typename FunT::argument_type 120 >::type type; 121 }; 122 template< typename FunT, bool HasArg1V > 123 struct first_argument_type_of_impl< FunT, false, false, true, HasArg1V > 124 { 125 typedef typename root_type< 126 typename FunT::first_argument_type 127 >::type type; 128 }; 129 template< typename FunT > 130 struct first_argument_type_of_impl< FunT, false, false, false, true > 131 { 132 typedef typename root_type< 133 typename FunT::arg1_type 134 >::type type; 135 }; 136 137 //! The metafunction returns the first argument type of a function 138 template< typename FunT > 139 struct first_argument_type_of : 140 public first_argument_type_of_impl< FunT > 141 { 142 }; 143 144 145 template< 146 typename FunT, 147 bool = function_types::is_nonmember_callable_builtin< FunT >::value, 148 bool = has_second_argument_type< FunT >::value, 149 bool = has_arg2_type< FunT >::value 150 > 151 struct second_argument_type_of_impl 152 { 153 }; 154 template< typename FunT > 155 struct second_argument_type_of_impl< FunT, true, false, false > 156 { 157 typedef typename root_type< 158 typename mpl::front< 159 typename mpl::pop_front< 160 typename function_types::parameter_types< FunT >::type 161 >::type 162 >::type 163 >::type type; 164 }; 165 template< typename FunT, bool HasArg2V > 166 struct second_argument_type_of_impl< FunT, false, true, HasArg2V > 167 { 168 typedef typename root_type< 169 typename FunT::second_argument_type 170 >::type type; 171 }; 172 template< typename FunT > 173 struct second_argument_type_of_impl< FunT, false, false, true > 174 { 175 typedef typename root_type< 176 typename FunT::arg2_type 177 >::type type; 178 }; 179 180 //! The metafunction returns the second argument type of a function 181 template< typename FunT > 182 struct second_argument_type_of : 183 public second_argument_type_of_impl< FunT > 184 { 185 }; 186 187 188 template< 189 typename FunT, 190 bool = function_types::is_nonmember_callable_builtin< FunT >::value, 191 bool = has_arity< FunT >::value, 192 bool = has_argument_type< FunT >::value, 193 bool = has_second_argument_type< FunT >::value 194 > 195 struct arity_of_impl 196 { 197 }; 198 template< typename FunT > 199 struct arity_of_impl< FunT, true, false, false, false > : 200 public function_types::function_arity< FunT > 201 { 202 }; 203 template< typename FunT, bool HasArgumentTypeV, bool HasSecondArgumentTypeV > 204 struct arity_of_impl< FunT, false, true, HasArgumentTypeV, HasSecondArgumentTypeV > : 205 public mpl::int_< FunT::arity > 206 { 207 }; 208 template< typename FunT, bool HasArgumentTypeV > 209 struct arity_of_impl< FunT, false, false, HasArgumentTypeV, true > : 210 public mpl::int_< 2 > 211 { 212 }; 213 template< typename FunT > 214 struct arity_of_impl< FunT, false, false, true, false > : 215 public mpl::int_< 1 > 216 { 217 }; 218 219 //! The metafunction returns the arity of a function 220 template< typename FunT > 221 struct arity_of : 222 public arity_of_impl< FunT > 223 { 224 }; 225 226 } // namespace aux 227 228 BOOST_LOG_CLOSE_NAMESPACE // namespace log 229 230 } // namespace boost 231 232 #include <boost/log/detail/footer.hpp> 233 234 #endif // defined(BOOST_NO_SFINAE) || defined(BOOST_MPL_CFG_NO_HAS_XXX) 235 236 #endif // BOOST_LOG_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED_ 237