-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Add movable cast support to type casters #851
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Looks good to me! |
include/pybind11/cast.h
Outdated
@@ -374,11 +374,31 @@ class type_caster_generic { | |||
object temp; | |||
}; | |||
|
|||
/* Determine suitable casting operator */ | |||
/** Determine suitable casting operator for pointer-or-lvalue-casting type casters. The type caster | |||
* needs to provide `operator T*()` and `operator T&()` operators. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style nitpick: could the first and second text line be aligned? I.e.:
/**
* Determine suitable casting operator for pointer-or-lvalue-casting type casters. The type caster
* needs to provide `operator T*()` and `operator T&()` operators.
*/
(The misalignment probably bothers me more than it should.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that does look better. 37b2383 does this on master, and I'll update this PR.
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.
e328bd6
to
5a0e8ac
Compare
This looks great! The 4KB change is definitely above the noise floor :) |
Now that pybind#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.
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.
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. their cast op is a 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 a
std::pair
or variousstl.h
containers. For types that don't support value moving, these casts fall 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.
.so size (before adding the tests) is slightly reduced, though the reduction is small enough (just under 4K) that it could just be noise; suffice it to say, there is no significant increase.