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