only do numpy contiguous C/Fortran array conversion when explicitly requested
diff --git a/docs/advanced.rst b/docs/advanced.rst
index ec09534..d35192b 100644
--- a/docs/advanced.rst
+++ b/docs/advanced.rst
@@ -902,16 +902,30 @@
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<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<double> 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<double, py::array::c_style> 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 cf46c33..42d027a 100644
--- a/include/pybind11/numpy.h
+++ b/include/pybind11/numpy.h
@@ -77,6 +77,11 @@
PYBIND11_OBJECT_DEFAULT(array, buffer, lookup_api().PyArray_Check_)
+ enum {
+ c_style = API::NPY_C_CONTIGUOUS_,
+ f_style = API::NPY_F_CONTIGUOUS_
+ };
+
template <typename Type> array(size_t size, const Type *ptr) {
API& api = lookup_api();
PyObject *descr = api.PyArray_DescrFromType_(npy_format_descriptor<Type>::value);
@@ -120,7 +125,7 @@
}
};
-template <typename T> class array_t : public array {
+template <typename T, int ExtraFlags = 0> 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 @@
API &api = lookup_api();
PyObject *descr = api.PyArray_DescrFromType_(npy_format_descriptor<T>::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;
}