1 // Copyright Daniel Wallin 2006.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5 
6 #include <boost/parameter/config.hpp>
7 
8 #if (BOOST_PARAMETER_MAX_ARITY < 4)
9 #error Define BOOST_PARAMETER_MAX_ARITY as 4 or greater.
10 #endif
11 
12 namespace test {
13 
14     struct X
15     {
16     };
17 
18     struct Y : X
19     {
20     };
21 } // namespace test
22 
23 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
24 #include <type_traits>
25 #else
26 #include <boost/mpl/bool.hpp>
27 #include <boost/mpl/if.hpp>
28 #include <boost/type_traits/is_base_of.hpp>
29 #include <boost/type_traits/remove_const.hpp>
30 #include <boost/type_traits/remove_reference.hpp>
31 #endif
32 
33 namespace test {
34 
35     struct Z
36     {
37         template <typename T, typename Args>
38 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
39         using fn = std::is_base_of<
40             X
41           , typename std::remove_const<
42                 typename std::remove_reference<T>::type
43             >::type
44         >;
45 #else
46         struct apply
47           : boost::mpl::if_<
48                 boost::is_base_of<
49                     X
50                   , typename boost::remove_const<
51                         typename boost::remove_reference<T>::type
52                     >::type
53                 >
54               , boost::mpl::true_
55               , boost::mpl::false_
56             >::type
57         {
58         };
59 #endif  // BOOST_PARAMETER_CAN_USE_MP11
60     };
61 } // namespace test
62 
63 #include <boost/parameter/template_keyword.hpp>
64 
65 namespace test {
66 
67     template <typename T = int>
68     struct a0_is : boost::parameter::template_keyword<test::a0_is<>,T>
69     {
70     };
71 
72     template <typename T = int>
73     struct a1_is : boost::parameter::template_keyword<test::a1_is<>,T>
74     {
75     };
76 
77     template <typename T = int>
78     struct a2_is : boost::parameter::template_keyword<test::a2_is<>,T>
79     {
80     };
81 
82     template <typename T = int>
83     struct a3_is : boost::parameter::template_keyword<test::a3_is<>,T>
84     {
85     };
86 } // namespace test
87 
88 #include <boost/parameter/parameters.hpp>
89 #include <boost/parameter/optional.hpp>
90 #include <boost/parameter/deduced.hpp>
91 #include <boost/parameter/binding.hpp>
92 
93 namespace test {
94 
95     template <
96         typename A0 = boost::parameter::void_
97       , typename A1 = boost::parameter::void_
98       , typename A2 = boost::parameter::void_
99       , typename A3 = boost::parameter::void_
100     >
101     struct with_ntp
102     {
103         typedef typename boost::parameter::parameters<
104             test::a0_is<>
105           , test::a1_is<>
106           , test::a2_is<>
107           , boost::parameter::optional<
108                 boost::parameter::deduced<test::a3_is<> >
109               , Z
110             >
111         >::BOOST_NESTED_TEMPLATE bind<
112             A0
113           , A1
114           , A2
115           , A3
116 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
117           , boost::parameter::void_
118 #endif
119         >::type args;
120         typedef typename boost::parameter::binding<
121             args
122           , test::a0_is<>
123           , void*
124         >::type a0;
125         typedef typename boost::parameter::binding<
126             args
127           , test::a1_is<>
128           , void*
129         >::type a1;
130         typedef typename boost::parameter::binding<
131             args
132           , test::a2_is<>
133           , void*
134         >::type a2;
135         typedef typename boost::parameter::binding<
136             args
137           , test::a3_is<>
138           , void*
139         >::type a3;
140         typedef void(*type)(a0, a1, a2, a3);
141     };
142 } // namespace test
143 
144 #include <boost/mpl/aux_/test.hpp>
145 
146 #if !defined(BOOST_PARAMETER_CAN_USE_MP11)
147 #include <boost/mpl/assert.hpp>
148 #include <boost/type_traits/is_same.hpp>
149 #endif
150 
MPL_TEST_CASE()151 MPL_TEST_CASE()
152 {
153 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
154     static_assert(
155         std::is_same<
156             test::with_ntp<>::type
157           , void(*)(void*, void*, void*, void*)
158         >::value
159       , "type must be void(*)(void*, void*, void*, void*)"
160     );
161     static_assert(
162         std::is_same<
163             test::with_ntp<test::a2_is<int> >::type
164           , void(*)(void*, void*, int, void*)
165         >::value
166       , "type must be void(*)(void*, void*, int, void*)"
167     );
168     static_assert(
169         std::is_same<
170             test::with_ntp<test::a1_is<int> >::type
171           , void(*)(void*, int, void*, void*)
172         >::value
173       , "type must be void(*)(void*, int, void*, void*)"
174     );
175     static_assert(
176         std::is_same<
177             test::with_ntp<test::a2_is<int const>,test::a1_is<float> >::type
178           , void(*)(void*, float, int const, void*)
179         >::value
180       , "type must be void(*)(void*, float, int const, void*)"
181     );
182     static_assert(
183         std::is_same<
184             test::with_ntp<int const>::type
185           , void(*)(int const, void*, void*, void*)
186         >::value
187       , "type must be void(*)(int const, void*, void*, void*)"
188     );
189     static_assert(
190         std::is_same<
191             test::with_ntp<int,float>::type
192           , void(*)(int, float, void*, void*)
193         >::value
194       , "type must be void(*)(int, float, void*, void*)"
195     );
196     static_assert(
197         std::is_same<
198             test::with_ntp<int,float,char>::type
199           , void(*)(int, float, char, void*)
200         >::value
201       , "type must be void(*)(int, float, char, void*)"
202     );
203     static_assert(
204         std::is_same<
205             test::with_ntp<test::a0_is<int>,test::Y>::type
206           , void(*)(int, void*, void*, test::Y)
207         >::value
208       , "type must be must be void(*)(int, void*, void*, test::Y)"
209     );
210     static_assert(
211         std::is_same<
212             test::with_ntp<int&,test::a2_is<char>,test::Y>::type
213           , void(*)(int&, void*, char, test::Y)
214         >::value
215       , "type must be void(*)(int&, void*, char, test::Y)"
216     );
217 #else   // !defined(BOOST_PARAMETER_CAN_USE_MP11)
218     BOOST_MPL_ASSERT((
219         boost::mpl::if_<
220             boost::is_same<
221                 test::with_ntp<>::type
222               , void(*)(void*, void*, void*, void*)
223             >
224           , boost::mpl::true_
225           , boost::mpl::false_
226         >::type
227     ));
228     BOOST_MPL_ASSERT((
229         boost::mpl::if_<
230             boost::is_same<
231                 test::with_ntp<test::a2_is<int> >::type
232               , void(*)(void*, void*, int, void*)
233             >
234           , boost::mpl::true_
235           , boost::mpl::false_
236         >::type
237     ));
238     BOOST_MPL_ASSERT((
239         boost::mpl::if_<
240             boost::is_same<
241                 test::with_ntp<test::a1_is<int> >::type
242               , void(*)(void*, int, void*, void*)
243             >
244           , boost::mpl::true_
245           , boost::mpl::false_
246         >::type
247     ));
248     BOOST_MPL_ASSERT((
249         boost::mpl::if_<
250             boost::is_same<
251                 test::with_ntp<
252                     test::a2_is<int const>
253                   , test::a1_is<float>
254                 >::type
255               , void(*)(void*, float, int const, void*)
256             >
257           , boost::mpl::true_
258           , boost::mpl::false_
259         >::type
260     ));
261     BOOST_MPL_ASSERT((
262         boost::mpl::if_<
263             boost::is_same<
264                 test::with_ntp<int const>::type
265               , void(*)(int const, void*, void*, void*)
266             >
267           , boost::mpl::true_
268           , boost::mpl::false_
269         >::type
270     ));
271     BOOST_MPL_ASSERT((
272         boost::mpl::if_<
273             boost::is_same<
274                 test::with_ntp<int,float>::type
275               , void(*)(int, float, void*, void*)
276             >
277           , boost::mpl::true_
278           , boost::mpl::false_
279         >::type
280     ));
281     BOOST_MPL_ASSERT((
282         boost::mpl::if_<
283             boost::is_same<
284                 test::with_ntp<int,float,char>::type
285               , void(*)(int, float, char, void*)
286             >
287           , boost::mpl::true_
288           , boost::mpl::false_
289         >::type
290     ));
291     BOOST_MPL_ASSERT((
292         boost::mpl::if_<
293             boost::is_same<
294                 test::with_ntp<test::a0_is<int>,test::Y>::type
295               , void(*)(int, void*, void*, test::Y)
296             >
297           , boost::mpl::true_
298           , boost::mpl::false_
299         >::type
300     ));
301     BOOST_MPL_ASSERT((
302         boost::mpl::if_<
303             boost::is_same<
304                 test::with_ntp<int&,test::a2_is<char>,test::Y>::type
305               , void(*)(int&, void*, char, test::Y)
306             >
307           , boost::mpl::true_
308           , boost::mpl::false_
309         >::type
310     ));
311 #endif  // BOOST_PARAMETER_CAN_USE_MP11
312 
313     typedef int test_array[1];
314     typedef void(*test_function)();
315 
316 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
317     static_assert(
318         std::is_same<
319             test::with_ntp<test_array,test_function>::type
320           , void(*)(test_array&, test_function, void*, void*)
321         >::value
322       , "type must be void(*)(test_array&, test_function, void*, void*)"
323     );
324 #else
325     BOOST_MPL_ASSERT((
326         boost::mpl::if_<
327             boost::is_same<
328                 test::with_ntp<test_array,test_function>::type
329               , void(*)(test_array&, test_function, void*, void*)
330             >
331           , boost::mpl::true_
332           , boost::mpl::false_
333         >::type
334     ));
335 #endif
336 }
337 
338