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(w: test_wrap_type(t: 2), u: 2); |
233 | #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC) |
234 | check_wrap(w: test_wrap_type(t: a), u: a); |
235 | check_make_pair(c: test::make_pair(t1: a, t2: a), u: a, v: 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 | |
419 | |