diff --git a/src/Magnum/Math/Bezier.h b/src/Magnum/Math/Bezier.h index cbefc87e9..38c488cb6 100644 --- a/src/Magnum/Math/Bezier.h +++ b/src/Magnum/Math/Bezier.h @@ -50,6 +50,8 @@ Implementation of M-order N-dimensional template class Bezier { static_assert(order != 0, "Bezier cannot have zero order"); + template friend class Bezier; + public: typedef T Type; /**< @brief Underlying data type */ @@ -85,6 +87,14 @@ template class Bezier { static_assert(sizeof...(U) + 1 == order + 1, "Wrong number of arguments"); } + /** + * @brief Construct Bézier curve from another of different type + * + * Performs only default casting on the values, no rounding or + * anything else. + */ + template constexpr explicit Bezier(const Bezier& other) noexcept: Bezier{typename Implementation::GenerateSequence::Type(), other} {} + /** * @brief Subdivide the curve * @param t The interpolation factor @@ -137,6 +147,9 @@ template class Bezier { } private: + /* Implementation for Bezier::Bezier(const Bezier&) */ + template constexpr explicit Bezier(Implementation::Sequence, const Bezier& other) noexcept: _data{Vector(other._data[sequence])...} {} + /* Implementation for Bezier::Bezier(ZeroInitT) and Bezier::Bezier(NoInitT) */ /* MSVC 2015 can't handle {} here */ template constexpr explicit Bezier(Implementation::Sequence, U): _data{Vector((static_cast(sequence), U{typename U::Init{}}))...} {} diff --git a/src/Magnum/Math/Test/BezierTest.cpp b/src/Magnum/Math/Test/BezierTest.cpp index 210fcb3be..987ad10a5 100644 --- a/src/Magnum/Math/Test/BezierTest.cpp +++ b/src/Magnum/Math/Test/BezierTest.cpp @@ -35,7 +35,9 @@ namespace Magnum { namespace Math { namespace Test { typedef Math::Vector2 Vector2; +typedef Math::Vector2 Vector2d; typedef Math::QuadraticBezier2D QuadraticBezier2D; +typedef Math::QuadraticBezier2D QuadraticBezier2Dd; typedef Math::CubicBezier2D CubicBezier2D; struct BezierTest : Corrade::TestSuite::Tester { @@ -44,6 +46,7 @@ struct BezierTest : Corrade::TestSuite::Tester { void construct(); void constructDefault(); void constructNoInit(); + void constructConversion(); void constructCopy(); void data(); @@ -61,6 +64,7 @@ BezierTest::BezierTest() { addTests({&BezierTest::construct, &BezierTest::constructDefault, &BezierTest::constructNoInit, + &BezierTest::constructConversion, &BezierTest::constructCopy, &BezierTest::data, @@ -100,6 +104,18 @@ void BezierTest::constructNoInit() { CORRADE_VERIFY((std::is_nothrow_constructible::value)); } +void BezierTest::constructConversion() { + constexpr QuadraticBezier2Dd a{Vector2d{0.5, 1.0}, Vector2d{1.1, 0.3}, Vector2d{0.1, 1.2}}; + constexpr QuadraticBezier2D b{a}; + + CORRADE_COMPARE(b, (QuadraticBezier2D{Vector2{0.5f, 1.0f}, Vector2{1.1f, 0.3f}, Vector2{0.1f, 1.2f}})); + + /* Implicit conversion is not allowed */ + CORRADE_VERIFY(!(std::is_convertible::value)); + + CORRADE_VERIFY((std::is_nothrow_constructible::value)); +} + void BezierTest::constructCopy() { constexpr QuadraticBezier2D a{Vector2{0.5f, 1.0f}, Vector2{1.1f, 0.3f}, Vector2{0.1f, 1.2f}}; constexpr QuadraticBezier2D b{a};