]>
Commit | Line | Data |
---|---|---|
1 | // boost::compressed_pair test program | |
2 | ||
3 | // (C) Copyright John Maddock 2000. | |
4 | // Use, modification and distribution are subject to the Boost Software License, | |
5 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
6 | // http://www.boost.org/LICENSE_1_0.txt). | |
7 | ||
8 | ||
9 | // standalone test program for <boost/call_traits.hpp> | |
10 | // 18 Mar 2002: | |
11 | // Changed some names to prevent conflicts with some new type_traits additions. | |
12 | // 03 Oct 2000: | |
13 | // Enabled extra tests for VC6. | |
14 | ||
15 | #include <iostream> | |
16 | #include <iomanip> | |
17 | #include <algorithm> | |
18 | #include <typeinfo> | |
19 | #include <boost/call_traits.hpp> | |
20 | ||
21 | #include <libs/type_traits/test/test.hpp> | |
22 | #include <libs/type_traits/test/check_type.hpp> | |
23 | ||
24 | #ifdef BOOST_MSVC | |
25 | #pragma warning(disable:4181) // : warning C4181: qualifier applied to reference type; ignored | |
26 | #endif | |
27 | ||
28 | // a way prevent warnings for unused variables | |
29 | template<class T> inline void unused_variable(const T&) {} | |
30 | ||
31 | // | |
32 | // struct contained models a type that contains a type (for example std::pair) | |
33 | // arrays are contained by value, and have to be treated as a special case: | |
34 | // | |
35 | template <class T> | |
36 | struct contained | |
37 | { | |
38 | // define our typedefs first, arrays are stored by value | |
39 | // so value_type is not the same as result_type: | |
40 | typedef typename boost::call_traits<T>::param_type param_type; | |
41 | typedef typename boost::call_traits<T>::reference reference; | |
42 | typedef typename boost::call_traits<T>::const_reference const_reference; | |
43 | typedef T value_type; | |
44 | typedef typename boost::call_traits<T>::value_type result_type; | |
45 | ||
46 | // stored value: | |
47 | value_type v_; | |
48 | ||
49 | // constructors: | |
50 | contained() {} | |
51 | contained(param_type p) : v_(p){} | |
52 | // return byval: | |
53 | result_type value()const { return v_; } | |
54 | // return by_ref: | |
55 | reference get() { return v_; } | |
56 | const_reference const_get()const { return v_; } | |
57 | // pass value: | |
58 | void call(param_type){} | |
59 | private: | |
60 | contained& operator=(const contained&); | |
61 | }; | |
62 | ||
63 | #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
64 | template <class T, std::size_t N> | |
65 | struct contained<T[N]> | |
66 | { | |
67 | typedef typename boost::call_traits<T[N]>::param_type param_type; | |
68 | typedef typename boost::call_traits<T[N]>::reference reference; | |
69 | typedef typename boost::call_traits<T[N]>::const_reference const_reference; | |
70 | typedef T value_type[N]; | |
71 | typedef typename boost::call_traits<T[N]>::value_type result_type; | |
72 | ||
73 | value_type v_; | |
74 | ||
75 | contained(param_type p) | |
76 | { | |
77 | std::copy(p, p+N, v_); | |
78 | } | |
79 | // return byval: | |
80 | result_type value()const { return v_; } | |
81 | // return by_ref: | |
82 | reference get() { return v_; } | |
83 | const_reference const_get()const { return v_; } | |
84 | void call(param_type){} | |
85 | private: | |
86 | contained& operator=(const contained&); | |
87 | }; | |
88 | #endif | |
89 | ||
90 | template <class T> | |
91 | contained<typename boost::call_traits<T>::value_type> test_wrap_type(const T& t) | |
92 | { | |
93 | typedef typename boost::call_traits<T>::value_type ct; | |
94 | return contained<ct>(t); | |
95 | } | |
96 | ||
97 | namespace test{ | |
98 | ||
99 | template <class T1, class T2> | |
100 | std::pair< | |
101 | typename boost::call_traits<T1>::value_type, | |
102 | typename boost::call_traits<T2>::value_type> | |
103 | make_pair(const T1& t1, const T2& t2) | |
104 | { | |
105 | return std::pair< | |
106 | typename boost::call_traits<T1>::value_type, | |
107 | typename boost::call_traits<T2>::value_type>(t1, t2); | |
108 | } | |
109 | ||
110 | } // namespace test | |
111 | ||
112 | using namespace std; | |
113 | ||
114 | // | |
115 | // struct call_traits_checker: | |
116 | // verifies behaviour of contained example: | |
117 | // | |
118 | template <class T> | |
119 | struct call_traits_checker | |
120 | { | |
121 | typedef typename boost::call_traits<T>::param_type param_type; | |
122 | void operator()(param_type); | |
123 | }; | |
124 | ||
125 | template <class T> | |
126 | void call_traits_checker<T>::operator()(param_type p) | |
127 | { | |
128 | T t(p); | |
129 | contained<T> c(t); | |
130 | cout << "checking contained<" << typeid(T).name() << ">..." << endl; | |
131 | BOOST_CHECK(t == c.value()); | |
132 | BOOST_CHECK(t == c.get()); | |
133 | BOOST_CHECK(t == c.const_get()); | |
134 | #ifndef __ICL | |
135 | //cout << "typeof contained<" << typeid(T).name() << ">::v_ is: " << typeid(&contained<T>::v_).name() << endl; | |
136 | cout << "typeof contained<" << typeid(T).name() << ">::value() is: " << typeid(&contained<T>::value).name() << endl; | |
137 | cout << "typeof contained<" << typeid(T).name() << ">::get() is: " << typeid(&contained<T>::get).name() << endl; | |
138 | cout << "typeof contained<" << typeid(T).name() << ">::const_get() is: " << typeid(&contained<T>::const_get).name() << endl; | |
139 | cout << "typeof contained<" << typeid(T).name() << ">::call() is: " << typeid(&contained<T>::call).name() << endl; | |
140 | cout << endl; | |
141 | #endif | |
142 | } | |
143 | ||
144 | #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
145 | template <class T, std::size_t N> | |
146 | struct call_traits_checker<T[N]> | |
147 | { | |
148 | typedef typename boost::call_traits<T[N]>::param_type param_type; | |
149 | void operator()(param_type t) | |
150 | { | |
151 | contained<T[N]> c(t); | |
152 | cout << "checking contained<" << typeid(T[N]).name() << ">..." << endl; | |
153 | unsigned int i = 0; | |
154 | for(i = 0; i < N; ++i) | |
155 | BOOST_CHECK(t[i] == c.value()[i]); | |
156 | for(i = 0; i < N; ++i) | |
157 | BOOST_CHECK(t[i] == c.get()[i]); | |
158 | for(i = 0; i < N; ++i) | |
159 | BOOST_CHECK(t[i] == c.const_get()[i]); | |
160 | ||
161 | cout << "typeof contained<" << typeid(T[N]).name() << ">::v_ is: " << typeid(&contained<T[N]>::v_).name() << endl; | |
162 | cout << "typeof contained<" << typeid(T[N]).name() << ">::value is: " << typeid(&contained<T[N]>::value).name() << endl; | |
163 | cout << "typeof contained<" << typeid(T[N]).name() << ">::get is: " << typeid(&contained<T[N]>::get).name() << endl; | |
164 | cout << "typeof contained<" << typeid(T[N]).name() << ">::const_get is: " << typeid(&contained<T[N]>::const_get).name() << endl; | |
165 | cout << "typeof contained<" << typeid(T[N]).name() << ">::call is: " << typeid(&contained<T[N]>::call).name() << endl; | |
166 | cout << endl; | |
167 | } | |
168 | }; | |
169 | #endif | |
170 | ||
171 | // | |
172 | // check_wrap: | |
173 | template <class W, class U> | |
174 | void check_wrap(const W& w, const U& u) | |
175 | { | |
176 | cout << "checking " << typeid(W).name() << "..." << endl; | |
177 | BOOST_CHECK(w.value() == u); | |
178 | } | |
179 | ||
180 | // | |
181 | // check_make_pair: | |
182 | // verifies behaviour of "make_pair": | |
183 | // | |
184 | template <class T, class U, class V> | |
185 | void check_make_pair(T c, U u, V v) | |
186 | { | |
187 | cout << "checking std::pair<" << typeid(c.first).name() << ", " << typeid(c.second).name() << ">..." << endl; | |
188 | BOOST_CHECK(c.first == u); | |
189 | BOOST_CHECK(c.second == v); | |
190 | cout << endl; | |
191 | } | |
192 | ||
193 | ||
194 | struct comparible_UDT | |
195 | { | |
196 | int i_; | |
197 | comparible_UDT() : i_(2){} | |
198 | comparible_UDT(const comparible_UDT& other) : i_(other.i_){} | |
199 | comparible_UDT& operator=(const comparible_UDT& other) | |
200 | { | |
201 | i_ = other.i_; | |
202 | return *this; | |
203 | } | |
204 | bool operator == (const comparible_UDT& v){ return v.i_ == i_; } | |
205 | }; | |
206 | ||
207 | int main() | |
208 | { | |
209 | call_traits_checker<comparible_UDT> c1; | |
210 | comparible_UDT u; | |
211 | c1(u); | |
212 | call_traits_checker<int> c2; | |
213 | call_traits_checker<enum_UDT> c2b; | |
214 | int i = 2; | |
215 | c2(i); | |
216 | c2b(one); | |
217 | int* pi = &i; | |
218 | int a[2] = {1,2}; | |
219 | #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) && !defined(__ICL) | |
220 | call_traits_checker<int*> c3; | |
221 | c3(pi); | |
222 | call_traits_checker<int&> c4; | |
223 | c4(i); | |
224 | call_traits_checker<const int&> c5; | |
225 | c5(i); | |
226 | #if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__MWERKS__) && !defined(__SUNPRO_CC) | |
227 | call_traits_checker<int[2]> c6; | |
228 | c6(a); | |
229 | #endif | |
230 | #endif | |
231 | ||
232 | check_wrap(test_wrap_type(2), 2); | |
233 | #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC) | |
234 | check_wrap(test_wrap_type(a), a); | |
235 | check_make_pair(test::make_pair(a, a), a, a); | |
236 | #endif | |
237 | ||
238 | // cv-qualifiers applied to reference types should have no effect | |
239 | // declare these here for later use with is_reference and remove_reference: | |
240 | typedef int& r_type; | |
241 | typedef const r_type cr_type; | |
242 | ||
243 | BOOST_CHECK_TYPE(comparible_UDT, boost::call_traits<comparible_UDT>::value_type); | |
244 | BOOST_CHECK_TYPE(comparible_UDT&, boost::call_traits<comparible_UDT>::reference); | |
245 | BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::const_reference); | |
246 | BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::param_type); | |
247 | BOOST_CHECK_TYPE(int, boost::call_traits<int>::value_type); | |
248 | BOOST_CHECK_TYPE(int&, boost::call_traits<int>::reference); | |
249 | BOOST_CHECK_TYPE(const int&, boost::call_traits<int>::const_reference); | |
250 | BOOST_CHECK_TYPE(const int, boost::call_traits<int>::param_type); | |
251 | BOOST_CHECK_TYPE(int*, boost::call_traits<int*>::value_type); | |
252 | BOOST_CHECK_TYPE(int*&, boost::call_traits<int*>::reference); | |
253 | BOOST_CHECK_TYPE(int*const&, boost::call_traits<int*>::const_reference); | |
254 | BOOST_CHECK_TYPE(int*const, boost::call_traits<int*>::param_type); | |
255 | #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) | |
256 | BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::value_type); | |
257 | BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::reference); | |
258 | BOOST_CHECK_TYPE(const int&, boost::call_traits<int&>::const_reference); | |
259 | BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::param_type); | |
260 | #if !(defined(__GNUC__) && ((__GNUC__ < 3) || (__GNUC__ == 3) && (__GNUC_MINOR__ < 1))) | |
261 | BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::value_type); | |
262 | BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::reference); | |
263 | BOOST_CHECK_TYPE(const int&, boost::call_traits<cr_type>::const_reference); | |
264 | BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::param_type); | |
265 | #else | |
266 | std::cout << "Your compiler cannot instantiate call_traits<int&const>, skipping four tests (4 errors)" << std::endl; | |
267 | #endif | |
268 | BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::value_type); | |
269 | BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::reference); | |
270 | BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::const_reference); | |
271 | BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::param_type); | |
272 | #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
273 | BOOST_CHECK_TYPE(const int*, boost::call_traits<int[3]>::value_type); | |
274 | BOOST_CHECK_TYPE(int(&)[3], boost::call_traits<int[3]>::reference); | |
275 | BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<int[3]>::const_reference); | |
276 | BOOST_CHECK_TYPE(const int*const, boost::call_traits<int[3]>::param_type); | |
277 | BOOST_CHECK_TYPE(const int*, boost::call_traits<const int[3]>::value_type); | |
278 | BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::reference); | |
279 | BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::const_reference); | |
280 | BOOST_CHECK_TYPE(const int*const, boost::call_traits<const int[3]>::param_type); | |
281 | // test with abstract base class: | |
282 | BOOST_CHECK_TYPE(test_abc1, boost::call_traits<test_abc1>::value_type); | |
283 | BOOST_CHECK_TYPE(test_abc1&, boost::call_traits<test_abc1>::reference); | |
284 | BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::const_reference); | |
285 | BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::param_type); | |
286 | #else | |
287 | std::cout << "You're compiler does not support partial template specialiation, skipping 8 tests (8 errors)" << std::endl; | |
288 | #endif | |
289 | #else | |
290 | std::cout << "You're compiler does not support partial template specialiation, skipping 20 tests (20 errors)" << std::endl; | |
291 | #endif | |
292 | // test with an incomplete type: | |
293 | BOOST_CHECK_TYPE(incomplete_type, boost::call_traits<incomplete_type>::value_type); | |
294 | BOOST_CHECK_TYPE(incomplete_type&, boost::call_traits<incomplete_type>::reference); | |
295 | BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::const_reference); | |
296 | BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::param_type); | |
297 | // test enum: | |
298 | BOOST_CHECK_TYPE(enum_UDT, boost::call_traits<enum_UDT>::value_type); | |
299 | BOOST_CHECK_TYPE(enum_UDT&, boost::call_traits<enum_UDT>::reference); | |
300 | BOOST_CHECK_TYPE(const enum_UDT&, boost::call_traits<enum_UDT>::const_reference); | |
301 | BOOST_CHECK_TYPE(const enum_UDT, boost::call_traits<enum_UDT>::param_type); | |
302 | return 0; | |
303 | } | |
304 | ||
305 | // | |
306 | // define call_traits tests to check that the assertions in the docs do actually work | |
307 | // this is an compile-time only set of tests: | |
308 | // | |
309 | template <typename T, bool isarray = false> | |
310 | struct call_traits_test | |
311 | { | |
312 | typedef ::boost::call_traits<T> ct; | |
313 | typedef typename ct::param_type param_type; | |
314 | typedef typename ct::reference reference; | |
315 | typedef typename ct::const_reference const_reference; | |
316 | typedef typename ct::value_type value_type; | |
317 | static void assert_construct(param_type val); | |
318 | }; | |
319 | ||
320 | template <typename T, bool isarray> | |
321 | void call_traits_test<T, isarray>::assert_construct(typename call_traits_test<T, isarray>::param_type val) | |
322 | { | |
323 | // | |
324 | // this is to check that the call_traits assertions are valid: | |
325 | T t(val); | |
326 | value_type v(t); | |
327 | reference r(t); | |
328 | const_reference cr(t); | |
329 | param_type p(t); | |
330 | value_type v2(v); | |
331 | value_type v3(r); | |
332 | value_type v4(p); | |
333 | reference r2(v); | |
334 | reference r3(r); | |
335 | const_reference cr2(v); | |
336 | const_reference cr3(r); | |
337 | const_reference cr4(cr); | |
338 | const_reference cr5(p); | |
339 | param_type p2(v); | |
340 | param_type p3(r); | |
341 | param_type p4(p); | |
342 | ||
343 | unused_variable(v2); | |
344 | unused_variable(v3); | |
345 | unused_variable(v4); | |
346 | unused_variable(r2); | |
347 | unused_variable(r3); | |
348 | unused_variable(cr2); | |
349 | unused_variable(cr3); | |
350 | unused_variable(cr4); | |
351 | unused_variable(cr5); | |
352 | unused_variable(p2); | |
353 | unused_variable(p3); | |
354 | unused_variable(p4); | |
355 | } | |
356 | #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
357 | template <typename T> | |
358 | struct call_traits_test<T, true> | |
359 | { | |
360 | typedef ::boost::call_traits<T> ct; | |
361 | typedef typename ct::param_type param_type; | |
362 | typedef typename ct::reference reference; | |
363 | typedef typename ct::const_reference const_reference; | |
364 | typedef typename ct::value_type value_type; | |
365 | static void assert_construct(param_type val); | |
366 | }; | |
367 | ||
368 | template <typename T> | |
369 | void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>::param_type val) | |
370 | { | |
371 | // | |
372 | // this is to check that the call_traits assertions are valid: | |
373 | T t; | |
374 | value_type v(t); | |
375 | value_type v5(val); | |
376 | reference r = t; | |
377 | const_reference cr = t; | |
378 | reference r2 = r; | |
379 | #ifndef __BORLANDC__ | |
380 | // C++ Builder buglet: | |
381 | const_reference cr2 = r; | |
382 | #endif | |
383 | param_type p(t); | |
384 | value_type v2(v); | |
385 | const_reference cr3 = cr; | |
386 | value_type v3(r); | |
387 | value_type v4(p); | |
388 | param_type p2(v); | |
389 | param_type p3(r); | |
390 | param_type p4(p); | |
391 | ||
392 | unused_variable(v2); | |
393 | unused_variable(v3); | |
394 | unused_variable(v4); | |
395 | unused_variable(v5); | |
396 | #ifndef __BORLANDC__ | |
397 | unused_variable(r2); | |
398 | unused_variable(cr2); | |
399 | #endif | |
400 | unused_variable(cr3); | |
401 | unused_variable(p2); | |
402 | unused_variable(p3); | |
403 | unused_variable(p4); | |
404 | } | |
405 | #endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
406 | // | |
407 | // now check call_traits assertions by instantiating call_traits_test: | |
408 | template struct call_traits_test<int>; | |
409 | template struct call_traits_test<const int>; | |
410 | template struct call_traits_test<int*>; | |
411 | #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) | |
412 | template struct call_traits_test<int&>; | |
413 | template struct call_traits_test<const int&>; | |
414 | #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC) | |
415 | template struct call_traits_test<int[2], true>; | |
416 | #endif | |
417 | #endif | |
418 |