diff --git a/nano/core_test/numbers.cpp b/nano/core_test/numbers.cpp index d6b141fa5..a30b2eb10 100644 --- a/nano/core_test/numbers.cpp +++ b/nano/core_test/numbers.cpp @@ -8,22 +8,185 @@ #include #include +TEST (numbers, identity) +{ + ASSERT_EQ (1, nano::uint128_union (1).number ().convert_to ()); + ASSERT_EQ (1, nano::uint256_union (1).number ().convert_to ()); + ASSERT_EQ (1, nano::uint512_union (1).number ().convert_to ()); +} + namespace { -template -void assert_union_types (); +template +void check_operator_less_than (Type lhs, Type rhs) +{ + ASSERT_TRUE (lhs < rhs); + ASSERT_FALSE (rhs < lhs); + ASSERT_FALSE (lhs < lhs); + ASSERT_FALSE (rhs < rhs); +} -template -void test_union_operator_less_than (); +template +void test_operator_less_than () +{ + using underlying_t = typename Type::underlying_type; -template -void check_operator_less_than (Num lhs, Num rhs); + // Small + check_operator_less_than (Type{ 123 }, Type{ 124 }); + check_operator_less_than (Type{ 124 }, Type{ 125 }); -template -void test_union_operator_greater_than (); + // Medium + check_operator_less_than (Type{ std::numeric_limits::max () - 1 }, Type{ std::numeric_limits::max () + 1 }); + check_operator_less_than (Type{ std::numeric_limits::max () - 12345678 }, Type{ std::numeric_limits::max () - 123456 }); -template -void check_operator_greater_than (Num lhs, Num rhs); + // Large + check_operator_less_than (Type{ std::numeric_limits::max () - 555555555555 }, Type{ std::numeric_limits::max () - 1 }); + + // Boundary values + check_operator_less_than (Type{ std::numeric_limits::min () }, Type{ std::numeric_limits::max () }); +} + +template +void check_operator_greater_than (Type lhs, Type rhs) +{ + ASSERT_TRUE (lhs > rhs); + ASSERT_FALSE (rhs > lhs); + ASSERT_FALSE (lhs > lhs); + ASSERT_FALSE (rhs > rhs); +} + +template +void test_operator_greater_than () +{ + using underlying_t = typename Type::underlying_type; + + // Small + check_operator_greater_than (Type{ 124 }, Type{ 123 }); + check_operator_greater_than (Type{ 125 }, Type{ 124 }); + + // Medium + check_operator_greater_than (Type{ std::numeric_limits::max () + 1 }, Type{ std::numeric_limits::max () - 1 }); + check_operator_greater_than (Type{ std::numeric_limits::max () - 123456 }, Type{ std::numeric_limits::max () - 12345678 }); + + // Large + check_operator_greater_than (Type{ std::numeric_limits::max () - 1 }, Type{ std::numeric_limits::max () - 555555555555 }); + + // Boundary values + check_operator_greater_than (Type{ std::numeric_limits::max () }, Type{ std::numeric_limits::min () }); +} + +template +void test_comparison () +{ + test_operator_less_than (); + test_operator_greater_than (); +} +} + +TEST (numbers, comparison) +{ + test_comparison (); + test_comparison (); + test_comparison (); + test_comparison (); + test_comparison (); + test_comparison (); + test_comparison (); + test_comparison (); + test_comparison (); + test_comparison (); + test_comparison (); +} + +namespace +{ +template class Hash> +void test_hashing () +{ + Hash hash; + using underlying_t = typename Type::underlying_type; + + // Basic equality tests + ASSERT_EQ (hash (Type{}), hash (Type{})); + ASSERT_EQ (hash (Type{ 123 }), hash (Type{ 123 })); + + // Basic inequality tests + ASSERT_NE (hash (Type{ 123 }), hash (Type{ 124 })); + ASSERT_NE (hash (Type{ 0 }), hash (Type{ 1 })); + + // Boundary value tests + constexpr auto min_val = std::numeric_limits::min (); + constexpr auto max_val = std::numeric_limits::max (); + + // Min/Max tests + ASSERT_EQ (hash (Type{ min_val }), hash (Type{ min_val })); + ASSERT_EQ (hash (Type{ max_val }), hash (Type{ max_val })); + ASSERT_NE (hash (Type{ min_val }), hash (Type{ max_val })); + + // Near boundary tests + ASSERT_NE (hash (Type{ min_val }), hash (Type{ min_val + 1 })); + ASSERT_NE (hash (Type{ max_val }), hash (Type{ max_val - 1 })); + ASSERT_NE (hash (Type{ min_val + 1 }), hash (Type{ max_val })); + ASSERT_NE (hash (Type{ max_val - 1 }), hash (Type{ min_val })); + + // Common value tests + std::vector common_values = { + 0, // Zero + 1, // One + 42, // Common test value + 0xFF, // Byte boundary + 0xFFFF, // Word boundary + min_val, // Minimum + max_val, // Maximum + max_val / 2, // Middle value + min_val + (max_val / 2) // Offset middle + }; + + // Test all common values against each other + for (size_t i = 0; i < common_values.size (); ++i) + { + for (size_t j = i + 1; j < common_values.size (); ++j) + { + if (common_values[i] != common_values[j]) + { + ASSERT_NE (hash (Type{ common_values[i] }), hash (Type{ common_values[j] })); + } + else + { + ASSERT_EQ (hash (Type{ common_values[i] }), hash (Type{ common_values[j] })); + } + } + } +} +} + +TEST (numbers, hashing) +{ + // Using std::hash + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + + // Using boost::hash + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); } TEST (uint128_union, decode_dec) @@ -66,16 +229,6 @@ TEST (uint128_union, decode_dec_overflow) ASSERT_TRUE (error); } -TEST (uint128_union, operator_less_than) -{ - test_union_operator_less_than (); -} - -TEST (uint128_union, operator_greater_than) -{ - test_union_operator_greater_than (); -} - struct test_punct : std::moneypunct { pattern do_pos_format () const @@ -151,13 +304,6 @@ TEST (uint128_union, decode_decimal) ASSERT_EQ (1230 * nano::Knano_ratio, amount.number ()); } -TEST (unions, identity) -{ - ASSERT_EQ (1, nano::uint128_union (1).number ().convert_to ()); - ASSERT_EQ (1, nano::uint256_union (1).number ().convert_to ()); - ASSERT_EQ (1, nano::uint512_union (1).number ().convert_to ()); -} - TEST (uint256_union, key_encryption) { nano::keypair key1; @@ -451,16 +597,6 @@ TEST (uint256_union, bounds) ASSERT_TRUE (key.decode_account (bad2)); } -TEST (uint256_union, operator_less_than) -{ - test_union_operator_less_than (); -} - -TEST (uint256_union, operator_greater_than) -{ - test_union_operator_greater_than (); -} - TEST (uint64_t, parse) { uint64_t value0 (1); @@ -511,163 +647,4 @@ TEST (uint512_union, hash) ASSERT_NE (h (x1), h (x2)); } } -} - -namespace -{ -template -void assert_union_types () -{ - static_assert ((std::is_same::value && std::is_same::value) || (std::is_same::value && std::is_same::value) || (std::is_same::value && std::is_same::value), - "Union type needs to be consistent with the lower/upper Bound type"); -} - -template -void test_union_operator_less_than () -{ - assert_union_types (); - - // Small - check_operator_less_than (Union (123), Union (124)); - check_operator_less_than (Union (124), Union (125)); - - // Medium - check_operator_less_than (Union (std::numeric_limits::max () - 1), Union (std::numeric_limits::max () + 1)); - check_operator_less_than (Union (std::numeric_limits::max () - 12345678), Union (std::numeric_limits::max () - 123456)); - - // Large - check_operator_less_than (Union (std::numeric_limits::max () - 555555555555), Union (std::numeric_limits::max () - 1)); - - // Boundary values - check_operator_less_than (Union (std::numeric_limits::min ()), Union (std::numeric_limits::max ())); -} - -template -void check_operator_less_than (Num lhs, Num rhs) -{ - ASSERT_TRUE (lhs < rhs); - ASSERT_FALSE (rhs < lhs); - ASSERT_FALSE (lhs < lhs); - ASSERT_FALSE (rhs < rhs); -} - -template -void test_union_operator_greater_than () -{ - assert_union_types (); - - // Small - check_operator_greater_than (Union (124), Union (123)); - check_operator_greater_than (Union (125), Union (124)); - - // Medium - check_operator_greater_than (Union (std::numeric_limits::max () + 1), Union (std::numeric_limits::max () - 1)); - check_operator_greater_than (Union (std::numeric_limits::max () - 123456), Union (std::numeric_limits::max () - 12345678)); - - // Large - check_operator_greater_than (Union (std::numeric_limits::max () - 1), Union (std::numeric_limits::max () - 555555555555)); - - // Boundary values - check_operator_greater_than (Union (std::numeric_limits::max ()), Union (std::numeric_limits::min ())); -} - -template -void check_operator_greater_than (Num lhs, Num rhs) -{ - ASSERT_TRUE (lhs > rhs); - ASSERT_FALSE (rhs > lhs); - ASSERT_FALSE (lhs > lhs); - ASSERT_FALSE (rhs > rhs); -} -} - -namespace -{ -template class Hash> -void test_hashing () -{ - Hash hash; - using underlying_t = typename Type::underlying_type; - - // Basic equality tests - ASSERT_EQ (hash (Type{}), hash (Type{})); - ASSERT_EQ (hash (Type{ 123 }), hash (Type{ 123 })); - - // Basic inequality tests - ASSERT_NE (hash (Type{ 123 }), hash (Type{ 124 })); - ASSERT_NE (hash (Type{ 0 }), hash (Type{ 1 })); - - // Boundary value tests - constexpr auto min_val = std::numeric_limits::min (); - constexpr auto max_val = std::numeric_limits::max (); - - // Min/Max tests - ASSERT_EQ (hash (Type{ min_val }), hash (Type{ min_val })); - ASSERT_EQ (hash (Type{ max_val }), hash (Type{ max_val })); - ASSERT_NE (hash (Type{ min_val }), hash (Type{ max_val })); - - // Near boundary tests - ASSERT_NE (hash (Type{ min_val }), hash (Type{ min_val + 1 })); - ASSERT_NE (hash (Type{ max_val }), hash (Type{ max_val - 1 })); - ASSERT_NE (hash (Type{ min_val + 1 }), hash (Type{ max_val })); - ASSERT_NE (hash (Type{ max_val - 1 }), hash (Type{ min_val })); - - // Common value tests - std::vector common_values = { - 0, // Zero - 1, // One - 42, // Common test value - 0xFF, // Byte boundary - 0xFFFF, // Word boundary - min_val, // Minimum - max_val, // Maximum - max_val / 2, // Middle value - min_val + (max_val / 2) // Offset middle - }; - - // Test all common values against each other - for (size_t i = 0; i < common_values.size (); ++i) - { - for (size_t j = i + 1; j < common_values.size (); ++j) - { - if (common_values[i] != common_values[j]) - { - ASSERT_NE (hash (Type{ common_values[i] }), hash (Type{ common_values[j] })); - } - else - { - ASSERT_EQ (hash (Type{ common_values[i] }), hash (Type{ common_values[j] })); - } - } - } -} -} - -TEST (numbers, hashing) -{ - // Using std::hash - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - - // Using boost::hash - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); -} +} \ No newline at end of file