Patrick Kelley 8fd444092b initial
2025-05-07 15:35:15 -04:00

196 lines
6.0 KiB
C++

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "TestMain.h"
#include "TestCase.h"
template <typename T, typename U>
void SubVerifyBase(const char* types)
{
TestVector< T, U, OpType::Sub > tests;
TestCase< T, U, OpType::Sub > test = tests.GetNext();
while (!tests.Done())
{
T ret;
if (SafeSubtract(test.x, test.y, ret) != test.fExpected)
{
std::string msg = std::string("Error in case ") + types;
err_msg(msg.c_str(), test.x, test.y, test.fExpected);
}
// Now test throwing version
bool fSuccess = true;
try
{
SafeInt<T> si(test.x);
si -= test.y;
}
catch (...)
{
fSuccess = false;
}
if (fSuccess != test.fExpected)
{
std::string msg = std::string("Error in case ") + types + " throw (1): ";
err_msg(msg.c_str(), test.x, test.y, test.fExpected);
}
// Also need to test the version that assigns back out
// to a plain int, as it has different logic
fSuccess = true;
try
{
T x(test.x);
x -= SafeInt<U>(test.y);
}
catch (...)
{
fSuccess = false;
}
if (fSuccess != test.fExpected)
{
std::string msg = std::string("Error in case ") + types + " throw (2): ";
err_msg(msg.c_str(), test.x, test.y, test.fExpected);
}
test = tests.GetNext();
}
}
namespace sub_verify
{
void SubVerify()
{
std::cout << "Verifying Subtraction:" << std::endl;
// Unsigned int64, unsigned cases
SubVerifyBase< std::uint64_t, std::uint64_t>("uint64_uint64");
SubVerifyBase< std::uint64_t, std::uint32_t >("uint64_uint32");
SubVerifyBase< std::uint64_t, std::uint16_t >("uint64_uint16");
SubVerifyBase< std::uint64_t, std::uint8_t >("uint64_uint8");
// Unsigned int64, signed cases
SubVerifyBase< std::uint64_t, std::int64_t >("uint64_int64");
SubVerifyBase< std::uint64_t, std::int32_t >("uint64_int32");
SubVerifyBase< std::uint64_t, std::int16_t >("uint64_int16");
SubVerifyBase< std::uint64_t, std::int8_t >("uint64_int8");
/////////////////////////////////////
SubVerifyBase< std::uint32_t, std::uint64_t >("uint32_uint64");
SubVerifyBase< std::uint32_t, std::uint32_t >("uint32_uint32");
SubVerifyBase< std::uint32_t, std::int64_t >("uint32_int64");
SubVerifyBase< std::uint32_t, std::int32_t >("uint32_int32");
SubVerifyBase< std::int32_t, std::uint64_t >("int32_uint64");
SubVerifyBase< std::int32_t, std::uint32_t >("int32_uint32");
SubVerifyBase< std::int32_t, std::int64_t >("int32_int64");
SubVerifyBase< std::int32_t, std::int32_t >("int32_int32");
// Unsigned int8, unsigned cases
SubVerifyBase< std::uint8_t, std::uint64_t >("uint8_uint64");
SubVerifyBase< std::uint8_t, std::uint32_t >("uint8_uint32");
SubVerifyBase< std::uint8_t, std::uint16_t >("uint8_uint16");
SubVerifyBase< std::uint8_t, std::uint8_t >("uint8_uint8");
// Unsigned int8, signed cases
SubVerifyBase< std::uint8_t, std::int64_t >("uint8_int64");
SubVerifyBase< std::uint8_t, std::int32_t >("uint8_int32");
SubVerifyBase< std::uint8_t, std::int16_t >("uint8_int16");
SubVerifyBase< std::uint8_t, std::int8_t >("uint8_int8");
/////////////////////////////////////
// Signed int64, unsigned cases
SubVerifyBase< std::int64_t, std::uint64_t >("int64_uint64");
SubVerifyBase< std::int64_t, std::uint32_t >("int64_uint32");
SubVerifyBase< std::int64_t, std::uint16_t >("int64_uint16");
SubVerifyBase< std::int64_t, std::uint8_t >("int64_uint8");
// Signed int64, signed cases
SubVerifyBase< std::int64_t, std::int64_t >("int64_int64");
SubVerifyBase< std::int64_t, std::int32_t >("int64_int32");
SubVerifyBase< std::int64_t, std::int16_t >("int64_int16");
SubVerifyBase< std::int64_t, std::int8_t >("int64_int8");
/////////////////////////////////////
// Signed int8, unsigned cases
SubVerifyBase< std::int8_t, std::uint64_t >("int8_uint64");
SubVerifyBase< std::int8_t, std::uint32_t >("int8_uint32");
SubVerifyBase< std::int8_t, std::uint16_t >("int8_uint16");
SubVerifyBase< std::int8_t, std::uint8_t >("int8_uint8");
// Signed int8, signed cases
SubVerifyBase< std::int8_t, std::int64_t >("int8_int64");
SubVerifyBase< std::int8_t, std::int32_t >("int8_int32");
SubVerifyBase< std::int8_t, std::int16_t >("int8_int16");
SubVerifyBase< std::int8_t, std::int8_t >("int8_int8");
}
}
namespace negation_verify
{
template < typename T >
void NegationVerifyT()
{
T minInt = std::numeric_limits<T>::min();
T test = 2;
bool result = false;
T out = 0;
try
{
out = -SafeInt< T >(minInt);
}
catch (...)
{
result = true;
}
if (result == false)
std::cerr << "Error in NegationVerifyT throw (1): " << std::endl;
try
{
out = -SafeInt< T >(test);
}
catch (...)
{
result = false;
}
if (result == false)
std::cerr << "Error in NegationVerifyT throw (2): " << std::endl;
// Now try the non-throwing version
result = SafeNegation(minInt, out);
if (result != false)
std::cerr << "Error in NegationVerifyT nothrow (1): " << std::endl;
result = SafeNegation(test, out);
if (result == false)
std::cerr << "Error in NegationVerifyT nothrow (2): " << std::endl;
}
void NegationVerifyAll()
{
NegationVerifyT< std::int8_t>();
NegationVerifyT< std::int16_t>();
NegationVerifyT< std::int32_t>();
NegationVerifyT< std::int64_t>();
}
void NegationVerify()
{
std::cout << "Verifying Negation:" << std::endl;
NegationVerifyAll();
}
}