mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-30 20:40:28 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			214 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			214 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* boost limits_test.cpp   test your <limits> file for important
 | |
|  *
 | |
|  * Copyright Jens Maurer 2000
 | |
|  * Distributed under the Boost Software License, Version 1.0. (See
 | |
|  * accompanying file LICENSE_1_0.txt or copy at
 | |
|  * http://www.boost.org/LICENSE_1_0.txt)
 | |
|  *
 | |
|  * $Id$
 | |
|  */
 | |
| 
 | |
| #include <boost/limits.hpp>
 | |
| #include <boost/detail/lightweight_main.hpp>
 | |
| #include <boost/core/lightweight_test.hpp>
 | |
| #include <iostream>
 | |
| 
 | |
| /*
 | |
|  * General portability note:
 | |
|  * MSVC mis-compiles explicit function template instantiations.
 | |
|  * For example, f<A>() and f<B>() are both compiled to call f<A>().
 | |
|  * BCC is unable to implicitly convert a "const char *" to a std::string
 | |
|  * when using explicit function template instantiations.
 | |
|  *
 | |
|  * Therefore, avoid explicit function template instantiations.
 | |
|  */
 | |
| #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
 | |
| template<typename T> inline T make_char_numeric_for_streaming(T x) { return x; }
 | |
| namespace fix{
 | |
| inline int make_char_numeric_for_streaming(char c) { return c; }
 | |
| inline int make_char_numeric_for_streaming(signed char c) { return c; }
 | |
| inline int make_char_numeric_for_streaming(unsigned char c) { return c; }
 | |
| }
 | |
| using namespace fix;
 | |
| #  if defined(_YVALS) && !defined(_CPPLIB_VER) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
 | |
| // fix for missing operator<< in original Dinkumware lib:
 | |
| std::ostream& operator<<(std::ostream& os, __int64 i )
 | |
| {
 | |
|     char buf[80];
 | |
|     sprintf(buf,"%I64d", i );
 | |
|     os << buf;
 | |
|     return os;
 | |
| }
 | |
| std::ostream& operator<<(std::ostream& os, unsigned __int64 i )
 | |
| {
 | |
|     char buf[80];
 | |
|     sprintf(buf,"%I64u", i );
 | |
|     os << buf;
 | |
|     return os;
 | |
| }
 | |
| #  endif
 | |
| #else
 | |
| template<typename T> inline T make_char_numeric_for_streaming(T x) { return x; }
 | |
| inline int make_char_numeric_for_streaming(char c) { return c; }
 | |
| inline int make_char_numeric_for_streaming(signed char c) { return c; }
 | |
| inline int make_char_numeric_for_streaming(unsigned char c) { return c; }
 | |
| #endif
 | |
| 
 | |
| #if (defined(_GLIBCPP_VERSION) || defined(_GLIBCXX_VERSION)) \
 | |
|    && defined(BOOST_HAS_LONG_LONG) \
 | |
|    && !defined(_GLIBCPP_USE_LONG_LONG) \
 | |
|    && !defined(_GLIBCXX_USE_LONG_LONG)
 | |
| //
 | |
| // Some libstdc++ versions have numeric_limits<long long> but no
 | |
| // iostream support for long long.  TODO, find a better fix!!
 | |
| //
 | |
| std::ostream& operator<<(std::ostream& os, long long i )
 | |
| {
 | |
|     return os << static_cast<long double>(i);
 | |
| }
 | |
| std::ostream& operator<<(std::ostream& os, unsigned long long i )
 | |
| {
 | |
|     return os << static_cast<long double>(i);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| template<class T>
 | |
| void test_integral_limits(const T &, const char * msg)
 | |
| {
 | |
|   typedef std::numeric_limits<T> lim;
 | |
|   std::cout << "Testing " << msg
 | |
|             << " (size " << sizeof(T) << ")"
 | |
|             << " min: " << make_char_numeric_for_streaming((lim::min)())
 | |
|             << ", max: " << make_char_numeric_for_streaming((lim::max)())
 | |
|             << std::endl;
 | |
| 
 | |
|   BOOST_TEST(static_cast<bool>(lim::is_specialized));
 | |
|   BOOST_TEST(static_cast<bool>(lim::is_integer));
 | |
|   // BOOST_TEST(lim::is_modulo);
 | |
|   BOOST_TEST(static_cast<bool>((lim::min)() < (lim::max)()));
 | |
| }
 | |
| 
 | |
| template <class T>
 | |
| void print_hex_val(T t, const char* name)
 | |
| {
 | |
|   const unsigned char* p = (const unsigned char*)&t;
 | |
|   std::cout << "hex value of " << name << " is: ";
 | |
|   for (unsigned int i = 0; i < sizeof(T); ++i) {
 | |
|     if(p[i] <= 0xF)
 | |
|       std::cout << "0";
 | |
|     std::cout << std::hex << (int)p[i];
 | |
|   }
 | |
|   std::cout << std::dec << std::endl;
 | |
| }
 | |
| 
 | |
| template<class T>
 | |
| void test_float_limits(const T &, const char * msg)
 | |
| {
 | |
|   std::cout << "\nTesting " << msg << std::endl;
 | |
|   typedef std::numeric_limits<T> lim;
 | |
| 
 | |
|   BOOST_TEST(static_cast<bool>(lim::is_specialized));
 | |
|   BOOST_TEST(static_cast<bool>(!lim::is_modulo));
 | |
|   BOOST_TEST(static_cast<bool>(!lim::is_integer));
 | |
|   BOOST_TEST(static_cast<bool>(lim::is_signed));
 | |
| 
 | |
|   const T infinity = lim::infinity();
 | |
|   const T qnan = lim::quiet_NaN();
 | |
|   const T snan = lim::signaling_NaN();
 | |
| 
 | |
|   std::cout << "IEEE-compatible: " << lim::is_iec559
 | |
|        << ", traps: " << lim::traps
 | |
|        << ", bounded: " << lim::is_bounded
 | |
|        << ", exact: " << lim::is_exact << '\n'
 | |
|        << "min: " << (lim::min)() << ", max: " << (lim::max)() << '\n'
 | |
|        << "infinity: " << infinity << ", QNaN: " << qnan << '\n';
 | |
|   print_hex_val((lim::max)(), "max");
 | |
|   print_hex_val(infinity, "infinity");
 | |
|   print_hex_val(qnan, "qnan");
 | |
|   print_hex_val(snan, "snan");
 | |
| 
 | |
|   BOOST_TEST((lim::max)() > 1000);
 | |
|   BOOST_TEST((lim::min)() > 0);
 | |
|   BOOST_TEST((lim::min)() < 0.001);
 | |
|   BOOST_TEST(lim::epsilon() > 0);
 | |
| 
 | |
|   if(lim::is_iec559) {
 | |
|     BOOST_TEST(static_cast<bool>(lim::has_infinity));
 | |
|     BOOST_TEST(static_cast<bool>(lim::has_quiet_NaN));
 | |
|     BOOST_TEST(static_cast<bool>(lim::has_signaling_NaN));
 | |
|   } else {
 | |
|     std::cout << "Does not claim IEEE conformance" << std::endl;
 | |
|   }
 | |
| 
 | |
|   if(lim::has_infinity) {
 | |
|     // Make sure those values are not 0 or similar nonsense.
 | |
|     // Infinity must compare as if larger than the maximum representable value.
 | |
|     BOOST_TEST(infinity > (lim::max)());
 | |
|     BOOST_TEST(-infinity < -(lim::max)());
 | |
|   } else {
 | |
|     std::cout << "Does not have infinity" << std::endl;
 | |
|   }
 | |
| 
 | |
|   if(lim::has_quiet_NaN) {
 | |
|     // NaNs shall always compare "false" when compared for equality
 | |
|     // If one of these fail, your compiler may be optimizing incorrectly,
 | |
|     // or the standard library is incorrectly configured.
 | |
|     BOOST_TEST(! (qnan == 42));
 | |
|     BOOST_TEST(qnan != 42);
 | |
|     if(lim::is_iec559)
 | |
|     {
 | |
|       BOOST_TEST(! (qnan == qnan));
 | |
|       BOOST_TEST(qnan != qnan);
 | |
|     }
 | |
| 
 | |
|     // The following tests may cause arithmetic traps.
 | |
|     // BOOST_TEST(! (qnan < 42));
 | |
|     // BOOST_TEST(! (qnan > 42));
 | |
|     // BOOST_TEST(! (qnan <= 42));
 | |
|     // BOOST_TEST(! (qnan >= 42));
 | |
|   } else {
 | |
|     std::cout << "Does not have QNaN" << std::endl;
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| int cpp_main(int, char*[])
 | |
| {
 | |
|   test_integral_limits(bool(), "bool");
 | |
|   test_integral_limits(char(), "char");
 | |
|   typedef signed char signed_char;
 | |
|   test_integral_limits(signed_char(), "signed char");
 | |
|   typedef unsigned char unsigned_char;
 | |
|   test_integral_limits(unsigned_char(), "unsigned char");
 | |
|   test_integral_limits(wchar_t(), "wchar_t");
 | |
|   test_integral_limits(short(), "short");
 | |
|   typedef unsigned short unsigned_short;
 | |
|   test_integral_limits(unsigned_short(), "unsigned short");
 | |
|   test_integral_limits(int(), "int");
 | |
|   typedef unsigned int unsigned_int;
 | |
|   test_integral_limits(unsigned_int(), "unsigned int");
 | |
|   test_integral_limits(long(), "long");
 | |
|   typedef unsigned long unsigned_long;
 | |
|   test_integral_limits(unsigned_long(), "unsigned long");
 | |
| #if defined(BOOST_HAS_LONG_LONG)
 | |
|   test_integral_limits(::boost::long_long_type(), "long long");
 | |
|   test_integral_limits(::boost::ulong_long_type(), "unsigned long long");
 | |
| #endif
 | |
| #ifdef BOOST_HAS_MS_INT64
 | |
|   typedef __int64 long_long2;
 | |
|   test_integral_limits(long_long2(), "__int64");
 | |
|   typedef unsigned __int64 unsigned_long_long2;
 | |
|   test_integral_limits(unsigned_long_long2(), "unsigned __int64");
 | |
| #endif
 | |
| 
 | |
|   test_float_limits(float(), "float");
 | |
|   test_float_limits(double(), "double");
 | |
|   typedef long double long_double;
 | |
|   test_float_limits(long_double(), "long double");
 | |
|   // Some compilers don't pay attention to std:3.6.1/5 and issue a
 | |
|   // warning here if "return 0;" is omitted.
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| 
 |