mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-21 03:29:40 +00:00
435 lines
11 KiB
C++
435 lines
11 KiB
C++
|
// (C) Copyright 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.
|
||
|
|
||
|
// common test code for type-traits tests
|
||
|
// WARNING: contains code as well as declarations!
|
||
|
|
||
|
|
||
|
#ifndef BOOST_TYPE_TRAITS_TEST_HPP
|
||
|
#define BOOST_TYPE_TRAITS_TEST_HPP
|
||
|
#include <iostream>
|
||
|
#include <typeinfo>
|
||
|
#include <boost/config.hpp>
|
||
|
#include <boost/utility.hpp>
|
||
|
#include <boost/type_traits/alignment_traits.hpp>
|
||
|
//
|
||
|
// define tests here
|
||
|
unsigned failures = 0;
|
||
|
unsigned test_count = 0;
|
||
|
//
|
||
|
// This must get defined within the test file.
|
||
|
// All compilers have bugs, set this to the number of
|
||
|
// regressions *expected* from a given compiler,
|
||
|
// if there are no workarounds for the bugs, *and*
|
||
|
// the regressions have been investigated.
|
||
|
//
|
||
|
extern unsigned int expected_failures;
|
||
|
//
|
||
|
// proc check_result()
|
||
|
// Checks that there were no regressions:
|
||
|
//
|
||
|
int check_result(int argc, char** argv)
|
||
|
{
|
||
|
std::cout << test_count << " tests completed, "
|
||
|
<< failures << " failures found, "
|
||
|
<< expected_failures << " failures expected from this compiler." << std::endl;
|
||
|
if((argc == 2)
|
||
|
&& (argv[1][0] == '-')
|
||
|
&& (argv[1][1] == 'a')
|
||
|
&& (argv[1][2] == 0))
|
||
|
{
|
||
|
std::cout << "Press any key to continue...";
|
||
|
std::cin.get();
|
||
|
}
|
||
|
return (failures == expected_failures)
|
||
|
? 0
|
||
|
: (failures != 0) ? static_cast<int>(failures) : -1;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// this one is to verify that a constant is indeed a
|
||
|
// constant-integral-expression:
|
||
|
//
|
||
|
// HP aCC cannot deal with missing names for template value parameters
|
||
|
template <bool b>
|
||
|
struct checker
|
||
|
{
|
||
|
static void check(bool, bool, const char*, bool){ ++test_count; }
|
||
|
};
|
||
|
|
||
|
template <>
|
||
|
struct checker<false>
|
||
|
{
|
||
|
static void check(bool o, bool n, const char* name, bool soft)
|
||
|
{
|
||
|
++test_count;
|
||
|
++failures;
|
||
|
// if this is a soft test, then failure is expected,
|
||
|
// or may depend upon factors outside our control
|
||
|
// (like compiler options)...
|
||
|
if(soft)++expected_failures;
|
||
|
std::cout << "checking value of " << name << "...failed" << std::endl;
|
||
|
std::cout << "\tfound: " << n << " expected " << o << std::endl;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template <class T>
|
||
|
struct typify{};
|
||
|
|
||
|
template <class T, class U>
|
||
|
struct type_checker
|
||
|
{
|
||
|
static void check(const char* TT, const char*, const char* expression)
|
||
|
{
|
||
|
++test_count;
|
||
|
if(typeid(typify<T>) != typeid(typify<U>))
|
||
|
{
|
||
|
++failures;
|
||
|
std::cout << "checking type of " << expression << "...failed" << std::endl;
|
||
|
std::cout << " evaluating: type_checker<" << TT << "," << expression << ">" << std::endl;
|
||
|
std::cout << " expected: type_checker<" << TT << "," << TT << ">" << std::endl;
|
||
|
std::cout << " but got: " << typeid(type_checker<T,U>).name() << std::endl;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||
|
template <class T>
|
||
|
struct type_checker<T,T>
|
||
|
{
|
||
|
static void check(const char*, const char*, const char*)
|
||
|
{
|
||
|
++test_count;
|
||
|
}
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#define value_test(v, x) checker<(v == x)>::check(v, x, #x, false);
|
||
|
#define soft_value_test(v, x) checker<(v == x)>::check(v, x, #x, true);
|
||
|
|
||
|
#define value_fail(v, x) \
|
||
|
++test_count; \
|
||
|
++failures; \
|
||
|
++expected_failures;\
|
||
|
std::cout << "checking value of " << #x << "...failed" << std::endl; \
|
||
|
std::cout << " " #x " does not compile on this compiler" << std::endl;
|
||
|
|
||
|
|
||
|
#define type_test(v, x) type_checker<v,x>::check(#v, #x, #x);
|
||
|
#define type_test3(v, x, z) type_checker<v,x,z>::check(#v, #x "," #z, #x "," #z);
|
||
|
#ifndef SHORT_TRANSFORM_TEST
|
||
|
#define transform_check(name, from_suffix, to_suffix)\
|
||
|
type_test(bool to_suffix, name<bool from_suffix>::type);\
|
||
|
type_test(char to_suffix, name<char from_suffix>::type);\
|
||
|
type_test(wchar_t to_suffix, name<wchar_t from_suffix>::type);\
|
||
|
type_test(signed char to_suffix, name<signed char from_suffix>::type);\
|
||
|
type_test(unsigned char to_suffix, name<unsigned char from_suffix>::type);\
|
||
|
type_test(short to_suffix, name<short from_suffix>::type);\
|
||
|
type_test(unsigned short to_suffix, name<unsigned short from_suffix>::type);\
|
||
|
type_test(int to_suffix, name<int from_suffix>::type);\
|
||
|
type_test(unsigned int to_suffix, name<unsigned int from_suffix>::type);\
|
||
|
type_test(long to_suffix, name<long from_suffix>::type);\
|
||
|
type_test(unsigned long to_suffix, name<unsigned long from_suffix>::type);\
|
||
|
type_test(float to_suffix, name<float from_suffix>::type);\
|
||
|
type_test(long double to_suffix, name<long double from_suffix>::type);\
|
||
|
type_test(double to_suffix, name<double from_suffix>::type);\
|
||
|
type_test(UDT to_suffix, name<UDT from_suffix>::type);\
|
||
|
type_test(enum1 to_suffix, name<enum1 from_suffix>::type);
|
||
|
#else
|
||
|
#define transform_check(name, from_suffix, to_suffix)\
|
||
|
type_test(int to_suffix, name<int from_suffix>::type);\
|
||
|
type_test(UDT to_suffix, name<UDT from_suffix>::type);\
|
||
|
type_test(enum1 to_suffix, name<enum1 from_suffix>::type);
|
||
|
#endif
|
||
|
|
||
|
#define boost_dummy_macro_param
|
||
|
|
||
|
template <class T>
|
||
|
struct test_align
|
||
|
{
|
||
|
struct padded
|
||
|
{
|
||
|
char c;
|
||
|
T t;
|
||
|
};
|
||
|
static void do_it()
|
||
|
{
|
||
|
padded p;
|
||
|
unsigned a = reinterpret_cast<char*>(&(p.t)) - reinterpret_cast<char*>(&p);
|
||
|
++test_count;
|
||
|
// only fail if we do not have a multiple of the actual value:
|
||
|
if((a > ::boost::alignment_of<T>::value) || (a % ::boost::alignment_of<T>::value))
|
||
|
{
|
||
|
++failures;
|
||
|
std::cout << "checking value of " << typeid(boost::alignment_of<T>).name() << "...failed" << std::endl;
|
||
|
std::cout << "\tfound: " << boost::alignment_of<T>::value << " expected " << a << std::endl;
|
||
|
}
|
||
|
// suppress warnings about unused variables:
|
||
|
(void)p;
|
||
|
(void)a;
|
||
|
}
|
||
|
};
|
||
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||
|
template <class T>
|
||
|
struct test_align<T&>
|
||
|
{
|
||
|
static void do_it()
|
||
|
{
|
||
|
//
|
||
|
// we can't do the usual test because we can't take the address
|
||
|
// of a reference, so check that the result is the same as for a
|
||
|
// pointer type instead:
|
||
|
unsigned a = boost::alignment_of<T*>::value;
|
||
|
++test_count;
|
||
|
if(a != boost::alignment_of<T&>::value)
|
||
|
{
|
||
|
++failures;
|
||
|
std::cout << "checking value of " << typeid(boost::alignment_of<T&>).name() << "...failed" << std::endl;
|
||
|
std::cout << "\tfound: " << boost::alignment_of<T&>::value << " expected " << a << std::endl;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
#define align_test(T) test_align<T>::do_it()
|
||
|
|
||
|
template<class T>
|
||
|
struct test_type_with_align
|
||
|
{
|
||
|
typedef typename boost::type_with_alignment<
|
||
|
(boost::alignment_of<T>::value)>::type
|
||
|
align_t;
|
||
|
|
||
|
static void do_it()
|
||
|
{
|
||
|
int align = boost::alignment_of<T>::value;
|
||
|
int new_align = boost::alignment_of<align_t>::value;
|
||
|
++test_count;
|
||
|
if (new_align % align != 0) {
|
||
|
++failures;
|
||
|
std::cerr << "checking for an object with same alignment as "
|
||
|
<< typeid(T).name() << "...failed" << std::endl;
|
||
|
std::cerr << "\tfound: " << typeid(align_t).name() << std::endl;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
#define type_with_align_test(T) test_type_with_align<T>::do_it()
|
||
|
|
||
|
//
|
||
|
// the following code allows us to test that a particular
|
||
|
// template functions correctly when instanciated inside another template
|
||
|
// (some bugs only show up in that situation). For each template
|
||
|
// we declare one NESTED_DECL(classname) that sets up the template class
|
||
|
// and multiple NESTED_TEST(classname, template-arg) declarations, to carry
|
||
|
// the actual tests:
|
||
|
template <bool b>
|
||
|
struct nested_test
|
||
|
{
|
||
|
typedef nested_test type;
|
||
|
bool run_time_value;
|
||
|
const char* what;
|
||
|
nested_test(bool b2, const char* w) : run_time_value(b2), what(w) { check(); }
|
||
|
void check()
|
||
|
{
|
||
|
++test_count;
|
||
|
if(b != run_time_value)
|
||
|
{
|
||
|
++failures;
|
||
|
std::cerr << "Mismatch between runtime and compile time values in " << what << std::endl;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
#ifndef __SUNPRO_CC
|
||
|
#define NESTED_DECL(what)\
|
||
|
template <class T> \
|
||
|
struct BOOST_TT_JOIN(nested_tester_,what){\
|
||
|
nested_test< (::boost::type_traits::ice_ne<0, ::boost::what<T>::value>::value)> tester;\
|
||
|
BOOST_TT_JOIN(nested_tester_,what)(const char* s) : tester(::boost::what<T>::value, s){}\
|
||
|
};
|
||
|
#define NESTED_TEST(what, with)\
|
||
|
{BOOST_TT_JOIN(nested_tester_,what)<with> check(#what "<" #with ">"); (void)check;}
|
||
|
#else
|
||
|
#define NESTED_DECL(what)
|
||
|
#define NESTED_TEST(what, with)
|
||
|
#endif
|
||
|
|
||
|
#define BOOST_TT_JOIN( X, Y ) BOOST_DO_TT_JOIN( X, Y )
|
||
|
#define BOOST_DO_TT_JOIN( X, Y ) X##Y
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// define some types to test with:
|
||
|
//
|
||
|
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);
|
||
|
};
|
||
|
|
||
|
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);
|
||
|
typedef int (UDT::*mp);
|
||
|
typedef int (UDT::*cmf)(int) const;
|
||
|
|
||
|
// cv-qualifiers applied to reference types should have no effect
|
||
|
// declare these here for later use with is_reference and remove_reference:
|
||
|
# ifdef BOOST_MSVC
|
||
|
# pragma warning(push)
|
||
|
# pragma warning(disable: 4181)
|
||
|
# elif defined(__ICL)
|
||
|
# pragma warning(push)
|
||
|
# pragma warning(disable: 21)
|
||
|
# endif
|
||
|
//
|
||
|
// This is intentional:
|
||
|
// r_type and cr_type should be the same type
|
||
|
// but some compilers wrongly apply cv-qualifiers
|
||
|
// to reference types (this may generate a warning
|
||
|
// on some compilers):
|
||
|
//
|
||
|
typedef int& r_type;
|
||
|
typedef const r_type cr_type;
|
||
|
# ifdef BOOST_MSVC
|
||
|
# pragma warning(pop)
|
||
|
# elif defined(__ICL)
|
||
|
# pragma warning(pop)
|
||
|
# pragma warning(disable: 985) // identifier truncated in debug information
|
||
|
# endif
|
||
|
|
||
|
struct POD_UDT { int x; };
|
||
|
struct empty_UDT
|
||
|
{
|
||
|
~empty_UDT(){};
|
||
|
empty_UDT& operator=(const empty_UDT&){ return *this; }
|
||
|
bool operator==(const empty_UDT&)const
|
||
|
{ return true; }
|
||
|
};
|
||
|
struct empty_POD_UDT
|
||
|
{
|
||
|
empty_POD_UDT& operator=(const empty_POD_UDT&){ return *this; }
|
||
|
bool operator==(const empty_POD_UDT&)const
|
||
|
{ return true; }
|
||
|
};
|
||
|
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{};
|
||
|
|
||
|
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_int_pointer
|
||
|
{
|
||
|
int i;
|
||
|
operator int*(){return &i;}
|
||
|
};
|
||
|
struct int_constructible
|
||
|
{
|
||
|
int_constructible(int);
|
||
|
};
|
||
|
struct int_convertible
|
||
|
{
|
||
|
operator int();
|
||
|
};
|
||
|
//
|
||
|
// struct non_empty:
|
||
|
// used to verify that is_empty does not emit
|
||
|
// spurious warnings or errors.
|
||
|
//
|
||
|
struct non_empty : private boost::noncopyable
|
||
|
{
|
||
|
int i;
|
||
|
};
|
||
|
//
|
||
|
// abstract base classes:
|
||
|
struct test_abc1
|
||
|
{
|
||
|
virtual void foo() = 0;
|
||
|
virtual void foo2() = 0;
|
||
|
};
|
||
|
|
||
|
struct test_abc2
|
||
|
{
|
||
|
virtual void foo() = 0;
|
||
|
virtual void foo2() = 0;
|
||
|
};
|
||
|
|
||
|
struct incomplete_type;
|
||
|
|
||
|
|
||
|
#endif // BOOST_TYPE_TRAITS_TEST_HPP
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|