constexpr bool
check(P p, Q q, unsigned long long r)
{
using R = std::common_type_t;
static_assert( std::is_same_v );
static_assert( std::is_same_v );
R r1 = std::gcd(p, q);
// Check non-negative, so conversion to unsigned long doesn't alter value.
VERIFY( r1 >= 0 );
// Check for expected result
VERIFY( (unsigned long long)r1 == r );
// Check reversing arguments doesn't change result
VERIFY( std::gcd(q, p) == r1 );
P pabs = p < 0 ? -p : p;
VERIFY( std::gcd(p, p) == pabs );
VERIFY( std::gcd(0, p) == pabs );
VERIFY( std::gcd(p, 0) == pabs );
VERIFY( std::gcd(1, p) == 1 );
VERIFY( std::gcd(p, 1) == 1 );
Q qabs = q < 0 ? -q : q;
VERIFY( std::gcd(q, q) == qabs );
VERIFY( std::gcd(0, q) == qabs );
VERIFY( std::gcd(q, 0) == qabs );
VERIFY( std::gcd(1, q) == 1 );
VERIFY( std::gcd(q, 1) == 1 );
VERIFY( std::gcd(r, r) == r );
VERIFY( std::gcd(0, r) == r );
VERIFY( std::gcd(r, 0) == r );
VERIFY( std::gcd(1, r) == 1 );
VERIFY( std::gcd(r, 1) == 1 );
return true;
}
constexpr bool
test01()
{
for (auto t : testcases)
{
check(t.p, t.q, t.r);
if (t.p <= LONG_MAX && t.q <= LONG_MAX)
{
check( (long)t.p, (long)t.p, t.p);
check(-(long)t.p, (long)t.p, t.p);
check(-(long)t.p, -(long)t.p, t.p);
check( (long)t.p, t.q, t.r);
check(-(long)t.p, t.q, t.r);
check(t.p, (long)t.q, t.r);
check(t.p, -(long)t.q, t.r);
check( (long)t.p, (long)t.q, t.r);
check( (long)t.p, -(long)t.q, t.r);
check(-(long)t.p, (long)t.q, t.r);
check(-(long)t.p, -(long)t.q, t.r);
}
if (t.p <= INT_MAX && t.q <= INT_MAX)
{
check((long)t.p, (int)t.q, t.r);
check(-(int)t.p, (long)t.q, t.r);
check( (int)t.p, (unsigned)t.q, t.r);
check(-(int)t.p, (unsigned)t.q, t.r);
check(-(int)t.p, -(int)t.q, t.r);
check(-(int)t.p, -(long)t.q, t.r);
}
if (t.p <= SHRT_MAX && t.q <= SHRT_MAX)
{
check( (long)t.p, (short)t.q, t.r);
check(-(short)t.p, (long)t.q, t.r);
check( (short)t.p, (unsigned short)t.q, t.r);
check(-(short)t.p, (unsigned short)t.q, t.r);
check(-(short)t.p, -(short)t.q, t.r);
check(-(short)t.p, -(long)t.q, t.r);
}
}
return true;
}
int main()
{
static_assert( test01() ); // constexpr
VERIFY( test01() ); // non-constexpr
}