diff --git a/docs/advanced.rst b/docs/advanced.rst index ec09534d..d35192be 100644 --- a/docs/advanced.rst +++ b/docs/advanced.rst @@ -902,16 +902,30 @@ type of Python object satisfying the buffer protocol). In many situations, we want to define a function which only accepts a NumPy array of a certain data type. This is possible via the ``py::array_t`` template. For instance, the following function requires the argument to be a -dense array of doubles in C-style ordering. +NumPy array containing double precision values. .. code-block:: cpp void f(py::array_t array); -When it is invoked with a different type (e.g. an integer), the binding code -will attempt to cast the input into a NumPy array of the requested type. Note -that this feature requires the :file:``pybind11/numpy.h`` header to be -included. +When it is invoked with a different type (e.g. an integer or a list of +integers), the binding code will attempt to cast the input into a NumPy array +of the requested type. Note that this feature requires the +:file:``pybind11/numpy.h`` header to be included. + +Data in NumPy arrays is not guaranteed to packed in a dense manner; +furthermore, entries can be separated by arbitrary column and row strides. +Sometimes, it can be useful to require a function to only accept dense arrays +using either the C (row-major) or Fortran (column-major) ordering. This can be +accomplished via a second template argument with values ``py::array::c_style`` +or ``py::array::f_style``. + +.. code-block:: cpp + + void f(py::array_t array); + +As before, the implementation will attempt to convert non-conforming arguments +into an array satisfying the specified requirements. Vectorizing functions ===================== diff --git a/include/pybind11/numpy.h b/include/pybind11/numpy.h index cf46c337..42d027a6 100644 --- a/include/pybind11/numpy.h +++ b/include/pybind11/numpy.h @@ -77,6 +77,11 @@ public: PYBIND11_OBJECT_DEFAULT(array, buffer, lookup_api().PyArray_Check_) + enum { + c_style = API::NPY_C_CONTIGUOUS_, + f_style = API::NPY_F_CONTIGUOUS_ + }; + template array(size_t size, const Type *ptr) { API& api = lookup_api(); PyObject *descr = api.PyArray_DescrFromType_(npy_format_descriptor::value); @@ -120,7 +125,7 @@ protected: } }; -template class array_t : public array { +template class array_t : public array { public: PYBIND11_OBJECT_CVT(array_t, array, is_non_null, m_ptr = ensure(m_ptr)); array_t() : array() { } @@ -131,8 +136,9 @@ public: API &api = lookup_api(); PyObject *descr = api.PyArray_DescrFromType_(npy_format_descriptor::value); PyObject *result = api.PyArray_FromAny_( - ptr, descr, 0, 0, API::NPY_C_CONTIGUOUS_ | API::NPY_ENSURE_ARRAY_ - | API::NPY_ARRAY_FORCECAST_, nullptr); + ptr, descr, 0, 0, + API::NPY_ENSURE_ARRAY_ | API::NPY_ARRAY_FORCECAST_ | ExtraFlags, + nullptr); Py_DECREF(ptr); return result; }