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 parameter_tools.hpp |
9 | * \author Andrey Semashev |
10 | * \date 28.06.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_PARAMETER_TOOLS_HPP_INCLUDED_ |
17 | #define BOOST_LOG_DETAIL_PARAMETER_TOOLS_HPP_INCLUDED_ |
18 | |
19 | #include <boost/mpl/or.hpp> |
20 | #include <boost/core/enable_if.hpp> |
21 | #include <boost/parameter/keyword.hpp> |
22 | #include <boost/type_traits/is_base_of.hpp> |
23 | #include <boost/preprocessor/control/if.hpp> |
24 | #include <boost/preprocessor/comparison/equal.hpp> |
25 | #include <boost/preprocessor/repetition/enum_params.hpp> |
26 | #include <boost/preprocessor/repetition/enum_binary_params.hpp> |
27 | #include <boost/preprocessor/repetition/repeat_from_to.hpp> |
28 | #include <boost/preprocessor/facilities/intercept.hpp> |
29 | #include <boost/preprocessor/arithmetic/dec.hpp> |
30 | #include <boost/preprocessor/tuple/elem.hpp> |
31 | #include <boost/log/detail/config.hpp> |
32 | #include <boost/log/detail/sfinae_tools.hpp> |
33 | #include <boost/log/detail/header.hpp> |
34 | |
35 | #ifdef BOOST_HAS_PRAGMA_ONCE |
36 | #pragma once |
37 | #endif |
38 | |
39 | #ifndef BOOST_LOG_MAX_PARAMETER_ARGS |
40 | //! The maximum number of named arguments that are accepted by constructors and functions |
41 | #define BOOST_LOG_MAX_PARAMETER_ARGS 16 |
42 | #endif |
43 | |
44 | // The macro applies the passed macro with the specified arguments BOOST_LOG_MAX_PARAMETER_ARGS times |
45 | #define BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_GEN(macro, args)\ |
46 | public:\ |
47 | BOOST_PP_REPEAT_FROM_TO(1, BOOST_LOG_MAX_PARAMETER_ARGS, macro, args) |
48 | |
49 | #define BOOST_LOG_CTOR_FORWARD_1(z, n, types)\ |
50 | template< typename T0 >\ |
51 | explicit BOOST_PP_TUPLE_ELEM(2, 0, types)(T0 const& arg0, typename boost::log::aux::enable_if_named_parameters< T0, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :\ |
52 | BOOST_PP_TUPLE_ELEM(2, 1, types)((BOOST_PP_ENUM_PARAMS_Z(z, n, arg))) {} |
53 | |
54 | #define BOOST_LOG_CTOR_FORWARD_N(z, n, types)\ |
55 | template< BOOST_PP_ENUM_PARAMS_Z(z, n, typename T) >\ |
56 | explicit BOOST_PP_TUPLE_ELEM(2, 0, types)(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, T, const& arg)) :\ |
57 | BOOST_PP_TUPLE_ELEM(2, 1, types)((BOOST_PP_ENUM_PARAMS_Z(z, n, arg))) {} |
58 | |
59 | #define BOOST_LOG_CTOR_FORWARD(z, n, types)\ |
60 | BOOST_PP_IF(BOOST_PP_EQUAL(n, 1), BOOST_LOG_CTOR_FORWARD_1, BOOST_LOG_CTOR_FORWARD_N)(z, n, types) |
61 | |
62 | // The macro expands to a number of templated constructors that aggregate their named arguments |
63 | // into an ArgumentsPack and pass it to the base class constructor. |
64 | #define BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_FORWARD(class_type, base_type)\ |
65 | BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_GEN(BOOST_LOG_CTOR_FORWARD, (class_type, base_type)) |
66 | |
67 | #define BOOST_LOG_CTOR_CALL_1(z, n, types)\ |
68 | template< typename T0 >\ |
69 | explicit BOOST_PP_TUPLE_ELEM(2, 0, types)(T0 const& arg0, typename boost::log::aux::enable_if_named_parameters< T0, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy())\ |
70 | { BOOST_PP_TUPLE_ELEM(2, 1, types)((BOOST_PP_ENUM_PARAMS_Z(z, n, arg))); } |
71 | |
72 | #define BOOST_LOG_CTOR_CALL_N(z, n, types)\ |
73 | template< BOOST_PP_ENUM_PARAMS_Z(z, n, typename T) >\ |
74 | explicit BOOST_PP_TUPLE_ELEM(2, 0, types)(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, T, const& arg))\ |
75 | { BOOST_PP_TUPLE_ELEM(2, 1, types)((BOOST_PP_ENUM_PARAMS_Z(z, n, arg))); } |
76 | |
77 | #define BOOST_LOG_CTOR_CALL(z, n, types)\ |
78 | BOOST_PP_IF(BOOST_PP_EQUAL(n, 1), BOOST_LOG_CTOR_CALL_1, BOOST_LOG_CTOR_CALL_N)(z, n, types) |
79 | |
80 | // The macro expands to a number of templated constructors that aggregate their named arguments |
81 | // into an ArgumentsPack and pass it to a function call. |
82 | #define BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_CALL(class_type, fun)\ |
83 | BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_GEN(BOOST_LOG_CTOR_CALL, (class_type, fun)) |
84 | |
85 | namespace boost { |
86 | |
87 | BOOST_LOG_OPEN_NAMESPACE |
88 | |
89 | namespace aux { |
90 | |
91 | // Yeah, not too cute. The empty_arg_list class should really be public. |
92 | // https://svn.boost.org/trac/boost/ticket/7247 |
93 | typedef boost::parameter::aux::empty_arg_list empty_arg_list; |
94 | |
95 | #if !(defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_LOG_NO_CXX11_ARG_PACKS_TO_NON_VARIADIC_ARGS_EXPANSION)) |
96 | |
97 | //! The metafunction generates argument pack |
98 | template< typename ArgT0, typename... ArgsT > |
99 | struct make_arg_list |
100 | { |
101 | typedef boost::parameter::aux::arg_list< ArgT0, typename make_arg_list< ArgsT... >::type > type; |
102 | }; |
103 | |
104 | template< typename ArgT0 > |
105 | struct make_arg_list< ArgT0 > |
106 | { |
107 | typedef boost::parameter::aux::arg_list< ArgT0 > type; |
108 | }; |
109 | |
110 | #else |
111 | |
112 | //! The metafunction generates argument pack |
113 | template< typename ArgT0, BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_DEC(BOOST_LOG_MAX_PARAMETER_ARGS), typename T, = void BOOST_PP_INTERCEPT) > |
114 | struct make_arg_list |
115 | { |
116 | typedef boost::parameter::aux::arg_list< ArgT0, typename make_arg_list< BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(BOOST_LOG_MAX_PARAMETER_ARGS), T) >::type > type; |
117 | }; |
118 | |
119 | template< typename ArgT0 > |
120 | struct make_arg_list< ArgT0, BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(BOOST_LOG_MAX_PARAMETER_ARGS), void BOOST_PP_INTERCEPT) > |
121 | { |
122 | typedef boost::parameter::aux::arg_list< ArgT0 > type; |
123 | }; |
124 | |
125 | #endif |
126 | |
127 | #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) |
128 | |
129 | template< typename T, typename R > |
130 | using enable_if_named_parameters = boost::enable_if_c< boost::mpl::or_< boost::is_base_of< boost::parameter::aux::tagged_argument_base, T >, boost::is_base_of< empty_arg_list, T > >::value, R >; |
131 | |
132 | #else // !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) |
133 | |
134 | template< typename T, typename R > |
135 | struct enable_if_named_parameters : |
136 | public boost::enable_if_c< boost::mpl::or_< boost::is_base_of< boost::parameter::aux::tagged_argument_base, T >, boost::is_base_of< empty_arg_list, T > >::value, R > |
137 | { |
138 | }; |
139 | |
140 | #endif // !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) |
141 | |
142 | } // namespace aux |
143 | |
144 | BOOST_LOG_CLOSE_NAMESPACE // namespace log |
145 | |
146 | } // namespace boost |
147 | |
148 | #include <boost/log/detail/footer.hpp> |
149 | |
150 | #endif // BOOST_LOG_DETAIL_PARAMETER_TOOLS_HPP_INCLUDED_ |
151 | |