$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: zeux_at_[hidden]
Date: 2007-06-07 08:14:30
Author: zeux
Date: 2007-06-07 08:14:29 EDT (Thu, 07 Jun 2007)
New Revision: 4481
URL: http://svn.boost.org/trac/boost/changeset/4481
Log:
Added to_number and can_convert_to tests, fixed bugs found with new tests :), modified todo.txt accordingly
Added:
   sandbox/SOC/2007/bigint/libs/bigint/test/can_convert_to.cpp
   sandbox/SOC/2007/bigint/libs/bigint/test/number_conversion.cpp
      - copied, changed from r4480, /sandbox/SOC/2007/bigint/libs/bigint/test/number_ctors.cpp
Removed:
   sandbox/SOC/2007/bigint/libs/bigint/test/number_ctors.cpp
Text files modified: 
   sandbox/SOC/2007/bigint/boost/bigint/bigint_gmp.hpp            |    77 ++++++++++++++------------------------- 
   sandbox/SOC/2007/bigint/libs/bigint/test/Jamfile.v2            |     3 +                                       
   sandbox/SOC/2007/bigint/libs/bigint/test/number_conversion.cpp |    10 ++++-                                   
   sandbox/SOC/2007/bigint/libs/bigint/todo.txt                   |    18 ++++++---                               
   4 files changed, 50 insertions(+), 58 deletions(-)
Modified: sandbox/SOC/2007/bigint/boost/bigint/bigint_gmp.hpp
==============================================================================
--- sandbox/SOC/2007/bigint/boost/bigint/bigint_gmp.hpp	(original)
+++ sandbox/SOC/2007/bigint/boost/bigint/bigint_gmp.hpp	2007-06-07 08:14:29 EDT (Thu, 07 Jun 2007)
@@ -298,74 +298,53 @@
                         return result;
                 }
                 
-		template <typename T> bool _can_convert_to_signed() const
+		boost::uint64_t _to_uint64() const
                 {
-			switch (mpz_sgn(data))
-			{
-			case 1: return _can_convert_to_unsigned<T>(); // Reuse
-			case 0: return true;
-			}
-			
-			boost::uint64_t max_value = static_cast<boost::uint64_t>(-static_cast<boost::int64_t>((std::numeric_limits<T>::min)()));
-			
-			int count = -data->_mp_size; // we have a negative number
-			
-			if (GMP_NUMB_BITS >= sizeof(boost::uint64_t) * 8) // we're going to have problems with >>= down there - but the check is simple
-				return (count == 1 && max_value >= data->_mp_d[0]);
-				
+			boost::uint64_t value = 0;
+			boost::uint64_t power = 1;
+
+			int count = data->_mp_size >= 0 ? data->_mp_size : -data->_mp_size; // abs() does not work on MSVC8
+
                         for (int i = 0; i < count; ++i)
                         {
-				if (max_value < data->_mp_d[i]) return false;
-				max_value >>= GMP_NUMB_BITS;
+				value += data->_mp_d[i] * power;
+				power <<= GMP_NUMB_BITS;
                         }
                         
-			return true;
+			return value;
                 }
 
-		template <typename T> bool _can_convert_to_unsigned() const
+		template <typename T> bool can_convert_to() const
                 {
-			switch (mpz_sgn(data))
-			{
-			case 0: return true;
-			case -1: return false; // Negative numbers can't fit into unsigned types
-			}
-			
-			boost::uint64_t max_value = (std::numeric_limits<T>::max)();
+			// Only integer types supported
+			if (!std::numeric_limits<T>::is_integer) return false;
                         
-			if (GMP_NUMB_BITS >= sizeof(T) * 8) // we're going to have problems with >>= wodn there - but the check is simple
-				return (data->_mp_size == 1 && max_value >= data->_mp_d[0]);
+			boost::uint64_t max_value;
+			int count;
                         
-			for (int i = 0; i < data->_mp_size; ++i)
+			if (mpz_sgn(data) < 0)
                         {
-				if (max_value < data->_mp_d[i]) return false;
-				max_value >>= GMP_NUMB_BITS;
+				count = -data->_mp_size;
+				max_value = static_cast<boost::uint64_t>(-static_cast<boost::int64_t>((std::numeric_limits<T>::min)()));
+			}
+			else
+			{
+				count = data->_mp_size;
+				max_value = (std::numeric_limits<T>::max)();
                         }
-			
-			return true;
-		}
 
-		template <typename T> bool can_convert_to() const
-		{
-			// Only integer types supported
-			if (!std::numeric_limits<T>::is_integer) return false;
-			
-			return std::numeric_limits<T>::is_signed ? _can_convert_to_signed<T>() : _can_convert_to_unsigned<T>();
+			if (count * GMP_NUMB_BITS > sizeof(boost::uint64_t) * 8) // we can't fit in uint64 => we won't fit in anything else
+				return false;
+
+			return max_value >= _to_uint64();
                 }
                 
                 template <typename T> T to_number() const
                 {
                         if (!std::numeric_limits<T>::is_integer) return T();
                         
-			boost::uint64_t value = 0;
-			
-			int count = data->_mp_size >= 0 ? data->_mp_size : -data->_mp_size; // abs() does not work on MSVC8
-			
-			for (int i = 0; i < count; ++i)
-			{
-				value <<= GMP_NUMB_BITS;
-				value += data->_mp_d[i];
-			}
-			
+			boost::uint64_t value = _to_uint64();
+						
                         return data->_mp_size >= 0 ? static_cast<T>(value) : static_cast<T>(-static_cast<boost::int64_t>(value));
                 }
 
Modified: sandbox/SOC/2007/bigint/libs/bigint/test/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/bigint/libs/bigint/test/Jamfile.v2	(original)
+++ sandbox/SOC/2007/bigint/libs/bigint/test/Jamfile.v2	2007-06-07 08:14:29 EDT (Thu, 07 Jun 2007)
@@ -10,8 +10,9 @@
   test-suite bigint
    :
    [ run bigint_simple_test.cpp ]
-   [ run number_ctors.cpp ]
+   [ run number_conversion.cpp ]
    [ run string_conversion.cpp ]
+   [ run can_convert_to.cpp ]
    ;
 }
 
Added: sandbox/SOC/2007/bigint/libs/bigint/test/can_convert_to.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/bigint/libs/bigint/test/can_convert_to.cpp	2007-06-07 08:14:29 EDT (Thu, 07 Jun 2007)
@@ -0,0 +1,158 @@
+/* Boost can_convert_to.cpp test file
+ *
+ * Copyright 2007 Arseny Kapoulkine
+ *
+ * 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)
+ */
+
+#define BOOST_DISABLE_WIN32
+
+#include <boost/test/included/test_exec_monitor.hpp>
+
+#include <boost/bigint/bigint.hpp>
+
+#include <sstream>
+
+#include <iostream>
+
+#pragma comment(lib, "libgmp-3.lib")
+
+template <typename I> void test()
+{
+	typedef boost::bigint_base<I> number;
+
+	// char
+	BOOST_CHECK(!number("-129").can_convert_to<char>());
+	BOOST_CHECK( number("-128").can_convert_to<char>());
+	BOOST_CHECK( number("-127").can_convert_to<char>());
+
+	BOOST_CHECK( number("-1").can_convert_to<char>());
+	BOOST_CHECK( number("0").can_convert_to<char>());
+	BOOST_CHECK( number("1").can_convert_to<char>());
+
+	BOOST_CHECK( number("127").can_convert_to<char>());
+	BOOST_CHECK(!number("128").can_convert_to<char>());
+	BOOST_CHECK(!number("129").can_convert_to<char>());
+
+	// unsigned char
+	BOOST_CHECK(!number("-12930").can_convert_to<unsigned char>());
+	BOOST_CHECK(!number("-1").can_convert_to<unsigned char>());
+
+	BOOST_CHECK( number("0").can_convert_to<unsigned char>());
+	BOOST_CHECK( number("1").can_convert_to<unsigned char>());
+
+	BOOST_CHECK( number("127").can_convert_to<unsigned char>());
+	BOOST_CHECK( number("128").can_convert_to<unsigned char>());
+	BOOST_CHECK( number("129").can_convert_to<unsigned char>());
+
+	BOOST_CHECK( number("255").can_convert_to<unsigned char>());
+	BOOST_CHECK(!number("256").can_convert_to<unsigned char>());
+
+	// short
+	BOOST_CHECK(!number("-32769").can_convert_to<short>());
+	BOOST_CHECK( number("-32768").can_convert_to<short>());
+	BOOST_CHECK( number("-32767").can_convert_to<short>());
+
+	BOOST_CHECK( number("-1").can_convert_to<short>());
+	BOOST_CHECK( number("0").can_convert_to<short>());
+	BOOST_CHECK( number("1").can_convert_to<short>());
+
+	BOOST_CHECK( number("32767").can_convert_to<short>());
+	BOOST_CHECK(!number("32768").can_convert_to<short>());
+	BOOST_CHECK(!number("32769").can_convert_to<short>());
+
+	// unsigned short
+	BOOST_CHECK(!number("-12930").can_convert_to<unsigned short>());
+	BOOST_CHECK(!number("-1").can_convert_to<unsigned short>());
+
+	BOOST_CHECK( number("0").can_convert_to<unsigned short>());
+	BOOST_CHECK( number("1").can_convert_to<unsigned short>());
+
+	BOOST_CHECK( number("32767").can_convert_to<unsigned short>());
+	BOOST_CHECK( number("32768").can_convert_to<unsigned short>());
+	BOOST_CHECK( number("32769").can_convert_to<unsigned short>());
+
+	BOOST_CHECK( number("65535").can_convert_to<unsigned short>());
+	BOOST_CHECK(!number("65536").can_convert_to<unsigned short>());
+
+	// int
+	BOOST_CHECK(!number("-80000001", 16).can_convert_to<int>());
+	BOOST_CHECK( number("-80000000", 16).can_convert_to<int>());
+	BOOST_CHECK( number("-7fffffff", 16).can_convert_to<int>());
+	
+	BOOST_CHECK( number("-1").can_convert_to<int>());
+	BOOST_CHECK( number("0").can_convert_to<int>());
+	BOOST_CHECK( number("1").can_convert_to<int>());
+
+	BOOST_CHECK( number("7fffffff", 16).can_convert_to<int>());
+	BOOST_CHECK(!number("80000000", 16).can_convert_to<int>());
+	BOOST_CHECK(!number("80000001", 16).can_convert_to<int>());
+
+	// unsigned int
+	BOOST_CHECK(!number("-12930").can_convert_to<unsigned int>());
+	BOOST_CHECK(!number("-1").can_convert_to<unsigned int>());
+
+	BOOST_CHECK( number("0").can_convert_to<unsigned int>());
+	BOOST_CHECK( number("1").can_convert_to<unsigned int>());
+
+	BOOST_CHECK( number("7fffffff", 16).can_convert_to<unsigned int>());
+	BOOST_CHECK( number("80000000", 16).can_convert_to<unsigned int>());
+	BOOST_CHECK( number("80000001", 16).can_convert_to<unsigned int>());
+
+	BOOST_CHECK( number("ffffffff", 16).can_convert_to<unsigned int>());
+	BOOST_CHECK(!number("100000000", 16).can_convert_to<unsigned int>());
+
+	// int64_t
+	BOOST_CHECK(!number("-8000000000000001", 16).can_convert_to<boost::int64_t>());
+	BOOST_CHECK( number("-8000000000000000", 16).can_convert_to<boost::int64_t>());
+	BOOST_CHECK( number("-7fffffffffffffff", 16).can_convert_to<boost::int64_t>());
+	
+	BOOST_CHECK( number("-80000001", 16).can_convert_to<boost::int64_t>());
+	BOOST_CHECK( number("-80000000", 16).can_convert_to<boost::int64_t>());
+	BOOST_CHECK( number("-7fffffff", 16).can_convert_to<boost::int64_t>());
+
+	BOOST_CHECK( number("-1").can_convert_to<boost::int64_t>());
+	BOOST_CHECK( number("0").can_convert_to<boost::int64_t>());
+	BOOST_CHECK( number("1").can_convert_to<boost::int64_t>());
+
+	BOOST_CHECK( number("7fffffff", 16).can_convert_to<boost::int64_t>());
+	BOOST_CHECK( number("80000000", 16).can_convert_to<boost::int64_t>());
+
+	BOOST_CHECK( number("7fffffffffffffff", 16).can_convert_to<boost::int64_t>());
+	BOOST_CHECK(!number("8000000000000000", 16).can_convert_to<boost::int64_t>());
+	BOOST_CHECK(!number("8000000000000001", 16).can_convert_to<boost::int64_t>());
+
+	// uint64_t
+	BOOST_CHECK(!number("-12930").can_convert_to<boost::uint64_t>());
+	BOOST_CHECK(!number("-1").can_convert_to<boost::uint64_t>());
+
+	BOOST_CHECK( number("0").can_convert_to<boost::uint64_t>());
+	BOOST_CHECK( number("1").can_convert_to<boost::uint64_t>());
+
+	BOOST_CHECK( number("7fffffff", 16).can_convert_to<boost::uint64_t>());
+	BOOST_CHECK( number("80000000", 16).can_convert_to<boost::uint64_t>());
+	BOOST_CHECK( number("80000001", 16).can_convert_to<boost::uint64_t>());
+
+	BOOST_CHECK( number("ffffffff", 16).can_convert_to<boost::uint64_t>());
+	BOOST_CHECK( number("100000000", 16).can_convert_to<boost::uint64_t>());
+	
+	BOOST_CHECK( number("7fffffffffffffff", 16).can_convert_to<boost::uint64_t>());
+	BOOST_CHECK( number("8000000000000000", 16).can_convert_to<boost::uint64_t>());
+	BOOST_CHECK( number("8000000000000001", 16).can_convert_to<boost::uint64_t>());
+	
+	BOOST_CHECK( number("7fffffffffffffff", 16).can_convert_to<boost::uint64_t>());
+	BOOST_CHECK( number("8000000000000000", 16).can_convert_to<boost::uint64_t>());
+	BOOST_CHECK( number("8000000000000001", 16).can_convert_to<boost::uint64_t>());
+	
+	BOOST_CHECK( number("ffffffffffffffff", 16).can_convert_to<boost::uint64_t>());
+	BOOST_CHECK(!number("10000000000000001", 16).can_convert_to<boost::uint64_t>());
+}
+
+int test_main(int argc, char* argv[])
+{
+  test<boost::detail::bigint_gmp_implementation>();
+
+  return 0;
+}
Copied: sandbox/SOC/2007/bigint/libs/bigint/test/number_conversion.cpp (from r4480, /sandbox/SOC/2007/bigint/libs/bigint/test/number_ctors.cpp)
==============================================================================
--- /sandbox/SOC/2007/bigint/libs/bigint/test/number_ctors.cpp	(original)
+++ sandbox/SOC/2007/bigint/libs/bigint/test/number_conversion.cpp	2007-06-07 08:14:29 EDT (Thu, 07 Jun 2007)
@@ -1,4 +1,4 @@
-/* Boost number_ctors.cpp test file
+/* Boost number_conversion.cpp test file
  *
  * Copyright 2007 Arseny Kapoulkine
  *
@@ -46,7 +46,13 @@
                 std::ostringstream oss;
                 oss << convert_to_number(values[i]);
 
-		BOOST_CHECK_EQUAL(oss.str(), number(values[i]).str());
+		// number -> bigint
+		number v(values[i]);
+		BOOST_CHECK_EQUAL(oss.str(), v.str());
+
+		// bigint -> number
+		BOOST_CHECK(v.can_convert_to<T>()); // we should be able to convert to T
+		BOOST_CHECK_EQUAL(convert_to_number(v.to_number<T>()), convert_to_number(values[i]));
         }
 }
 
Deleted: sandbox/SOC/2007/bigint/libs/bigint/test/number_ctors.cpp
==============================================================================
--- sandbox/SOC/2007/bigint/libs/bigint/test/number_ctors.cpp	2007-06-07 08:14:29 EDT (Thu, 07 Jun 2007)
+++ (empty file)
@@ -1,144 +0,0 @@
-/* Boost number_ctors.cpp test file
- *
- * Copyright 2007 Arseny Kapoulkine
- *
- * 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)
- */
-
-#define BOOST_DISABLE_WIN32
-
-#include <boost/test/included/test_exec_monitor.hpp>
-
-#include <boost/bigint/bigint.hpp>
-
-#include <sstream>
-
-#include <iostream>
-
-#pragma comment(lib, "libgmp-3.lib")
-
-// This macro is not quite good, but - it's ok for our needs
-#define ARRAY_SIZE(array) sizeof(array) / sizeof(array[0])
-
-template <typename T> T convert_to_number(T value)
-{
-	return value;
-}
-
-int convert_to_number(char value)
-{
-	return value;
-}
-
-unsigned int convert_to_number(unsigned char value)
-{
-	return value;
-}
-
-template <typename I, typename T> void test_number_ctors(T* values, size_t count)
-{
-	typedef boost::bigint_base<I> number;
-
-	for (size_t i = 0; i < count; ++i)
-	{
-		std::ostringstream oss;
-		oss << convert_to_number(values[i]);
-
-		BOOST_CHECK_EQUAL(oss.str(), number(values[i]).str());
-	}
-}
-
-template <typename I> void test()
-{
-	{
-		char values[] = {-128, -127, -10, -1, 0, 1, 33, 124, 125, 126, 127};
-
-		test_number_ctors<I>(values, ARRAY_SIZE(values));
-	}
-
-	{
-		unsigned char values[] = {0, 1, 33, 124, 125, 126, 127, 200, 240, 254, 255};
-		
-		test_number_ctors<I>(values, ARRAY_SIZE(values));
-	}
-
-	{
-		short values[] = {-32768, -32767, -23032, -3407, -10, -1, 0, 1, 33, 124, 125, 126, 127, 3489, 31900, 32766, 32767};
-
-		test_number_ctors<I>(values, ARRAY_SIZE(values));
-	}
-
-	{
-		unsigned short values[] = {0, 1, 33, 124, 125, 126, 127, 200, 240, 254, 255, 3000, 48950, 65534, 65535};
-		
-		test_number_ctors<I>(values, ARRAY_SIZE(values));
-	}
-	
-	{
-		int values[] = {-2147483647 - 1, -2147483647, -2147483646, -34294039, -3409, -1, 0, 1, 3940, 4950424, 2147483646, 2147483647};
-
-		test_number_ctors<I>(values, ARRAY_SIZE(values));
-	}
-
-	{
-		unsigned int values[] = {0, 1, 200, 65535, 384983, 23849384, 1203002930, 2147483648, 4294967294, 4294967295};
-		
-		test_number_ctors<I>(values, ARRAY_SIZE(values));
-	}
-	
-	{
-		boost::int64_t values[] = {-2147483647 - 1, -2147483647, -2147483646, -34294039, -3409, -1, 0, 1, 3940, 4950424, 2147483646, 2147483647};
-
-		// small values
-		test_number_ctors<I>(values, ARRAY_SIZE(values));
-
-		for (size_t i = 0; i < ARRAY_SIZE(values); ++i)
-		{
-			values[i] *= 2147483648; // 2^31
-			values[i] *= 2;          // 2^32
-		}
-
-		// first element is -2^31 * 2^32 == -2^63 - ok
-		// last element is (2^31 - 1) * 2^32 == 2^63 - 2^32 - too small
-		values[ARRAY_SIZE(values) - 1] += 4294967295;
-
-		// testing unit tests
-		BOOST_CHECK(values[0] < 0 && values[0] - 1 > 0); // underflow
-		BOOST_CHECK(values[ARRAY_SIZE(values) - 1] > 0 && values[ARRAY_SIZE(values) - 1] + 1 < 0); // overflow
-		BOOST_CHECK_EQUAL(values[0] - 1, values[ARRAY_SIZE(values) - 1]);
-		
-		// large values
-		test_number_ctors<I>(values, ARRAY_SIZE(values));
-	}
-
-	{
-		boost::uint64_t values[] = {0, 1, 200, 65535, 384983, 23849384, 1203002930, 2147483648, 4294967294, 4294967295};
-
-		// small values
-		test_number_ctors<I>(values, ARRAY_SIZE(values));
-
-		for (size_t i = 0; i < ARRAY_SIZE(values); ++i)
-		{
-			values[i] *= 2147483648; // 2^31
-			values[i] *= 2;          // 2^32
-		}
-
-		// last element is (2^32 - 1) * 2^32 == 2^64 - 2^32 - too small
-		values[ARRAY_SIZE(values) - 1] += 4294967295;
-
-		// testing unit tests
-		BOOST_CHECK_EQUAL(values[ARRAY_SIZE(values) - 1] + 1, 0); // overflow
-		
-		// large values
-		test_number_ctors<I>(values, ARRAY_SIZE(values));
-	}
-}
-
-int test_main(int argc, char* argv[])
-{
-  test<boost::detail::bigint_gmp_implementation>();
-
-  return 0;
-}
Modified: sandbox/SOC/2007/bigint/libs/bigint/todo.txt
==============================================================================
--- sandbox/SOC/2007/bigint/libs/bigint/todo.txt	(original)
+++ sandbox/SOC/2007/bigint/libs/bigint/todo.txt	2007-06-07 08:14:29 EDT (Thu, 07 Jun 2007)
@@ -91,6 +91,12 @@
 + fix bug in wstr() - sometimes mpz_sizeinbase returns slightly bigger size
 Status: fixed
 
++ fix bug in to_number() - fails for 64-bit integers
+Status: fixed
+
++ fix bug in can_convert_to() - fails for boundary case (-2^63-1) for boost::int64_t
+Status: fixed
+
 - remove warnings for both MSVC and GCC
 Status: needs fixing
 
@@ -105,6 +111,12 @@
 + test string conversion (various bases - 2, 9, 18, 27, 36)
 Status: implemented (merged with "test all ctors for strings")
 
++ test can_convert_to (char, short, int, int64 - both signed and unsigned, boundary cases)
+Status: implemented
+
++ test to_number (char, short, int, int64 - both signed and unsigned, boundary cases)
+Status: implemented
+
 - test copy construction and assignment
 Status: needs implementing
 
@@ -123,12 +135,6 @@
 - test bool conversion and operator!
 Status: needs implementing
 
-- test can_convert_to (char, short, int, int64 - both signed and unsigned, boundary cases)
-Status: needs implementing
-
-- test to_number (char, short, int, int64 - both signed and unsigned, boundary cases)
-Status: needs implementing
-
 - test comparison operators
 Status: needs implementing