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.
6 // common test code for type-traits tests
7 // WARNING: contains code as well as declarations!
10 #ifndef BOOST_TYPE_TRAITS_TEST_HPP
11 #define BOOST_TYPE_TRAITS_TEST_HPP
14 #include <boost/utility.hpp>
17 unsigned failures = 0;
18 unsigned test_count = 0;
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.
26 extern unsigned int expected_failures;
28 // proc check_result()
29 // Checks that there were no regressions:
31 int check_result(int argc, char** argv)
33 std::cout << test_count << " tests completed, "
34 << failures << " failures found, "
35 << expected_failures << " failures expected from this compiler." << std::endl;
37 && (argv[1][0] == '-')
38 && (argv[1][1] == 'a')
41 std::cout << "Press any key to continue...";
44 return (failures == expected_failures) ? 0 : failures;
49 // this one is to verify that a constant is indeed a
50 // constant-integral-expression:
52 // HP aCC cannot deal with missing names for template value parameters
56 static void check(bool, bool, const char*, bool){ ++test_count; }
62 static void check(bool o, bool n, const char* name, bool soft)
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;
75 template <class T, class U>
78 static void check(const char* TT, const char* TU, const char* expression)
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))
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
100 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
102 struct type_checker<T,T>
104 static void check(const char*, const char*, const char*)
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);
115 #define value_fail(v, x) \
118 std::cout << "checking value of " << #x << "...failed" << std::endl; \
119 std::cout << " " #x " does not compile on this compiler" << std::endl;
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);
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);
149 #define boost_dummy_macro_param
162 unsigned a = reinterpret_cast<char*>(&(p.t)) - reinterpret_cast<char*>(&p);
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))
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;
171 // suppress warnings about unused variables:
176 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
178 struct test_align<T&>
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;
188 if(a != boost::alignment_of<T&>::value)
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;
198 #define align_test(T) test_align<T>::do_it()
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
210 typedef nested_test type;
213 nested_test(bool b2, const char* w) : run_time_value(b2), what(w) { check(); }
217 if(b != run_time_value)
220 std::cerr << "Mismatch between runtime and compile time values in " << what << std::endl;
226 #define NESTED_DECL(what)\
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){}\
232 #define NESTED_TEST(what, with)\
233 {BOOST_TT_JOIN(nested_tester_,what)<with> check(#what "<" #with ">"); (void)check;}
235 #define NESTED_DECL(what)
236 #define NESTED_TEST(what, with)
239 #define BOOST_TT_JOIN( X, Y ) BOOST_DO_TT_JOIN( X, Y )
240 #define BOOST_DO_TT_JOIN( X, Y ) X##Y
245 // define some types to test with:
247 enum enum_UDT{ one, two, three };
253 UDT& operator=(const UDT&);
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);
271 // cv-qualifiers applied to reference types should have no effect
272 // declare these here for later use with is_reference and remove_reference:
274 # pragma warning(push)
275 # pragma warning(disable: 4181)
276 # endif // BOOST_MSVC
278 typedef const r_type cr_type;
280 # pragma warning(pop)
281 # endif // BOOST_MSVC
283 struct POD_UDT { int x; };
287 empty_UDT& operator=(const empty_UDT&){ return *this; }
288 bool operator==(const empty_UDT&)const
293 empty_POD_UDT& operator=(const empty_POD_UDT&){ return *this; }
294 bool operator==(const empty_POD_UDT&)const
308 union empty_union_UDT
312 union empty_POD_union_UDT{};
316 class Deriverd : public Base { };
318 class NonDerived { };
340 // struct non_pointer:
341 // used to verify that is_pointer does not return
342 // true for class types that implement operator void*()
346 operator void*(){return this;}
348 struct non_int_pointer
351 operator int*(){return &i;}
353 struct int_constructible
355 int_constructible(int);
357 struct int_convertible
363 // used to verify that is_empty does not emit
364 // spurious warnings or errors.
366 struct non_empty : boost::noncopyable
371 // abstract base classes:
374 virtual void foo() = 0;
375 virtual void foo2() = 0;
380 virtual void foo() = 0;
381 virtual void foo2() = 0;
385 #endif // BOOST_TYPE_TRAITS_TEST_HPP