Commit Graph

134 Commits

Author SHA1 Message Date
Jason Rhinelander
423a49b8be array: add unchecked access via proxy object
This adds bounds-unchecked access to arrays through a `a.unchecked<Type,
Dimensions>()` method.  (For `array_t<T>`, the `Type` template parameter
is omitted).  The mutable version (which requires the array have the
`writeable` flag) is available as `a.mutable_unchecked<...>()`.

Specifying the Dimensions as a template parameter allows storage of an
std::array; having the strides and sizes stored that way (as opposed to
storing a copy of the array's strides/shape pointers) allows the
compiler to make significant optimizations of the shape() method that it
can't make with a pointer; testing with nested loops of the form:

    for (size_t i0 = 0; i0 < r.shape(0); i0++)
        for (size_t i1 = 0; i1 < r.shape(1); i1++)
            ...
                r(i0, i1, ...) += 1;

over a 10 million element array gives around a 25% speedup (versus using
a pointer) for the 1D case, 33% for 2D, and runs more than twice as fast
with a 5D array.
2017-03-22 16:13:59 -03:00
Jason Rhinelander
b0292c1df3 vectorize: trivial handling for F-order arrays
This extends the trivial handling to support trivial handling for
Fortran-order arrays (i.e. column major): if inputs aren't all
C-contiguous, but *are* all F-contiguous, the resulting array will be
F-contiguous and we can do trivial processing.

For anything else (e.g. C-contiguous, or inputs requiring non-trivial
processing), the result is in (numpy-default) C-contiguous layout.
2017-03-21 18:53:56 -03:00
Jason Rhinelander
ae5a8f7eb3 Stop forcing c-contiguous in py::vectorize
The only part of the vectorize code that actually needs c-contiguous is
the "trivial" broadcast; for non-trivial arguments, the code already
uses strides properly (and so handles C-style, F-style, neither, slices,
etc.)

This commit rewrites `broadcast` to additionally check for C-contiguous
storage, then takes off the `c_style` flag for the arguments, which
will keep the functionality more or less the same, except for no longer
requiring an array copy for non-c-contiguous input arrays.

Additionally, if we're given a singleton slice (e.g. a[0::4, 0::4] for a
4x4 or smaller array), we no longer fail triviality because the trivial
code path never actually uses the strides on a singleton.
2017-03-21 18:53:56 -03:00
Patrick Stewart
0b6d08a008 Add function for comparing buffer_info formats to types
Allows equivalent integral types and numpy dtypes
2017-03-14 02:50:04 +01:00
Dean Moldovan
16afbcef46 Improve py::array_t scalar type information (#724)
* Add value_type member alias to py::array_t (resolve #632)

* Use numpy scalar name in py::array_t function signatures (e.g. float32/64 instead of just float)
2017-03-13 19:17:18 +01:00
Jason Rhinelander
c44fe6fda5 array_t overload resolution support
This makes array_t respect overload resolution and noconvert by failing
to load when `convert = false` if the src isn't already an array of the
correct type.
2017-03-06 14:56:22 -05:00
Dean Moldovan
5143989623 Fix compilation of Eigen casters with complex scalars 2017-02-28 19:25:09 +01:00
Jason Rhinelander
fd7517037b Change array's writeable exception to a ValueError
Numpy raises ValueError when attempting to modify an array, while
py::array is raising a RuntimeError.  This changes the exception to a
std::domain_error, which gets mapped to the expected ValueError in
python.
2017-02-24 23:19:50 +01:00
Jason Rhinelander
f86dddf7ba array: fix base handling
numpy arrays aren't currently properly setting base: by setting `->base`
directly, the base doesn't follow what numpy expects and documents (that
is, following chained array bases to the root array).

This fixes the behaviour by using numpy's PyArray_SetBaseObject to set
the base instead, and then updates the tests to reflect the fixed
behaviour.
2017-02-24 23:19:50 +01:00
Jason Rhinelander
88fff9d189 Change numpy constants to non-deprecated versions
A few of pybind's numpy constants are using the numpy-deprecated names
(without "ARRAY_" in them); updated our names to be consistent with
current numpy code.
2017-02-24 23:19:50 +01:00
Jason Rhinelander
1d7998e333 Revert noexcept deduction in favour of better SFINAE on lambda functions (#677)
noexcept deduction, added in PR #555, doesn't work with clang's
-std=c++1z; and while it works with g++, it isn't entirely clear to me
that it is required to work in C++17.

What should work, however, is that C++17 allows implicit conversion of a
`noexcept(true)` function pointer to a `noexcept(false)` (i.e.  default,
noexcept-not-specified) function pointer.  That was breaking in pybind11
because the cpp_function template used for lambdas provided a better
match (i.e. without requiring an implicit conversion), but it then
failed.

This commit takes a different approach of using SFINAE on the lambda
function to prevent it from matching a non-lambda object, which then
gets implicit conversion from a `noexcept` function pointer to a
`noexcept(false)` function pointer.  This much nicer solution also gets
rid of the C++17 NOEXCEPT macros, and works in both clang and g++.
2017-02-17 12:56:41 +01:00
Dean Moldovan
329d983392 Revert "Template array constructor (#582)"
This reverts commit bee8827a98.
2017-02-14 11:39:03 +01:00
Sylvain Corlay
bee8827a98 Template array constructor (#582) 2017-02-14 10:55:01 +01:00
Matthew Woehlke
e15fa9f99a Avoid C-style const casts (#659)
* Avoid C-style const casts

Replace C-style casts that discard `const` with `const_cast` (and, where
necessary, `reinterpret_cast` as well).

* Warn about C-style const-discarding casts

Change pybind11_enable_warnings to also enable `-Wcast-qual` (warn if a
C-style cast discards `const`) by default. The previous commit should
have gotten rid of all of these (at least, all the ones that tripped in
my build, which included the tests), and this should discourage more
from newly appearing.
2017-02-08 23:43:08 +01:00
Wenzel Jakob
0defac5977 renamed _check -> check_
(Identifiers starting with underscores are reserved by the standard)
Also fixed a typo in a comment.
2017-02-07 00:06:07 +01:00
Jason Rhinelander
f7f5bc8e37 Numpy: better compilation errors, long double support (#619)
* Clarify PYBIND11_NUMPY_DTYPE documentation

The current documentation and example reads as though
PYBIND11_NUMPY_DTYPE is a declarative macro along the same lines as
PYBIND11_DECLARE_HOLDER_TYPE, but it isn't.  The changes the
documentation and docs example to make it clear that you need to "call"
the macro.

* Add satisfies_{all,any,none}_of<T, Preds>

`satisfies_all_of<T, Pred1, Pred2, Pred3>` is a nice legibility-enhanced
shortcut for `is_all<Pred1<T>, Pred2<T>, Pred3<T>>`.

* Give better error message for non-POD dtype attempts

If you try to use a non-POD data type, you get difficult-to-interpret
compilation errors (about ::name() not being a member of an internal
pybind11 struct, among others), for which isn't at all obvious what the
problem is.

This adds a static_assert for such cases.

It also changes the base case from an empty struct to the is_pod_struct
case by no longer using `enable_if<is_pod_struct>` but instead using a
static_assert: thus specializations avoid the base class, POD types
work, and non-POD types (and unimplemented POD types like std::array)
get a more informative static_assert failure.

* Prefix macros with PYBIND11_

numpy.h uses unprefixed macros, which seems undesirable.  This prefixes
them with PYBIND11_ to match all the other macros in numpy.h (and
elsewhere).

* Add long double support

This adds long double and std::complex<long double> support for numpy
arrays.

This allows some simplification of the code used to generate format
descriptors; the new code uses fewer macros, instead putting the code as
different templated options; the template conditions end up simpler with
this because we are now supporting all basic C++ arithmetic types (and
so can use is_arithmetic instead of is_integral + multiple
different specializations).

In addition to testing that it is indeed working in the test script, it
also adds various offset and size calculations there, which
fixes the test failures under x86 compilations.
2017-01-31 17:00:15 +01:00
Dean Moldovan
5f07facef5 Fix pointer to reference error in type_caster on MSVC (#583) 2017-01-03 11:52:05 +01:00
Jason Rhinelander
6e036e78a7 Support binding noexcept function/methods in C++17
When compiling in C++17 mode the noexcept specifier is part of the
function type.  This causes a failure in pybind11 because, by omitting
a noexcept specifier when deducing function return and argument types,
we are implicitly making `noexcept(false)` part of the type.

This means that functions with `noexcept` fail to match the function
templates in cpp_function (and other places), and we get compilation
failure (we end up trying to fit it into the lambda function version,
which fails since a function pointer has no `operator()`).

We can, however, deduce the true/false `B` in noexcept(B), so we don't
need to add a whole other set of overloads, but need to deduce the extra
argument when under C++17.  That will *not* work under pre-C++17,
however.

This commit adds two macros to fix the problem: under C++17 (with the
appropriate feature macro set) they provide an extra `bool NoExceptions`
template argument and provide the `noexcept(NoExceptions)` deduced
specifier.  Under pre-C++17 they expand to nothing.

This is needed to compile pybind11 with gcc7 under -std=c++17.
2016-12-14 20:40:49 +01:00
Dean Moldovan
8c85a85747 Use C++14 index_sequence when possible
Newer standard libraries use compiler intrinsics for std::index_sequence
which makes it ‘free’. This prevents hitting instantiation limits for
recursive templates (-ftemplate-depth).
2016-12-03 23:13:53 +01:00
Patrick Stewart
5271576828 Use correct itemsize when constructing a numpy dtype from a buffer_info 2016-11-22 22:01:03 +01:00
patstew
47681c183d Only mark unaligned types in buffers (#505)
Previously all types are marked unaligned in buffer format strings,
now we test for alignment before adding the '=' marker.
2016-11-22 12:17:07 +01:00
Sylvain Corlay
b14f065fa9 numpy.h replace macros with functions (#514) 2016-11-22 11:29:55 +01:00
Dean Moldovan
4de271027d Improve consistency of array and array_t with regard to other pytypes
* `array_t(const object &)` now throws on error
* `array_t::ensure()` is intended for casters —- old constructor is
  deprecated
* `array` and `array_t` get default constructors (empty array)
* `array` gets a converting constructor
* `py::isinstance<array_T<T>>()` checks the type (but not flags)

There is only one special thing which must remain: `array_t` gets
its own `type_caster` specialization which uses `ensure` instead
of a simple check.
2016-11-17 08:55:42 +01:00
Dean Moldovan
c7ac16bb2e Add py::reinterpret_borrow<T>()/steal<T>() for low-level unchecked casts
The pytype converting constructors are convenient and safe for user
code, but for library internals the additional type checks and possible
conversions are sometimes not desired. `reinterpret_borrow<T>()` and
`reinterpret_steal<T>()` serve as the low-level unsafe counterparts
of `cast<T>()`.

This deprecates the `object(handle, bool)` constructor.

Renamed `borrowed` parameter to `is_borrowed` to avoid shadowing
warnings on MSVC.
2016-11-17 08:55:42 +01:00
Dean Moldovan
e18bc02fc9 Add default and converting constructors for all concrete Python types
* Deprecate the `py::object::str()` member function since `py::str(obj)`
  is now equivalent and preferred

* Make `py::repr()` a free function

* Make sure obj.cast<T>() works as expected when T is a Python type

`obj.cast<T>()` should be the same as `T(obj)`, i.e. it should convert
the given object to a different Python type. However, `obj.cast<T>()`
usually calls `type_caster::load()` which only checks the type without
doing any actual conversion. That causes a very unexpected `cast_error`.
This commit makes it so that `obj.cast<T>()` and `T(obj)` are the same
when T is a Python type.

* Simplify pytypes converting constructor implementation

It's not necessary to maintain a full set of converting constructors
and assignment operators + const& and &&. A single converting const&
constructor will work and there is no impact on binary size. On the
other hand, the conversion functions can be significantly simplified.
2016-11-17 08:55:42 +01:00
Dean Moldovan
b4498ef44d Add py::isinstance<T>(obj) for generalized Python type checking
Allows checking the Python types before creating an object instead of
after. For example:
```c++
auto l = list(ptr, true);
if (l.check())
   // ...
```
The above is replaced with:
```c++
if (isinstance<list>(ptr)) {
    auto l = reinterpret_borrow(ptr);
    // ...
}
```

This deprecates `py::object::check()`. `py::isinstance()` covers the
same use case, but it can also check for user-defined types:
```c++
class Pet { ... };
py::class_<Pet>(...);

m.def("is_pet", [](py::object obj) {
    return py::isinstance<Pet>(obj); // works as expected
});
```
2016-11-17 08:55:42 +01:00
Sylvain Corlay
5027c4f95b Switch NumPy variadic indexing to per-value arguments (#500)
* Also added unsafe version without checks
2016-11-16 17:53:37 +01:00
Wenzel Jakob
cc4efe69c2 more code style checks in Travis CI :) 2016-11-08 10:53:30 +01:00
Ivan Smirnov
cc8ff16547 Move register_dtype() outside of the template
(avoid code bloat if possible)
2016-11-03 09:35:05 +00:00
Ivan Smirnov
2dbf029705 Add public shared_data API
NumPy internals are stored under "_numpy_internals" key.
2016-11-03 09:35:05 +00:00
Ivan Smirnov
2184f6d4d6 NumPy dtypes are now shared across extensions 2016-11-03 09:35:05 +00:00
Ivan Smirnov
e8b50360fe Add dtype binding macro that allows setting names
PYBIND11_NUMPY_DTYPE_EX(Type, F1, "N1", F2, "N2", ...)
2016-11-01 13:27:35 +00:00
Wenzel Jakob
dd9bd7778f Merge pull request #453 from aldanor/feature/numpy-scalars
NumPy scalars to ctypes conversion support
2016-10-25 01:15:25 +02:00
Ivan Smirnov
a6e6a8b108 Require existing typeinfo for direct conversions
This avoid a hashmap lookup since the pointer to the list of
direct converters is now cached in the typeinfo.
2016-10-23 15:29:10 +01:00
Ivan Smirnov
43a88f4574 Reraise existing exception if dtype ctor fails 2016-10-22 18:57:07 +02:00
Ivan Smirnov
694269435b Allow implicit casts from literal strings to dtype 2016-10-22 18:57:07 +02:00
Ivan Smirnov
ef5a38044c A few dtype method docstrings 2016-10-22 18:57:07 +02:00
Ivan Smirnov
f70cc112f0 Make dtype from string ctor accept const ref 2016-10-22 18:57:07 +02:00
Ivan Smirnov
7edd72db24 Disallow registering dtypes multiple times 2016-10-20 16:57:12 +01:00
Ivan Smirnov
7bf90e8008 Add a direct converter for numpy scalars 2016-10-20 16:11:08 +01:00
Ivan Smirnov
ba08db4da5 Import a few more numpy extern symbols 2016-10-20 16:09:10 +01:00
Ivan Smirnov
fb74df50c9 Implement format/numpy descriptors for enums 2016-10-20 12:38:43 +01:00
Jason Rhinelander
12d76600f8 Disable most implicit conversion constructors
We have various classes that have non-explicit constructors that accept
a single argument, which is implicitly making them implicitly
convertible from the argument.  In a few cases, this is desirable (e.g.
implicit conversion of std::string to py::str, or conversion of double
to py::float_); in many others, however, it is unintended (e.g. implicit
conversion of size_t to some pre-declared py::array_t<T> type).

This disables most of the unwanted implicit conversions by marking them
`explicit`, and comments the ones that are deliberately left implicit.
2016-10-16 16:27:42 -04:00
Wenzel Jakob
c01a1c1ade added array::ensure() function wrapping PyArray_FromAny
This convenience function ensures that a py::object is either a
py::array, or the implementation will try to convert it into one. Layout
requirements (such as c_style or f_style) can be also be provided.
2016-10-14 01:08:07 +02:00
Wenzel Jakob
fac7c09458 NumPy "base" feature: integrated feedback by @aldanor 2016-10-13 10:49:53 +02:00
Wenzel Jakob
369e9b3937 Permit creation of NumPy arrays with a "base" object that owns the data
This patch adds an extra base handle parameter to most ``py::array`` and
``py::array_t<>`` constructors. If specified along with a pointer to
data, the base object will be registered within NumPy, which increases
the base's reference count. This feature is useful to create shallow
copies of C++ or Python arrays while ensuring that the owners of the
underlying can't be garbage collected while referenced by NumPy.

The commit also adds a simple test function involving a ``wrap()``
function that creates shallow copies of various N-D arrays.
2016-10-13 01:03:40 +02:00
Wenzel Jakob
ba7678016c numpy.h: added array::squeeze() method 2016-10-07 11:19:57 +02:00
Dean Moldovan
242b146a51 Extend attribute and item accessor interface using object_api 2016-09-23 02:00:01 +02:00
Dean Moldovan
865e43034b Make attr and item accessors throw on error instead of returning nullptr
This also adds the `hasattr` and `getattr` functions which are needed
with the new attribute behavior. The new functions behave exactly like
their Python counterparts.

Similarly `object` gets a `contains` method which calls `__contains__`,
i.e. it's the same as the `in` keyword in Python.
2016-09-23 01:40:22 +02:00
Dzhelil Rufat
c250ee5146 Use more consistent indentation and typenames names. 2016-09-22 14:51:41 -07:00