Browse Source

Math: make all literals usable with Utility::Tweakable.

pull/297/head
Vladimír Vondruš 8 years ago
parent
commit
d7d8e49de2
  1. 8
      doc/changelog.dox
  2. 1
      src/Magnum/CMakeLists.txt
  3. 125
      src/Magnum/Math/Angle.cpp
  4. 54
      src/Magnum/Math/Angle.h
  5. 132
      src/Magnum/Math/Color.cpp
  6. 74
      src/Magnum/Math/Color.h
  7. 34
      src/Magnum/Math/Half.cpp
  8. 16
      src/Magnum/Math/Half.h
  9. 100
      src/Magnum/Math/Test/AngleTest.cpp
  10. 288
      src/Magnum/Math/Test/ColorTest.cpp
  11. 73
      src/Magnum/Math/Test/HalfTest.cpp

8
doc/changelog.dox

@ -38,6 +38,14 @@ See also:
@section changelog-latest Changes since 2018.10
@subsection changelog-latest-new New features
@subsubsection changelog-latest-new-math Math library
- Support for using the @ref Math::Deg, @ref Math::Rad, @ref Math::Half,
@ref Math::Color3 and @ref Math::Color4 literals with the new experimental
@ref Corrade::Utility::Tweakable utility. See also @ref tweakableliterals.
@subsection changelog-latest-bugfixes Bug fixes
- Fixed @ref Platform::Sdl2Application and @ref Platform::GlfwApplication to

1
src/Magnum/CMakeLists.txt

@ -132,6 +132,7 @@ endif()
# Files shared between main library and math unit test library
set(MagnumMath_SRCS
Math/Angle.cpp
Math/Color.cpp
Math/Half.cpp
Math/Functions.cpp

125
src/Magnum/Math/Angle.cpp

@ -0,0 +1,125 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "Angle.h"
#if defined(DOXYGEN_GENERATING_OUTPUT) || defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT)) || defined(CORRADE_TARGET_EMSCRIPTEN)
#include <algorithm>
#include <Corrade/Containers/ArrayView.h>
#include <Corrade/Utility/String.h>
#include <Corrade/Utility/TweakableParser.h>
namespace Corrade { namespace Utility {
std::pair<TweakableState, Magnum::Math::Deg<Magnum::Float>> TweakableParser<Magnum::Math::Deg<Magnum::Float>>::parse(const Containers::ArrayView<const char> value) {
char* end;
const Magnum::Float result = std::strtof(value, &end);
if(end == value.begin() || std::find(value.begin(), value.end(), '.') == value.end()) {
Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "is not an angle literal";
return {TweakableState::Recompile, {}};
}
if(!String::viewEndsWith(value, "_degf")) {
Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "has an unexpected suffix, expected _degf";
return {TweakableState::Recompile, {}};
}
if(end != value.end() - 5) {
Warning{} << "Utility::TweakableParser: unexpected characters" << std::string{const_cast<const char*>(end), value.end()} << "after an angle literal";
return {TweakableState::Recompile, {}};
}
return {TweakableState::Success, Magnum::Math::Deg<Magnum::Float>{result}};
}
std::pair<TweakableState, Magnum::Math::Deg<Magnum::Double>> TweakableParser<Magnum::Math::Deg<Magnum::Double>>::parse(const Containers::ArrayView<const char> value) {
char* end;
const Magnum::Double result = std::strtod(value, &end);
if(end == value.begin() || std::find(value.begin(), value.end(), '.') == value.end()) {
Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "is not an angle literal";
return {TweakableState::Recompile, {}};
}
if(!String::viewEndsWith(value, "_deg")) {
Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "has an unexpected suffix, expected _deg";
return {TweakableState::Recompile, {}};
}
if(end != value.end() - 4) {
Warning{} << "Utility::TweakableParser: unexpected characters" << std::string{const_cast<const char*>(end), value.end()} << "after an angle literal";
return {TweakableState::Recompile, {}};
}
return {TweakableState::Success, Magnum::Math::Deg<Magnum::Double>{result}};
}
std::pair<TweakableState, Magnum::Math::Rad<Magnum::Float>> TweakableParser<Magnum::Math::Rad<Magnum::Float>>::parse(const Containers::ArrayView<const char> value) {
char* end;
const Magnum::Float result = std::strtof(value, &end);
if(end == value.begin() || std::find(value.begin(), value.end(), '.') == value.end()) {
Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "is not an angle literal";
return {TweakableState::Recompile, {}};
}
if(!String::viewEndsWith(value, "_radf")) {
Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "has an unexpected suffix, expected _radf";
return {TweakableState::Recompile, {}};
}
if(end != value.end() - 5) {
Warning{} << "Utility::TweakableParser: unexpected characters" << std::string{const_cast<const char*>(end), value.end()} << "after an angle literal";
return {TweakableState::Recompile, {}};
}
return {TweakableState::Success, Magnum::Math::Rad<Magnum::Float>{result}};
}
std::pair<TweakableState, Magnum::Math::Rad<Magnum::Double>> TweakableParser<Magnum::Math::Rad<Magnum::Double>>::parse(const Containers::ArrayView<const char> value) {
char* end;
const Magnum::Double result = std::strtod(value, &end);
if(end == value.begin() || std::find(value.begin(), value.end(), '.') == value.end()) {
Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "is not an angle literal";
return {TweakableState::Recompile, {}};
}
if(!String::viewEndsWith(value, "_rad")) {
Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "has an unexpected suffix, expected _rad";
return {TweakableState::Recompile, {}};
}
if(end != value.end() - 4) {
Warning{} << "Utility::TweakableParser: unexpected characters" << std::string{const_cast<const char*>(end), value.end()} << "after an angle literal";
return {TweakableState::Recompile, {}};
}
return {TweakableState::Success, Magnum::Math::Rad<Magnum::Double>{result}};
}
}}
#endif

54
src/Magnum/Math/Angle.h

@ -282,6 +282,60 @@ template<class T> struct ConfigurationValue<Magnum::Math::Rad<T>> {
}
};
#if defined(DOXYGEN_GENERATING_OUTPUT) || defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT)) || defined(CORRADE_TARGET_EMSCRIPTEN)
/**
@tweakableliteral{Magnum::Math::Deg}
Parses the @link Magnum::Math::Literals::operator""_degf @endlink literal.
@experimental
*/
template<> struct MAGNUM_EXPORT TweakableParser<Magnum::Math::Deg<Magnum::Float>> {
TweakableParser() = delete;
/** @brief Parse the value */
static std::pair<TweakableState, Magnum::Math::Deg<Magnum::Float>> parse(Containers::ArrayView<const char> value);
};
/**
@tweakableliteral{Magnum::Math::Deg}
Parses the @link Magnum::Math::Literals::operator""_deg @endlink literal.
@experimental
*/
template<> struct MAGNUM_EXPORT TweakableParser<Magnum::Math::Deg<Magnum::Double>> {
TweakableParser() = delete;
/** @brief Parse the value */
static std::pair<TweakableState, Magnum::Math::Deg<Magnum::Double>> parse(Containers::ArrayView<const char> value);
};
/**
@tweakableliteral{Magnum::Math::Rad}
Parses the @link Magnum::Math::Literals::operator""_radf @endlink literal.
@experimental
*/
template<> struct MAGNUM_EXPORT TweakableParser<Magnum::Math::Rad<Magnum::Float>> {
TweakableParser() = delete;
/** @brief Parse the value */
static std::pair<TweakableState, Magnum::Math::Rad<Magnum::Float>> parse(Containers::ArrayView<const char> value);
};
/**
@tweakableliteral{Magnum::Math::Rad}
Parses the @link Magnum::Math::Literals::operator""_rad @endlink literal.
@experimental
*/
template<> struct MAGNUM_EXPORT TweakableParser<Magnum::Math::Rad<Magnum::Double>> {
TweakableParser() = delete;
/** @brief Parse the value */
static std::pair<TweakableState, Magnum::Math::Rad<Magnum::Double>> parse(Containers::ArrayView<const char> value);
};
}}
#endif
#endif

132
src/Magnum/Math/Color.cpp

@ -25,6 +25,12 @@
#include "Color.h"
#if defined(DOXYGEN_GENERATING_OUTPUT) || defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT)) || defined(CORRADE_TARGET_EMSCRIPTEN)
#include <cstring>
#include <Corrade/Utility/String.h>
#include <Corrade/Utility/Tweakable.h>
#endif
namespace Magnum { namespace Math {
namespace {
@ -56,3 +62,129 @@ Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug& debug, const Color4
}
}}
#if defined(DOXYGEN_GENERATING_OUTPUT) || defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT)) || defined(CORRADE_TARGET_EMSCRIPTEN)
namespace Corrade { namespace Utility {
std::pair<TweakableState, Magnum::Math::Color3<Magnum::UnsignedByte>> TweakableParser<Magnum::Math::Color3<Magnum::UnsignedByte>>::parse(const Containers::ArrayView<const char> value) {
if(value.size() < 2 || value[0] != '0' || (value[1] != 'x' && value[1] != 'X')) {
Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "is not a hexadecimal color literal";
return {TweakableState::Recompile, {}};
}
const bool isSrgb = String::viewEndsWith(value, "_srgb");
if(!isSrgb && !String::viewEndsWith(value, "_rgb")) {
Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "has an unexpected suffix, expected _rgb or _srgb";
return {TweakableState::Recompile, {}};
}
char* end;
const Magnum::UnsignedInt result = std::strtoul(value, &end, 16);
if(end != value.end() - (isSrgb ? 5 : 4)) {
Warning{} << "Utility::TweakableParser: unexpected characters" << std::string{const_cast<const char*>(end), value.end()} << "after a color literal";
return {TweakableState::Recompile, {}};
}
if(value.size() != (isSrgb ? 13 : 12)) {
Error{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "doesn't have expected number of digits";
return {TweakableState::Error, {}};
}
return {TweakableState::Success,
isSrgb ? Magnum::Math::Literals::operator "" _srgb(result) :
Magnum::Math::Literals::operator "" _rgb(result)};
}
std::pair<TweakableState, Magnum::Math::Color4<Magnum::UnsignedByte>> TweakableParser<Magnum::Math::Color4<Magnum::UnsignedByte>>::parse(const Containers::ArrayView<const char> value) {
if(value.size() < 2 || value[0] != '0' || (value[1] != 'x' && value[1] != 'X')) {
Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "is not a hexadecimal color literal";
return {TweakableState::Recompile, {}};
}
const bool isSrgb = String::viewEndsWith(value, "_srgba");
if(!isSrgb && !String::viewEndsWith(value, "_rgba")) {
Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "has an unexpected suffix, expected _rgba or _srgba";
return {TweakableState::Recompile, {}};
}
char* end;
const Magnum::UnsignedInt result = std::strtoul(value, &end, 16);
if(end != value.end() - (isSrgb ? 6 : 5)) {
Warning{} << "Utility::TweakableParser: unexpected characters" << std::string{const_cast<const char*>(end), value.end()} << "after a color literal";
return {TweakableState::Recompile, {}};
}
if(value.size() != (isSrgb ? 16 : 15)) {
Error{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "doesn't have expected number of digits";
return {TweakableState::Error, {}};
}
return {TweakableState::Success,
isSrgb ? Magnum::Math::Literals::operator "" _srgba(result) :
Magnum::Math::Literals::operator "" _rgba(result)};
}
std::pair<TweakableState, Magnum::Math::Color3<Magnum::Float>> TweakableParser<Magnum::Math::Color3<Magnum::Float>>::parse(const Containers::ArrayView<const char> value) {
if(value.size() < 2 || value[0] != '0' || (value[1] != 'x' && value[1] != 'X')) {
Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "is not a hexadecimal color literal";
return {TweakableState::Recompile, {}};
}
const bool isSrgb = String::viewEndsWith(value, "_srgbf");
if(!isSrgb && !String::viewEndsWith(value, "_rgbf")) {
Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "has an unexpected suffix, expected _rgbf or _srgbf";
return {TweakableState::Recompile, {}};
}
char* end;
const Magnum::UnsignedInt result = std::strtoul(value, &end, 16);
if(end != value.end() - (isSrgb ? 6 : 5)) {
Warning{} << "Utility::TweakableParser: unexpected characters" << std::string{const_cast<const char*>(end), value.end()} << "after a color literal";
return {TweakableState::Recompile, {}};
}
if(value.size() != (isSrgb ? 14 : 13)) {
Error{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "doesn't have expected number of digits";
return {TweakableState::Error, {}};
}
return {TweakableState::Success,
isSrgb ? Magnum::Math::Literals::operator "" _srgbf(result) :
Magnum::Math::Literals::operator "" _rgbf(result)};
}
std::pair<TweakableState, Magnum::Math::Color4<Magnum::Float>> TweakableParser<Magnum::Math::Color4<Magnum::Float>>::parse(const Containers::ArrayView<const char> value) {
if(value.size() < 2 || value[0] != '0' || (value[1] != 'x' && value[1] != 'X')) {
Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "is not a hexadecimal color literal";
return {TweakableState::Recompile, {}};
}
const bool isSrgb = String::viewEndsWith(value, "_srgbaf");
if(!isSrgb && !String::viewEndsWith(value, "_rgbaf")) {
Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "has an unexpected suffix, expected _rgbaf or _srgbaf";
return {TweakableState::Recompile, {}};
}
char* end;
const Magnum::UnsignedInt result = std::strtoul(value, &end, 16);
if(end != value.end() - (isSrgb ? 7 : 6)) {
Warning{} << "Utility::TweakableParser: unexpected characters" << std::string{const_cast<const char*>(end), value.end()} << "after a color literal";
return {TweakableState::Recompile, {}};
}
if(value.size() != (isSrgb ? 17 : 16)) {
Error{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "doesn't have expected number of digits";
return {TweakableState::Error, {}};
}
return {TweakableState::Success,
isSrgb ? Magnum::Math::Literals::operator "" _srgbaf(result) :
Magnum::Math::Literals::operator "" _rgbaf(result)};
}
}}
#endif

74
src/Magnum/Math/Color.h

@ -1277,11 +1277,77 @@ namespace Implementation {
}}
namespace Corrade { namespace Utility {
/** @configurationvalue{Magnum::Color3} */
template<class T> struct ConfigurationValue<Magnum::Math::Color3<T>>: public ConfigurationValue<Magnum::Math::Vector<3, T>> {};
/** @configurationvalue{Magnum::Color4} */
template<class T> struct ConfigurationValue<Magnum::Math::Color4<T>>: public ConfigurationValue<Magnum::Math::Vector<4, T>> {};
/** @configurationvalue{Magnum::Color3} */
template<class T> struct ConfigurationValue<Magnum::Math::Color3<T>>: ConfigurationValue<Magnum::Math::Vector<3, T>> {};
/** @configurationvalue{Magnum::Color4} */
template<class T> struct ConfigurationValue<Magnum::Math::Color4<T>>: ConfigurationValue<Magnum::Math::Vector<4, T>> {};
/**
@tweakableliteral{Magnum::Math::Color3}
Parses the @link Magnum::Math::Literals::operator""_rgb @endlink and
@link Magnum::Math::Literals::operator""_srgb @endlink literals.
@experimental
*/
template<> struct MAGNUM_EXPORT TweakableParser<Magnum::Math::Color3<Magnum::UnsignedByte>> {
TweakableParser() = delete;
/** @brief Parse the value */
static std::pair<TweakableState, Magnum::Math::Color3<Magnum::UnsignedByte>> parse(Containers::ArrayView<const char> value);
};
#ifndef DOXYGEN_GENERATING_OUTPUT
template<> struct MAGNUM_EXPORT TweakableParser<Magnum::Math::Vector3<Magnum::UnsignedByte>>: TweakableParser<Magnum::Math::Color3<Magnum::UnsignedByte>> {};
#endif
/**
@tweakableliteral{Magnum::Math::Color4}
Parses the @link Magnum::Math::Literals::operator""_rgba @endlink and
@link Magnum::Math::Literals::operator""_srgba @endlink literals.
@experimental
*/
template<> struct MAGNUM_EXPORT TweakableParser<Magnum::Math::Color4<Magnum::UnsignedByte>> {
TweakableParser() = delete;
/** @brief Parse the value */
static std::pair<TweakableState, Magnum::Math::Color4<Magnum::UnsignedByte>> parse(Containers::ArrayView<const char> value);
};
#ifndef DOXYGEN_GENERATING_OUTPUT
template<> struct MAGNUM_EXPORT TweakableParser<Magnum::Math::Vector4<Magnum::UnsignedByte>>: TweakableParser<Magnum::Math::Color4<Magnum::UnsignedByte>> {};
#endif
/**
@tweakableliteral{Magnum::Math::Color3}
Parses the @link Magnum::Math::Literals::operator""_rgbf @endlink and
@link Magnum::Math::Literals::operator""_srgbf @endlink literals.
@experimental
*/
template<> struct MAGNUM_EXPORT TweakableParser<Magnum::Math::Color3<Magnum::Float>> {
TweakableParser() = delete;
/** @brief Parse the value */
static std::pair<TweakableState, Magnum::Math::Color3<Magnum::Float>> parse(Containers::ArrayView<const char> value);
};
/**
@tweakableliteral{Magnum::Math::Color4}
Parses the @link Magnum::Math::Literals::operator""_rgbaf @endlink and
@link Magnum::Math::Literals::operator""_srgbaf @endlink literals.
@experimental
*/
template<> struct MAGNUM_EXPORT TweakableParser<Magnum::Math::Color4<Magnum::Float>> {
TweakableParser() = delete;
/** @brief Parse the value */
static std::pair<TweakableState, Magnum::Math::Color4<Magnum::Float>> parse(Containers::ArrayView<const char> value);
};
}}
#endif

34
src/Magnum/Math/Half.cpp

@ -28,6 +28,12 @@
#include <iomanip>
#include <sstream>
#if defined(DOXYGEN_GENERATING_OUTPUT) || defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT)) || defined(CORRADE_TARGET_EMSCRIPTEN)
#include <algorithm>
#include <Corrade/Utility/String.h>
#include <Corrade/Utility/TweakableParser.h>
#endif
namespace Magnum { namespace Math {
Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug& debug, Half value) {
@ -39,3 +45,31 @@ Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug& debug, Half value)
}
}}
#if defined(DOXYGEN_GENERATING_OUTPUT) || defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT)) || defined(CORRADE_TARGET_EMSCRIPTEN)
namespace Corrade { namespace Utility {
std::pair<TweakableState, Magnum::Math::Half> TweakableParser<Magnum::Math::Half>::parse(const Containers::ArrayView<const char> value) {
char* end;
const Magnum::Float result = std::strtof(value, &end);
if(end == value.begin() || std::find(value.begin(), value.end(), '.') == value.end()) {
Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "is not a half literal";
return {TweakableState::Recompile, {}};
}
if(!String::viewEndsWith(value, "_h")) {
Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "has an unexpected suffix, expected _h";
return {TweakableState::Recompile, {}};
}
if(end != value.end() - 2) {
Warning{} << "Utility::TweakableParser: unexpected characters" << std::string{const_cast<const char*>(end), value.end()} << "after a half literal";
return {TweakableState::Recompile, {}};
}
return {TweakableState::Success, Magnum::Math::Half{result}};
}
}}
#endif

16
src/Magnum/Math/Half.h

@ -163,4 +163,20 @@ MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug& debug
}}
namespace Corrade { namespace Utility {
/**
@tweakableliteral{Magnum::Math::Half}
Parses the @link Magnum::Math::Literals::operator""_h @endlink literal.
*/
template<> struct MAGNUM_EXPORT TweakableParser<Magnum::Math::Half> {
TweakableParser() = delete;
/** @brief Parse the value */
static std::pair<TweakableState, Magnum::Math::Half> parse(Containers::ArrayView<const char> value);
};
}}
#endif

100
src/Magnum/Math/Test/AngleTest.cpp

@ -23,9 +23,13 @@
DEALINGS IN THE SOFTWARE.
*/
#include <cstring>
#include <sstream>
#include <Corrade/Containers/ArrayView.h>
#include <Corrade/TestSuite/Tester.h>
#include <Corrade/Utility/Configuration.h>
#include <Corrade/Utility/Format.h>
#include <Corrade/Utility/TweakableParser.h>
#include "Magnum/Math/Angle.h"
@ -47,6 +51,8 @@ struct AngleTest: Corrade::TestSuite::Tester {
void debugRad();
void configurationDeg();
void configurationRad();
template<class T> void tweakable();
template<class T> void tweakableError();
};
typedef Math::Deg<Float> Deg;
@ -54,6 +60,58 @@ typedef Math::Rad<Float> Rad;
typedef Math::Deg<Double> Degd;
typedef Math::Rad<Double> Radd;
using namespace Literals;
namespace {
constexpr struct {
const char* name;
const char* data;
float result;
} TweakableData[] {
{"fixed", "35.0_{}", 35.0f},
{"no zero before", ".5_{}", 0.5f},
{"no zero after", "35._{}", 35.0f},
{"positive", "+35.0_{}", 35.0f},
{"negative", "-35.0_{}", -35.0}
};
constexpr struct {
const char* name;
const char* data;
Corrade::Utility::TweakableState state;
const char* error;
} TweakableErrorData[] {
{"empty", "", Corrade::Utility::TweakableState::Recompile,
"Utility::TweakableParser: is not an angle literal\n"},
{"integral", "42_{}", Corrade::Utility::TweakableState::Recompile,
"Utility::TweakableParser: 42_{} is not an angle literal\n"},
{"garbage after", "42.b_{}", Corrade::Utility::TweakableState::Recompile,
"Utility::TweakableParser: unexpected characters b_{} after an angle literal\n"},
{"different suffix", "42.0u", Corrade::Utility::TweakableState::Recompile, /* not for double */
"Utility::TweakableParser: 42.0u has an unexpected suffix, expected _{}\n"}
};
template<class> struct TweakableTraits;
template<> struct TweakableTraits<Deg> {
static const char* name() { return "Deg"; }
static const char* literal() { return "degf"; }
};
template<> struct TweakableTraits<Degd> {
static const char* name() { return "Degd"; }
static const char* literal() { return "deg"; }
};
template<> struct TweakableTraits<Rad> {
static const char* name() { return "Rad"; }
static const char* literal() { return "radf"; }
};
template<> struct TweakableTraits<Radd> {
static const char* name() { return "Radd"; }
static const char* literal() { return "rad"; }
};
}
AngleTest::AngleTest() {
addTests({&AngleTest::construct,
&AngleTest::constructDefault,
@ -68,6 +126,20 @@ AngleTest::AngleTest() {
&AngleTest::debugRad,
&AngleTest::configurationDeg,
&AngleTest::configurationRad});
addInstancedTests<AngleTest>({
&AngleTest::tweakable<Deg>,
&AngleTest::tweakable<Degd>,
&AngleTest::tweakable<Rad>,
&AngleTest::tweakable<Radd>},
Corrade::Containers::arraySize(TweakableData));
addInstancedTests<AngleTest>({
&AngleTest::tweakableError<Deg>,
&AngleTest::tweakableError<Degd>,
&AngleTest::tweakableError<Rad>,
&AngleTest::tweakableError<Radd>},
Corrade::Containers::arraySize(TweakableErrorData));
}
void AngleTest::construct() {
@ -162,8 +234,6 @@ void AngleTest::constructCopy() {
}
void AngleTest::literals() {
using namespace Literals;
constexpr auto a = 25.0_deg;
CORRADE_VERIFY((std::is_same<decltype(a), const Degd>::value));
CORRADE_COMPARE(Double(a), 25.0);
@ -234,6 +304,32 @@ void AngleTest::configurationRad() {
CORRADE_COMPARE(c.value<Rad>("angle"), angle);
}
template<class T> void AngleTest::tweakable() {
auto&& data = TweakableData[testCaseInstanceId()];
setTestCaseName(Corrade::Utility::formatString("tweakable<{}>", TweakableTraits<T>::name()));
setTestCaseDescription(data.name);
std::string input = Corrade::Utility::formatString(data.data, TweakableTraits<T>::literal());
Corrade::Utility::TweakableState state;
T result;
std::tie(state, result) = Corrade::Utility::TweakableParser<T>::parse({input.data(), input.size()});
CORRADE_COMPARE(state, Corrade::Utility::TweakableState::Success);
CORRADE_COMPARE(result, T(typename T::Type(data.result)));
}
template<class T> void AngleTest::tweakableError() {
auto&& data = TweakableErrorData[testCaseInstanceId()];
setTestCaseName(Corrade::Utility::formatString("tweakableError<{}>", TweakableTraits<T>::name()));
setTestCaseDescription(data.name);
std::string input = Corrade::Utility::formatString(data.data, TweakableTraits<T>::literal());
std::ostringstream out;
Warning redirectWarning{&out};
Error redirectError{&out};
Corrade::Utility::TweakableState state = Corrade::Utility::TweakableParser<T>::parse({input.data(), input.size()}).first;
CORRADE_COMPARE(out.str(), Corrade::Utility::formatString(data.error, TweakableTraits<T>::literal()));
CORRADE_COMPARE(state, data.state);
}
}}}
CORRADE_TEST_MAIN(Magnum::Math::Test::AngleTest)

288
src/Magnum/Math/Test/ColorTest.cpp

@ -27,6 +27,8 @@
#include <Corrade/TestSuite/Tester.h>
#include <Corrade/TestSuite/Compare/Numeric.h>
#include <Corrade/Utility/Configuration.h>
#include <Corrade/Utility/Format.h>
#include <Corrade/Utility/Tweakable.h>
#include "Magnum/Math/Color.h"
@ -105,6 +107,24 @@ struct ColorTest: Corrade::TestSuite::Tester {
void debug();
void debugUb();
void configuration();
void tweakableRgb();
void tweakableSrgb();
void tweakableRgbf();
void tweakableSrgbf();
void tweakableRgba();
void tweakableSrgba();
void tweakableRgbaf();
void tweakableSrgbaf();
void tweakableErrorRgb();
void tweakableErrorSrgb();
void tweakableErrorRgba();
void tweakableErrorSrgba();
void tweakableErrorRgbf();
void tweakableErrorSrgbf();
void tweakableErrorRgbaf();
void tweakableErrorSrgbaf();
};
typedef Math::Vector3<Float> Vector3;
@ -117,6 +137,44 @@ typedef Math::Color4<UnsignedByte> Color4ub;
typedef Math::Deg<Float> Deg;
using namespace Literals;
namespace {
const struct {
const char* name;
const char* dataRgb;
const char* dataRgba;
Color4 result;
Color4 resultSrgba;
Color4ub resultUb;
} TweakableData[] {
{"lowercase", "0xff3366_{}", "0xff3366aa_{}", 0xff3366aa_rgbaf, 0xff3366aa_srgbaf, 0xff3366aa_rgba},
{"uppercase", "0XFF3366_{}", "0XFF3366AA_{}", 0xff3366aa_rgbaf, 0xff3366aa_srgbaf, 0xff3366aa_rgba}
};
constexpr struct {
const char* name;
const char* data;
Corrade::Utility::TweakableState state;
const char* error;
} TweakableErrorData[] {
{"empty", "", Corrade::Utility::TweakableState::Recompile,
"Utility::TweakableParser: is not a hexadecimal color literal\n"},
{"char", "'a'", Corrade::Utility::TweakableState::Recompile,
"Utility::TweakableParser: 'a' is not a hexadecimal color literal\n"},
{"not hex", "{}_{}", Corrade::Utility::TweakableState::Recompile,
"Utility::TweakableParser: {0}_{2}{1} is not a hexadecimal color literal\n"},
{"garbage after", "0x{}._{}", Corrade::Utility::TweakableState::Recompile,
"Utility::TweakableParser: unexpected characters ._{2}{1} after a color literal\n"},
{"different suffix", "0x{}f", Corrade::Utility::TweakableState::Recompile,
"Utility::TweakableParser: 0x{0}f has an unexpected suffix, expected _{1} or _s{1}\n"},
{"bad size", "0x333_{1}", Corrade::Utility::TweakableState::Error,
"Utility::TweakableParser: 0x333_{2}{1} doesn't have expected number of digits\n"},
};
}
ColorTest::ColorTest() {
addTests({&ColorTest::construct,
&ColorTest::constructDefault,
@ -157,6 +215,26 @@ ColorTest::ColorTest() {
&ColorTest::debug,
&ColorTest::debugUb,
&ColorTest::configuration});
addInstancedTests({&ColorTest::tweakableRgb,
&ColorTest::tweakableSrgb,
&ColorTest::tweakableRgba,
&ColorTest::tweakableSrgba,
&ColorTest::tweakableRgbf,
&ColorTest::tweakableSrgbf,
&ColorTest::tweakableRgbaf,
&ColorTest::tweakableSrgbaf},
Corrade::Containers::arraySize(TweakableData));
addInstancedTests({&ColorTest::tweakableErrorRgb,
&ColorTest::tweakableErrorSrgb,
&ColorTest::tweakableErrorRgba,
&ColorTest::tweakableErrorSrgba,
&ColorTest::tweakableErrorRgbf,
&ColorTest::tweakableErrorSrgbf,
&ColorTest::tweakableErrorRgbaf,
&ColorTest::tweakableErrorSrgbaf},
Corrade::Containers::arraySize(TweakableErrorData));
}
void ColorTest::construct() {
@ -365,8 +443,6 @@ void ColorTest::data() {
}
void ColorTest::literals() {
using namespace Literals;
constexpr Color3ub a = 0x33b27f_rgb;
CORRADE_COMPARE(a, (Color3ub{0x33, 0xb2, 0x7f}));
@ -423,8 +499,6 @@ void ColorTest::colors() {
}
void ColorTest::hue() {
using namespace Literals;
CORRADE_COMPARE(Color3::fromHsv( 27.0_degf, 1.0f, 1.0f), (Color3{1.0f, 0.45f, 0.0f}));
CORRADE_COMPARE(Color3::fromHsv( 86.0_degf, 1.0f, 1.0f), (Color3{0.566667f, 1.0f, 0.0f}));
CORRADE_COMPARE(Color3::fromHsv(134.0_degf, 1.0f, 1.0f), (Color3{0.0f, 1.0f, 0.233333f}));
@ -453,8 +527,6 @@ void ColorTest::hue() {
}
void ColorTest::saturation() {
using namespace Literals;
CORRADE_COMPARE(Color3::fromHsv(0.0_degf, 0.702f, 1.0f), (Color3{1.0f, 0.298f, 0.298f}));
CORRADE_COMPARE((Color3{1.0f, 0.298f, 0.298f}).saturation(), 0.702f);
@ -476,8 +548,6 @@ void ColorTest::saturation() {
}
void ColorTest::value() {
using namespace Literals;
CORRADE_COMPARE(Color3::fromHsv(0.0_degf, 1.0f, 0.522f), (Color3{0.522f, 0.0f, 0.0f}));
CORRADE_COMPARE((Color3{0.522f, 0.0f, 0.0f}).value(), 0.522f);
@ -499,8 +569,6 @@ void ColorTest::value() {
}
void ColorTest::hsv() {
using namespace Literals;
CORRADE_COMPARE(Color3::fromHsv(std::make_tuple(230.0_degf, 0.749f, 0.427f)),
(Color3{0.107177f, 0.160481f, 0.427f}));
CORRADE_COMPARE(Color3::fromHsv(230.0_degf, 0.749f, 0.427f),
@ -552,8 +620,6 @@ void ColorTest::hsv() {
}
void ColorTest::fromHsvHueOverflow() {
using namespace Literals;
CORRADE_COMPARE(Color3::fromHsv( 27.0_degf - 360.0_degf, 1.0f, 1.0f), (Color3{1.0f, 0.45f, 0.0f}));
CORRADE_COMPARE(Color3::fromHsv( 86.0_degf - 360.0_degf, 1.0f, 1.0f), (Color3{0.566667f, 1.0f, 0.0f}));
CORRADE_COMPARE(Color3::fromHsv(134.0_degf - 360.0_degf, 1.0f, 1.0f), (Color3{0.0f, 1.0f, 0.233333f}));
@ -570,8 +636,6 @@ void ColorTest::fromHsvHueOverflow() {
}
void ColorTest::fromHsvDefaultAlpha() {
using namespace Literals;
CORRADE_COMPARE(Color4::fromHsv(std::make_tuple(230.0_degf, 0.749f, 0.427f)),
(Color4{0.107177f, 0.160481f, 0.427f, 1.0f}));
CORRADE_COMPARE(Color4::fromHsv(230.0_degf, 0.749f, 0.427f),
@ -697,8 +761,6 @@ void ColorTest::srgbMonotonic() {
}
void ColorTest::srgbLiterals() {
using namespace Literals;
constexpr Math::Vector3<UnsignedByte> a = 0x33b27f_srgb;
CORRADE_COMPARE(a, (Math::Vector3<UnsignedByte>{0x33, 0xb2, 0x7f}));
@ -808,8 +870,6 @@ void ColorTest::debug() {
}
void ColorTest::debugUb() {
using namespace Magnum::Math::Literals;
std::ostringstream o;
Debug(&o) << 0x123456_rgb << 0x789abc_rgb;
CORRADE_COMPARE(o.str(), "#123456 #789abc\n");
@ -837,6 +897,198 @@ void ColorTest::configuration() {
CORRADE_COMPARE(c.value<Color4>("color4"), color4);
}
void ColorTest::tweakableRgb() {
auto&& data = TweakableData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::string input = Corrade::Utility::formatString(data.dataRgb, "rgb");
Corrade::Utility::TweakableState state;
Color3ub result;
std::tie(state, result) = Corrade::Utility::TweakableParser<Color3ub>::parse({input.data(), input.size()});
CORRADE_COMPARE(state, Corrade::Utility::TweakableState::Success);
CORRADE_COMPARE(result, data.resultUb.rgb());
}
void ColorTest::tweakableSrgb() {
auto&& data = TweakableData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::string input = Corrade::Utility::formatString(data.dataRgb, "srgb");
Corrade::Utility::TweakableState state;
Math::Vector3<UnsignedByte> result;
std::tie(state, result) = Corrade::Utility::TweakableParser<Math::Vector3<UnsignedByte>>::parse({input.data(), input.size()});
CORRADE_COMPARE(state, Corrade::Utility::TweakableState::Success);
CORRADE_COMPARE(result, data.resultUb.rgb());
}
void ColorTest::tweakableRgba() {
auto&& data = TweakableData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::string input = Corrade::Utility::formatString(data.dataRgba, "rgba");
Corrade::Utility::TweakableState state;
Color4ub result;
std::tie(state, result) = Corrade::Utility::TweakableParser<Color4ub>::parse({input.data(), input.size()});
CORRADE_COMPARE(state, Corrade::Utility::TweakableState::Success);
CORRADE_COMPARE(result, data.resultUb);
}
void ColorTest::tweakableSrgba() {
auto&& data = TweakableData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::string input = Corrade::Utility::formatString(data.dataRgba, "srgba");
Corrade::Utility::TweakableState state;
Math::Vector4<UnsignedByte> result;
std::tie(state, result) = Corrade::Utility::TweakableParser<Math::Vector4<UnsignedByte>>::parse({input.data(), input.size()});
CORRADE_COMPARE(state, Corrade::Utility::TweakableState::Success);
CORRADE_COMPARE(result, data.resultUb);
}
void ColorTest::tweakableRgbf() {
auto&& data = TweakableData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::string input = Corrade::Utility::formatString(data.dataRgb, "rgbf");
Corrade::Utility::TweakableState state;
Color3 result;
std::tie(state, result) = Corrade::Utility::TweakableParser<Color3>::parse({input.data(), input.size()});
CORRADE_COMPARE(state, Corrade::Utility::TweakableState::Success);
CORRADE_COMPARE(result, data.result.rgb());
}
void ColorTest::tweakableSrgbf() {
auto&& data = TweakableData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::string input = Corrade::Utility::formatString(data.dataRgb, "srgbf");
Corrade::Utility::TweakableState state;
Color3 result;
std::tie(state, result) = Corrade::Utility::TweakableParser<Color3>::parse({input.data(), input.size()});
CORRADE_COMPARE(state, Corrade::Utility::TweakableState::Success);
CORRADE_COMPARE(result, data.resultSrgba.rgb());
}
void ColorTest::tweakableRgbaf() {
auto&& data = TweakableData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::string input = Corrade::Utility::formatString(data.dataRgba, "rgbaf");
Corrade::Utility::TweakableState state;
Color4 result;
std::tie(state, result) = Corrade::Utility::TweakableParser<Color4>::parse({input.data(), input.size()});
CORRADE_COMPARE(state, Corrade::Utility::TweakableState::Success);
CORRADE_COMPARE(result, data.result);
}
void ColorTest::tweakableSrgbaf() {
auto&& data = TweakableData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::string input = Corrade::Utility::formatString(data.dataRgba, "srgbaf");
Corrade::Utility::TweakableState state;
Color4 result;
std::tie(state, result) = Corrade::Utility::TweakableParser<Color4>::parse({input.data(), input.size()});
CORRADE_COMPARE(state, Corrade::Utility::TweakableState::Success);
CORRADE_COMPARE(result, data.resultSrgba);
}
void ColorTest::tweakableErrorRgb() {
auto&& data = TweakableErrorData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::string input = Corrade::Utility::formatString(data.data, "ff3366", "rgb");
std::ostringstream out;
Warning redirectWarning{&out};
Error redirectError{&out};
Corrade::Utility::TweakableState state = Corrade::Utility::TweakableParser<Color3ub>::parse({input.data(), input.size()}).first;
CORRADE_COMPARE(out.str(), Corrade::Utility::formatString(data.error, "ff3366", "rgb", ""));
CORRADE_COMPARE(state, data.state);
}
void ColorTest::tweakableErrorSrgb() {
auto&& data = TweakableErrorData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::string input = Corrade::Utility::formatString(data.data, "ff3366", "srgb");
std::ostringstream out;
Warning redirectWarning{&out};
Error redirectError{&out};
Corrade::Utility::TweakableState state = Corrade::Utility::TweakableParser<Math::Vector3<UnsignedByte>>::parse({input.data(), input.size()}).first;
CORRADE_COMPARE(out.str(), Corrade::Utility::formatString(data.error, "ff3366", "rgb", "s"));
CORRADE_COMPARE(state, data.state);
}
void ColorTest::tweakableErrorRgba() {
auto&& data = TweakableErrorData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::string input = Corrade::Utility::formatString(data.data, "ff3366aa", "rgba");
std::ostringstream out;
Warning redirectWarning{&out};
Error redirectError{&out};
Corrade::Utility::TweakableState state = Corrade::Utility::TweakableParser<Color4ub>::parse({input.data(), input.size()}).first;
CORRADE_COMPARE(out.str(), Corrade::Utility::formatString(data.error, "ff3366aa", "rgba", ""));
CORRADE_COMPARE(state, data.state);
}
void ColorTest::tweakableErrorSrgba() {
auto&& data = TweakableErrorData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::string input = Corrade::Utility::formatString(data.data, "ff3366aa", "srgba");
std::ostringstream out;
Warning redirectWarning{&out};
Error redirectError{&out};
Corrade::Utility::TweakableState state = Corrade::Utility::TweakableParser<Math::Vector4<UnsignedByte>>::parse({input.data(), input.size()}).first;
CORRADE_COMPARE(out.str(), Corrade::Utility::formatString(data.error, "ff3366aa", "rgba", "s"));
CORRADE_COMPARE(state, data.state);
}
void ColorTest::tweakableErrorRgbf() {
auto&& data = TweakableErrorData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::string input = Corrade::Utility::formatString(data.data, "ff3366", "rgbf");
std::ostringstream out;
Warning redirectWarning{&out};
Error redirectError{&out};
Corrade::Utility::TweakableState state = Corrade::Utility::TweakableParser<Color3>::parse({input.data(), input.size()}).first;
CORRADE_COMPARE(out.str(), Corrade::Utility::formatString(data.error, "ff3366", "rgbf", ""));
CORRADE_COMPARE(state, data.state);
}
void ColorTest::tweakableErrorSrgbf() {
auto&& data = TweakableErrorData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::string input = Corrade::Utility::formatString(data.data, "ff3366", "srgbf");
std::ostringstream out;
Warning redirectWarning{&out};
Error redirectError{&out};
Corrade::Utility::TweakableState state = Corrade::Utility::TweakableParser<Color3>::parse({input.data(), input.size()}).first;
CORRADE_COMPARE(out.str(), Corrade::Utility::formatString(data.error, "ff3366", "rgbf", "s"));
CORRADE_COMPARE(state, data.state);
}
void ColorTest::tweakableErrorRgbaf() {
auto&& data = TweakableErrorData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::string input = Corrade::Utility::formatString(data.data, "ff3366aa", "rgbaf");
std::ostringstream out;
Warning redirectWarning{&out};
Error redirectError{&out};
Corrade::Utility::TweakableState state = Corrade::Utility::TweakableParser<Color4>::parse({input.data(), input.size()}).first;
CORRADE_COMPARE(out.str(), Corrade::Utility::formatString(data.error, "ff3366aa", "rgbaf", ""));
CORRADE_COMPARE(state, data.state);
}
void ColorTest::tweakableErrorSrgbaf() {
auto&& data = TweakableErrorData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::string input = Corrade::Utility::formatString(data.data, "ff3366aa", "srgbaf");
std::ostringstream out;
Warning redirectWarning{&out};
Error redirectError{&out};
Corrade::Utility::TweakableState state = Corrade::Utility::TweakableParser<Color4>::parse({input.data(), input.size()}).first;
CORRADE_COMPARE(out.str(), Corrade::Utility::formatString(data.error, "ff3366aa", "rgbaf", "s"));
CORRADE_COMPARE(state, data.state);
}
}}}
CORRADE_TEST_MAIN(Magnum::Math::Test::ColorTest)

73
src/Magnum/Math/Test/HalfTest.cpp

@ -23,8 +23,11 @@
DEALINGS IN THE SOFTWARE.
*/
#include <cstring>
#include <algorithm>
#include <sstream>
#include <Corrade/TestSuite/Tester.h>
#include <Corrade/Utility/Tweakable.h>
#include "Magnum/Math/Half.h"
#include "Magnum/Math/Vector3.h"
@ -59,6 +62,8 @@ struct HalfTest: Corrade::TestSuite::Tester {
void literal();
void debug();
void tweakable();
void tweakableError();
private:
/* Naive / ground-truth packing helpers */
@ -79,6 +84,42 @@ struct HalfTest: Corrade::TestSuite::Tester {
typedef Math::Constants<Float> Constants;
using namespace Literals;
namespace {
const struct {
const char* name;
const char* data;
Half result;
} TweakableData[] {
{"fixed", "35.0_h", 35.0_h},
{"no zero before", ".5_h", 0.5_h},
{"no zero after", "35._h", 35.0_h},
{"exponential positive", "3.5e+1_h", 3.5e+1_h},
{"exponential negative", "350.0e-1_h", 350.0e-1_h},
{"positive", "+35.0_h", +35.0_h},
{"negative", "-35.0_h", -35.0_h}
};
constexpr struct {
const char* name;
const char* data;
Corrade::Utility::TweakableState state;
const char* error;
} TweakableErrorData[] {
{"empty", "", Corrade::Utility::TweakableState::Recompile,
"Utility::TweakableParser: is not a half literal\n"},
{"integral", "42_h", Corrade::Utility::TweakableState::Recompile,
"Utility::TweakableParser: 42_h is not a half literal\n"},
{"garbage after", "42.b_h", Corrade::Utility::TweakableState::Recompile,
"Utility::TweakableParser: unexpected characters b_h after a half literal\n"},
{"different suffix", "42.0u", Corrade::Utility::TweakableState::Recompile, /* not for double */
"Utility::TweakableParser: 42.0u has an unexpected suffix, expected _h\n"}
};
}
HalfTest::HalfTest() {
addTests({&HalfTest::unpack,
&HalfTest::pack});
@ -109,6 +150,12 @@ HalfTest::HalfTest() {
&HalfTest::literal,
&HalfTest::debug});
addInstancedTests({&HalfTest::tweakable},
Corrade::Containers::arraySize(TweakableData));
addInstancedTests({&HalfTest::tweakableError},
Corrade::Containers::arraySize(TweakableErrorData));
/* Calculate tables for table-based benchmark */
_mantissaTable[0] = 0;
for(std::size_t i = 1; i != 1024; ++i)
@ -597,16 +644,12 @@ void HalfTest::negation() {
}
void HalfTest::literal() {
using namespace Literals;
Half a = 3.5_h;
CORRADE_COMPARE(a, Half{UnsignedShort(0x4300)});
CORRADE_COMPARE(a, Half{3.5f});
}
void HalfTest::debug() {
using namespace Literals;
std::ostringstream out;
Debug{&out} << -36.41_h << Half{Constants::inf()}
@ -618,6 +661,28 @@ void HalfTest::debug() {
#endif
}
void HalfTest::tweakable() {
auto&& data = TweakableData[testCaseInstanceId()];
setTestCaseDescription(data.name);
Corrade::Utility::TweakableState state;
Half result;
std::tie(state, result) = Corrade::Utility::TweakableParser<Half>::parse({data.data, std::strlen(data.data)});
CORRADE_COMPARE(state, Corrade::Utility::TweakableState::Success);
CORRADE_COMPARE(result, data.result);
}
void HalfTest::tweakableError() {
auto&& data = TweakableErrorData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::ostringstream out;
Warning redirectWarning{&out};
Error redirectError{&out};
Corrade::Utility::TweakableState state = Corrade::Utility::TweakableParser<Half>::parse({data.data, std::strlen(data.data)}).first;
CORRADE_COMPARE(out.str(), data.error);
CORRADE_COMPARE(state, data.state);
}
}}}
CORRADE_TEST_MAIN(Magnum::Math::Test::HalfTest)

Loading…
Cancel
Save