Rework VECTOR2D promotion rules

VECTOR + scalar = vector type (KiROUND when VECTOR is integral and
scalar is float)
VECTOR + VECTOR = common type vector

Implemented with concepts in template rules - SWIG compatible
This commit is contained in:
Seth Hillbrand 2024-06-15 13:33:15 -07:00
parent 5ba2896968
commit e3231e6996
2 changed files with 35 additions and 26 deletions

View File

@ -425,6 +425,13 @@ const std::string VECTOR2<T>::Format() const
}
template <class T>
concept FloatingPoint = std::is_floating_point<T>::value;
template <class T>
concept Integral = std::is_integral<T>::value;
template <class T, class U>
VECTOR2<std::common_type_t<T, U>> operator+( const VECTOR2<T>& aLHS, const VECTOR2<U>& aRHS )
{
@ -432,27 +439,26 @@ VECTOR2<std::common_type_t<T, U>> operator+( const VECTOR2<T>& aLHS, const VECTO
}
template <class T, class U>
VECTOR2<std::common_type_t<T, U>> operator+( const VECTOR2<T>& aLHS, const U& aScalar )
template <FloatingPoint T, class U>
VECTOR2<T> operator+( const VECTOR2<T>& aLHS, const U& aScalar )
{
return VECTOR2<std::common_type_t<T, U>>( aLHS.x + aScalar, aLHS.y + aScalar );
return VECTOR2<T>( aLHS.x + aScalar, aLHS.y + aScalar );
}
// SWIG doesn't handle this template correctly
#ifndef SWIG
template <class T>
VECTOR2<T> operator+( const VECTOR2<T>& aVector, std::unsigned_integral auto aScalar )
template <Integral T, Integral U>
VECTOR2<T> operator+( const VECTOR2<T>& aLHS, const U& aScalar )
{
return VECTOR2<T>( aVector.x + aScalar, aVector.y + aScalar );
return VECTOR2<T>( aLHS.x + aScalar, aLHS.y + aScalar );
}
#else
template <class T>
VECTOR2<T> operator+( const VECTOR2<T>& aVector, unsigned aScalar )
template <Integral T, FloatingPoint U>
VECTOR2<T> operator+( const VECTOR2<T>& aLHS, const U& aScalar )
{
return VECTOR2<T>( aVector.x + aScalar, aVector.y + aScalar );
return VECTOR2<T>( KiROUND( aLHS.x + aScalar ), KiROUND( aLHS.y + aScalar ) );
}
#endif
template <class T, class U>
VECTOR2<std::common_type_t<T, U>> operator-( const VECTOR2<T>& aLHS, const VECTOR2<U>& aRHS )
@ -461,25 +467,25 @@ VECTOR2<std::common_type_t<T, U>> operator-( const VECTOR2<T>& aLHS, const VECTO
}
template <class T, class U>
VECTOR2<std::common_type_t<T, U>> operator-( const VECTOR2<T>& aLHS, const U& aScalar )
template <FloatingPoint T, class U>
VECTOR2<T> operator-( const VECTOR2<T>& aLHS, U aScalar )
{
return VECTOR2<std::common_type_t<T, U>>( aLHS.x - aScalar, aLHS.y - aScalar );
return VECTOR2<T>( aLHS.x - aScalar, aLHS.y - aScalar );
}
#ifndef SWIG
template <class T>
VECTOR2<T> operator-( const VECTOR2<T>& aVector, std::unsigned_integral auto aScalar )
template <Integral T, Integral U>
VECTOR2<T> operator-( const VECTOR2<T>& aLHS, U aScalar )
{
return VECTOR2<T>( aVector.x - aScalar, aVector.y - aScalar );
return VECTOR2<T>( aLHS.x - aScalar, aLHS.y - aScalar );
}
#else
template <class T>
VECTOR2<T> operator-( const VECTOR2<T>& aVector, unsigned aScalar )
template <Integral T, FloatingPoint U>
VECTOR2<T> operator-( const VECTOR2<T>& aLHS, const U& aScalar )
{
return VECTOR2<T>( aVector.x - aScalar, aVector.y - aScalar );
return VECTOR2<T>( KiROUND( aLHS.x - aScalar ), KiROUND( aLHS.y - aScalar ) );
}
#endif
template <class T>

View File

@ -136,23 +136,26 @@ BOOST_AUTO_TEST_CASE( test_casting )
BOOST_CHECK_EQUAL( vdouble, VECTOR2D( -3.0, -4.0 ) );
BOOST_CHECK_EQUAL( vlong, VECTOR2L( -3, -4 ) );
BOOST_CHECK_EQUAL( vfloat, VECTOR2<float>( -3.0f, -4.0f ) );
BOOST_CHECK_EQUAL( vunsigned, VECTOR2<unsigned>( 0, 0 ) ); // unsigned can't be negative, so we clamp
BOOST_CHECK_EQUAL( vunsigned, VECTOR2<unsigned>( 4294967293, 4294967292 ) ); // roll over unsigned when explicitly subtracting.
// Check that negative initial values are handled correctly
vint = VECTOR2I( -4, -3 );
vdouble = VECTOR2D( -4.0, -3.0 );
vlong = VECTOR2L( -4, -3 );
vfloat = VECTOR2<float>( -4.0f, -3.0f );
vunsigned = VECTOR2<unsigned>( -4, -3 );
vint = vint - 1;
vdouble = vdouble - 1;
vlong = vlong - 1;
vfloat = vfloat - 1;
vunsigned = vunsigned - 1;
BOOST_CHECK_EQUAL( vint, VECTOR2I( -5, -4 ) );
BOOST_CHECK_EQUAL( vdouble, VECTOR2D( -5.0, -4.0 ) );
BOOST_CHECK_EQUAL( vlong, VECTOR2L( -5, -4 ) );
BOOST_CHECK_EQUAL( vfloat, VECTOR2<float>( -5.0f, -4.0f ) );
BOOST_CHECK_EQUAL( vunsigned, VECTOR2<unsigned>( 4294967291, 4294967292 ) );
vint = vint - 1u;
vdouble = vdouble - 1u;