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
29template<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//
35template <class T>
36struct 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){}
59private:
60 contained& operator=(const contained&);
61};
62
63#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
64template <class T, std::size_t N>
65struct 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){}
85private:
86 contained& operator=(const contained&);
87};
88#endif
89
90template <class T>
91contained<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
97namespace test{
98
99template <class T1, class T2>
100std::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
112using namespace std;
113
114//
115// struct call_traits_checker:
116// verifies behaviour of contained example:
117//
118template <class T>
119struct call_traits_checker
120{
121 typedef typename boost::call_traits<T>::param_type param_type;
122 void operator()(param_type);
123};
124
125template <class T>
126void 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
145template <class T, std::size_t N>
146struct 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:
173template <class W, class U>
174void 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//
184template <class T, class U, class V>
185void 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
194struct 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
207int 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//
309template <typename T, bool isarray = false>
310struct 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
320template <typename T, bool isarray>
321void 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
357template <typename T>
358struct 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
368template <typename T>
369void 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:
408template struct call_traits_test<int>;
409template struct call_traits_test<const int>;
410template struct call_traits_test<int*>;
411#if defined(BOOST_MSVC6_MEMBER_TEMPLATES)
412template struct call_traits_test<int&>;
413template struct call_traits_test<const int&>;
414#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC)
415template struct call_traits_test<int[2], true>;
416#endif
417#endif
418
419

source code of boost/libs/utility/call_traits_test.cpp