blob: 9e86953857864e745b6e2706806b1fea69b1ebd3 [file] [log] [blame]
// -*- C++ -*-
/***************************************************************************
*
* 20.meta.trans.sign.cpp - test exercising meta.trans.sign
*
* $Id$
*
***************************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* Copyright 1999-2008 Rogue Wave Software, Inc.
*
**************************************************************************/
#include <rw_driver.h>
#include <rw/_defs.h>
// compile out all test code if extensions disabled
#ifndef _RWSTD_NO_EXT_CXX_0X
#include <type_traits>
#include <stddef.h>
/**************************************************************************/
template <class T, class U>
struct test_is_same
{
enum { value = 0 };
};
template <class T>
struct test_is_same<T,T>
{
enum { value = 1 };
};
template <class T>
int test_cv_qual (T&) {
return 0;
}
template <class T>
int test_cv_qual (const T&) {
return 1;
}
template <class T>
int test_cv_qual (volatile T&) {
return 2;
}
template <class T>
int test_cv_qual (const volatile T&) {
return 3;
}
enum enum_SS { Ess_v = _RWSTD_SCHAR_MAX };
enum enum_MS { Ems_v = _RWSTD_INT_MAX };
enum enum_LS { Els_v = _RWSTD_LONG_MAX };
enum enum_SU { Esu_v = _RWSTD_UCHAR_MAX };
enum enum_MU { Emu_v = _RWSTD_UINT_MAX };
enum enum_LU { Elu_v = _RWSTD_ULONG_MAX };
/**************************************************************************/
const char* get_type_name (const volatile void*)
{
return "unknown";
}
#define _RETURN_TYPE_NAME(T) \
const char* get_type_name (T*) { return #T; }
#define _RETURN_TYPE_NAME_CV(T) \
_RETURN_TYPE_NAME(T) \
_RETURN_TYPE_NAME(const T) \
_RETURN_TYPE_NAME(volatile T) \
_RETURN_TYPE_NAME(const volatile T)
_RETURN_TYPE_NAME_CV(bool)
_RETURN_TYPE_NAME_CV(char)
#ifndef _RWSTD_NO_WCHAR_T
_RETURN_TYPE_NAME_CV(wchar_t)
#endif // _RWSTD_NO_WCHAR_T
_RETURN_TYPE_NAME_CV( signed char)
_RETURN_TYPE_NAME_CV(unsigned char)
_RETURN_TYPE_NAME_CV( signed short)
_RETURN_TYPE_NAME_CV(unsigned short)
_RETURN_TYPE_NAME_CV( signed int)
_RETURN_TYPE_NAME_CV(unsigned int)
_RETURN_TYPE_NAME_CV( signed long)
_RETURN_TYPE_NAME_CV(unsigned long)
#ifndef _RWSTD_NO_LONG_LONG
_RETURN_TYPE_NAME_CV( signed long long)
_RETURN_TYPE_NAME_CV(unsigned long long)
#endif // _RWSTD_NO_LONG_LONG
void test_trait (int line, bool same,
const char* trait,
const char* typeT,
const char* typeU,
const char* typeV)
{
rw_assert (same, 0, line,
"%s<%s>::type is%{?}n't%{;} %s; got %s",
trait, typeT, !same, typeU, typeV);
}
#define _TEST(Trait,TypeT,TypeU) \
test_trait(__LINE__, \
std::is_same<Trait<TypeT>::type, TypeU>::value, \
#Trait, #TypeT, #TypeU, get_type_name((Trait<TypeT>::type*)0))
#define TEST(Trait,TypeT,TypeU) \
_TEST(Trait, TypeT, TypeU); \
_TEST(Trait, const TypeT, const TypeU); \
_TEST(Trait, volatile TypeT, volatile TypeU); \
_TEST(Trait, const volatile TypeT, const volatile TypeU)
void test_sign_and_cv (int line,
const char* trait_name,
const char* type_name,
size_t got_size, size_t exp_size,
bool got_sign, bool exp_sign,
bool got_c, bool exp_c,
bool got_v, bool exp_v)
{
const char* qualifiers[] = {
"unqualified", "const", "volatile", "cv-qualified"
};
const unsigned got_cv = got_c + (got_v << 1);
const unsigned exp_cv = exp_c + (exp_v << 1);
const bool success = got_size == exp_size
&& got_cv == exp_cv
&& got_sign == exp_sign;
rw_assert (success, 0, line,
"%s<%s>::type is a %zu-byte %s %{?}un%{;}signed type, "
"expected a %zu-byte %s %{?}un%{;}signed type.",
trait_name, type_name,
got_size, qualifiers[got_cv], !got_sign,
exp_size, qualifiers[exp_cv], !exp_sign);
}
#define _TEST_SIGN_AND_CV(Trait,Type,Signed) \
test_sign_and_cv(__LINE__, #Trait, #Type, \
sizeof (Trait<Type>::type), \
sizeof (Type), \
std::is_signed<Trait<Type>::type>::value, \
Signed, \
std::is_const<Trait<Type>::type>::value, \
std::is_const<Type>::value, \
std::is_volatile<Trait<Type>::type>::value, \
std::is_volatile<Type>::value)
#define TEST_MAKE_SIGNED(Type) \
_TEST_SIGN_AND_CV (std::make_signed, Type, true); \
_TEST_SIGN_AND_CV (std::make_signed, const Type, true); \
_TEST_SIGN_AND_CV (std::make_signed, volatile Type, true); \
_TEST_SIGN_AND_CV (std::make_signed, const volatile Type, true)
#define TEST_MAKE_UNSIGNED(Type) \
_TEST_SIGN_AND_CV (std::make_unsigned, Type, false); \
_TEST_SIGN_AND_CV (std::make_unsigned, const Type, false); \
_TEST_SIGN_AND_CV (std::make_unsigned, volatile Type, false); \
_TEST_SIGN_AND_CV (std::make_unsigned, const volatile Type, false)
/**************************************************************************/
static void test_make_signed ()
{
#if (_RWSTD_CHAR_MIN < 0)
TEST (std::make_signed, char, char);
#else
TEST (std::make_signed, char, signed char);
#endif
TEST (std::make_signed, signed char, signed char);
TEST (std::make_signed, unsigned char, signed char); // unsure
TEST (std::make_signed, signed short, signed short);
TEST (std::make_signed, unsigned short, signed short);
TEST (std::make_signed, signed int, signed int);
TEST (std::make_signed, unsigned int, signed int);
TEST (std::make_signed, signed long, signed long);
TEST (std::make_signed, unsigned long, signed long);
#ifndef _RWSTD_NO_LONG_LONG
TEST (std::make_signed, signed long long, signed long long);
TEST (std::make_signed, unsigned long long, signed long long);
#endif // _RWSTD_NO_LONG_LONG
TEST_MAKE_SIGNED (char);
#ifndef _RWSTD_NO_NATIVE_WCHAR_T
TEST_MAKE_SIGNED (wchar_t);
#endif // _RWSTD_NO_NATIVE_WCHAR_T
TEST_MAKE_SIGNED (enum_SS);
TEST_MAKE_SIGNED (enum_MS);
TEST_MAKE_SIGNED (enum_LS);
TEST_MAKE_SIGNED (enum_SU);
TEST_MAKE_SIGNED (enum_MU);
TEST_MAKE_SIGNED (enum_LU);
}
static void test_make_unsigned ()
{
#if (_RWSTD_CHAR_MIN < 0)
TEST (std::make_unsigned, char, unsigned char);
#else
TEST (std::make_unsigned, char, char);
#endif
TEST (std::make_unsigned, signed char, unsigned char); // unsure
TEST (std::make_unsigned, unsigned char, unsigned char);
TEST (std::make_unsigned, signed short, unsigned short);
TEST (std::make_unsigned, unsigned short, unsigned short);
TEST (std::make_unsigned, signed int, unsigned int);
TEST (std::make_unsigned, unsigned int, unsigned int);
TEST (std::make_unsigned, signed long, unsigned long);
TEST (std::make_unsigned, unsigned long, unsigned long);
#ifndef _RWSTD_NO_LONG_LONG
TEST (std::make_unsigned, signed long long, unsigned long long);
TEST (std::make_unsigned, unsigned long long, unsigned long long);
#endif // _RWSTD_NO_LONG_LONG
TEST_MAKE_UNSIGNED (char);
#ifndef _RWSTD_NO_NATIVE_WCHAR_T
TEST_MAKE_UNSIGNED (wchar_t);
#endif // _RWSTD_NO_NATIVE_WCHAR_T
TEST_MAKE_UNSIGNED (enum_SS);
TEST_MAKE_UNSIGNED (enum_MS);
TEST_MAKE_UNSIGNED (enum_LS);
TEST_MAKE_UNSIGNED (enum_SU);
TEST_MAKE_UNSIGNED (enum_MU);
TEST_MAKE_UNSIGNED (enum_LU);
}
/**************************************************************************/
static int run_test (int, char*[])
{
test_make_signed ();
test_make_unsigned ();
return 0;
}
/**************************************************************************/
#else // _RWSTD_NO_EXT_CXX_0X
/**************************************************************************/
static int run_test (int, char*[])
{
rw_warn (0, 0, __LINE__,
"test disabled because _RWSTD_NO_EXT_CXX_0X is defined");
return 0;
}
#endif // !_RWSTD_NO_EXT_CXX_0X
/**************************************************************************/
int main (int argc, char *argv[])
{
return rw_test (argc, argv, __FILE__,
"meta.trans.sign",
0 /* no comment */,
run_test,
0);
}