]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.TypeErasure library |
2 | // | |
3 | // Copyright 2012 Steven Watanabe | |
4 | // | |
5 | // Distributed under the Boost Software License Version 1.0. (See | |
6 | // accompanying file LICENSE_1_0.txt or copy at | |
7 | // http://www.boost.org/LICENSE_1_0.txt) | |
8 | // | |
9 | // $Id$ | |
10 | ||
11 | #if !defined(BOOST_PP_IS_ITERATING) | |
12 | ||
13 | #ifndef BOOST_TYPE_ERASURE_DETAIL_CHECK_CALL_HPP_INCLUDED | |
14 | #define BOOST_TYPE_ERASURE_DETAIL_CHECK_CALL_HPP_INCLUDED | |
15 | ||
16 | #include <boost/mpl/eval_if.hpp> | |
17 | #include <boost/mpl/bool.hpp> | |
18 | #include <boost/mpl/and.hpp> | |
19 | #include <boost/type_traits/is_convertible.hpp> | |
20 | #include <boost/type_traits/remove_reference.hpp> | |
21 | #include <boost/type_traits/remove_cv.hpp> | |
22 | #include <boost/type_traits/is_reference.hpp> | |
23 | #include <boost/type_traits/is_const.hpp> | |
24 | #include <boost/type_traits/function_traits.hpp> | |
25 | #include <boost/preprocessor/iteration/iterate.hpp> | |
26 | #include <boost/preprocessor/repetition/enum_params.hpp> | |
27 | #include <boost/preprocessor/repetition/enum_trailing_params.hpp> | |
28 | #include <boost/preprocessor/repetition/repeat.hpp> | |
29 | #include <boost/preprocessor/cat.hpp> | |
30 | #include <boost/type_erasure/placeholder_of.hpp> | |
31 | ||
32 | namespace boost { | |
33 | namespace type_erasure { | |
34 | namespace detail { | |
35 | ||
36 | template<class Sig, class Args> | |
37 | struct check_call : ::boost::mpl::false_ {}; | |
38 | ||
39 | template<class T, class Enable = void> | |
40 | struct qualified_placeholder | |
41 | { | |
42 | typedef void type; | |
43 | }; | |
44 | ||
45 | template<class T> | |
46 | struct qualified_placeholder<T&, typename T::_boost_type_erasure_is_any> | |
47 | { | |
48 | typedef typename ::boost::type_erasure::placeholder_of<T>::type placeholder; | |
49 | typedef typename ::boost::remove_reference<placeholder>::type unref; | |
50 | typedef typename ::boost::mpl::if_< ::boost::is_const<T>, | |
51 | const unref, | |
52 | unref | |
53 | >::type add_const; | |
54 | typedef typename ::boost::mpl::if_< ::boost::is_reference<placeholder>, | |
55 | placeholder, | |
56 | add_const& | |
57 | >::type type; | |
58 | }; | |
59 | ||
60 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES | |
61 | ||
62 | template<class T> | |
63 | struct qualified_placeholder<T&&, typename T::_boost_type_erasure_is_any> | |
64 | { | |
65 | typedef typename ::boost::type_erasure::placeholder_of<T>::type placeholder; | |
66 | typedef placeholder&& type; | |
67 | }; | |
68 | ||
69 | #endif | |
70 | ||
71 | template<class P, class A> | |
72 | struct check_placeholder_arg_impl : ::boost::mpl::false_ {}; | |
73 | ||
74 | template<class P> | |
75 | struct check_placeholder_arg_impl<P, P&> : ::boost::mpl::true_ {}; | |
76 | ||
77 | template<class P> | |
78 | struct check_placeholder_arg_impl<P, const P&> : ::boost::mpl::true_ {}; | |
79 | ||
80 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES | |
81 | ||
82 | template<class P> | |
83 | struct check_placeholder_arg_impl<P, P&&> : ::boost::mpl::true_ {}; | |
84 | ||
85 | #endif | |
86 | ||
87 | template<class P> | |
88 | struct check_placeholder_arg_impl<P&, P&> : ::boost::mpl::true_ {}; | |
89 | ||
90 | template<class P> | |
91 | struct check_placeholder_arg_impl<const P&, P&> : ::boost::mpl::true_ {}; | |
92 | ||
93 | template<class P> | |
94 | struct check_placeholder_arg_impl<const P&, const P&> : ::boost::mpl::true_ {}; | |
95 | ||
96 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES | |
97 | ||
98 | template<class P> | |
99 | struct check_placeholder_arg_impl<const P&, P&&> : ::boost::mpl::true_ {}; | |
100 | ||
101 | template<class P> | |
102 | struct check_placeholder_arg_impl<P&&, P&&> : ::boost::mpl::true_ {}; | |
103 | ||
104 | #endif | |
105 | ||
106 | template<class P, class Arg> | |
107 | struct check_placeholder_arg : | |
108 | check_placeholder_arg_impl< | |
109 | P, | |
110 | typename ::boost::type_erasure::detail::qualified_placeholder<Arg>::type | |
111 | >::type | |
112 | {}; | |
113 | ||
114 | #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ | |
115 | ((defined(__GNUC__) && !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6))) || \ | |
116 | defined(__MINGW32__) || defined(__MINGW64__)) | |
117 | #define BOOST_TYPE_ERASURE_BROKEN_RVALUE_IS_CONVERTIBLE | |
118 | #endif | |
119 | ||
120 | template<class FormalArg, class ActualArg> | |
121 | struct check_arg | |
122 | { | |
123 | typedef typename ::boost::mpl::eval_if< | |
124 | is_placeholder< | |
125 | typename ::boost::remove_cv< | |
126 | typename ::boost::remove_reference<FormalArg>::type | |
127 | >::type | |
128 | >, | |
129 | ::boost::type_erasure::detail::check_placeholder_arg<FormalArg, ActualArg>, | |
130 | #ifdef BOOST_TYPE_ERASURE_BROKEN_RVALUE_IS_CONVERTIBLE | |
131 | ::boost::mpl::true_ | |
132 | #else | |
133 | ::boost::is_convertible<ActualArg, FormalArg> | |
134 | #endif | |
135 | >::type type; | |
136 | }; | |
137 | ||
138 | #define BOOST_PP_FILENAME_1 <boost/type_erasure/detail/check_call.hpp> | |
139 | #define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_ARITY) | |
140 | #include BOOST_PP_ITERATE() | |
141 | ||
142 | } | |
143 | } | |
144 | } | |
145 | ||
146 | #endif | |
147 | ||
148 | #else | |
149 | ||
150 | #define N BOOST_PP_ITERATION() | |
151 | ||
152 | #define BOOST_TYPE_ERASURE_CHECK_ARG(z, n, data) \ | |
153 | typedef typename ::boost::type_erasure::detail::check_arg< \ | |
154 | BOOST_PP_CAT(T, n), \ | |
155 | BOOST_PP_CAT(U, n) \ | |
156 | >::type BOOST_PP_CAT(check, n); \ | |
157 | typedef typename ::boost::mpl::and_< \ | |
158 | BOOST_PP_CAT(type, n), \ | |
159 | BOOST_PP_CAT(check, n) \ | |
160 | >::type BOOST_PP_CAT(type, BOOST_PP_INC(n)); | |
161 | ||
162 | template< | |
163 | class R | |
164 | BOOST_PP_ENUM_TRAILING_PARAMS(N, class T) | |
165 | BOOST_PP_ENUM_TRAILING_PARAMS(N, class U) | |
166 | > | |
167 | struct check_call<R(BOOST_PP_ENUM_PARAMS(N, T)), void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, u))> { | |
168 | typedef ::boost::mpl::true_ type0; | |
169 | BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_CHECK_ARG, ~) | |
170 | typedef BOOST_PP_CAT(type, N) type; | |
171 | }; | |
172 | ||
173 | #undef N | |
174 | ||
175 | #endif |