From 257e0afe07327650d15ef7239f98bd8a38a0aa15 Mon Sep 17 00:00:00 2001
From: Wilson <wilson.jallet@polytechnique.org>
Date: Mon, 15 May 2023 23:05:14 +0200
Subject: [PATCH] WIP: Expose boost::none_t type (and std::nullopt_t when
 available) (#367)

* optional: expose to-value converter for boost::none_t (and std::nullopt_t if possible)

+ add src/optional.cpp to expose none types
+ this allows to have None as a default arg value for functions (also, shows up in stubs)
+ also allows to have none_t return/argument type

* Run pre-commit
---
 CMakeLists.txt                |  1 +
 include/eigenpy/optional.hpp  |  9 +++++++++
 src/eigenpy.cpp               |  4 ++++
 src/optional.cpp              | 12 ++++++++++++
 unittest/bind_optional.cpp.in |  2 +-
 5 files changed, 27 insertions(+), 1 deletion(-)
 create mode 100644 src/optional.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index fe143b1..5e1f1b4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -207,6 +207,7 @@ set(${PROJECT_NAME}_SOURCES
     src/quaternion.cpp
     src/geometry-conversion.cpp
     src/std-vector.cpp
+    src/optional.cpp
     src/version.cpp)
 
 add_library(${PROJECT_NAME} SHARED ${${PROJECT_NAME}_SOURCES}
diff --git a/include/eigenpy/optional.hpp b/include/eigenpy/optional.hpp
index 8394ba7..be6fbe4 100644
--- a/include/eigenpy/optional.hpp
+++ b/include/eigenpy/optional.hpp
@@ -56,6 +56,15 @@ struct nullopt_helper<std::optional> {
 };
 #endif
 
+template <typename NoneType>
+struct NoneToPython {
+  static PyObject *convert(const NoneType &) { Py_RETURN_NONE; }
+
+  static void registration() {
+    bp::to_python_converter<NoneType, NoneToPython, false>();
+  }
+};
+
 template <typename T,
           template <typename> class OptionalTpl = EIGENPY_DEFAULT_OPTIONAL>
 struct OptionalToPython {
diff --git a/src/eigenpy.cpp b/src/eigenpy.cpp
index 62b9f88..6e13f13 100644
--- a/src/eigenpy.cpp
+++ b/src/eigenpy.cpp
@@ -22,6 +22,8 @@ void exposeMatrixComplexFloat();
 void exposeMatrixComplexDouble();
 void exposeMatrixComplexLongDouble();
 
+void exposeNoneType();
+
 /* Enable Eigen-Numpy serialization for a set of standard MatrixBase instances.
  */
 void enableEigenPy() {
@@ -54,6 +56,8 @@ void enableEigenPy() {
   exposeMatrixComplexFloat();
   exposeMatrixComplexDouble();
   exposeMatrixComplexLongDouble();
+
+  exposeNoneType();
 }
 
 }  // namespace eigenpy
diff --git a/src/optional.cpp b/src/optional.cpp
new file mode 100644
index 0000000..eb56912
--- /dev/null
+++ b/src/optional.cpp
@@ -0,0 +1,12 @@
+/// Copyright 2023 CNRS, INRIA
+
+#include "eigenpy/optional.hpp"
+
+namespace eigenpy {
+void exposeNoneType() {
+  detail::NoneToPython<boost::none_t>::registration();
+#ifdef EIGENPY_WITH_CXX17_SUPPORT
+  detail::NoneToPython<std::nullopt_t>::registration();
+#endif
+}
+}  // namespace eigenpy
diff --git a/unittest/bind_optional.cpp.in b/unittest/bind_optional.cpp.in
index f71773d..844449b 100644
--- a/unittest/bind_optional.cpp.in
+++ b/unittest/bind_optional.cpp.in
@@ -74,6 +74,6 @@ BOOST_PYTHON_MODULE(@MODNAME@) {
           bp::make_setter(&mystruct::msg));
 
   bp::def("none_if_zero", none_if_zero, bp::args("i"));
-  bp::def("create_if_true", create_if_true, bp::args("flag", "b"));
+  bp::def("create_if_true", create_if_true, (bp::arg("flag"), bp::arg("b") = OPT_NONE));
   bp::def("random_mat_if_true", random_mat_if_true, bp::args("flag"));
 }
-- 
GitLab