]> git.lyx.org Git - lyx.git/blob - boost/boost/type_traits/type_traits_test.hpp
update boost
[lyx.git] / boost / boost / type_traits / type_traits_test.hpp
1 //  (C) Copyright John Maddock 2000. Permission to copy, use, modify, sell and   
2 //  distribute this software is granted provided this copyright notice appears   
3 //  in all copies. This software is provided "as is" without express or implied   
4 //  warranty, and with no claim as to its suitability for any purpose.   
5
6 //  common test code for type-traits tests
7 //  WARNING: contains code as well as declarations!
8
9
10 #ifndef BOOST_TYPE_TRAITS_TEST_HPP
11 #define BOOST_TYPE_TRAITS_TEST_HPP
12 #include <iostream>
13 #include <typeinfo>
14 #include <boost/config.hpp>
15 #include <boost/utility.hpp>
16 #include <boost/type_traits/alignment_traits.hpp>
17 //
18 // define tests here
19 unsigned failures = 0;
20 unsigned test_count = 0;
21 //
22 // This must get defined within the test file.
23 // All compilers have bugs, set this to the number of
24 // regressions *expected* from a given compiler,
25 // if there are no workarounds for the bugs, *and*
26 // the regressions have been investigated.
27 //
28 extern unsigned int expected_failures;
29 //
30 // proc check_result()
31 // Checks that there were no regressions:
32 //
33 int check_result(int argc, char** argv)
34 {
35    std::cout << test_count << " tests completed, "
36       << failures << " failures found, "
37       << expected_failures << " failures expected from this compiler." << std::endl;
38    if((argc == 2) 
39       && (argv[1][0] == '-')
40       && (argv[1][1] == 'a')
41       && (argv[1][2] == 0))
42    {
43       std::cout << "Press any key to continue...";
44       std::cin.get();
45    }
46    return (failures == expected_failures)
47        ? 0
48        : (failures != 0) ? static_cast<int>(failures) : -1;
49 }
50
51
52 //
53 // this one is to verify that a constant is indeed a
54 // constant-integral-expression:
55 //
56 // HP aCC cannot deal with missing names for template value parameters
57 template <bool b>
58 struct checker
59 {
60    static void check(bool, bool, const char*, bool){ ++test_count; }
61 };
62
63 template <>
64 struct checker<false>
65 {
66    static void check(bool o, bool n, const char* name, bool soft)
67    {
68       ++test_count;
69       ++failures;
70       // if this is a soft test, then failure is expected,
71       // or may depend upon factors outside our control
72       // (like compiler options)...
73       if(soft)++expected_failures;
74       std::cout << "checking value of " << name << "...failed" << std::endl;
75       std::cout << "\tfound: " << n << " expected " << o << std::endl;
76    }
77 };
78
79 template <class T>
80 struct typify{};
81
82 template <class T, class U>
83 struct type_checker
84 {
85    static void check(const char* TT, const char*, const char* expression)
86    {
87       ++test_count;
88       if(typeid(typify<T>) != typeid(typify<U>))
89       {
90          ++failures;
91          std::cout << "checking type of " << expression << "...failed" << std::endl;
92          std::cout << "   evaluating:  type_checker<" << TT << "," << expression << ">" << std::endl;
93          std::cout << "   expected:    type_checker<" << TT << "," << TT << ">" << std::endl;
94          std::cout << "   but got:     " << typeid(type_checker<T,U>).name() << std::endl;
95       }
96    }
97 };
98
99 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
100 template <class T>
101 struct type_checker<T,T>
102 {
103    static void check(const char*, const char*, const char*)
104    {
105       ++test_count;
106    }
107 };
108 #endif
109
110
111 #define value_test(v, x) checker<(v == x)>::check(v, x, #x, false);
112 #define soft_value_test(v, x) checker<(v == x)>::check(v, x, #x, true);
113
114 #define value_fail(v, x) \
115       ++test_count; \
116       ++failures; \
117       ++expected_failures;\
118       std::cout << "checking value of " << #x << "...failed" << std::endl; \
119       std::cout << "   " #x " does not compile on this compiler" << std::endl;
120
121
122 #define type_test(v, x) type_checker<v,x>::check(#v, #x, #x);
123 #define type_test3(v, x, z) type_checker<v,x,z>::check(#v, #x "," #z, #x "," #z);
124 #ifndef SHORT_TRANSFORM_TEST
125 #define transform_check(name, from_suffix, to_suffix)\
126    type_test(bool to_suffix, name<bool from_suffix>::type);\
127    type_test(char to_suffix, name<char from_suffix>::type);\
128    type_test(wchar_t to_suffix, name<wchar_t from_suffix>::type);\
129    type_test(signed char to_suffix, name<signed char from_suffix>::type);\
130    type_test(unsigned char to_suffix, name<unsigned char from_suffix>::type);\
131    type_test(short to_suffix, name<short from_suffix>::type);\
132    type_test(unsigned short to_suffix, name<unsigned short from_suffix>::type);\
133    type_test(int to_suffix, name<int from_suffix>::type);\
134    type_test(unsigned int to_suffix, name<unsigned int from_suffix>::type);\
135    type_test(long to_suffix, name<long from_suffix>::type);\
136    type_test(unsigned long to_suffix, name<unsigned long from_suffix>::type);\
137    type_test(float to_suffix, name<float from_suffix>::type);\
138    type_test(long double to_suffix, name<long double from_suffix>::type);\
139    type_test(double to_suffix, name<double from_suffix>::type);\
140    type_test(UDT to_suffix, name<UDT from_suffix>::type);\
141    type_test(enum1 to_suffix, name<enum1 from_suffix>::type);
142 #else
143 #define transform_check(name, from_suffix, to_suffix)\
144    type_test(int to_suffix, name<int from_suffix>::type);\
145    type_test(UDT to_suffix, name<UDT from_suffix>::type);\
146    type_test(enum1 to_suffix, name<enum1 from_suffix>::type);
147 #endif
148
149 #define boost_dummy_macro_param
150
151 template <class T>
152 struct test_align
153 {
154    struct padded
155    {
156       char c;
157       T t;
158    };
159    static void do_it()
160    {
161       padded p;
162       unsigned a = reinterpret_cast<char*>(&(p.t)) - reinterpret_cast<char*>(&p);
163       ++test_count;
164       // only fail if we do not have a multiple of the actual value:
165       if((a > ::boost::alignment_of<T>::value) || (a % ::boost::alignment_of<T>::value))
166       {
167          ++failures;
168          std::cout << "checking value of " << typeid(boost::alignment_of<T>).name() << "...failed" << std::endl;
169          std::cout << "\tfound: " << boost::alignment_of<T>::value << " expected " << a << std::endl;
170       }
171       // suppress warnings about unused variables:
172       (void)p;
173       (void)a;
174    }
175 };
176 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
177 template <class T>
178 struct test_align<T&>
179 {
180    static void do_it()
181    {
182       //
183       // we can't do the usual test because we can't take the address
184       // of a reference, so check that the result is the same as for a
185       // pointer type instead:
186       unsigned a = boost::alignment_of<T*>::value;
187       ++test_count;
188       if(a != boost::alignment_of<T&>::value)
189       {
190          ++failures;
191          std::cout << "checking value of " << typeid(boost::alignment_of<T&>).name() << "...failed" << std::endl;
192          std::cout << "\tfound: " << boost::alignment_of<T&>::value << " expected " << a << std::endl;
193       }
194    }
195 };
196 #endif
197
198 #define align_test(T) test_align<T>::do_it()
199
200 template<class T>
201 struct test_type_with_align 
202 {
203   typedef typename boost::type_with_alignment<
204                      (boost::alignment_of<T>::value)>::type 
205     align_t;
206
207   static void do_it()
208   {
209     int align = boost::alignment_of<T>::value;
210     int new_align = boost::alignment_of<align_t>::value;
211     ++test_count;
212     if (new_align % align != 0) {
213       ++failures;
214       std::cerr << "checking for an object with same alignment as " 
215       << typeid(T).name() << "...failed" << std::endl;
216       std::cerr << "\tfound: " << typeid(align_t).name() << std::endl;
217     }
218   }
219 };
220
221 #define type_with_align_test(T) test_type_with_align<T>::do_it()
222
223 //
224 // the following code allows us to test that a particular
225 // template functions correctly when instanciated inside another template
226 // (some bugs only show up in that situation).  For each template
227 // we declare one NESTED_DECL(classname) that sets up the template class
228 // and multiple NESTED_TEST(classname, template-arg) declarations, to carry
229 // the actual tests:
230 template <bool b>
231 struct nested_test
232 {
233    typedef nested_test type;
234    bool run_time_value;
235    const char* what;
236    nested_test(bool b2, const char* w) : run_time_value(b2), what(w) { check(); }
237    void check()
238    {
239       ++test_count;
240       if(b != run_time_value)
241       {
242          ++failures;
243          std::cerr << "Mismatch between runtime and compile time values in " << what << std::endl;
244       }
245    }
246 };
247
248 #ifndef __SUNPRO_CC
249 #define NESTED_DECL(what)\
250 template <class T> \
251 struct BOOST_TT_JOIN(nested_tester_,what){\
252    nested_test< (::boost::type_traits::ice_ne<0, ::boost::what<T>::value>::value)> tester;\
253    BOOST_TT_JOIN(nested_tester_,what)(const char* s) : tester(::boost::what<T>::value, s){}\
254 };
255 #define NESTED_TEST(what, with)\
256 {BOOST_TT_JOIN(nested_tester_,what)<with> check(#what "<" #with ">"); (void)check;}
257 #else
258 #define NESTED_DECL(what)
259 #define NESTED_TEST(what, with)
260 #endif
261
262 #define BOOST_TT_JOIN( X, Y ) BOOST_DO_TT_JOIN( X, Y )
263 #define BOOST_DO_TT_JOIN( X, Y ) X##Y
264
265
266
267 //
268 // define some types to test with:
269 //
270 enum enum_UDT{ one, two, three };
271 struct UDT
272 {
273    UDT(){};
274    ~UDT(){};
275    UDT(const UDT&);
276    UDT& operator=(const UDT&);
277    int i;
278
279    void f1();
280    int f2();
281    int f3(int);
282    int f4(int, float);
283 };
284
285 typedef void(*f1)();
286 typedef int(*f2)(int);
287 typedef int(*f3)(int, bool);
288 typedef void (UDT::*mf1)();
289 typedef int (UDT::*mf2)();
290 typedef int (UDT::*mf3)(int);
291 typedef int (UDT::*mf4)(int, float);
292 typedef int (UDT::*mp);
293 typedef int (UDT::*cmf)(int) const;
294
295 // cv-qualifiers applied to reference types should have no effect
296 // declare these here for later use with is_reference and remove_reference:
297 # ifdef BOOST_MSVC
298 #  pragma warning(push)
299 #  pragma warning(disable: 4181)
300 # elif defined(__ICL)
301 #  pragma warning(push)
302 #  pragma warning(disable: 21)
303 # endif
304 //
305 // This is intentional:
306 // r_type and cr_type should be the same type
307 // but some compilers wrongly apply cv-qualifiers
308 // to reference types (this may generate a warning
309 // on some compilers):
310 //
311 typedef int& r_type;
312 typedef const r_type cr_type;
313 # ifdef BOOST_MSVC
314 #  pragma warning(pop)
315 # elif defined(__ICL)
316 #  pragma warning(pop)
317 #  pragma warning(disable: 985) // identifier truncated in debug information
318 # endif
319
320 struct POD_UDT { int x; };
321 struct empty_UDT
322 {
323    ~empty_UDT(){};
324    empty_UDT& operator=(const empty_UDT&){ return *this; }
325    bool operator==(const empty_UDT&)const
326    { return true; }
327 };
328 struct empty_POD_UDT
329 {
330    empty_POD_UDT& operator=(const empty_POD_UDT&){ return *this; }
331    bool operator==(const empty_POD_UDT&)const
332    { return true; }
333 };
334 union union_UDT
335 {
336   int x;
337   double y;
338   ~union_UDT();
339 };
340 union POD_union_UDT
341 {
342   int x;
343   double y;
344 };
345 union empty_union_UDT
346 {
347   ~empty_union_UDT();
348 };
349 union empty_POD_union_UDT{};
350
351 class Base { };
352
353 class Derived : public Base { };
354
355 class NonDerived { };
356
357 enum enum1
358 {
359    one_,two_
360 };
361
362 enum enum2
363 {
364    three_,four_
365 };
366
367 struct VB
368 {
369    virtual ~VB(){};
370 };
371
372 struct VD : VB
373 {
374    ~VD(){};
375 };
376 //
377 // struct non_pointer:
378 // used to verify that is_pointer does not return
379 // true for class types that implement operator void*()
380 //
381 struct non_pointer
382 {
383    operator void*(){return this;}
384 };
385 struct non_int_pointer
386 {
387    int i;
388    operator int*(){return &i;}
389 };
390 struct int_constructible
391 {
392    int_constructible(int);
393 };
394 struct int_convertible
395 {
396    operator int();
397 };
398 //
399 // struct non_empty:
400 // used to verify that is_empty does not emit
401 // spurious warnings or errors.
402 //
403 struct non_empty : private boost::noncopyable
404 {
405    int i;
406 };
407 //
408 // abstract base classes:
409 struct test_abc1
410 {
411    virtual void foo() = 0;
412    virtual void foo2() = 0;
413 };
414
415 struct test_abc2
416 {
417    virtual void foo() = 0;
418    virtual void foo2() = 0;
419 };
420
421 struct incomplete_type;
422
423
424 #endif // BOOST_TYPE_TRAITS_TEST_HPP
425
426
427
428
429
430
431
432
433
434