Browse Source

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.
pull/7/head
Vladimír Vondruš 13 years ago
parent
commit
f7a8641081
  1. 14
      src/Math/Test/VectorTest.cpp
  2. 17
      src/Math/Vector.h

14
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() {

17
src/Math/Vector.h

@ -135,18 +135,17 @@ template<std::size_t size, class T> class Vector {
* @param first First value
* @param next Next values
*/
template<class ...U> 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<class ...U> inline constexpr /*implicit*/ Vector(T first, U... next);
#else
template<class ...U, class V = typename std::enable_if<sizeof...(U)+1 == size, T>::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<class U> inline explicit Vector(typename std::enable_if<std::is_same<T, U>::value && size != 1, U>::type value) {
template<class U, class V = typename std::enable_if<std::is_same<T, U>::value && size != 1, T>::type> inline explicit Vector(U value) {
#endif
for(std::size_t i = 0; i != size; ++i)
_data[i] = value;

Loading…
Cancel
Save