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