// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. // Permission to copy, use, modify, sell and // distribute this software is granted provided this copyright notice appears // in all copies. This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // standalone test program for /* Release notes: 31 Jan 2001: Added a test for is_array using a const array and a test for is_convertible with a user-defined implicit conversion. Changed signature of main() so that this program will link under MSVC. (Jeremy Siek) 20 Jan 2001: Suppress an expected warning for MSVC Added a test to prove that we can use void with is_same<> Removed "press any key to exit" as it interferes with testing in large batches. (David Abahams) 31st July 2000: Added extra tests for is_empty, is_convertible, alignment_of. 23rd July 2000: Removed all call_traits tests to call_traits_test.cpp Removed all compressed_pair tests to compressed_pair_tests.cpp Improved tests macros Tidied up specialistions of type_types classes for test cases. */ #include #include #include #include #include "type_traits_test.hpp" using namespace boost; // Since there is no compiler support, we should specialize: // is_enum for all enumerations (is_enum implies is_POD) // is_union for all unions // is_empty for all empty composites // is_POD for all PODs (except enums) (is_POD implies has_*) // has_* for any UDT that has that trait and is not POD enum enum_UDT{ one, two, three }; struct UDT { UDT(); ~UDT(); UDT(const UDT&); UDT& operator=(const UDT&); int i; void f1(); int f2(); int f3(int); int f4(int, float); }; struct POD_UDT { int x; }; struct empty_UDT{ ~empty_UDT(){}; }; struct empty_POD_UDT{}; union union_UDT { int x; double y; ~union_UDT(); }; union POD_union_UDT { int x; double y; }; union empty_union_UDT { ~empty_union_UDT(); }; union empty_POD_union_UDT{}; #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION namespace boost { template <> struct is_enum { static const bool value = true; }; template <> struct is_POD { static const bool value = true; }; // this type is not POD, so we have to specialize the has_* individually template <> struct has_trivial_constructor { static const bool value = true; }; template <> struct has_trivial_copy { static const bool value = true; }; template <> struct has_trivial_assign { static const bool value = true; }; template <> struct is_POD { static const bool value = true; }; template <> struct is_union { static const bool value = true; }; template <> struct is_union { static const bool value = true; }; template <> struct is_POD { static const bool value = true; }; template <> struct is_union { static const bool value = true; }; // this type is not POD, so we have to specialize the has_* individually template <> struct has_trivial_constructor { static const bool value = true; }; template <> struct has_trivial_copy { static const bool value = true; }; template <> struct has_trivial_assign { static const bool value = true; }; template <> struct is_union { static const bool value = true; }; template <> struct is_POD { static const bool value = true; }; } #else namespace boost { template <> struct is_enum { enum{ value = true }; }; template <> struct is_POD { enum{ value = true }; }; // this type is not POD, so we have to specialize the has_* individually template <> struct has_trivial_constructor { enum{ value = true }; }; template <> struct has_trivial_copy { enum{ value = true }; }; template <> struct has_trivial_assign { enum{ value = true }; }; template <> struct is_POD { enum{ value = true }; }; template <> struct is_union { enum{ value = true }; }; template <> struct is_union { enum{ value = true }; }; template <> struct is_POD { enum{ value = true }; }; template <> struct is_union { enum{ value = true }; }; // this type is not POD, so we have to specialize the has_* individually template <> struct has_trivial_constructor { enum{ value = true }; }; template <> struct has_trivial_copy { enum{ value = true }; }; template <> struct has_trivial_assign { enum{ value = true }; }; template <> struct is_union { enum{ value = true }; }; template <> struct is_POD { enum{ value = true }; }; } #endif class Base { }; class Derived : public Base { }; class NonDerived { }; enum enum1 { one_,two_ }; enum enum2 { three_,four_ }; struct VB { virtual ~VB(){}; }; struct VD : VB { ~VD(){}; }; // // struct non_pointer: // used to verify that is_pointer does not return // true for class types that implement operator void*() // struct non_pointer { operator void*(){return this;} }; // // struct non_empty: // used to verify that is_empty does not emit // spurious warnings or errors. // struct non_empty : boost::noncopyable { int i; }; struct implicitly_convertible_to_int { operator int() { return 0; } }; // Steve: All comments that I (Steve Cleary) have added below are prefixed with // "Steve:" The failures that BCB4 has on the tests are due to Borland's // not considering cv-qual's as a part of the type -- they are considered // compiler hints only. These failures should be fixed before long. int main(int, char*[]) { std::cout << "Checking type operations..." << std::endl << std::endl; // cv-qualifiers applied to reference types should have no effect // declare these here for later use with is_reference and remove_reference: typedef int& r_type; #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable:4181) // qualifier applied to reference type ignored #endif typedef const r_type cr_type; #ifdef BOOST_MSVC # pragma warning(pop) #endif type_test(int, remove_reference::type) type_test(const int, remove_reference::type) type_test(int, remove_reference::type) type_test(const int, remove_reference::type) type_test(volatile int, remove_reference::type) type_test(int, remove_reference::type) type_test(int, remove_const::type) // Steve: fails on BCB4 type_test(volatile int, remove_const::type) // Steve: fails on BCB4 type_test(volatile int, remove_const::type) type_test(int, remove_const::type) type_test(int*, remove_const::type) type_test(int, remove_volatile::type) // Steve: fails on BCB4 type_test(const int, remove_volatile::type) // Steve: fails on BCB4 type_test(const int, remove_volatile::type) type_test(int, remove_volatile::type) type_test(int*, remove_volatile::type) type_test(int, remove_cv::type) type_test(int, remove_cv::type) type_test(int, remove_cv::type) type_test(int, remove_cv::type) type_test(int*, remove_cv::type) type_test(int*, remove_cv::type) type_test(int*, remove_cv::type) type_test(const int *, remove_cv::type) type_test(int, remove_bounds::type) type_test(int*, remove_bounds::type) type_test(int, remove_bounds::type) type_test(int[3], remove_bounds::type) std::cout << std::endl << "Checking type properties..." << std::endl << std::endl; value_test(true, (is_same::value)) value_test(false, (is_same::value)) value_test(false, (is_same::value)) value_test(true, (is_same::value)) value_test(false, (is_same::value)) value_test(false, (is_same::value)) value_test(false, (is_same::value)) value_test(false, (is_same::value)) value_test(false, (is_same::value)) value_test(false, (is_same::value)) value_test(false, (is_same::value)) value_test(false, is_const::value) value_test(true, is_const::value) value_test(false, is_const::value) value_test(true, is_const::value) value_test(false, is_volatile::value) value_test(false, is_volatile::value) value_test(true, is_volatile::value) value_test(true, is_volatile::value) value_test(true, is_void::value) // Steve: fails on BCB4 // JM: but looks as though it should according to [3.9.3p1]? //value_test(false, is_void::value) value_test(false, is_void::value) value_test(false, is_standard_unsigned_integral::value) value_test(false, is_standard_unsigned_integral::value) value_test(false, is_standard_unsigned_integral::value) value_test(false, is_standard_unsigned_integral::value) value_test(false, is_standard_unsigned_integral::value) value_test(true, is_standard_unsigned_integral::value) value_test(false, is_standard_unsigned_integral::value) value_test(false, is_standard_unsigned_integral::value) value_test(true, is_standard_unsigned_integral::value) value_test(false, is_standard_unsigned_integral::value) value_test(true, is_standard_unsigned_integral::value) value_test(false, is_standard_unsigned_integral::value) value_test(true, is_standard_unsigned_integral::value) value_test(false, is_standard_unsigned_integral::value) value_test(false, is_standard_unsigned_integral::value) value_test(false, is_standard_unsigned_integral::value) #ifdef ULLONG_MAX value_test(false, is_standard_unsigned_integral::value) value_test(false, is_standard_unsigned_integral::value) #endif #if defined(__BORLANDC__) || defined(_MSC_VER) value_test(false, is_standard_unsigned_integral<__int64>::value) value_test(false, is_standard_unsigned_integral::value) #endif value_test(false, is_standard_signed_integral::value) value_test(false, is_standard_signed_integral::value) value_test(false, is_standard_signed_integral::value) value_test(false, is_standard_signed_integral::value) value_test(true, is_standard_signed_integral::value) value_test(false, is_standard_signed_integral::value) value_test(false, is_standard_signed_integral::value) value_test(true, is_standard_signed_integral::value) value_test(false, is_standard_signed_integral::value) value_test(true, is_standard_signed_integral::value) value_test(false, is_standard_signed_integral::value) value_test(true, is_standard_signed_integral::value) value_test(false, is_standard_signed_integral::value) value_test(false, is_standard_signed_integral::value) value_test(false, is_standard_signed_integral::value) value_test(false, is_standard_signed_integral::value) #ifdef ULLONG_MAX value_test(false, is_standard_signed_integral::value) value_test(false, is_standard_signed_integral::value) #endif #if defined(__BORLANDC__) || defined(_MSC_VER) value_test(false, is_standard_signed_integral<__int64>::value) value_test(false, is_standard_signed_integral::value) #endif value_test(false, is_standard_arithmetic::value) value_test(false, is_standard_arithmetic::value) value_test(true, is_standard_arithmetic::value) value_test(true, is_standard_arithmetic::value) value_test(true, is_standard_arithmetic::value) value_test(true, is_standard_arithmetic::value) value_test(true, is_standard_arithmetic::value) value_test(true, is_standard_arithmetic::value) value_test(true, is_standard_arithmetic::value) value_test(true, is_standard_arithmetic::value) value_test(true, is_standard_arithmetic::value) value_test(true, is_standard_arithmetic::value) value_test(true, is_standard_arithmetic::value) value_test(true, is_standard_arithmetic::value) value_test(true, is_standard_arithmetic::value) value_test(true, is_standard_arithmetic::value) #ifdef ULLONG_MAX value_test(false, is_standard_arithmetic::value) value_test(false, is_standard_arithmetic::value) #endif #if defined(__BORLANDC__) || defined(_MSC_VER) value_test(false, is_standard_arithmetic<__int64>::value) value_test(false, is_standard_arithmetic::value) #endif value_test(false, is_standard_fundamental::value) value_test(true, is_standard_fundamental::value) value_test(true, is_standard_fundamental::value) value_test(true, is_standard_fundamental::value) value_test(true, is_standard_fundamental::value) value_test(true, is_standard_fundamental::value) value_test(true, is_standard_fundamental::value) value_test(true, is_standard_fundamental::value) value_test(true, is_standard_fundamental::value) value_test(true, is_standard_fundamental::value) value_test(true, is_standard_fundamental::value) value_test(true, is_standard_fundamental::value) value_test(true, is_standard_fundamental::value) value_test(true, is_standard_fundamental::value) value_test(true, is_standard_fundamental::value) value_test(true, is_standard_fundamental::value) #ifdef ULLONG_MAX value_test(false, is_standard_fundamental::value) value_test(false, is_standard_fundamental::value) #endif #if defined(__BORLANDC__) || defined(_MSC_VER) value_test(false, is_standard_fundamental<__int64>::value) value_test(false, is_standard_fundamental::value) #endif value_test(false, is_arithmetic::value) value_test(true, is_arithmetic::value) value_test(true, is_arithmetic::value) value_test(true, is_arithmetic::value) value_test(true, is_arithmetic::value) value_test(true, is_arithmetic::value) value_test(true, is_arithmetic::value) value_test(true, is_arithmetic::value) value_test(true, is_arithmetic::value) value_test(true, is_arithmetic::value) value_test(true, is_arithmetic::value) value_test(true, is_arithmetic::value) value_test(true, is_arithmetic::value) value_test(true, is_arithmetic::value) value_test(true, is_arithmetic::value) #ifdef ULLONG_MAX value_test(true, is_arithmetic::value) value_test(true, is_arithmetic::value) #endif #if defined(__BORLANDC__) || defined(_MSC_VER) value_test(true, is_arithmetic<__int64>::value) value_test(true, is_arithmetic::value) #endif value_test(false, is_array::value) value_test(false, is_array::value) value_test(false, is_array::value) value_test(false, is_array::value) value_test(true, is_array::value) value_test(true, is_array::value) value_test(true, is_array::value) value_test(true, is_array::value) value_test(true, is_array::value) value_test(false, is_array::value) value_test(true, is_array::value) typedef void(*f1)(); typedef int(*f2)(int); typedef int(*f3)(int, bool); typedef void (UDT::*mf1)(); typedef int (UDT::*mf2)(); typedef int (UDT::*mf3)(int); typedef int (UDT::*mf4)(int, float); value_test(false, is_const::value) value_test(false, is_reference::value) value_test(false, is_array::value) value_test(false, is_pointer::value) value_test(false, is_pointer::value) value_test(true, is_pointer::value) value_test(true, is_pointer::value) value_test(true, is_pointer::value) value_test(true, is_pointer::value) // Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1 value_test(false, is_pointer::value) // Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1 value_test(false, is_pointer::value) // Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1 value_test(false, is_pointer::value) // JM 02 Oct 2000: value_test(false, is_pointer::value) value_test(false, is_pointer::value) value_test(false, is_pointer::value) value_test(false, is_pointer::value) value_test(false, is_pointer::value) value_test(true, is_pointer::value) value_test(true, is_pointer::value) value_test(true, is_pointer::value) // Steve: was 'true', should be 'false', via 3.9.2p3 value_test(false, is_pointer::value) // Steve: was 'true', should be 'false', via 3.9.2p3 value_test(false, is_pointer::value) // Steve: was 'true', should be 'false', via 3.9.2p3 value_test(false, is_pointer::value) // Steve: was 'true', should be 'false', via 3.9.2p3 value_test(false, is_pointer::value) value_test(false, is_reference::value) value_test(true, is_reference::value) value_test(true, is_reference::value) value_test(true, is_reference::value) value_test(true, is_reference::value) value_test(true, is_reference::value) value_test(true, is_reference::value) value_test(false, is_class::value) value_test(false, is_class::value) value_test(false, is_class::value) value_test(false, is_class::value) value_test(false, is_class::value) value_test(false, is_class::value) value_test(false, is_class::value) value_test(false, is_class::value) value_test(false, is_class::value) value_test(false, is_class::value) value_test(true, is_class::value) value_test(true, is_class::value) value_test(true, is_class::value) value_test(true, is_class::value) value_test(true, is_class::value) value_test(false, is_class::value) value_test(false, is_class::value) value_test(false, is_class::value) value_test(true, is_object::value) value_test(true, is_object::value) value_test(false, is_object::value) value_test(false, is_object::value) value_test(true, is_standard_scalar::value) value_test(true, is_extension_scalar::value) value_test(false, is_enum::value) value_test(true, is_enum::value) value_test(false, is_member_pointer::value) value_test(false, is_member_pointer::value) value_test(false, is_member_pointer::value) value_test(true, is_member_pointer::value) value_test(true, is_member_pointer::value) value_test(true, is_member_pointer::value) value_test(true, is_member_pointer::value) value_test(false, is_empty::value) value_test(false, is_empty::value) value_test(false, is_empty::value) #if defined(__MWERKS__) || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) // apparent compiler bug causes this to fail to compile: value_fail(false, is_empty::value) #else value_test(false, is_empty::value) #endif #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) value_fail(false, is_empty::value) #else value_test(false, is_empty::value) #endif value_test(false, is_empty::value) value_test(false, is_empty::value) value_test(true, is_empty::value) value_test(true, is_empty::value) #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) value_fail(true, is_empty::value) #else value_test(true, is_empty::value) #endif value_test(false, is_empty::value) value_test(true, is_empty::value) value_test(false, is_empty::value) value_test(true, has_trivial_constructor::value) value_test(true, has_trivial_constructor::value) value_test(true, has_trivial_constructor::value) value_test(true, has_trivial_constructor::value) value_test(true, has_trivial_constructor::value) value_test(true, has_trivial_constructor::value) value_test(true, has_trivial_constructor::value) value_test(true, has_trivial_constructor::value) value_test(true, has_trivial_constructor::value) value_test(true, has_trivial_constructor::value) value_test(false, has_trivial_constructor::value) value_test(true, has_trivial_constructor::value) value_test(true, has_trivial_constructor::value) value_test(true, has_trivial_copy::value) value_test(true, has_trivial_copy::value) value_test(true, has_trivial_copy::value) value_test(true, has_trivial_copy::value) // Steve: was 'false' -- should be 'true' via 3.9p3, 3.9p10 value_test(true, has_trivial_copy::value) value_test(true, has_trivial_copy::value) value_test(true, has_trivial_copy::value) value_test(true, has_trivial_copy::value) value_test(true, has_trivial_copy::value) value_test(true, has_trivial_copy::value) value_test(false, has_trivial_copy::value) value_test(true, has_trivial_copy::value) value_test(true, has_trivial_copy::value) value_test(true, has_trivial_assign::value) value_test(true, has_trivial_assign::value) value_test(true, has_trivial_assign::value) value_test(true, has_trivial_assign::value) // Steve: was 'false' -- should be 'true' via 3.9p3, 3.9p10 value_test(true, has_trivial_assign::value) value_test(true, has_trivial_assign::value) value_test(true, has_trivial_assign::value) value_test(true, has_trivial_assign::value) value_test(true, has_trivial_assign::value) value_test(true, has_trivial_assign::value) value_test(false, has_trivial_assign::value) value_test(true, has_trivial_assign::value) value_test(true, has_trivial_assign::value) value_test(true, has_trivial_destructor::value) value_test(true, has_trivial_destructor::value) value_test(true, has_trivial_destructor::value) value_test(true, has_trivial_destructor::value) value_test(true, has_trivial_destructor::value) value_test(true, has_trivial_destructor::value) value_test(true, has_trivial_destructor::value) value_test(true, has_trivial_destructor::value) value_test(true, has_trivial_destructor::value) value_test(true, has_trivial_destructor::value) value_test(false, has_trivial_destructor::value) value_test(false, has_trivial_destructor::value) value_test(true, has_trivial_destructor::value) value_test(true, is_POD::value) value_test(true, is_POD::value) // Steve: was 'true', should be 'false', via 3.9p10 value_test(false, is_POD::value) value_test(true, is_POD::value) value_test(true, is_POD::value) // Steve: was 'false', should be 'true', via 3.9p10 value_test(true, is_POD::value) // Steve: was 'true', should be 'false', via 3.9p10 value_test(false, is_POD::value) value_test(true, is_POD::value) value_test(true, is_POD::value) value_test(true, is_POD::value) value_test(true, is_POD::value) value_test(true, is_POD::value) value_test(false, is_POD::value) value_test(false, is_POD::value) value_test(true, is_POD::value) value_test(true, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); value_test(false, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); value_test(false, (boost::is_convertible::value)); value_test(false, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) value_test(false, (boost::is_convertible::value)); value_test(false, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); #endif value_test(true, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); value_test(false, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); value_test(false, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); value_test(false, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); value_test(false, (boost::is_convertible::value)); value_test(false, (boost::is_convertible::value)); value_test(false, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); value_test(false, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); value_test(true, (boost::is_convertible::value)); value_test(false, (boost::is_convertible::value)); align_test(int); align_test(char); align_test(double); align_test(int[4]); align_test(int(*)(int)); #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION align_test(char&); align_test(char (&)(int)); align_test(char(&)[4]); #endif align_test(int*); //align_test(const int); align_test(VB); align_test(VD); std::cout << std::endl << test_count << " tests completed (" << failures << " failures)"; return failures; }