From f7a86410819eda61449666e200d24e21666681ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 30 Jan 2013 16:20:23 +0100 Subject: [PATCH] Math: fixed one-argument Vector constructors. It is now possible to implicitly create one-element Vector and also explicitly fill more-element Vector with one value without any ambiguous overload conflicts: Vector<1, int> a1 = 1; // calls implicit constructor //Vector<3, int> a3 = 1; // error! Vector<1, int> b1(1); // still calls the implicit constructor, the // explicit is disabled for one-element vector Vector<3, int> b3(1); // calls the explicit "filling" constructor, // the implicit is disabled for only one argument The downside of this is that now specifying improper element count in constructor doesn't lead to static_assert with human readable error, but rather cryptic "no match" error. --- src/Math/Test/VectorTest.cpp | 14 +++++++++++--- src/Math/Vector.h | 17 ++++++++--------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/Math/Test/VectorTest.cpp b/src/Math/Test/VectorTest.cpp index ba53288cc..66ade42a7 100644 --- a/src/Math/Test/VectorTest.cpp +++ b/src/Math/Test/VectorTest.cpp @@ -29,6 +29,7 @@ class VectorTest: public Corrade::TestSuite::Tester { void constructFromData(); void constructDefault(); void constructOneValue(); + void constructOneComponent(); void constructConversion(); void data(); @@ -68,6 +69,7 @@ VectorTest::VectorTest() { addTests(&VectorTest::constructFromData, &VectorTest::constructDefault, &VectorTest::constructOneValue, + &VectorTest::constructOneComponent, &VectorTest::constructConversion, &VectorTest::data, @@ -109,9 +111,15 @@ void VectorTest::constructDefault() { } void VectorTest::constructOneValue() { - CORRADE_EXPECT_FAIL("Constructing Vector from one value is broken."); - CORRADE_VERIFY(false); -// CORRADE_COMPARE(Vector4(7.25f), Vector4(7.25f, 7.25f, 7.25f, 7.25f)); + CORRADE_COMPARE(Vector4(7.25f), Vector4(7.25f, 7.25f, 7.25f, 7.25f)); +} + +void VectorTest::constructOneComponent() { + typedef Vector<1, float> Vector1; + + /* Implicit constructor must work */ + Vector1 vec = 1; + CORRADE_COMPARE(vec, Vector1(1)); } void VectorTest::constructConversion() { diff --git a/src/Math/Vector.h b/src/Math/Vector.h index f05b2ff6f..97568a4cf 100644 --- a/src/Math/Vector.h +++ b/src/Math/Vector.h @@ -135,18 +135,17 @@ template class Vector { * @param first First value * @param next Next values */ - template inline constexpr /*implicit*/ Vector(T first, U... next): _data{first, next...} { - static_assert(sizeof...(next)+1 == size, "Improper number of arguments passed to Vector constructor"); - } + #ifdef DOXYGEN_GENERATING_OUTPUT + template inline constexpr /*implicit*/ Vector(T first, U... next); + #else + template::type> inline constexpr /*implicit*/ Vector(T first, U... next): _data{first, next...} {} + #endif - /** - * @brief Construct vector with one value for all fields - * @todo Fix this to be actually usable (not only in subclasses) - */ + /** @brief Construct vector with one value for all fields */ #ifdef DOXYGEN_GENERATING_OUTPUT - inline explicit Vector(T value) { + inline explicit Vector(T value); #else - template inline explicit Vector(typename std::enable_if::value && size != 1, U>::type value) { + template::value && size != 1, T>::type> inline explicit Vector(U value) { #endif for(std::size_t i = 0; i != size; ++i) _data[i] = value;