Browse Source

Math: add an ability to construct a Range1D from Math::Vector<1, T>.

A Vector<1, T> is implicitly constructible from T but not vice versa (to
avoid nasty collisions with builtin operators on scalars) so this is
needed.
pull/529/head
Vladimír Vondruš 5 years ago
parent
commit
7d82352a13
  1. 26
      src/Magnum/Math/Range.h
  2. 13
      src/Magnum/Math/Test/RangeTest.cpp

26
src/Magnum/Math/Range.h

@ -37,9 +37,24 @@ namespace Magnum { namespace Math {
namespace Implementation {
template<UnsignedInt, class> struct RangeTraits;
template<class T> struct RangeTraits<1, T> { typedef T Type; };
template<class T> struct RangeTraits<2, T> { typedef Vector2<T> Type; };
template<class T> struct RangeTraits<3, T> { typedef Vector3<T> Type; };
template<class T> struct RangeTraits<1, T> {
typedef T Type;
constexpr static Type fromVector(const Vector<1, T>& value) {
return value[0];
}
};
template<class T> struct RangeTraits<2, T> {
typedef Vector2<T> Type;
constexpr static Type fromVector(const Vector<2, T>& value) {
return value;
}
};
template<class T> struct RangeTraits<3, T> {
typedef Vector3<T> Type;
constexpr static Type fromVector(const Vector<3, T>& value) {
return value;
}
};
template<UnsignedInt, class, class> struct RangeConverter;
}
@ -117,6 +132,11 @@ template<UnsignedInt dimensions, class T> class Range {
/** @brief Construct a range from minimal and maximal coordinates */
constexpr /*implicit*/ Range(const VectorType& min, const VectorType& max) noexcept: _min{min}, _max{max} {}
/** @overload */
#ifndef DOXYGEN_GENERATING_OUTPUT
template<UnsignedInt d = dimensions, class = typename std::enable_if<d == 1>::type>
#endif
constexpr /*implicit*/ Range(const Vector<dimensions, T>& min, const Vector<dimensions, T>& max) noexcept: _min{Implementation::RangeTraits<dimensions, T>::fromVector(min)}, _max{Implementation::RangeTraits<dimensions, T>::fromVector(max)} {}
/**
* @brief Construct a range from a pair of minimal and maximal coordinates

13
src/Magnum/Math/Test/RangeTest.cpp

@ -101,6 +101,7 @@ struct RangeTest: Corrade::TestSuite::Tester {
explicit RangeTest();
void construct();
void construct1DFromVectors();
void constructDefault();
void constructNoInit();
void constructFromSize();
@ -156,6 +157,7 @@ typedef Vector3<Int> Vector3i;
RangeTest::RangeTest() {
addTests({&RangeTest::construct,
&RangeTest::construct1DFromVectors,
&RangeTest::constructDefault,
&RangeTest::constructNoInit,
&RangeTest::constructFromSize,
@ -211,6 +213,17 @@ void RangeTest::construct() {
CORRADE_VERIFY(std::is_nothrow_constructible<Range3Di, Vector3i, Vector3i>::value);
}
void RangeTest::construct1DFromVectors() {
/* Used by EigenIntegration for Range3D conversion. Implementing the same
there would be a massive verbose pain and this could be useful elsewhere
as well, so implementing that directly on a Range. */
constexpr Range1Di a = {Vector<1, Int>{3}, Vector<1, Int>{23}};
CORRADE_COMPARE(a, (Range<1, Int>(3, 23)));
CORRADE_VERIFY(std::is_nothrow_constructible<Range1Di, Vector<1, Int>, Vector<1, Int>>::value);
}
void RangeTest::constructDefault() {
constexpr Range1Di a1;
constexpr Range2Di b1;

Loading…
Cancel
Save