Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/utility/call_traits_test.cpp @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 15.6 KB
Line 
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 <cassert>
16#include <iostream>
17#include <iomanip>
18#include <algorithm>
19#include <typeinfo>
20#include <boost/call_traits.hpp>
21
22#include <libs/type_traits/test/test.hpp>
23#include <libs/type_traits/test/check_type.hpp>
24
25//
26// define tests here
27unsigned failures = 0;
28unsigned test_count = 0;
29//
30// This must get defined within the test file.
31// All compilers have bugs, set this to the number of
32// regressions *expected* from a given compiler,
33// if there are no workarounds for the bugs, *and*
34// the regressions have been investigated.
35//
36extern unsigned int expected_failures;
37//
38// proc check_result()
39// Checks that there were no regressions:
40//
41int check_result(int argc, char** argv)
42{
43   std::cout << test_count << " tests completed, "
44      << failures << " failures found, "
45      << expected_failures << " failures expected from this compiler." << std::endl;
46   if((argc == 2) 
47      && (argv[1][0] == '-')
48      && (argv[1][1] == 'a')
49      && (argv[1][2] == 0))
50   {
51      std::cout << "Press any key to continue...";
52      std::cin.get();
53   }
54   return (failures == expected_failures)
55       ? 0
56       : (failures != 0) ? static_cast<int>(failures) : -1;
57}
58
59// a way prevent warnings for unused variables
60template<class T> inline void unused_variable(const T&) {}
61
62//
63// struct contained models a type that contains a type (for example std::pair)
64// arrays are contained by value, and have to be treated as a special case:
65//
66template <class T>
67struct contained
68{
69   // define our typedefs first, arrays are stored by value
70   // so value_type is not the same as result_type:
71   typedef typename boost::call_traits<T>::param_type       param_type;
72   typedef typename boost::call_traits<T>::reference        reference;
73   typedef typename boost::call_traits<T>::const_reference  const_reference;
74   typedef T                                                value_type;
75   typedef typename boost::call_traits<T>::value_type       result_type;
76
77   // stored value:
78   value_type v_;
79   
80   // constructors:
81   contained() {}
82   contained(param_type p) : v_(p){}
83   // return byval:
84   result_type value()const { return v_; }
85   // return by_ref:
86   reference get() { return v_; }
87   const_reference const_get()const { return v_; }
88   // pass value:
89   void call(param_type){}
90
91};
92
93#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
94template <class T, std::size_t N>
95struct contained<T[N]>
96{
97   typedef typename boost::call_traits<T[N]>::param_type       param_type;
98   typedef typename boost::call_traits<T[N]>::reference        reference;
99   typedef typename boost::call_traits<T[N]>::const_reference  const_reference;
100   typedef T                                                   value_type[N];
101   typedef typename boost::call_traits<T[N]>::value_type       result_type;
102
103   value_type v_;
104
105   contained(param_type p)
106   {
107      std::copy(p, p+N, v_);
108   }
109   // return byval:
110   result_type value()const { return v_; }
111   // return by_ref:
112   reference get() { return v_; }
113   const_reference const_get()const { return v_; }
114   void call(param_type){}
115};
116#endif
117
118template <class T>
119contained<typename boost::call_traits<T>::value_type> test_wrap_type(const T& t)
120{
121   typedef typename boost::call_traits<T>::value_type ct;
122   return contained<ct>(t);
123}
124
125namespace test{
126
127template <class T1, class T2>
128std::pair<
129   typename boost::call_traits<T1>::value_type,
130   typename boost::call_traits<T2>::value_type>
131      make_pair(const T1& t1, const T2& t2)
132{
133   return std::pair<
134      typename boost::call_traits<T1>::value_type,
135      typename boost::call_traits<T2>::value_type>(t1, t2);
136}
137
138} // namespace test
139
140using namespace std;
141
142//
143// struct call_traits_checker:
144// verifies behaviour of contained example:
145//
146template <class T>
147struct call_traits_checker
148{
149   typedef typename boost::call_traits<T>::param_type param_type;
150   void operator()(param_type);
151};
152
153template <class T>
154void call_traits_checker<T>::operator()(param_type p)
155{
156   T t(p);
157   contained<T> c(t);
158   cout << "checking contained<" << typeid(T).name() << ">..." << endl;
159   assert(t == c.value());
160   assert(t == c.get());
161   assert(t == c.const_get());
162#ifndef __ICL
163   //cout << "typeof contained<" << typeid(T).name() << ">::v_ is:           " << typeid(&contained<T>::v_).name() << endl;
164   cout << "typeof contained<" << typeid(T).name() << ">::value() is:      " << typeid(&contained<T>::value).name() << endl;
165   cout << "typeof contained<" << typeid(T).name() << ">::get() is:        " << typeid(&contained<T>::get).name() << endl;
166   cout << "typeof contained<" << typeid(T).name() << ">::const_get() is:  " << typeid(&contained<T>::const_get).name() << endl;
167   cout << "typeof contained<" << typeid(T).name() << ">::call() is:       " << typeid(&contained<T>::call).name() << endl;
168   cout << endl;
169#endif
170}
171
172#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
173template <class T, std::size_t N>
174struct call_traits_checker<T[N]>
175{
176   typedef typename boost::call_traits<T[N]>::param_type param_type;
177   void operator()(param_type t)
178   {
179      contained<T[N]> c(t);
180      cout << "checking contained<" << typeid(T[N]).name() << ">..." << endl;
181      unsigned int i = 0;
182      for(i = 0; i < N; ++i)
183         assert(t[i] == c.value()[i]);
184      for(i = 0; i < N; ++i)
185         assert(t[i] == c.get()[i]);
186      for(i = 0; i < N; ++i)
187         assert(t[i] == c.const_get()[i]);
188
189      cout << "typeof contained<" << typeid(T[N]).name() << ">::v_ is:         " << typeid(&contained<T[N]>::v_).name() << endl;
190      cout << "typeof contained<" << typeid(T[N]).name() << ">::value is:      " << typeid(&contained<T[N]>::value).name() << endl;
191      cout << "typeof contained<" << typeid(T[N]).name() << ">::get is:        " << typeid(&contained<T[N]>::get).name() << endl;
192      cout << "typeof contained<" << typeid(T[N]).name() << ">::const_get is:  " << typeid(&contained<T[N]>::const_get).name() << endl;
193      cout << "typeof contained<" << typeid(T[N]).name() << ">::call is:       " << typeid(&contained<T[N]>::call).name() << endl;
194      cout << endl;
195   }
196};
197#endif
198
199//
200// check_wrap:
201template <class W, class U>
202void check_wrap(const W& w, const U& u)
203{
204   cout << "checking " << typeid(W).name() << "..." << endl;
205   assert(w.value() == u);
206}
207
208//
209// check_make_pair:
210// verifies behaviour of "make_pair":
211//
212template <class T, class U, class V>
213void check_make_pair(T c, U u, V v)
214{
215   cout << "checking std::pair<" << typeid(c.first).name() << ", " << typeid(c.second).name() << ">..." << endl;
216   assert(c.first == u);
217   assert(c.second == v);
218   cout << endl;
219}
220
221
222struct comparible_UDT
223{
224   int i_;
225   comparible_UDT() : i_(2){}
226   comparible_UDT(const comparible_UDT& other) : i_(other.i_){}
227   comparible_UDT& operator=(const comparible_UDT& other)
228   { 
229      i_ = other.i_;
230      return *this;
231   }
232   bool operator == (const comparible_UDT& v){ return v.i_ == i_; }
233};
234
235int main(int argc, char *argv[ ])
236{
237   call_traits_checker<comparible_UDT> c1;
238   comparible_UDT u;
239   c1(u);
240   call_traits_checker<int> c2;
241   int i = 2;
242   c2(i);
243   int* pi = &i;
244   int a[2] = {1,2};
245#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) && !defined(__ICL)
246   call_traits_checker<int*> c3;
247   c3(pi);
248   call_traits_checker<int&> c4;
249   c4(i);
250   call_traits_checker<const int&> c5;
251   c5(i);
252#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__MWERKS__) && !defined(__SUNPRO_CC)
253   call_traits_checker<int[2]> c6;
254   c6(a);
255#endif
256#endif
257
258   check_wrap(test_wrap_type(2), 2);
259#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC)
260   check_wrap(test_wrap_type(a), a);
261   check_make_pair(test::make_pair(a, a), a, a);
262#endif
263
264   // cv-qualifiers applied to reference types should have no effect
265   // declare these here for later use with is_reference and remove_reference:
266   typedef int& r_type;
267   typedef const r_type cr_type;
268
269   BOOST_CHECK_TYPE(comparible_UDT, boost::call_traits<comparible_UDT>::value_type);
270   BOOST_CHECK_TYPE(comparible_UDT&, boost::call_traits<comparible_UDT>::reference);
271   BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::const_reference);
272   BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::param_type);
273   BOOST_CHECK_TYPE(int, boost::call_traits<int>::value_type);
274   BOOST_CHECK_TYPE(int&, boost::call_traits<int>::reference);
275   BOOST_CHECK_TYPE(const int&, boost::call_traits<int>::const_reference);
276   BOOST_CHECK_TYPE(const int, boost::call_traits<int>::param_type);
277   BOOST_CHECK_TYPE(int*, boost::call_traits<int*>::value_type);
278   BOOST_CHECK_TYPE(int*&, boost::call_traits<int*>::reference);
279   BOOST_CHECK_TYPE(int*const&, boost::call_traits<int*>::const_reference);
280   BOOST_CHECK_TYPE(int*const, boost::call_traits<int*>::param_type);
281#if defined(BOOST_MSVC6_MEMBER_TEMPLATES)
282   BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::value_type);
283   BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::reference);
284   BOOST_CHECK_TYPE(const int&, boost::call_traits<int&>::const_reference);
285   BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::param_type);
286#if !(defined(__GNUC__) && ((__GNUC__ < 3) || (__GNUC__ == 3) && (__GNUC_MINOR__ < 1)))
287   BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::value_type);
288   BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::reference);
289   BOOST_CHECK_TYPE(const int&, boost::call_traits<cr_type>::const_reference);
290   BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::param_type);
291#else
292   std::cout << "Your compiler cannot instantiate call_traits<int&const>, skipping four tests (4 errors)" << std::endl;
293   failures += 4;
294   test_count += 4;
295#endif
296   BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::value_type);
297   BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::reference);
298   BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::const_reference);
299   BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::param_type);
300#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
301   BOOST_CHECK_TYPE(const int*, boost::call_traits<int[3]>::value_type);
302   BOOST_CHECK_TYPE(int(&)[3], boost::call_traits<int[3]>::reference);
303   BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<int[3]>::const_reference);
304   BOOST_CHECK_TYPE(const int*const, boost::call_traits<int[3]>::param_type);
305   BOOST_CHECK_TYPE(const int*, boost::call_traits<const int[3]>::value_type);
306   BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::reference);
307   BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::const_reference);
308   BOOST_CHECK_TYPE(const int*const, boost::call_traits<const int[3]>::param_type);
309   // test with abstract base class:
310   BOOST_CHECK_TYPE(test_abc1, boost::call_traits<test_abc1>::value_type);
311   BOOST_CHECK_TYPE(test_abc1&, boost::call_traits<test_abc1>::reference);
312   BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::const_reference);
313   BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::param_type);
314#else
315   std::cout << "You're compiler does not support partial template specialiation, skipping 8 tests (8 errors)" << std::endl;
316   failures += 12;
317   test_count += 12;
318#endif
319#else
320   std::cout << "You're compiler does not support partial template specialiation, skipping 20 tests (20 errors)" << std::endl;
321   failures += 24;
322   test_count += 24;
323#endif
324   // test with an incomplete type:
325   BOOST_CHECK_TYPE(incomplete_type, boost::call_traits<incomplete_type>::value_type);
326   BOOST_CHECK_TYPE(incomplete_type&, boost::call_traits<incomplete_type>::reference);
327   BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::const_reference);
328   BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::param_type);
329
330   return check_result(argc, argv);
331}
332
333//
334// define call_traits tests to check that the assertions in the docs do actually work
335// this is an instantiate only set of tests:
336//
337template <typename T, bool isarray = false>
338struct call_traits_test
339{
340   typedef ::boost::call_traits<T> ct;
341   typedef typename ct::param_type param_type;
342   typedef typename ct::reference reference;
343   typedef typename ct::const_reference const_reference;
344   typedef typename ct::value_type value_type;
345   static void assert_construct(param_type val);
346};
347
348template <typename T, bool isarray>
349void call_traits_test<T, isarray>::assert_construct(typename call_traits_test<T, isarray>::param_type val)
350{
351   //
352   // this is to check that the call_traits assertions are valid:
353   T t(val);
354   value_type v(t);
355   reference r(t);
356   const_reference cr(t);
357   param_type p(t);
358   value_type v2(v);
359   value_type v3(r);
360   value_type v4(p);
361   reference r2(v);
362   reference r3(r);
363   const_reference cr2(v);
364   const_reference cr3(r);
365   const_reference cr4(cr);
366   const_reference cr5(p);
367   param_type p2(v);
368   param_type p3(r);
369   param_type p4(p);
370   
371   unused_variable(v2);
372   unused_variable(v3);
373   unused_variable(v4);
374   unused_variable(r2);
375   unused_variable(r3);
376   unused_variable(cr2);
377   unused_variable(cr3);
378   unused_variable(cr4);
379   unused_variable(cr5);
380   unused_variable(p2);
381   unused_variable(p3);
382   unused_variable(p4);
383}
384#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
385template <typename T>
386struct call_traits_test<T, true>
387{
388   typedef ::boost::call_traits<T> ct;
389   typedef typename ct::param_type param_type;
390   typedef typename ct::reference reference;
391   typedef typename ct::const_reference const_reference;
392   typedef typename ct::value_type value_type;
393   static void assert_construct(param_type val);
394};
395
396template <typename T>
397void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>::param_type val)
398{
399   //
400   // this is to check that the call_traits assertions are valid:
401   T t;
402   value_type v(t);
403   value_type v5(val);
404   reference r = t;
405   const_reference cr = t;
406   reference r2 = r;
407   #ifndef __BORLANDC__
408   // C++ Builder buglet:
409   const_reference cr2 = r;
410   #endif
411   param_type p(t);
412   value_type v2(v);
413   const_reference cr3 = cr;
414   value_type v3(r);
415   value_type v4(p);
416   param_type p2(v);
417   param_type p3(r);
418   param_type p4(p);
419   
420   unused_variable(v2);
421   unused_variable(v3);
422   unused_variable(v4);
423   unused_variable(v5);
424#ifndef __BORLANDC__
425   unused_variable(r2);
426   unused_variable(cr2);
427#endif
428   unused_variable(cr3);
429   unused_variable(p2);
430   unused_variable(p3);
431   unused_variable(p4);
432}
433#endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
434//
435// now check call_traits assertions by instantiating call_traits_test:
436template struct call_traits_test<int>;
437template struct call_traits_test<const int>;
438template struct call_traits_test<int*>;
439#if defined(BOOST_MSVC6_MEMBER_TEMPLATES)
440template struct call_traits_test<int&>;
441template struct call_traits_test<const int&>;
442#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC)
443template struct call_traits_test<int[2], true>;
444#endif
445#endif
446
447#if defined(BOOST_MSVC) && _MSC_VER <= 1300
448unsigned int expected_failures = 12;
449#elif defined(__SUNPRO_CC)
450#if(__SUNPRO_CC <= 0x520)
451unsigned int expected_failures = 18;
452#elif(__SUNPRO_CC < 0x530)
453unsigned int expected_failures = 17;
454#else
455unsigned int expected_failures = 6;
456#endif
457#elif defined(__BORLANDC__)
458unsigned int expected_failures = 2;
459#elif (defined(__GNUC__) && ((__GNUC__ < 3) || (__GNUC__ == 3) && (__GNUC_MINOR__ < 1)))
460unsigned int expected_failures = 4;
461#elif defined(__HP_aCC)
462unsigned int expected_failures = 24;
463#else
464unsigned int expected_failures = 0;
465#endif
466
Note: See TracBrowser for help on using the repository browser.