From 76fcc1f65ee3e175e0c827a0d762ac4755e1fe01 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Sun, 24 Sep 2000 11:35:25 +0000 Subject: [PATCH] addition of INTXX_C support to integer library [SVN r7792] --- cstdint_test.cpp | 224 +++++++++++++++++++++++++++++++------- include/boost/cstdint.hpp | 7 +- include/boost/stdint.h | 122 ++++++++++++++++++++- integer_traits_test.cpp | 4 +- 4 files changed, 316 insertions(+), 41 deletions(-) diff --git a/cstdint_test.cpp b/cstdint_test.cpp index 3a6c938..2ca4499 100644 --- a/cstdint_test.cpp +++ b/cstdint_test.cpp @@ -9,66 +9,216 @@ // See http://www.boost.org for most recent version including documentation. // Revision History +// 23 Sept 00 Added INTXX_C constant macro support + int64_t support (John Maddock). // 28 Jun 00 Initial version - -#include #include #include +#include +// +// macros should not be defined by default: +// +#ifdef INT8_C +#error header incorrectly implemented +#endif +// +// now define the macros: +// +#define __STDC_CONSTANT_MACROS +#include #ifdef NDEBUG #error This test makes no sense with NDEBUG defined #endif +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +// +// the following class is designed to verify +// that the various INTXX_C macros can be used +// in integral constant expressions: +// +struct integral_constant_checker +{ + static const boost::int8_t int8 = INT8_C(-127); + static const boost::int_least8_t int_least8 = INT8_C(-127); + static const boost::int_fast8_t int_fast8 = INT8_C(-127); + + static const boost::uint8_t uint8 = UINT8_C(255); + static const boost::uint_least8_t uint_least8 = UINT8_C(255); + static const boost::uint_fast8_t uint_fast8 = UINT8_C(255); + + static const boost::int16_t int16 = INT16_C(-32767); + static const boost::int_least16_t int_least16 = INT16_C(-32767); + static const boost::int_fast16_t int_fast16 = INT16_C(-32767); + + static const boost::uint16_t uint16 = UINT16_C(65535); + static const boost::uint_least16_t uint_least16 = UINT16_C(65535); + static const boost::uint_fast16_t uint_fast16 = UINT16_C(65535); + + static const boost::int32_t int32 = INT32_C(-2147483647); + static const boost::int_least32_t int_least32 = INT32_C(-2147483647); + static const boost::int_fast32_t int_fast32 = INT32_C(-2147483647); + + static const boost::uint32_t uint32 = UINT32_C(4294967295); + static const boost::uint_least32_t uint_least32 = UINT32_C(4294967295); + static const boost::uint_fast32_t uint_fast32 = UINT32_C(4294967295); + + static void check(); +}; + +void integral_constant_checker::check() +{ + assert( int8 == -127 ); + assert( int_least8 == -127 ); + assert( int_fast8 == -127 ); + assert( uint8 == 255u ); + assert( uint_least8 == 255u ); + assert( uint_fast8 == 255u ); + assert( int16 == -32767 ); + assert( int_least16 == -32767 ); + assert( int_fast16 == -32767 ); + assert( uint16 == 65535u ); + assert( uint_least16 == 65535u ); + assert( uint_fast16 == 65535u ); + assert( int32 == -2147483647 ); + assert( int_least32 == -2147483647 ); + assert( int_fast32 == -2147483647 ); + assert( uint32 == 4294967295u ); + assert( uint_least32 == 4294967295u ); + assert( uint_fast32 == 4294967295u ); +} +#endif + +// +// the following function simply verifies that the type +// of an integral constant is correctly defined: +// +#ifdef __BORLANDC__ +#pragma option -w-8008 +#pragma option -w-8066 +#endif +template +void integral_constant_type_check(T1, T2) +{ + // + // the types T1 and T2 may not be exactly + // the same type, but they should be the + // same size and signedness. We could use + // numeric_limits to verify this, but + // numeric_limits implementations currently + // vary too much, or are incomplete or missing. + // + assert(sizeof(T1) == sizeof(T2)); + T1 t1 = -1; + T2 t2 = -1; + assert(t1 == t2); + if(t1 >= 0)assert(t2 >= 0); + else assert(t2 < 0); +} + + int main() { - boost::int8_t int8 = -127; - boost::int_least8_t int_least8 = -127; - boost::int_fast8_t int_fast8 = -127; +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION + integral_constant_checker::check(); +#endif + // + // verify the types of the integral constants: + // + integral_constant_type_check(int8_t(0), INT8_C(0)); + integral_constant_type_check(uint8_t(0), UINT8_C(0)); + integral_constant_type_check(int16_t(0), INT16_C(0)); + integral_constant_type_check(uint16_t(0), UINT16_C(0)); + integral_constant_type_check(int32_t(0), INT32_C(0)); + integral_constant_type_check(uint32_t(0), UINT32_C(0)); +#ifndef BOOST_NO_INT64_T + integral_constant_type_check(int64_t(0), INT64_C(0)); + integral_constant_type_check(uint64_t(0), UINT64_C(0)); +#endif + // + boost::int8_t int8 = INT8_C(-127); + boost::int_least8_t int_least8 = INT8_C(-127); + boost::int_fast8_t int_fast8 = INT8_C(-127); - boost::uint8_t uint8 = 255; - boost::uint_least8_t uint_least8 = 255; - boost::uint_fast8_t uint_fast8 = 255; - - boost::int16_t int16 = -32767; - boost::int_least16_t int_least16 = -32767; - boost::int_fast16_t int_fast16 = -32767; - - boost::uint16_t uint16 = 65535; - boost::uint_least16_t uint_least16 = 65535; - boost::uint_fast16_t uint_fast16 = 65535; - - boost::int32_t int32 = -2147483647; - boost::int_least32_t int_least32 = -2147483647; - boost::int_fast32_t int_fast32 = -2147483647; - - boost::uint32_t uint32 = 4294967295; - boost::uint_least32_t uint_least32 = 4294967295; - boost::uint_fast32_t uint_fast32 = 4294967295; + boost::uint8_t uint8 = UINT8_C(255); + boost::uint_least8_t uint_least8 = UINT8_C(255); + boost::uint_fast8_t uint_fast8 = UINT8_C(255); - boost::intmax_t intmax = -2147483647; - boost::uintmax_t uintmax = 4294967295; + boost::int16_t int16 = INT16_C(-32767); + boost::int_least16_t int_least16 = INT16_C(-32767); + boost::int_fast16_t int_fast16 = INT16_C(-32767); + + boost::uint16_t uint16 = UINT16_C(65535); + boost::uint_least16_t uint_least16 = UINT16_C(65535); + boost::uint_fast16_t uint_fast16 = UINT16_C(65535); + + boost::int32_t int32 = INT32_C(-2147483647); + boost::int_least32_t int_least32 = INT32_C(-2147483647); + boost::int_fast32_t int_fast32 = INT32_C(-2147483647); + + boost::uint32_t uint32 = UINT32_C(4294967295); + boost::uint_least32_t uint_least32 = UINT32_C(4294967295); + boost::uint_fast32_t uint_fast32 = UINT32_C(4294967295); + +#ifndef BOOST_NO_INT64_T + boost::int64_t int64 = INT64_C(-9223372036854775807); + boost::int_least64_t int_least64 = INT64_C(-9223372036854775807); + boost::int_fast64_t int_fast64 = INT64_C(-9223372036854775807); + + boost::uint64_t uint64 = UINT64_C(18446744073709551615); + boost::uint_least64_t uint_least64 = UINT64_C(18446744073709551615); + boost::uint_fast64_t uint_fast64 = UINT64_C(18446744073709551615); + + boost::intmax_t intmax = INTMAX_C(-9223372036854775807); + boost::uintmax_t uintmax = UINTMAX_C(18446744073709551615); +#else + boost::intmax_t intmax = INTMAX_C(-2147483647); + boost::uintmax_t uintmax = UINTMAX_C(4294967295); +#endif assert( int8 == -127 ); assert( int_least8 == -127 ); assert( int_fast8 == -127 ); - assert( uint8 == 255 ); - assert( uint_least8 == 255 ); - assert( uint_fast8 == 255 ); + assert( uint8 == 255u ); + assert( uint_least8 == 255u ); + assert( uint_fast8 == 255u ); assert( int16 == -32767 ); assert( int_least16 == -32767 ); assert( int_fast16 == -32767 ); - assert( uint16 == 65535 ); - assert( uint_least16 == 65535 ); - assert( uint_fast16 == 65535 ); + assert( uint16 == 65535u ); + assert( uint_least16 == 65535u ); + assert( uint_fast16 == 65535u ); assert( int32 == -2147483647 ); assert( int_least32 == -2147483647 ); assert( int_fast32 == -2147483647 ); - assert( uint32 == 4294967295 ); - assert( uint_least32 == 4294967295 ); - assert( uint_fast32 == 4294967295 ); + assert( uint32 == 4294967295u ); + assert( uint_least32 == 4294967295u ); + assert( uint_fast32 == 4294967295u ); + +#ifndef BOOST_NO_INT64_T + assert( int64 == INT64_C(-9223372036854775807) ); + assert( int_least64 == INT64_C(-9223372036854775807) ); + assert( int_fast64 == INT64_C(-9223372036854775807) ); + assert( uint64 == UINT64_C(18446744073709551615) ); + assert( uint_least64 == UINT64_C(18446744073709551615) ); + assert( uint_fast64 == UINT64_C(18446744073709551615) ); + assert( intmax == INT64_C(-9223372036854775807) ); + assert( uintmax == UINT64_C(18446744073709551615) ); +#else assert( intmax == -2147483647 ); - assert( uintmax == 4294967295 ); + assert( uintmax == 4294967295u ); +#endif + std::cout << "OK\n"; return 0; -} \ No newline at end of file +} + +// +// now verify that constant macros get undef'ed correctly: +// +#undef __STDC_CONSTANT_MACROS +#include + +#ifdef INT8_C +#error stdint.h not correctly defined +#endif diff --git a/include/boost/cstdint.hpp b/include/boost/cstdint.hpp index 3f8a92f..f2c5131 100644 --- a/include/boost/cstdint.hpp +++ b/include/boost/cstdint.hpp @@ -9,16 +9,20 @@ // See http://www.boost.org for most recent version including documentation. // Revision History +// 23 Sep 00 Added INTXX_C macro support (John Maddock). // 22 Sep 00 Better 64-bit support (John Maddock) // 29 Jun 00 Reimplement to avoid including stdint.h within namespace boost // 8 Aug 99 Initial version (Beman Dawes) +// +// this has to go before the include guard (JM): +#include + #ifndef BOOST_CSTDINT_HPP #define BOOST_CSTDINT_HPP #include // implementation artifact; not part of interface -#include namespace boost { @@ -61,3 +65,4 @@ namespace boost } // namespace boost #endif + diff --git a/include/boost/stdint.h b/include/boost/stdint.h index 2b84bb2..4de159d 100644 --- a/include/boost/stdint.h +++ b/include/boost/stdint.h @@ -12,6 +12,7 @@ // this header. // Revision History +// 23 Sep 00 INTXX_C support added (John Maddock) // 22 Sep 00 64-bit support for Borland & Microsoft compilers (John Maddock) // 8 Aug 99 Initial version (Beman Dawes) @@ -84,8 +85,8 @@ // 64-bit types + intmax_t and uintmax_t -----------------------------------// -# if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) -# if (defined(ULLONG_MAX) && ULLONG_MAX == 18446744073709551615) || \ +# if (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX)) && !(defined(_WIN32) && defined(__GNUC__)) +# if(defined(ULLONG_MAX) && ULLONG_MAX == 18446744073709551615) || \ (defined(ULONG_LONG_MAX) && ULONG_LONG_MAX == 18446744073709551615) // 2**64 - 1 typedef long long intmax_t; @@ -133,3 +134,120 @@ #endif // BOOST_SYSTEM_HAS_STDINT_H not defined #endif // BOOST_STDINT_H + +/**************************************************** + +Macro definition section: + +Define various INTXX_C macros only if +__STDC_CONSTANT_MACROS is defined. + +Undefine the macros if __STDC_CONSTANT_MACROS is +not defined and the macros are (cf ). + +Added 23rd September (John Maddock). + +******************************************************/ + +#if defined(__STDC_CONSTANT_MACROS) && !defined(BOOST__STDC_CONSTANT_MACROS_DEFINED) +#define BOOST__STDC_CONSTANT_MACROS_DEFINED +#if (defined(BOOST_MSVC) && (BOOST_MSVC >= 1100)) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x520)) +// +// Borland/Microsoft compilers have width specific suffixes: +// +#define INT8_C(value) value##i8 +#define INT16_C(value) value##i16 +#define INT32_C(value) value##i32 +#define INT64_C(value) value##i64 +#ifdef __BORLANDC__ +// Borland bug: appending ui8 makes the type +// a signed char!!!! +#define UINT8_C(value) static_cast(value##u) +#else +#define UINT8_C(value) value##ui8 +#endif +#define UINT16_C(value) value##ui16 +#define UINT32_C(value) value##ui32 +#define UINT64_C(value) value##ui64 +#define INTMAX_C(value) value##i64 +#define UINTMAX_C(value) value##ui64 + +#else +// do it the old fashioned way: +// 8-bit types -------------------------------------------------------------// + +# if UCHAR_MAX == 0xff +#define INT8_C(value) static_cast(value) +#define UINT8_C(value) static_cast(value##u) +# endif + +// 16-bit types ------------------------------------------------------------// + +# if USHRT_MAX == 0xffff +#define INT16_C(value) static_cast(value) +#define UINT16_C(value) static_cast(value##u) +# endif + +// 32-bit types ------------------------------------------------------------// + +# if UINT_MAX == 0xffffffff +#define INT32_C(value) value +#define UINT32_C(value) value##u +# elif ULONG_MAX == 0xffffffff +#define INT32_C(value) value##L +#define UINT32_C(value) value##uL +# endif + +// 64-bit types + intmax_t and uintmax_t -----------------------------------// + +# if defined(ULLONG_MAX) +# if ULLONG_MAX == 18446744073709551615 // 2**64 - 1 +#define INT64_C(value) value##LL +#define UINT64_C(value) value##uLL +# else +# error defaults not correct; you must hand modify boost/stdint.hpp +# endif +# elif ULONG_MAX != 0xffffffff + +# if ULONG_MAX == 18446744073709551615 // 2**64 - 1 +#define INT64_C(value) value##L +#define UINT64_C(value) value##uL +# else +# error defaults not correct; you must hand modify boost/stdint.hpp +# endif +# elif (defined(BOOST_MSVC) && (BOOST_MSVC >= 1100)) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x520)) + // + // we have Borland/Microsoft __int64: + // +#define INT64_C(value) value##i64 +#define UINT64_C(value) value##ui64 +# endif + +#ifdef BOOST_NO_INT64_T +#define INTMAX_C(value) INT32_C(value) +#define UINTMAX_C(value) UINT32_C(value) +#else +#define INTMAX_C(value) INT64_C(value) +#define UINTMAX_C(value) UINT64_C(value) +#endif + +#endif // Borland/MS specific + +#elif defined(BOOST__STDC_CONSTANT_MACROS_DEFINED) && !defined(__STDC_CONSTANT_MACROS) +// +// undef all the macros: +// +#undef INT8_C +#undef INT16_C +#undef INT32_C +#undef INT64_C +#undef UINT8_C +#undef UINT16_C +#undef UINT32_C +#undef UINT64_C +#undef INTMAX_C +#undef UINTMAX_C + +#endif // constant macros + + diff --git a/integer_traits_test.cpp b/integer_traits_test.cpp index f785149..5a62fad 100644 --- a/integer_traits_test.cpp +++ b/integer_traits_test.cpp @@ -70,7 +70,9 @@ int main() runtest("long", long()); typedef unsigned long unsigned_long; runtest("unsigned long", unsigned_long()); -#ifndef BOOST_NO_INT64_T +#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_MSVC) && !defined(__BORLANDC__) + // + // MS/Borland compilers can't support 64-bit member constants runtest("int64_t (possibly long long)", boost::int64_t()); runtest("uint64_t (possibly unsigned long long)", boost::uint64_t()); #endif