Skip to content
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

Add movable cast support to type casters #851

Merged
merged 1 commit into from
May 24, 2017

Conversation

jagerman
Copy link
Member

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 various stl.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.

@dean0x7d
Copy link
Member

Looks good to me!

@@ -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.
Copy link
Member

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.)

Copy link
Member Author

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.
@wjakob
Copy link
Member

wjakob commented May 24, 2017

This looks great! The 4KB change is definitely above the noise floor :)

@jagerman jagerman merged commit 813d7e8 into pybind:master May 24, 2017
bmerry added a commit to bmerry/pybind11 that referenced this pull request May 26, 2017
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.
dean0x7d pushed a commit that referenced this pull request May 27, 2017
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.
@dean0x7d dean0x7d modified the milestone: v2.2 Aug 13, 2017
@rwgk rwgk mentioned this pull request Feb 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants