]> git.lyx.org Git - lyx.git/blob - boost/boost/type_traits/type_traits_test.hpp
update from boost cvs
[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/utility.hpp>
15 //
16 // define tests here
17 unsigned failures = 0;
18 unsigned test_count = 0;
19 //
20 // This must get defined within the test file.
21 // All compilers have bugs, set this to the number of
22 // regressions *expected* from a given compiler,
23 // if there are no workarounds for the bugs, *and*
24 // the regressions have been investigated.
25 //
26 extern unsigned int expected_failures;
27 //
28 // proc check_result()
29 // Checks that there were no regressions:
30 //
31 int check_result(int argc, char** argv)
32 {
33    std::cout << test_count << " tests completed, "
34       << failures << " failures found, "
35       << expected_failures << " failures expected from this compiler." << std::endl;
36    if((argc == 2) 
37         && (argv[1][0] == '-')
38         && (argv[1][1] == 'a')
39         && (argv[1][2] == 0))
40    {
41       std::cout << "Press any key to continue...";
42       std::cin.get();
43    }
44    return (failures == expected_failures) ? 0 : failures;
45 }
46
47
48 //
49 // this one is to verify that a constant is indeed a
50 // constant-integral-expression:
51 //
52 // HP aCC cannot deal with missing names for template value parameters
53 template <bool b>
54 struct checker
55 {
56    static void check(bool, bool, const char*, bool){ ++test_count; }
57 };
58
59 template <>
60 struct checker<false>
61 {
62    static void check(bool o, bool n, const char* name, bool soft)
63    {
64       ++test_count;
65       ++failures;
66       // if this is a soft test, then failure is expected,
67       // or may depend upon factors outside our control
68       // (like compiler options)...
69       if(soft)++expected_failures;
70       std::cout << "checking value of " << name << "...failed" << std::endl;
71       std::cout << "\tfound: " << n << " expected " << o << std::endl;
72    }
73 };
74
75 template <class T, class U>
76 struct type_checker
77 {
78    static void check(const char* TT, const char* TU, const char* expression)
79    {
80       ++test_count;
81 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
82       if((typeid(T) != typeid(U))
83          || (::boost::is_reference<T>::value != ::boost::is_reference<U>::value)
84          || (::boost::is_const<T>::value != ::boost::is_const<U>::value)
85          || (::boost::is_volatile<T>::value != ::boost::is_volatile<U>::value))
86       {
87 #endif
88          ++failures;
89          std::cout << "checking type of " << expression << "...failed" << std::endl;
90          std::cout << "   expected type was " << TT << std::endl;
91          std::cout << "   typeid(" << TT << ") was: " << typeid(T).name() << std::endl;
92          std::cout << "   typeid(" << TU << ") was: " << typeid(U).name() << std::endl;
93          std::cout << "   In template class " << typeid(type_checker<T,U>).name() << std::endl;
94 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
95       }
96 #endif
97    }
98 };
99
100 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
101 template <class T>
102 struct type_checker<T,T>
103 {
104    static void check(const char*, const char*, const char*)
105    {
106       ++test_count;
107    }
108 };
109 #endif
110
111
112 #define value_test(v, x) checker<(v == x)>::check(v, x, #x, false);
113 #define soft_value_test(v, x) checker<(v == x)>::check(v, x, #x, true);
114
115 #define value_fail(v, x) \
116       ++test_count; \
117       ++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 //
201 // the following code allows us to test that a particular
202 // template functions correctly when instanciated inside another template
203 // (some bugs only show up in that situation).  For each template
204 // we declare one NESTED_DECL(classname) that sets up the template class
205 // and multiple NESTED_TEST(classname, template-arg) declarations, to carry
206 // the actual tests:
207 template <bool b>
208 struct nested_test
209 {
210    typedef nested_test type;
211    bool run_time_value;
212    const char* what;
213    nested_test(bool b2, const char* w) : run_time_value(b2), what(w) { check(); }
214    void check()
215    {
216       ++test_count;
217       if(b != run_time_value)
218       {
219          ++failures;
220          std::cerr << "Mismatch between runtime and compile time values in " << what << std::endl;
221       }
222    }
223 };
224
225 #ifndef __SUNPRO_CC
226 #define NESTED_DECL(what)\
227 template <class T> \
228 struct BOOST_TT_JOIN(nested_tester_,what){\
229    nested_test< (::boost::type_traits::ice_ne<0, ::boost::what<T>::value>::value)> tester;\
230    BOOST_TT_JOIN(nested_tester_,what)(const char* s) : tester(::boost::what<T>::value, s){}\
231 };
232 #define NESTED_TEST(what, with)\
233 {BOOST_TT_JOIN(nested_tester_,what)<with> check(#what "<" #with ">"); (void)check;}
234 #else
235 #define NESTED_DECL(what)
236 #define NESTED_TEST(what, with)
237 #endif
238
239 #define BOOST_TT_JOIN( X, Y ) BOOST_DO_TT_JOIN( X, Y )
240 #define BOOST_DO_TT_JOIN( X, Y ) X##Y
241
242
243
244 //
245 // define some types to test with:
246 //
247 enum enum_UDT{ one, two, three };
248 struct UDT
249 {
250    UDT(){};
251    ~UDT(){};
252    UDT(const UDT&);
253    UDT& operator=(const UDT&);
254    int i;
255
256    void f1();
257    int f2();
258    int f3(int);
259    int f4(int, float);
260 };
261
262 typedef void(*f1)();
263 typedef int(*f2)(int);
264 typedef int(*f3)(int, bool);
265 typedef void (UDT::*mf1)();
266 typedef int (UDT::*mf2)();
267 typedef int (UDT::*mf3)(int);
268 typedef int (UDT::*mf4)(int, float);
269 typedef int (UDT::*mp);
270
271 // cv-qualifiers applied to reference types should have no effect
272 // declare these here for later use with is_reference and remove_reference:
273 # ifdef BOOST_MSVC
274 #  pragma warning(push)
275 #  pragma warning(disable: 4181)
276 # endif // BOOST_MSVC
277 typedef int& r_type;
278 typedef const r_type cr_type;
279 # ifdef BOOST_MSVC
280 #  pragma warning(pop)
281 # endif // BOOST_MSVC
282
283 struct POD_UDT { int x; };
284 struct empty_UDT
285 {
286    ~empty_UDT(){};
287    empty_UDT& operator=(const empty_UDT&){ return *this; }
288    bool operator==(const empty_UDT&)const
289    { return true; }
290 };
291 struct empty_POD_UDT
292 {
293    empty_POD_UDT& operator=(const empty_POD_UDT&){ return *this; }
294    bool operator==(const empty_POD_UDT&)const
295    { return true; }
296 };
297 union union_UDT
298 {
299   int x;
300   double y;
301   ~union_UDT();
302 };
303 union POD_union_UDT
304 {
305   int x;
306   double y;
307 };
308 union empty_union_UDT
309 {
310   ~empty_union_UDT();
311 };
312 union empty_POD_union_UDT{};
313
314 class Base { };
315
316 class Deriverd : public Base { };
317
318 class NonDerived { };
319
320 enum enum1
321 {
322    one_,two_
323 };
324
325 enum enum2
326 {
327    three_,four_
328 };
329
330 struct VB
331 {
332    virtual ~VB(){};
333 };
334
335 struct VD : VB
336 {
337    ~VD(){};
338 };
339 //
340 // struct non_pointer:
341 // used to verify that is_pointer does not return
342 // true for class types that implement operator void*()
343 //
344 struct non_pointer
345 {
346    operator void*(){return this;}
347 };
348 struct non_int_pointer
349 {
350    int i;
351    operator int*(){return &i;}
352 };
353 struct int_constructible
354 {
355    int_constructible(int);
356 };
357 struct int_convertible
358 {
359    operator int();
360 };
361 //
362 // struct non_empty:
363 // used to verify that is_empty does not emit
364 // spurious warnings or errors.
365 //
366 struct non_empty : boost::noncopyable
367 {
368    int i;
369 };
370 //
371 // abstract base classes:
372 struct test_abc1
373 {
374    virtual void foo() = 0;
375    virtual void foo2() = 0;
376 };
377
378 struct test_abc2
379 {
380    virtual void foo() = 0;
381    virtual void foo2() = 0;
382 };
383
384
385 #endif // BOOST_TYPE_TRAITS_TEST_HPP
386
387
388
389
390
391
392
393