changeset 340:06b8aeea456f

Add functions to conversion API to extract bool, double, and complex values * oct-py-types.cc, oct-py-types.h (pytave::extract_py_bool, pytave::extract_py_complex, pytave::extract_py_float): New functions to extract numeric values from Python numeric types. * python_to_octave.cc (pytave::pyobj_to_octvalue): Use them.
author Mike Miller <mtmiller@octave.org>
date Mon, 15 Aug 2016 21:52:50 -0700
parents 832ee1f14862
children b0d012e9975f
files oct-py-types.cc oct-py-types.h python_to_octave.cc
diffstat 3 files changed, 61 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/oct-py-types.cc	Mon Aug 15 21:53:25 2016 -0700
+++ b/oct-py-types.cc	Mon Aug 15 21:52:50 2016 -0700
@@ -59,6 +59,43 @@
   return PyFloat_FromDouble (value);
 }
 
+bool
+extract_py_bool (PyObject *obj)
+{
+  if (! obj)
+    throw object_convert_exception ("failed to extract boolean: null object");
+
+  if (! PyBool_Check (obj))
+    throw object_convert_exception ("failed to extract boolean: wrong type");
+
+  return (obj == Py_True);
+}
+
+std::complex<double>
+extract_py_complex (PyObject *obj)
+{
+  if (! obj)
+    throw object_convert_exception ("failed to extract complex: null object");
+
+  if (! PyComplex_Check (obj))
+    throw object_convert_exception ("failed to extract complex: wrong type");
+
+  Py_complex value = PyComplex_AsCComplex (obj);
+  return reinterpret_cast<std::complex<double>&> (value);
+}
+
+double
+extract_py_float (PyObject *obj)
+{
+  if (! obj)
+    throw object_convert_exception ("failed to extract float: null object");
+
+  if (! PyFloat_Check (obj))
+    throw object_convert_exception ("failed to extract float: wrong type");
+
+  return PyFloat_AsDouble (obj);
+}
+
 inline PyObject *
 make_py_int (int32_t value)
 {
--- a/oct-py-types.h	Mon Aug 15 21:53:25 2016 -0700
+++ b/oct-py-types.h	Mon Aug 15 21:52:50 2016 -0700
@@ -34,6 +34,13 @@
 namespace pytave
 {
 
+//! Extract the integer value of the given Python bool object.
+//!
+//! @param obj Python bool object
+//! @return @c true or @c false value of @a obj
+bool
+extract_py_bool (PyObject *obj);
+
 //! Create a Python bool object with the value of the given @c bool value.
 //!
 //! @param value @c true or @c false value
@@ -41,6 +48,13 @@
 PyObject *
 make_py_bool (bool value);
 
+//! Extract the complex value of the given Python complex object.
+//!
+//! @param obj Python complex object
+//! @return complex value of @a obj
+std::complex<double>
+extract_py_complex (PyObject *obj);
+
 //! Create a Python complex object with the value of the given @c complex value.
 //!
 //! @param value complex value
@@ -48,6 +62,13 @@
 PyObject *
 make_py_complex (std::complex<double> value);
 
+//! Extract the floating point value of the given Python float object.
+//!
+//! @param obj Python float object
+//! @return floating point value of @a obj
+double
+extract_py_float (PyObject *obj);
+
 //! Create a Python float object with the value of the given @c double value.
 //!
 //! @param value floating point value
--- a/python_to_octave.cc	Mon Aug 15 21:53:25 2016 -0700
+++ b/python_to_octave.cc	Mon Aug 15 21:52:50 2016 -0700
@@ -338,21 +338,18 @@
   void pyobj_to_octvalue (octave_value& oct_value,
                           const boost::python::object& py_object)
   {
-    extract<bool> boolx (py_object);
-    extract<double> doublex (py_object);
-    extract<Complex> complexx (py_object);
     extract<numeric::array> arrayx (py_object);
 
     if (PyBool_Check (py_object.ptr ()))
-      oct_value = boolx ();
+      oct_value = extract_py_bool (py_object.ptr ());
 #if PY_VERSION_HEX < 0x03000000
     else if (PyInt_Check (py_object.ptr ()))
       oct_value = octave_int64 (extract_py_int64 (py_object.ptr ()));
 #endif
     else if (PyFloat_Check (py_object.ptr ()))
-      oct_value = doublex ();
+      oct_value = extract_py_float (py_object.ptr ());
     else if (PyComplex_Check (py_object.ptr ()))
-      oct_value = complexx ();
+      oct_value = extract_py_complex (py_object.ptr ());
     else if (arrayx.check ())
       pyarr_to_octvalue (oct_value, (PyArrayObject*)py_object.ptr ());
     else if (PyBytes_Check (py_object.ptr ()) || PyUnicode_Check (py_object.ptr ()))