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

Adding py::smart_holder (for smart-pointer interoperability). #2672

Merged
merged 206 commits into from
Feb 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
206 commits
Select commit Hold shift + click to select a range
dcc440b
Adding test_unique_ptr_member (for desired PyCLIF behavior).
Nov 17, 2020
e96a186
unique_ptr or shared_ptr return
Nov 20, 2020
cd1f610
new test_variant_unique_shared with vptr_holder prototype
Nov 20, 2020
9447b50
moving prototype code to pybind11/vptr_holder.h, adding type_caster s…
Nov 20, 2020
c518aac
disabling GitHub Actions on pull_request (for this PR)
Nov 20, 2020
0f78357
disabling AppVeyor (for this PR)
Nov 20, 2020
b0806e7
TRIGGER_SEGSEV macro, annotations for GET_STACK (vptr::get), GET_INT_…
Nov 23, 2020
e82720e
adding test_promotion_of_disowned_to_shared
Dec 4, 2020
e839ffb
Copying tests as-is from xxx_value_ptr_xxx_holder branch.
Dec 18, 2020
971d611
Copying tests as-is from xxx_value_ptr_xxx_holder branch.
Dec 18, 2020
46a15af
Demonstration of Undefined Behavior in handling of shared_ptr holder.
Dec 20, 2020
204e713
Additional demonstration of Undefined Behavior in handling of shared_…
Dec 22, 2020
47e46c4
fixing up-down mixup in comment
Dec 24, 2020
aa98993
Demonstration of Undefined Behavior in handling of polymorphic pointers.
Dec 24, 2020
cd645e4
minor test_private_first_base.cpp simplification (after discovering t…
Dec 25, 2020
d4a9613
pybind11 equivalent of Boost.Python test similar to reproducer under …
Dec 30, 2020
0ef2c55
Snapshot of WIP, TODO: shared_ptr deleter with on/off switch
Jan 5, 2021
c5e112c
Adding vptr_deleter.
Jan 5, 2021
3c0c2e9
Adding from/as unique_ptr<T> and unique_ptr<T, D>.
Jan 6, 2021
06151c7
Adding from_shared_ptr. Some polishing.
Jan 6, 2021
6830a31
New tests/core/smart_holder_poc_test.cpp, using Catch2.
Jan 7, 2021
e20abab
Adding in vptr_deleter_guard_flag.
Jan 7, 2021
fea0ebf
Improved labeling of TEST_CASEs.
Jan 7, 2021
b9428a8
Shuffling existing TEST_CASEs into systematic matrix.
Jan 7, 2021
a4e0351
Implementing all [S]uccess tests.
Jan 7, 2021
673ef13
Implementing all [E]xception tests.
Jan 7, 2021
149738a
Testing of exceptions not covered by the from-as matrix.
Jan 7, 2021
d5bb169
Adding top-level comment.
Jan 7, 2021
b667d32
Converting from methods to factory functions (no functional change).
Jan 7, 2021
739aead
Removing obsolete and very incomplete test (replaced by Catch2-based …
Jan 9, 2021
a76d5eb
Removing stray file.
Jan 9, 2021
179466e
Adding type_caster_bare_interface_demo.
Jan 10, 2021
1c9b8eb
Adding shared_ptr<mpty>, shared_ptr<mpty const> casters.
Jan 10, 2021
c599d3c
Adding unique_ptr<mpty>, unique_ptr<mpty const> casters.
Jan 10, 2021
c225f40
Pure copy of `class class_` implementation in pybind11.h (master comm…
Jan 11, 2021
1bedec6
classh.h: renaming of class_ to classh + namespace; forking test_clas…
Jan 11, 2021
1c5c52f
Hard-coding smart_holder into classh.
Jan 11, 2021
83ef538
Adding mpty::mtxt string member.
Jan 11, 2021
6cb94e4
Adding isinstance<mpty> in type_caster::load functions.
Jan 12, 2021
8ed0206
Adding rvalue_ref, renaming const_value_ref to lvalue_ref & removing …
Jan 12, 2021
e90f6b0
Retrieving smart_holder pointer in type_caster<mpty>::load, and using…
Jan 12, 2021
f98322c
Factoring out smart_holder_type_caster_load.
Jan 12, 2021
f91e754
Retrieving smart_holder pointer in type_caster<std::shared_ptr<mpty[ …
Jan 12, 2021
efb5cf2
Improved error messaging: Cannot disown nullptr (as_unique_ptr).
Jan 12, 2021
4ba4faa
Retrieving smart_holder pointer in type_caster<std::unique_ptr<mpty[ …
Jan 12, 2021
4aedb51
Pure `clang-format --style=file -i` change.
Jan 12, 2021
b64294f
Pure `clang-format --style=file -i` change, with two `clang-format of…
Jan 12, 2021
f04515b
Fixing oversight (discovered by flake8).
Jan 12, 2021
e24cf09
flake8 cleanup
Jan 12, 2021
b8226c0
Systematically setting mtxt for all rtrn_mpty_* functions (preparatio…
Jan 12, 2021
14b585c
static cast handle for rtrn_cptr works by simply dropping in code fro…
Jan 12, 2021
c2137a9
static cast handle for rtrn_cref works by simply dropping in code fro…
Jan 12, 2021
1a4b6c0
static cast handle for rtrn_valu works by simply dropping in code fro…
Jan 12, 2021
0f3a21f
Copying type_caster_generic::cast into type_caster<mpty> as-is (prepa…
Jan 13, 2021
d4029ec
Pure clang-format change (applied to original type_caster_generic::ca…
Jan 13, 2021
012c160
Adding comment re potential use_count data race.
Jan 13, 2021
8bc1548
static handle cast implementations for rtrn_shmp, rtrn_shcp.
Jan 13, 2021
233709c
Adding MISSING comments in operator std::unique_ptr<mpty[ const]>.
Jan 13, 2021
19eec17
static handle cast implementations for rtrn_uqmp, rtrn_uqcp.
Jan 13, 2021
6c3c590
Bug fix: vptr_deleter_armed_flag_ptr has to live on the heap.
Jan 14, 2021
19dc356
Fixing bugs discovered by ASAN. The code is now ASAN, MSAN, UBSAN clean.
Jan 14, 2021
2b12cc9
Making test_type_caster_bare_interface_demo.cpp slightly more realist…
Jan 14, 2021
9e03cc7
Calling deregister_instance after disowning via unique_ptr.
Jan 15, 2021
5223e91
Removing enable_shared_from_this stub, simplifying existing code, cla…
Jan 15, 2021
7fd3d51
Cosmetical change around helper functions.
Jan 15, 2021
dc0f63e
Using type_caster_base<mpty>::src_and_type directly, removing copy. A…
Jan 15, 2021
cef065f
Fixing clang-format oversight.
Jan 15, 2021
fd11b71
Using factored-out make_constructor (PR #2798), removing duplicate code.
Jan 16, 2021
47b0352
Inserting additional assert to ensure a returned unique_ptr is always…
Jan 16, 2021
d189fa3
Adding minor comment (change to internals needed to distinguish unini…
Jan 16, 2021
5cbc400
Factoring out find_existing_python_instance().
Jan 17, 2021
0d6bceb
Moving factored-out make_constructor to test_classh_wip.cpp, restorin…
Jan 17, 2021
bd0c8fa
Copying classh type_casters from test_classh_wip.cpp UNMODIFIED, as a…
Jan 17, 2021
6dae732
Using pybind11/detail/classh_type_casters.h from test_classh_wip.cpp.
Jan 17, 2021
a2400b4
Adding & using PYBIND11_CLASSH_TYPE_CASTERS define.
Jan 17, 2021
a7b0745
Adding test_classh_inheritance, currently failing (passes with class_).
Jan 18, 2021
689e253
Removing .clang-format before git rebase master (where the file was a…
Jan 20, 2021
c87145c
Bringing back .clang-format, the previous rm was a bad idea.
Jan 20, 2021
cc50eaa
Folding in modified_type_caster_generic_load_impl, just enough to pas…
Jan 20, 2021
acb2c33
Minimal changes needed to pass test_classh_inheritance.
Jan 20, 2021
a11dfba
First pass adjusting try_implicit_casts and try_load_foreign_module_l…
Jan 20, 2021
d0c351b
Decoupling generic_type from type_caster_generic.
Jan 21, 2021
ed01fae
Changes and tests covering classh_type_casters try_implicit_casts.
Jan 22, 2021
d3ef4a9
Minimal test covering classh_type_casters load_impl Case 2b.
Jan 22, 2021
299bba4
Removing stray isinstance<T>(src): it interferes with the py::module_…
Jan 23, 2021
ce626e0
Tests for classh py::module_local() feature.
Jan 23, 2021
f646967
Pure renaming of function names in test_classh_inheritance, similar t…
Jan 23, 2021
678ecb9
Pure renaming of function and variable names, for better generalizati…
Jan 23, 2021
6e825d3
Adopting systematic naming scheme from test_classh_wip. NO functional…
Jan 23, 2021
4bd7394
Moving const after type name, for functions that cover a systematic s…
Jan 23, 2021
45dfd26
Adding smart_holder_type_caster_load::loaded_as_shared_ptr, currently…
Jan 23, 2021
49bf91f
Removing rtti_held from smart_holder. See updated comment.
Jan 23, 2021
f7ce730
Cleaning up loaded_as_raw_ptr_unowned, loaded_as_shared_ptr.
Jan 23, 2021
877218b
Factoring out convert_type and folding into loaded_as_unique_ptr.
Jan 23, 2021
be411c8
Folding convert_type into lvalue_ref and rvalue_ref paths. Some smart…
Jan 23, 2021
73cb257
Using unique_ptr in local_load to replace static variable. Also addin…
Jan 24, 2021
149be46
Converting test_unique_ptr_member to using classh: fully working, ASA…
Jan 24, 2021
60dc8f3
Removing debugging comments (GET_STACK, GET_INT_STACK). cast.h is ide…
Jan 24, 2021
b93c240
Purging obsolete pybind11/vptr_holder.h and associated test.
Jan 24, 2021
a0cf20c
Moving several tests to github.com/rwgk/rwgk_tbx/tree/main/pybind11_t…
Jan 24, 2021
8e5ca01
Adding py::smart_holder support to py::class_, purging py::classh com…
Jan 24, 2021
173032c
Renaming files in include directory, creating pybind11/smart_holder.h.
Jan 25, 2021
6e460b8
Renaming all "classh" to "smart_holder" in pybind11/detail/smart_hold…
Jan 25, 2021
b71f6ff
Systematically renaming tests to use "class_sh" in the name.
Jan 25, 2021
1613268
Renaming test_type_caster_bare_interface_demo to test_type_caster_bar…
Jan 25, 2021
9ef2cce
Renaming new tests/core subdirectory to tests/pure_cpp.
Jan 25, 2021
6ab0a02
Adding new tests to CMake config, resetting CI config.
Jan 25, 2021
8b04ea0
Changing CMake file so that test_class_sh_module_local.py actually runs.
Jan 25, 2021
e67d5a5
clang-tidy fixes.
Jan 25, 2021
02c4e24
32-bit compatibility.
Jan 25, 2021
76a090e
Reusing type_caster_base make_copy_constructor, make_move_constructor…
Jan 26, 2021
b1ef8b6
CMake COMPARE NATURAL is not available with older versions.
Jan 26, 2021
6f6a1ad
Adding copyright notices to new header files.
Jan 26, 2021
ed68519
Explicitly define copy/move constructors/assignments.
Jan 26, 2021
259d824
Adding new header files to tests/extra_python_package/test_files.py.
Jan 26, 2021
ef3f789
Adding tests/pure_cpp/CMakeLists.txt.
Jan 26, 2021
86dc9bd
Making use of the new find_existing_python_instance() function factor…
Jan 27, 2021
93e3d58
Moving define PYBIND11_SMART_HOLDER_TYPE_CASTERS(T) down in the file.…
Jan 27, 2021
098630e
Reintroducing py::classh, this time as a simple alias for py::class_<…
Jan 28, 2021
7ed08cb
Replacing detail::is_smart_holder<H> in cast.h with detail::is_smart_…
Jan 28, 2021
c9477c4
Fixing oversight.
Jan 29, 2021
7151287
Adding classu alias for class_<U, std::unique_ptr<U>>.
Jan 29, 2021
290f2d6
Giving up on idea to use legacy init_instance only if is_base_of<type…
Jan 29, 2021
13d861f
Removing test_type_caster_bare_interface, which was moved to the sepa…
Jan 29, 2021
8c87dc4
Moving up is_smart_holder_type_caster, to also use in cast_is_tempora…
Jan 30, 2021
aacc8ac
Adding smart_holder_type_casters for unique_ptr with custom deleter. …
Feb 1, 2021
6e515cc
Unification of unique_ptr, unique_ptr_with_deleter code in smart_hold…
Feb 2, 2021
c3617bf
Copying files as-is from branch test_unique_ptr_member (PR #2672).
Jan 29, 2021
d5cbfa8
Adding comment, simplifying naming, cmake addition.
Jan 29, 2021
3d34ba3
Introducing PYBIND11_USE_SMART_HOLDER_AS_DEFAULT macro (tested only u…
Jan 29, 2021
98b2751
Removing test_type_caster_bare_interface, which was moved to the sepa…
Jan 29, 2021
26525b6
Fixing oversight introduced with commit 95425f13d6c14fcb6ee479b62b602…
Jan 30, 2021
6ed9cc9
Setting record.default_holder correctly for PYBIND11_USE_SMART_HOLDER…
Jan 30, 2021
7070b52
Fixing up cast.h and smart_holder.h after rebase.
Feb 2, 2021
07dab2e
Removing detail/smart_holder_type_casters.h in separate commit.
Feb 2, 2021
3f8da23
Commenting out const in def_buffer(... const). With this, test_buffer…
Feb 2, 2021
9f6fa1c
Adding test_class_sh_factory_constructors, reproducing test_factory_c…
Feb 2, 2021
5bd693e
Removing include/pybind11/detail/smart_holder_type_casters.h from CMa…
Feb 3, 2021
16748f5
Adding // DANGER ZONE reminders.
Feb 3, 2021
e6e441d
Converting as many py::class_ to py::classh as possible, not breaking…
Feb 3, 2021
dfa00a1
Adding initimpl::construct() overloads, resulting in test_class_sh_fa…
Feb 3, 2021
9dd82f1
Adding enable_if !is_smart_holder_type_caster to existing initimpl::c…
Feb 4, 2021
fba0729
Disabling shared_ptr&, shared_ptr* tests when building with PYBIND11_…
Feb 4, 2021
c4e4da8
Factoring out struct and class definitions into anonymous namespace. …
Feb 4, 2021
0b73ef4
Simplifying from_unique_ptr(): typename D = std::default_delete<T> is…
Feb 4, 2021
576a456
Introducing PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS. Using it in t…
Feb 4, 2021
f65cb0c
Introducing 1. type_caster_for_class_, used in PYBIND11_MAKE_OPAQUE, …
Feb 5, 2021
4665ff6
Using __VA_ARGS__ in PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS.
Feb 5, 2021
6582fb3
Replacing condense_for_macro with much simpler approach.
Feb 5, 2021
4a9bc72
Softening static_assert, to only check specifically that smart_holder…
Feb 5, 2021
f439b2b
Adding PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS in test_class.cpp (…
Feb 5, 2021
efa7adb
Adding remaining PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS. static_a…
Feb 5, 2021
523bfd3
Introducing check_is_smart_holder_type_caster() function for runtime …
Feb 5, 2021
706ffbd
Bug fix: Adding have_value() to smart_holder_type_caster_load. With t…
Feb 6, 2021
8176a36
Adding unowned_void_ptr_from_direct_conversion to modified_type_caste…
Feb 6, 2021
5068524
Adding "Lazy allocation for unallocated values" (for old-style __init…
Feb 9, 2021
64e6a80
Changing std::shared_ptr pointer/reference to const pointer/reference…
Feb 9, 2021
2f79cd9
Adding return_value_policy::move to permissible policies for unique_p…
Feb 9, 2021
40a3afa
Overlooked flake8 fixes.
Feb 9, 2021
095d265
Manipulating failing ConstructorStats test to pass, to be able to run…
Feb 10, 2021
dab4495
Adding copy constructor and move constructor tracking to atyp. Prepar…
Feb 12, 2021
20446f1
Removing `operator T&&() &&` from smart_holder_type_caster, for compa…
Feb 12, 2021
bb79703
Fixing unfortunate editing mishap. This reverts the last remaining te…
Feb 12, 2021
8736910
GitHub CI clang-tidy fixes.
Feb 12, 2021
52238cb
Adding messages to terse `static_assert`s, for pre-C++17 compatibility.
Feb 12, 2021
3346a61
Using @pytest.mark.parametrize to run each assert separately (to see …
Feb 12, 2021
b792080
Systematically removing _atyp from function names, to make the test c…
Feb 12, 2021
2003b50
Using re.match to accommodate variable number of intermediate MvCtor.
Feb 12, 2021
823934f
Also removing `operator T()` from smart_holder_type_caster, to fix gc…
Feb 12, 2021
1909436
Systematically replacing `detail::enable_if_t<...smart_holder...>` wi…
Feb 12, 2021
823ae0a
Importing re before pytest after observing a PyPy CI flake when impor…
Feb 12, 2021
0bfa993
Copying MSVC 2015 compatibility change from branch pr2672_use_smart_h…
Feb 14, 2021
44bdc14
Introducing is_smart_holder_type_caster_base_tag, to keep smart_holde…
Feb 14, 2021
c51dec4
Working around MSVC 2015 bug.
Feb 14, 2021
23cbc2b
Expanding comment for MSVC 2015 workaround.
Feb 14, 2021
e0e3ff0
Systematically changing std::enable_if back to detail::enable_if_t, e…
Feb 14, 2021
795b2bc
Removing unused smart_holder_type_caster_load::loaded_as_rvalue_ref (…
Feb 14, 2021
ceb0ea7
Removing py::classu, because it does not seem useful enough.
Feb 14, 2021
3709ab3
Reverting commit 63495313066119dcf7510c2ae8b468b46c12ef8f by un-comme…
Feb 14, 2021
53c1064
Adding construct() overloads for constructing smart_holder from alias…
Feb 14, 2021
2bf0721
Adding test_class_sh_factory_constructors.cpp to tests/CMakeLists.txt…
Feb 15, 2021
fa54ccb
Compatibility with old clang versions (clang 3.6, 3.7 C++11).
Feb 15, 2021
010cdec
Cleaning up changes to existing unit tests.
Feb 15, 2021
413c23b
Systematically adding SMART_HOLDER_WIP tag. Removing minor UNTESTED t…
Feb 15, 2021
b222aa4
Splitting out smart_holder_type_casters again, into new detail/smart_…
Feb 15, 2021
348d893
Splitting out smart_holder_init_inline_include.h.
Feb 15, 2021
8cac3e0
Adding additional new include files to CMakeLists.txt, tests/extra_py…
Feb 15, 2021
4ffa561
clang-format cleanup of most smart_holder code.
Feb 15, 2021
81cd3cc
Adding source code comments in response to review.
Feb 18, 2021
baf51b4
Simple micro-benchmark ("ubench") comparing runtime performance for s…
Feb 20, 2021
0964419
Breaking out number_bucket.h, adding hook for also collecting perform…
Feb 21, 2021
1e8fe10
Accounting for ubench in MANIFEST.in (simply prune, for now).
Feb 21, 2021
227de40
Smarter determination of call_repetitions.
Feb 21, 2021
fb505c0
Also scaling performance data to PyCLIF.
Feb 22, 2021
a886a56
Adding ubench/python/number_bucket.clif here for general visibility.
Feb 22, 2021
044056a
Fix after rebase
Feb 23, 2021
3d31698
Merging detail/smart_holder_init_inline_include.h into detail/init.h.
Feb 23, 2021
658cf3b
Renaming detail/is_smart_holder_type_caster.h -> detail/smart_holder_…
Feb 23, 2021
3a303ee
Renaming is_smart_holder_type_caster -> type_uses_smart_holder_type_c…
Feb 23, 2021
ce40fb6
Renaming type_caster_type_is_smart_holder_type_caster -> wrapped_type…
Feb 23, 2021
c56bd3a
Renaming is_smart_holder_type_caster_base_tag -> smart_holder_type_ca…
Feb 23, 2021
62afdc0
Adding copyright notices and minor colateral cleanup.
Feb 23, 2021
4f5f441
iwyu cleanup (comprehensive only for cast.h and smart_holder*.h files).
Feb 24, 2021
f5dadd4
Fixing `git rebase master` accident.
Feb 24, 2021
4bae719
Moving large `pragma warning` block from pybind11.h to detail/common.h.
Feb 24, 2021
4255d6c
Fixing another `git rebase master` accident.
Feb 24, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ set(PYBIND11_HEADERS
include/pybind11/detail/descr.h
include/pybind11/detail/init.h
include/pybind11/detail/internals.h
include/pybind11/detail/smart_holder_poc.h
include/pybind11/detail/smart_holder_sfinae_hooks_only.h
include/pybind11/detail/smart_holder_type_casters.h
include/pybind11/detail/type_caster_base.h
include/pybind11/detail/typeid.h
include/pybind11/attr.h
Expand All @@ -124,6 +127,7 @@ set(PYBIND11_HEADERS
include/pybind11/operators.h
include/pybind11/pybind11.h
include/pybind11/pytypes.h
include/pybind11/smart_holder.h
include/pybind11/stl.h
include/pybind11/stl_bind.h)

Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ recursive-include pybind11 py.typed
recursive-include pybind11 *.pyi
include pybind11/share/cmake/pybind11/*.cmake
include LICENSE README.rst pyproject.toml setup.py setup.cfg
prune ubench
41 changes: 34 additions & 7 deletions include/pybind11/cast.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// clang-format off
/*
pybind11/cast.h: Partial template specializations to cast between
C++ and Python types
Expand All @@ -13,6 +14,7 @@
#include "pytypes.h"
#include "detail/common.h"
#include "detail/descr.h"
#include "detail/smart_holder_sfinae_hooks_only.h"
#include "detail/type_caster_base.h"
#include "detail/typeid.h"
#include <array>
Expand All @@ -27,6 +29,10 @@
#include <utility>
#include <vector>

#ifdef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
#include "detail/smart_holder_type_casters.h"
#endif

#if defined(PYBIND11_CPP17)
# if defined(__has_include)
# if __has_include(<string_view>)
Expand All @@ -47,8 +53,24 @@
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_NAMESPACE_BEGIN(detail)

template <typename type, typename SFINAE = void> class type_caster : public type_caster_base<type> { };
template <typename type> using make_caster = type_caster<intrinsic_t<type>>;
// clang-format on
#ifndef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
template <typename T>
class type_caster_for_class_ : public type_caster_base<T> {};
#endif

template <typename type, typename SFINAE = void>
class type_caster : public type_caster_for_class_<type> {};

template <typename type>
using make_caster = type_caster<intrinsic_t<type>>;

template <typename T>
struct type_uses_smart_holder_type_caster {
static constexpr bool value
= std::is_base_of<smart_holder_type_caster_base_tag, make_caster<T>>::value;
};
// clang-format off

// Shortcut for calling a caster's `cast_op_type` cast operator for casting a type_caster to a T
template <typename T> typename make_caster<T>::template cast_op_type<T> cast_op(make_caster<T> &caster) {
Expand Down Expand Up @@ -696,9 +718,11 @@ struct copyable_holder_caster : public type_caster_base<type> {
holder_type holder;
};

#ifndef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
/// Specialize for the common std::shared_ptr, so users don't need to
template <typename T>
class type_caster<std::shared_ptr<T>> : public copyable_holder_caster<T, std::shared_ptr<T>> { };
#endif

/// Type caster for holder types like std::unique_ptr.
/// Please consider the SFINAE hook an implementation detail, as explained
Expand All @@ -715,9 +739,11 @@ struct move_only_holder_caster {
static constexpr auto name = type_caster_base<type>::name;
};

#ifndef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
template <typename type, typename deleter>
class type_caster<std::unique_ptr<type, deleter>>
: public move_only_holder_caster<type, std::unique_ptr<type, deleter>> { };
#endif

template <typename type, typename holder_type>
using type_caster_holder = conditional_t<is_copy_constructible<holder_type>::value,
Expand Down Expand Up @@ -820,6 +846,7 @@ template <typename T> using move_never = none_of<move_always<T>, move_if_unrefer
template <typename type> using cast_is_temporary_value_reference = bool_constant<
(std::is_reference<type>::value || std::is_pointer<type>::value) &&
!std::is_base_of<type_caster_generic, make_caster<type>>::value &&
!type_uses_smart_holder_type_caster<intrinsic_t<type>>::value &&
!std::is_same<intrinsic_t<type>, void>::value
>;

Expand Down Expand Up @@ -1362,18 +1389,18 @@ PYBIND11_NAMESPACE_END(detail)

template<typename T>
handle type::handle_of() {
static_assert(
std::is_base_of<detail::type_caster_generic, detail::make_caster<T>>::value,
"py::type::of<T> only supports the case where T is a registered C++ types."
);
static_assert(
detail::any_of<std::is_base_of<detail::type_caster_generic, detail::make_caster<T>>,
detail::type_uses_smart_holder_type_caster<T>>::value,
"py::type::of<T> only supports the case where T is a registered C++ types.");

return detail::get_type_handle(typeid(T), true);
}


#define PYBIND11_MAKE_OPAQUE(...) \
namespace pybind11 { namespace detail { \
template<> class type_caster<__VA_ARGS__> : public type_caster_base<__VA_ARGS__> { }; \
template<> class type_caster<__VA_ARGS__> : public type_caster_for_class_<__VA_ARGS__> { }; \
}}

/// Lets you pass a type containing a `,` through a macro parameter without needing a separate
Expand Down
2 changes: 2 additions & 0 deletions include/pybind11/detail/class.h
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,8 @@ inline void clear_instance(PyObject *self) {

if (instance->owned || v_h.holder_constructed())
v_h.type->dealloc(v_h);
} else if (v_h.holder_constructed()) {
v_h.type->dealloc(v_h); // Disowned instance.
}
}
// Deallocate the value/holder layout internals:
Expand Down
32 changes: 32 additions & 0 deletions include/pybind11/detail/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,38 @@
#define PYBIND11_VERSION_MINOR 6
#define PYBIND11_VERSION_PATCH 3.dev1

#if defined(__INTEL_COMPILER)
# pragma warning push
# pragma warning disable 68 // integer conversion resulted in a change of sign
# pragma warning disable 186 // pointless comparison of unsigned integer with zero
# pragma warning disable 878 // incompatible exception specifications
# pragma warning disable 1334 // the "template" keyword used for syntactic disambiguation may only be used within a template
# pragma warning disable 1682 // implicit conversion of a 64-bit integral type to a smaller integral type (potential portability problem)
# pragma warning disable 1786 // function "strdup" was declared deprecated
# pragma warning disable 1875 // offsetof applied to non-POD (Plain Old Data) types is nonstandard
# pragma warning disable 2196 // warning #2196: routine is both "inline" and "noinline"
#elif defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable: 4100) // warning C4100: Unreferenced formal parameter
# pragma warning(disable: 4127) // warning C4127: Conditional expression is constant
# pragma warning(disable: 4512) // warning C4512: Assignment operator was implicitly defined as deleted
# pragma warning(disable: 4800) // warning C4800: 'int': forcing value to bool 'true' or 'false' (performance warning)
# pragma warning(disable: 4996) // warning C4996: The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name
# pragma warning(disable: 4702) // warning C4702: unreachable code
# pragma warning(disable: 4522) // warning C4522: multiple assignment operators specified
# pragma warning(disable: 4505) // warning C4505: 'PySlice_GetIndicesEx': unreferenced local function has been removed (PyPy only)
#elif defined(__GNUG__) && !defined(__clang__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
# pragma GCC diagnostic ignored "-Wunused-but-set-variable"
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
# pragma GCC diagnostic ignored "-Wstrict-aliasing"
# pragma GCC diagnostic ignored "-Wattributes"
# if __GNUC__ >= 7
# pragma GCC diagnostic ignored "-Wnoexcept-type"
# endif
#endif

#define PYBIND11_NAMESPACE_BEGIN(name) namespace name {
#define PYBIND11_NAMESPACE_END(name) }

Expand Down
69 changes: 67 additions & 2 deletions include/pybind11/detail/init.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// clang-format off
/*
pybind11/detail/init.h: init factory function implementation and support code.

Expand All @@ -10,6 +11,7 @@
#pragma once

#include "class.h"
#include "smart_holder_sfinae_hooks_only.h"

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_NAMESPACE_BEGIN(detail)
Expand Down Expand Up @@ -105,11 +107,13 @@ void construct(value_and_holder &v_h, Cpp<Class> *ptr, bool need_alias) {
// the holder and destruction happens when we leave the C++ scope, and the holder
// class gets to handle the destruction however it likes.
v_h.value_ptr() = ptr;
v_h.set_instance_registered(true); // To prevent init_instance from registering it
v_h.set_instance_registered(true); // SHORTCUT To prevent init_instance from registering it
// DANGER ZONE BEGIN: exceptions will leave v_h in an invalid state.
v_h.type->init_instance(v_h.inst, nullptr); // Set up the holder
Holder<Class> temp_holder(std::move(v_h.holder<Holder<Class>>())); // Steal the holder
v_h.type->dealloc(v_h); // Destroys the moved-out holder remains, resets value ptr to null
v_h.set_instance_registered(false);
// DANGER ZONE END.

construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(*ptr));
} else {
Expand All @@ -129,7 +133,8 @@ void construct(value_and_holder &v_h, Alias<Class> *alias_ptr, bool) {
// Holder return: copy its pointer, and move or copy the returned holder into the new instance's
// holder. This also handles types like std::shared_ptr<T> and std::unique_ptr<T> where T is a
// derived type (through those holder's implicit conversion from derived class holder constructors).
template <typename Class>
template <typename Class,
detail::enable_if_t<!detail::type_uses_smart_holder_type_caster<Cpp<Class>>::value, int> = 0>
void construct(value_and_holder &v_h, Holder<Class> holder, bool need_alias) {
auto *ptr = holder_helper<Holder<Class>>::get(holder);
no_nullptr(ptr);
Expand Down Expand Up @@ -166,6 +171,66 @@ void construct(value_and_holder &v_h, Alias<Class> &&result, bool) {
v_h.value_ptr() = new Alias<Class>(std::move(result));
}

// clang-format on
template <
typename Class,
typename D = std::default_delete<Cpp<Class>>,
detail::enable_if_t<detail::type_uses_smart_holder_type_caster<Cpp<Class>>::value, int> = 0>
void construct(value_and_holder &v_h, std::unique_ptr<Cpp<Class>, D> &&unq_ptr, bool need_alias) {
auto *ptr = unq_ptr.get();
no_nullptr(ptr);
if (Class::has_alias && need_alias)
throw type_error("pybind11::init(): construction failed: returned std::unique_ptr pointee "
"is not an alias instance");
auto smhldr
= type_caster<Cpp<Class>>::template smart_holder_from_unique_ptr(std::move(unq_ptr));
v_h.value_ptr() = ptr;
v_h.type->init_instance(v_h.inst, &smhldr);
}

template <
typename Class,
typename D = std::default_delete<Alias<Class>>,
detail::enable_if_t<detail::type_uses_smart_holder_type_caster<Alias<Class>>::value, int> = 0>
void construct(value_and_holder &v_h,
std::unique_ptr<Alias<Class>, D> &&unq_ptr,
bool /*need_alias*/) {
auto *ptr = unq_ptr.get();
no_nullptr(ptr);
auto smhldr
= type_caster<Alias<Class>>::template smart_holder_from_unique_ptr(std::move(unq_ptr));
v_h.value_ptr() = ptr;
v_h.type->init_instance(v_h.inst, &smhldr);
}

template <
typename Class,
detail::enable_if_t<detail::type_uses_smart_holder_type_caster<Cpp<Class>>::value, int> = 0>
void construct(value_and_holder &v_h, std::shared_ptr<Cpp<Class>> &&shd_ptr, bool need_alias) {
auto *ptr = shd_ptr.get();
no_nullptr(ptr);
if (Class::has_alias && need_alias)
throw type_error("pybind11::init(): construction failed: returned std::shared_ptr pointee "
"is not an alias instance");
auto smhldr = type_caster<Cpp<Class>>::template smart_holder_from_shared_ptr(shd_ptr);
v_h.value_ptr() = ptr;
v_h.type->init_instance(v_h.inst, &smhldr);
}

template <
typename Class,
detail::enable_if_t<detail::type_uses_smart_holder_type_caster<Alias<Class>>::value, int> = 0>
void construct(value_and_holder &v_h,
std::shared_ptr<Alias<Class>> &&shd_ptr,
bool /*need_alias*/) {
auto *ptr = shd_ptr.get();
no_nullptr(ptr);
auto smhldr = type_caster<Alias<Class>>::template smart_holder_from_shared_ptr(shd_ptr);
v_h.value_ptr() = ptr;
v_h.type->init_instance(v_h.inst, &smhldr);
}
// clang-format off

// Implementing class for py::init<...>()
template <typename... Args>
struct constructor {
Expand Down
Loading