diff --git a/src/python/magnum/gl.cpp b/src/python/magnum/gl.cpp index 14d1a29..2516108 100644 --- a/src/python/magnum/gl.cpp +++ b/src/python/magnum/gl.cpp @@ -28,6 +28,7 @@ #include #include #include +#include /** @todo drop once Containers::Pair is exposed directly */ #include #include #include @@ -300,7 +301,10 @@ void gl(py::module_& m) { ; m .def("version", static_cast(GL::version), "Enum value from major and minor version number", py::arg("major"), py::arg("minor")) - .def("version", static_cast(*)(GL::Version)>(GL::version), "Major and minor version number from enum value", py::arg("version")) + .def("version", [](GL::Version version) { + /** @todo bind Containers::Pair directly */ + return std::pair(GL::version(version)); + }, "Major and minor version number from enum value", py::arg("version")) .def("is_version_es", GL::isVersionES, "Whether given version is OpenGL ES or WebGL"); /* Context */ diff --git a/src/python/magnum/math.cpp b/src/python/magnum/math.cpp index fff1189..42fe7b1 100644 --- a/src/python/magnum/math.cpp +++ b/src/python/magnum/math.cpp @@ -26,6 +26,7 @@ #include #include #include +#include /** @todo drop once Containers::Pair is exposed directly */ #include #include #include @@ -160,7 +161,10 @@ template void angle(py::module_& m, py::class_& c) { .def("isnan", static_cast(Math::isNan), "If given number is a NaN") .def("min", static_cast(Math::min), "Minimum", py::arg("value"), py::arg("min")) .def("max", static_cast(Math::max), "Maximum", py::arg("value"), py::arg("min")) - .def("minmax", static_cast(*)(T, T)>(Math::minmax), "Minimum and maximum of two values") + .def("minmax", [](T a, T b) { + /** @todo bind Containers::Pair directly */ + return std::pair(Math::minmax(a, b)); + }, "Minimum and maximum of two values") .def("clamp", static_cast(Math::clamp), "Clamp value", py::arg("value"), py::arg("min"), py::arg("max")) .def("sign", Math::sign, "Sign") .def("abs", static_cast(Math::abs), "Absolute value") @@ -472,7 +476,10 @@ void math(py::module_& root, py::module_& m) { /* Functions */ m - .def("div", [](Long x, Long y) { return Math::div(x, y); }, "Integer division with remainder", py::arg("x"), py::arg("y")) + .def("div", [](Long x, Long y) { + /** @todo bind Containers::Pair directly */ + return std::pair(Math::div(x, y)); + }, "Integer division with remainder", py::arg("x"), py::arg("y")) /** @todo binomialCoefficient(), asserts are hard to replicate (have an internal variant returning an Optional?) */ .def("popcount", static_cast(Math::popcount), "Count of bits set in a number") @@ -481,7 +488,8 @@ void math(py::module_& root, py::module_& m) { .def("sin", [](Radd angle) { return Math::sin(angle); }, "Sine") .def("cos", [](Radd angle) { return Math::cos(angle); }, "Cosine") .def("sincos", [](Radd angle) { - return Math::sincos(angle); + /** @todo bind Containers::Pair directly */ + return std::pair(Math::sincos(angle)); }, "Sine and cosine") .def("tan", [](Radd angle) { return Math::tan(angle); }, "Tangent") .def("asin", [](Double angle) { return Math::asin(angle); }, "Arc sine") @@ -496,8 +504,14 @@ void math(py::module_& root, py::module_& m) { .def("min", static_cast(Math::min), "Minimum", py::arg("value"), py::arg("min")) .def("max", static_cast(Math::max), "Maximum", py::arg("value"), py::arg("min")) .def("max", static_cast(Math::max), "Maximum", py::arg("value"), py::arg("min")) - .def("minmax", static_cast(*)(Long, Long)>(Math::minmax), "Minimum and maximum of two values") - .def("minmax", static_cast(*)(Double, Double)>(Math::minmax), "Minimum and maximum of two values") + .def("minmax", [](Long a, Long b) { + /** @todo bind Containers::Pair directly */ + return std::pair(Math::minmax(a, b)); + }, "Minimum and maximum of two values") + .def("minmax", [](Double a, Double b) { + /** @todo bind Containers::Pair directly */ + return std::pair(Math::minmax(a, b)); + }, "Minimum and maximum of two values") .def("clamp", static_cast(Math::clamp), "Clamp value", py::arg("value"), py::arg("min"), py::arg("max")) .def("clamp", static_cast(Math::clamp), "Clamp value", py::arg("value"), py::arg("min"), py::arg("max")) .def("sign", Math::sign, "Sign") diff --git a/src/python/magnum/math.range.cpp b/src/python/magnum/math.range.cpp index bf8f008..4ed40b1 100644 --- a/src/python/magnum/math.range.cpp +++ b/src/python/magnum/math.range.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -53,7 +54,10 @@ template void range(py::module_& m, py::class_& c) { }, "Construct a zero range") .def(py::init(), "Default constructor") .def(py::init(), "Construct a range from minimal and maximal coordinates") - .def(py::init>(), "Construct a range from minimal and maximal coordinates") + .def(py::init([](const std::pair& minmax) { + /** @todo bind Containers::Pair directly */ + return T{minmax}; + }), "Construct a range from minimal and maximal coordinates") /* Comparison */ .def(py::self == py::self, "Equality comparison") diff --git a/src/python/magnum/math.vector.h b/src/python/magnum/math.vector.h index fc2ca86..bda25fd 100644 --- a/src/python/magnum/math.vector.h +++ b/src/python/magnum/math.vector.h @@ -26,6 +26,7 @@ */ #include +#include /** @todo drop once Containers::Pair is exposed directly */ #include #include #include @@ -212,7 +213,9 @@ template void vector(py::module_& m, py::class_& c) { return T{Math::max(value, max)}; }, "Maximum", py::arg("value"), py::arg("max")) .def("minmax", [](const T& a, const T& b) { - return std::pair{Math::minmax(a, b)}; + /** @todo clean up the cast once minmax() properly returns the + input type; bind Containers::Pair directly */ + return std::pair{Containers::Pair{Math::minmax(a, b)}}; }, "Minimum and maximum of two values") .def("clamp", [](const T& a, const T& min, const T& max) { return T{Math::clamp(a, min, max)}; diff --git a/src/python/magnum/test/test_math.py b/src/python/magnum/test/test_math.py index 0a71492..9d360ea 100644 --- a/src/python/magnum/test/test_math.py +++ b/src/python/magnum/test/test_math.py @@ -121,7 +121,22 @@ class Functions(unittest.TestCase): self.assertAlmostEqual(sincos[0], 1.0) self.assertAlmostEqual(sincos[1], 0.0) - def test_scalar(self): + def test_scalar_integer(self): + self.assertEqual(math.min(15, 3), 3) + self.assertEqual(math.max(15, 3), 15) + self.assertEqual(math.minmax(15, 3), (3, 15)) + self.assertEqual(math.clamp(7, -1, 5), 5) + + self.assertEqual(math.sign(-15), -1) + self.assertEqual(math.abs(-15), 15) + + self.assertEqual(math.lerp(2, 5, 0.5), 3) + self.assertEqual(math.lerp(2, 5, True), 5) + self.assertEqual(math.select(2, 5, 1.0), 5) + + self.assertEqual(math.fma(2.0, 3.0, 0.75), 6.75) + + def test_scalar_float(self): self.assertFalse(math.isinf(math.nan)) self.assertFalse(math.isnan(math.inf)) self.assertTrue(math.isinf(math.inf)) @@ -143,11 +158,8 @@ class Functions(unittest.TestCase): self.assertEqual(math.lerp(2.0, 5.0, 0.5), 3.5) self.assertEqual(math.lerp(2.0, 5.0, False), 2.0) - self.assertEqual(math.lerp(2, 5, 0.5), 3) - self.assertEqual(math.lerp(2, 5, True), 5) self.assertEqual(math.lerp_inverted(2.0, 5.0, 3.5), 0.5) self.assertEqual(math.select(2.0, 5.0, 0.6), 2.0) - self.assertEqual(math.select(2, 5, 1.0), 5) self.assertEqual(math.fma(2.0, 3.0, 0.75), 6.75)