This fixes#856. Instead of the weakref trick, the internals structure
holds an unordered_map from PyObject* to a vector of references. To
avoid the cost of the unordered_map lookup for objects that don't have
any keep_alive patients, a flag is added to each instance to indicate
whether there is anything to do.
Using `std::type_info::operator==` fails under libc++ because the .so
is loaded with RTLD_LOCAL. libc++ considers types under such .sos
distinct, and so comparing typeid() values directly isn't going to work.
This adds a custom hasher and equality class for the type lookup maps
when not under stdlibc++, and adds a `detail::same_type` function to
perform the equality test. It also converts a few pointer arguments to
const lvalue references, particularly since doing the pointer
comparison wasn't technically valid to being with (though in practice,
appeared to work everywhere).
This fixes#912.
Fixes a race condition when multiple threads try to acquire the GIL
before `detail::internals` have been initialized. `gil_scoped_release`
is now tasked with initializing `internals` (guaranteed single-threaded)
to ensure the safety of subsequent `acquire` calls from multiple threads.
Fixes the issue as described in the comments of commit e27ea47. This
just adds `enable_if_t<std::is_move_constructible<T>::value>` to
`make_move_constructor`. The change fixes MSVC and is harmless with
other compilers.
CLion slows to a crawl when evaluating the intricate `PYBIND11_NUMPY_DTYPE`
macro. This commit replaces the macro cascade with a simple `(void)0`
to ease IDE evaluation.
This commit allows multiple inheritance of pybind11 classes from
Python, e.g.
class MyType(Base1, Base2):
def __init__(self):
Base1.__init__(self)
Base2.__init__(self)
where Base1 and Base2 are pybind11-exported classes.
This requires collapsing the various builtin base objects
(pybind11_object_56, ...) introduced in 2.1 into a single
pybind11_object of a fixed size; this fixed size object allocates enough
space to contain either a simple object (one base class & small* holder
instance), or a pointer to a new allocation that can contain an
arbitrary number of base classes and holders, with holder size
unrestricted.
* "small" here means having a sizeof() of at most 2 pointers, which is
enough to fit unique_ptr (sizeof is 1 ptr) and shared_ptr (sizeof is 2
ptrs).
To minimize the performance impact, this repurposes
`internals::registered_types_py` to store a vector of pybind-registered
base types. For direct-use pybind types (e.g. the `PyA` for a C++ `A`)
this is simply storing the same thing as before, but now in a vector;
for Python-side inherited types, the map lets us avoid having to do a
base class traversal as long as we've seen the class before. The
change to vector is needed for multiple inheritance: Python types
inheriting from multiple registered bases have one entry per base.
Fixes#896.
From Python docs: "Once an iterator’s `__next__()` method raises
`StopIteration`, it must continue to do so on subsequent calls.
Implementations that do not obey this property are deemed broken."
Passing utf8 encoded strings from python to a C++ function taking a
std::string was broken. The previous version was trying to call
'PyUnicode_FromObject' on this data, which failed to convert the string
to unicode with the default ascii codec. Also this incurs an unnecessary
conversion to unicode for data this is immediately converted back to
utf8.
Fix by treating python 2 strings the same python 3 bytes objects, and just
copying over the data if possible.
libc++ 3.8 (and possibly others--including the derived version on OS X),
doesn't define the macro, but does support std::experimental::optional.
This removes the extra macro check and just assumes the header existing
is enough, which is what we do for <optional> and <variant>.
Py_Finalize could potentially invoke code that calls `get_internals()`,
which could create a new internals object if one didn't exist.
`finalize_interpreter()` didn't catch this because it only used the
pre-finalize interpreter pointer status; if this happens, it results in
the internals pointer not being properly destroyed with the interpreter,
which leaks, and also causes a `get_internals()` under a future
interpreter to return an internals object that is wrong in various ways.
`accessor` currently relies on an implicit default copy constructor, but that is deprecated in C++11 when a copy assignment operator is present and can, in some cases, raise deprecation warnings (see #888). This commit explicitly specifies the default copy constructor and also adds a default move constructor.
This reimplements the std::reference_wrapper<T> caster to be a shell
around the underlying T caster (rather than assuming T is a generic
type), which lets it work for things like `std::reference_wrapper<int>`
or anything else custom type caster with a lvalue cast operator.
This also makes it properly fail when None is provided, just as an
ordinary lvalue reference argument would similarly fail.
This also adds a static assert to test that T has an appropriate type
caster. It triggers for casters like `std::pair`, which have
return-by-value cast operators. (In theory this could be supported by
storing a local temporary for such types, but that's beyond the scope
of this PR).
This also replaces `automatic` or `take_ownership` return value policies
with `automatic_reference` as taking ownership of a reference inside a
reference_wrapper is not valid.
This commit also adds `doc()` to `object_api` as a shortcut for the
`attr("__doc__")` accessor.
The module macro changes from:
```c++
PYBIND11_PLUGIN(example) {
pybind11::module m("example", "pybind11 example plugin");
m.def("add", [](int a, int b) { return a + b; });
return m.ptr();
}
```
to:
```c++
PYBIND11_MODULE(example, m) {
m.doc() = "pybind11 example plugin";
m.def("add", [](int a, int b) { return a + b; });
}
```
Using the old macro results in a deprecation warning. The warning
actually points to the `pybind11_init` function (since attributes
don't bind to macros), but the message should be quite clear:
"PYBIND11_PLUGIN is deprecated, use PYBIND11_MODULE".
* Added template constructors to buffer_info that can deduce the item size, format string, and number of dimensions from the pointer type and the shape container
* Implemented actual buffer_info constructor as private delegate constructor taking rvalue reference as a workaround for the evaluation order move problem on GCC 4.8
Now that #851 has removed all multiple uses of a caster, it can just use
the default-constructed value with needing a reset. This fixes two
issues:
1. With std::experimental::optional (at least under GCC 5.4), the `= {}`
would construct an instance of the optional type and then move-assign
it, which fails if the value type isn't move-assignable.
2. With older versions of Boost, the `= {}` could fail because it is
ambiguous, allowing construction of either `boost::none` or the value
type.
The "extend" method for vectors defined in stl_bind.h used `reserve` to
allocate space for the extra growth. While this can sometimes make a
constant-factor improvement in performance, it can also cause
construction of a vector by repeated extension to take quadratic rather
than linear time, as memory is reallocated in small increments rather
than on an exponential schedule. For example, this Python code would
take time proportional to the square of the trip count:
```python
a = VectorInt([1, 2, 3])
b = VectorInt()
for i in range(100000):
b.extend(a)
```
This commit removes the `reserve` call. The alternative would be to try
to add some smarter heuristics, but the standard library may well have
its own heuristics (the iterators are random access iterators, so it can
easily determine the number of items being added) and trying to add more
heuristics on top of that seems like a bad idea.
This extends py::vectorize to automatically pass through
non-vectorizable arguments. This removes the need for the documented
"explicitly exclude an argument" workaround.
Vectorization now applies to arithmetic, std::complex, and POD types,
passed as plain value or by const lvalue reference (previously only
pass-by-value types were supported). Non-const lvalue references and
any other types are passed through as-is.
Functions with rvalue reference arguments (whether vectorizable or not)
are explicitly prohibited: an rvalue reference is inherently not
something that can be passed multiple times and is thus unsuitable to
being in a vectorized function.
The vectorize returned value is also now more sensitive to inputs:
previously it would return by value when all inputs are of size 1; this
is now amended to having all inputs of size 1 *and* 0 dimensions. Thus
if you pass in, for example, [[1]], you get back a 1x1, 2D array, while
previously you got back just the resulting single value.
Vectorization of member function specializations is now also supported
via `py::vectorize(&Class::method)`; this required passthrough support
for the initial object pointer on the wrapping function pointer.
Currently if you construct an `array_t<T, array::f_style>` with a shape
but not strides you get a C-style array; the only way to get F-style
strides was to calculate the strides manually. This commit fixes that
by adding logic to use f_style strides when the flag is set.
This also simplifies the existing c_style stride logic.
This allows calling of functions (typically void) over a parameter
pack, replacing usage such as:
bool unused[] = { (voidfunc(param_pack_arg), false)..., false };
(void) unused;
with a much cleaner:
PYBIND11_EXPAND_SIDE_EFFECTS(voidfunc(param_pack_arg));
This attribute lets you disable (or explicitly enable) passing None to
an argument that otherwise would allow it by accepting
a value by raw pointer or shared_ptr.
This commit allows type_casters to allow their local values to be moved
away, rather than copied, when the type caster instance itself is an rvalue.
This only applies (automatically) to type casters using
PYBIND11_TYPE_CASTER; the generic type type casters don't own their own
pointer, and various value casters (e.g. std::string, std::pair,
arithmetic types) already cast to an rvalue (i.e. they return by value).
This updates various calling code to attempt to get a movable value
whenever the value is itself coming from a type caster about to be
destroyed: for example, when constructing an std::pair or various stl.h
containers. For types that don't support value moving, the cast_op
falls back to an lvalue cast.
There wasn't an obvious place to add the tests, so I added them to
test_copy_move_policies, but also renamed it to drop the _policies as it
now tests more than just policies.
This changes javadoc-style documenting comments from:
/** Text starts here
* and continues here
*/
to:
/**
* Test starts here
* and continues here
*/
which looks a little better, and also matches the javadoc-recommended
way of writing documenting comments.
Using a dynamic_cast instead of a static_cast is needed to safely cast
from a base to a derived type. The previous static_pointer_cast isn't
safe, however, when downcasting (and fails to compile when downcasting
with virtual inheritance).
Switching this to always use a dynamic_pointer_cast shouldn't incur any
additional overhead when a static_pointer_cast is safe (i.e. when
upcasting, or self-casting): compilers don't need RTTI checks in those
cases.
Python 2 requires both `__div__` and `__truediv__` (and variants) for
compatibility with both regular Python 2 and Python 2 under `from
__future__ import division`. Without both, division fails in one or the
other case.
The Python method for /= was set as `__idiv__`, which should be
`__itruediv__` under Python 3.
This wasn't totally broken in that without it defined, Python constructs
a new object by calling __truediv__. The operator tests, however,
didn't actually test the /= operator: when I added it, I saw an extra
construction, leading to the problem. This commit also includes tests
for the previously untested *= operator, and adds some element-wise
vector multiplication and division operators.
Under gcc, the `static internals *internals_ptr` is shared across .so's,
which breaks for obvious reasons.
This commit fixes it by moving the static pointer declaration into a
pybind-version-templated function.
Currently, `py::int_(1).cast<variant<double, int>>()` fills the `double`
slot of the variant. This commit switches the loader to a 2-pass scheme
in order to correctly fill the `int` slot.
Many of our `is_none()` checks in type caster loading return true, but
this should really be considered a deferral so that, for example, an
overload with a `py::none` argument would win over one that takes
`py::none` as a null option.
This keeps None-accepting for the `!convert` pass only for std::optional
and void casters. (The `char` caster already deferred None; this just
extends that behaviour to other casters).
Under gcc 7 with -std=c++11, compilation results in several of the
following warnings:
In file included from /home/jagerman/src/pybind11/tests/test_sequences_and_iterators.cpp:13:0:
/home/jagerman/src/pybind11/include/pybind11/operators.h: In function ‘pybind11::detail::op_<(pybind11::detail::op_id)0, (pybind11::detail::op_type)0, pybind11::detail::self_t, pybind11::detail::self_t> pybind11::detail::operator+(const pybind11::detail::self_t&, const pybind11::detail::self_t&)’:
/home/jagerman/src/pybind11/include/pybind11/operators.h:78:76: warning: inline declaration of ‘pybind11::detail::op_<(pybind11::detail::op_id)0, (pybind11::detail::op_type)0, pybind11::detail::self_t, pybind11::detail::self_t> pybind11::detail::operator+(const pybind11::detail::self_t&, const pybind11::detail::self_t&)’ follows declaration with attribute noinline [-Wattributes]
inline op_<op_##id, op_l, self_t, self_t> op(const self_t &, const self_t &) { \
^
/home/jagerman/src/pybind11/include/pybind11/operators.h:109:1: note: in expansion of macro ‘PYBIND11_BINARY_OPERATOR’
PYBIND11_BINARY_OPERATOR(add, radd, operator+, l + r)
^~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/jagerman/src/pybind11/include/pybind11/cast.h:15:0,
from /home/jagerman/src/pybind11/include/pybind11/attr.h:13,
from /home/jagerman/src/pybind11/include/pybind11/pybind11.h:36,
from /home/jagerman/src/pybind11/tests/pybind11_tests.h:2,
from /home/jagerman/src/pybind11/tests/test_sequences_and_iterators.cpp:11:
/home/jagerman/src/pybind11/include/pybind11/descr.h:116:36: note: previous definition of ‘pybind11::detail::descr pybind11::detail::operator+(pybind11::detail::descr&&, pybind11::detail::descr&&)’ was here
PYBIND11_NOINLINE descr friend operator+(descr &&d1, descr &&d2) {
^~~~~~~~
This appears to be happening because gcc is considering implicit
construction of `descr` in some places using addition of two
`descr`-compatible arguments in the `descr.h` c++11 fallback code.
There's no particular reason that this operator needs to be a friend
function: this commit changes it to an rvalue-context member function
operator, which avoids the warning.
This exposed a few underlying issues:
1. is_pod_struct was too strict to allow this. I've relaxed it to
require only trivially copyable and standard layout, rather than POD
(which additionally requires a trivial constructor, which std::complex
violates).
2. format_descriptor<std::complex<T>>::format() returned numpy format
strings instead of PEP3118 format strings, but register_dtype
feeds format codes of its fields to _dtype_from_pep3118. I've changed it
to return PEP3118 format codes. format_descriptor is a public type, so
this may be considered an incompatible change.
3. register_structured_dtype tried to be smart about whether to mark
fields as unaligned (with ^). However, it's examining the C++ alignment,
rather than what numpy (or possibly PEP3118) thinks the alignment should
be. For complex values those are different. I've made it mark all fields
as ^ unconditionally, which should always be safe even if they are
aligned, because we explicitly mark the padding.
Resolves#800.
Both C++ arrays and std::array are supported, including mixtures like
std::array<int, 2>[4]. In a multi-dimensional array of char, the last
dimension is used to construct a numpy string type.
The PYBIND11_CPP14 macro started out as a guard for the compile-time
path code in `descr.h`, but has since come to mean other things. This
means that while the `descr.h` check has just checked the
`PYBIND11_CPP14` macro, various other places now check `PYBIND11_CPP14
|| _MSC_VER`. This reverses that by now setting the CPP14 macro when
MSVC is trying to support C++14, but disabling the `descr.h` C++14 code
(which still fails under MSVC 2017).
The CPP17 macro also gets enabled when MSVC 2017 is compiling with
/std:c++latest (the default is /std:c++14), which enables
`std::optional` and `std::variant` support under MSVC.
GCC 7 generates (when compiling in C++11/14 mode) warnings such as:
mangled name for ‘pybind11::class_<type_, options>&
pybind11::class_<type_, options>::def(const char*, Func&&, const Extra&
...) [with Func = int (test_exc_sp::C::*)(int) noexcept; Extra = {};
type_ = test_exc_sp::C; options = {}]’ will change in C++17 because the
exception specification is part of a function type [-Wnoexcept-type]
There's nothing we can actually do in the code to avoid this, so just
disable the warning.
GCC supports `deprecated(msg)` since v4.5 and VS supports the standard
[[deprecated(msg)]] since 2015 RTM.
The deprecated constructor change from `= default` to `{}` is
a workaround for a VS2015 bug.
We're current copy by creating an Eigen::Map into the input numpy
array, then assigning that to the basic eigen type, effectively having
Eigen do the copy. That doesn't work for negative strides, though:
Eigen doesn't allow them.
This commit makes numpy do the copying instead by allocating the eigen
type, then having numpy copy from the input array into a numpy reference
into the eigen object's data. This also saves a copy when type
conversion is required: numpy can do the conversion on-the-fly as part
of the copy.
Finally this commit also makes non-reference parameters respect the
convert flag, declining the load when called in a noconvert pass with a
convertible, but non-array input or an array with the wrong dtype.
`EigenConformable::stride_compatible` returns false if the strides are
negative. In this case, do not use `EigenConformable::stride`, as it
is {0,0}. We cannot write negative strides in this element, as Eigen
will throw an assertion if we do.
The `type_caster` specialization for regular, dense Eigen matrices now
does a second `array_t::ensure` to copy data in case of negative strides.
I'm not sure that this is the best way to implement this.
I have added "TODO" tags linking these changes to Eigen bug #747, which,
when fixed, will allow Eigen to accept negative strides.
If a bound std::function is invoked with a bound method, the implicit
bound self is lost because we use `detail::get_function` to unbox the
function. This commit amends the code to use py::function and only
unboxes in the special is-really-a-c-function case. This makes bound
methods stay bound rather than unbinding them by forcing extraction of
the c function.
Enumerations on Python 2.7 were not always implicitly converted to
integers (depending on the target size). This patch adds a __long__
conversion function (only enabled on 2.7) which fixes this issue.
The attached test case fails without this patch.
This removes the convert-from-arithemtic-scalar constructor of
any_container as it can result in ambiguous calls, as in:
py::array_t<float>({ 1, 2 })
which could be intepreted as either of:
py::array_t<float>(py::array_t<float>(1, 2))
py::array_t<float>(py::detail::any_container({ 1, 2 }))
Removing the convert-from-arithmetic constructor reduces the number of
implicit conversions, avoiding the ambiguity for array and array_t.
This also re-adds the array/array_t constructors taking a scalar
argument for backwards compatibility.
Python 3's `PyInstanceMethod_Type` hides itself via its `tp_descr_get`,
which prevents aliasing methods via `cls.attr("m2") = cls.attr("m1")`:
instead the `tp_descr_get` returns a plain function, when called on a
class, or a `PyMethod`, when called on an instance. Override that
behaviour for pybind11 types with a special bypass for
`PyInstanceMethod_Types`.
The Unicode support added in 2.1 (PR #624) inadvertently broke accepting
`bytes` as std::string/char* arguments. This restores it with a
separate path that does a plain conversion (i.e. completely bypassing
all the encoding/decoding code), but only for single-byte string types.
The numpy API constants can check past the end of the API array if the
numpy version is too old thus causing a segfault. The current list of
functions requires numpy >= 1.7.0, so this adds a check and exception if
numpy is too old.
The added feature version API element was added in numpy 1.4.0, so this
could still segfault if loaded in 1.3.0 or earlier, but given that
1.4.0 was released at the end of 2009, it seems reasonable enough to
not worry about that case. (1.7.0 was released in early 2013).
This commits adds base class pointers of offset base classes (i.e. due
to multiple inheritance) to `registered_instances` so that if such a
pointer is returned we properly recognize it as an existing instance.
Without this, returning a base class pointer will cast to the existing
instance if the pointer happens to coincide with the instance pointer,
but constructs a new instance (quite possibly with a segfault, if
ownership is applied) for unequal base class pointers due to multiple
inheritance.
When we are returned a base class pointer (either directly or via
shared_from_this()) we detect its runtime type (using `typeid`), then
end up essentially reinterpret_casting the pointer to the derived type.
This is invalid when the base class pointer was a non-first base, and we
end up with an invalid pointer. We could dynamic_cast to the
most-derived type, but if *that* type isn't pybind11-registered, the
resulting pointer given to the base `cast` implementation isn't necessarily valid
to be reinterpret_cast'ed back to the backup type.
This commit removes the "backup" type argument from the many-argument
`cast(...)` and instead does the derived-or-pointer type decision and
type lookup in type_caster_base, where the dynamic_cast has to be to
correctly get the derived pointer, but also has to do the type lookup to
ensure that we don't pass the wrong (derived) pointer when the backup
type (i.e. the type caster intrinsic type) pointer is needed.
Since the lookup is needed before calling the base cast(), this also
changes the input type to a detail::type_info rather than doing a
(second) lookup in cast().
This breaks up the instance management functions in class_support.h a
little bit so that other pybind11 code can use it. In particular:
- added make_new_instance() which does what pybind11_object_new does,
but also allows instance allocation without `value` allocation. This
lets `cast.h` use the same instance allocation rather than having its
own separate implementation.
- instance registration is now moved to a
`register_instance()`/deregister_instance()` pair (rather than having
individual code add or remove things from `registered_instances`
directory).
- clear_instance() does everything `pybind11_object_dealloc()` needs
except for the deallocation; this is helpful for factory construction
which needs to be able to replace the internals of an instance without
deallocating it.
- clear_instance() now also calls `dealloc` when `holder_constructed`
is true, even if `value` is false. This can happen in factory
construction when the pointer is moved from one instance to another,
but the holder itself is only copied (i.e. for a shared_ptr holder).
I got some unexpected errors from code using `overload_cast` until I
realized that I'd configured the build with -std=c++11.
This commit adds a fake `overload_cast` class in C++11 mode that
triggers a static_assert failure indicating that C++14 is needed.
We currently fail at runtime when trying to call a method that is
overloaded with both static and non-static methods. This is something
python won't allow: the object is either a function or an instance, and
can't be both.
This further reduces the constructors required in buffer_info/numpy by
removing the need for the constructors that take a single size_t and
just forward it on via an initializer_list to the container-accepting
constructor.
Unfortunately, in `array` one of the constructors runs into an ambiguity
problem with the deprecated `array(handle, bool)` constructor (because
both the bool constructor and the any_container constructor involve an
implicit conversion, so neither has precedence), so a forwarding
constructor is kept there (until the deprecated constructor is
eventually removed).
This adds support for constructing `buffer_info` and `array`s using
arbitrary containers or iterator pairs instead of requiring a vector.
This is primarily needed by PR #782 (which makes strides signed to
properly support negative strides, and will likely also make shape and
itemsize to avoid mixed integer issues), but also needs to preserve
backwards compatibility with 2.1 and earlier which accepts the strides
parameter as a vector of size_t's.
Rather than adding nearly duplicate constructors for each stride-taking
constructor, it seems nicer to simply allow any type of container (or
iterator pairs). This works by replacing the existing vector arguments
with a new `detail::any_container` class that handles implicit
conversion of arbitrary containers into a vector of the desired type.
It can also be explicitly instantiated with a pair of iterators (e.g.
by passing {begin, end} instead of the container).
Upcoming changes to buffer_info make it need some things declared in
common.h; it also feels a bit misplaced in common.h (which is arguably
too large already), so move it out. (Separating this and the subsequent
changes into separate commits to make the changes easier to distinguish
from the move.)
When attempting to get a raw array pointer we return nullptr if given a
nullptr, which triggers an error_already_set(), but we haven't set an
exception message, which results in "Unknown internal error".
Callers that want explicit allowing of a nullptr here already handle it
(by clearing the exception after the call).
Many of the Eigen type casters' name() methods weren't wrapping the type
description in a `type_descr` object, which thus wasn't adding the
"{...}" annotation used to identify an argument which broke the help
output by skipping eigen arguments.
The test code I had added even had some (unnoticed) broken output (with
the "arg0: " showing up in the return value).
This commit also adds test code to ensure that named eigen arguments
actually work properly, despite the invalid help output. (The added
tests pass without the rest of this commit).
The holder casters assume but don't check that a `holder<type>`'s `type`
is really a `type_caster_base<type>`; this adds a static_assert to make
sure this is really the case, to turn things like
`std::shared_ptr<array>` into a compilation failure.
Fixes#785
Fixes#775.
Assignments of the form `Type.static_prop = value` should be translated to
`Type.static_prop.__set__(value)` except when `isinstance(value, static_prop)`.
PR #771 deprecated them as they can cause linking failures (#770), but
the deprecation tags cause warnings on GCC 5.x through 6.2.x. Removing
them entirely will break backwards-compatibility consequences, but the
effects should be minimal (only code that was inheriting from `object`
could get at them at all as they are protected).
Fixes#777
When make_tuple fails (for example, when print() is called with a
non-convertible argument, as in #778) the error message a less helpful
than it could be:
make_tuple(): unable to convert arguments of types 'std::tuple<type1, type2>' to Python object
There is no actual std::tuple involved (only a parameter pack and a
Python tuple), but it also doesn't immediately reveal which type caused
the problem.
This commit changes the debugging mode output to show just the
problematic type:
make_tuple(): unable to convert argument of type 'type2' to Python object
This commit adds `error_already_set::matches()` convenience method to
check if the exception trapped by `error_already_set` matches a given
Python exception type. This will address #700 by providing a less
verbose way to check exceptions.
The constexpr static instances can cause linking failures if the
compiler doesn't optimize away the reference, as reported in #770.
There's no particularly nice way of fixing this in C++11/14: we can't
inline definitions to match the declaration aren't permitted for
non-templated static variables (C++17 *does* allows "inline" on
variables, but that obviously doesn't help us.)
One solution that could work around it is to add an extra inherited
subclass to `object`'s hierarchy, but that's a bit of a messy solution
and was decided against in #771 in favour of just deprecating (and
eventually dropping) the constexpr statics.
Fixes#770.
The extends the previous unchecked support with the ability to
determine the dimensions at runtime. This incurs a small performance
hit when used (versus the compile-time fixed alternative), but is still considerably
faster than the full checks on every call that happen with
`.at()`/`.mutable_at()`.
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.
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.
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.
Instead of a segfault. Fixes#751.
This covers the case of loading a custom holder from a default-holder
instance. Attempting to load one custom holder from a different custom
holder (i.e. not `std::unique_ptr`) yields undefined behavior, just as
#588 established for inheritance.
py::arg() doesn't only specify named arguments anymore, so the error
message was misleading (e.g. when using `py::arg().noconvert()` and
forgetting `py::arg()` for a second positional argument).