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

git merge smart_holder #30148

Merged
merged 2 commits into from
Aug 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ set(PYBIND11_HEADERS
include/pybind11/detail/init.h
include/pybind11/detail/internals.h
include/pybind11/detail/native_enum_data.h
include/pybind11/detail/smart_holder_poc.h
include/pybind11/detail/struct_smart_holder.h
include/pybind11/detail/try_as_void_ptr_capsule_get_pointer.h
include/pybind11/detail/type_caster_base.h
include/pybind11/detail/type_caster_odr_guard.h
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2020-2021 The Pybind Development Team.
// Copyright (c) 2020-2024 The Pybind Development Team.
// All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

Expand Down Expand Up @@ -44,16 +44,6 @@ High-level aspects:
* The `void_cast_raw_ptr` option is needed to make the `smart_holder` `vptr`
member invisible to the `shared_from_this` mechanism, in case the lifetime
of a `PyObject` is tied to the pointee.

* Regarding `PYBIND11_TESTS_PURE_CPP_SMART_HOLDER_POC_TEST_CPP` below:
This define serves as a marker for code that is NOT used
from smart_holder_type_casters.h, but is exercised only from
tests/pure_cpp/smart_holder_poc_test.cpp. The marked code was useful
mainly for bootstrapping the smart_holder work. At this stage, with
smart_holder_type_casters.h in production use (at Google) since around
February 2021, it could be moved from here to tests/pure_cpp/ (help welcome).
It will probably be best in most cases to add tests for new functionality
under test/test_class_sh_*.
*/

#pragma once
Expand Down Expand Up @@ -256,26 +246,6 @@ struct smart_holder {
return static_cast<T *>(vptr.get());
}

#ifdef PYBIND11_TESTS_PURE_CPP_SMART_HOLDER_POC_TEST_CPP // See comment near top.
template <typename T>
T &as_lvalue_ref() const {
static const char *context = "as_lvalue_ref";
ensure_is_populated(context);
ensure_has_pointee(context);
return *as_raw_ptr_unowned<T>();
}
#endif

#ifdef PYBIND11_TESTS_PURE_CPP_SMART_HOLDER_POC_TEST_CPP // See comment near top.
template <typename T>
T &&as_rvalue_ref() const {
static const char *context = "as_rvalue_ref";
ensure_is_populated(context);
ensure_has_pointee(context);
return std::move(*as_raw_ptr_unowned<T>());
}
#endif

template <typename T>
static smart_holder from_raw_ptr_take_ownership(T *raw_ptr, bool void_cast_raw_ptr = false) {
ensure_pointee_is_destructible<T>("from_raw_ptr_take_ownership");
Expand Down Expand Up @@ -319,16 +289,6 @@ struct smart_holder {
release_disowned();
}

#ifdef PYBIND11_TESTS_PURE_CPP_SMART_HOLDER_POC_TEST_CPP // See comment near top.
template <typename T>
T *as_raw_ptr_release_ownership(const char *context = "as_raw_ptr_release_ownership") {
ensure_can_release_ownership(context);
T *raw_ptr = as_raw_ptr_unowned<T>();
release_ownership();
return raw_ptr;
}
#endif

template <typename T, typename D>
static smart_holder from_unique_ptr(std::unique_ptr<T, D> &&unq_ptr,
void *void_ptr = nullptr) {
Expand All @@ -351,19 +311,6 @@ struct smart_holder {
return hld;
}

#ifdef PYBIND11_TESTS_PURE_CPP_SMART_HOLDER_POC_TEST_CPP // See comment near top.
template <typename T, typename D = std::default_delete<T>>
std::unique_ptr<T, D> as_unique_ptr() {
static const char *context = "as_unique_ptr";
ensure_compatible_rtti_uqp_del<T, D>(context);
ensure_use_count_1(context);
T *raw_ptr = as_raw_ptr_unowned<T>();
release_ownership();
// KNOWN DEFECT (see PR #4850): Does not copy the deleter.
return std::unique_ptr<T, D>(raw_ptr);
}
#endif

template <typename T>
static smart_holder from_shared_ptr(std::shared_ptr<T> shd_ptr) {
smart_holder hld;
Expand Down
2 changes: 1 addition & 1 deletion include/pybind11/detail/type_caster_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,7 @@ struct load_helper : value_and_holder_helper {

auto *gd = std::get_deleter<pybindit::memory::guarded_delete>(holder().vptr);
if (gd && gd->use_del_fun) { // Note the ensure_compatible_rtti_uqp_del<T, D>() call above.
// In smart_holder_poc, a custom deleter is always stored in a guarded delete.
// In struct_smart_holder, a custom deleter is always stored in a guarded delete.
// The guarded delete's std::function<void(void*)> actually points at the
// custom_deleter type, so we can verify it is of the custom deleter type and
// finally extract its deleter.
Expand Down
2 changes: 1 addition & 1 deletion include/pybind11/detail/using_smart_holder.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <type_traits>

#ifdef PYBIND11_HAS_INTERNALS_WITH_SMART_HOLDER_SUPPORT
# include "smart_holder_poc.h"
# include "struct_smart_holder.h"
#endif

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
Expand Down
2 changes: 1 addition & 1 deletion tests/extra_python_package/test_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"include/pybind11/detail/init.h",
"include/pybind11/detail/internals.h",
"include/pybind11/detail/native_enum_data.h",
"include/pybind11/detail/smart_holder_poc.h",
"include/pybind11/detail/struct_smart_holder.h",
"include/pybind11/detail/try_as_void_ptr_capsule_get_pointer.h",
"include/pybind11/detail/type_caster_base.h",
"include/pybind11/detail/type_caster_odr_guard.h",
Expand Down
51 changes: 51 additions & 0 deletions tests/pure_cpp/smart_holder_poc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) 2020-2024 The Pybind Development Team.
// All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#pragma once

#include "pybind11/detail/struct_smart_holder.h"

namespace pybindit {
namespace memory {
namespace smart_holder_poc { // Proof-of-Concept implementations.

template <typename T>
T &as_lvalue_ref(const smart_holder &hld) {
static const char *context = "as_lvalue_ref";
hld.ensure_is_populated(context);
hld.ensure_has_pointee(context);
return *hld.as_raw_ptr_unowned<T>();
}

template <typename T>
T &&as_rvalue_ref(const smart_holder &hld) {
static const char *context = "as_rvalue_ref";
hld.ensure_is_populated(context);
hld.ensure_has_pointee(context);
return std::move(*hld.as_raw_ptr_unowned<T>());
}

template <typename T>
T *as_raw_ptr_release_ownership(smart_holder &hld,
const char *context = "as_raw_ptr_release_ownership") {
hld.ensure_can_release_ownership(context);
T *raw_ptr = hld.as_raw_ptr_unowned<T>();
hld.release_ownership();
return raw_ptr;
}

template <typename T, typename D = std::default_delete<T>>
std::unique_ptr<T, D> as_unique_ptr(smart_holder &hld) {
static const char *context = "as_unique_ptr";
hld.ensure_compatible_rtti_uqp_del<T, D>(context);
hld.ensure_use_count_1(context);
T *raw_ptr = hld.as_raw_ptr_unowned<T>();
hld.release_ownership();
// KNOWN DEFECT (see PR #4850): Does not copy the deleter.
return std::unique_ptr<T, D>(raw_ptr);
}

} // namespace smart_holder_poc
} // namespace memory
} // namespace pybindit
Loading