Skip to content

Commit

Permalink
Merge pull request #30148 from rwgk/pybind11k_merge_sh
Browse files Browse the repository at this point in the history
git merge smart_holder
  • Loading branch information
Ralf W. Grosse-Kunstleve authored Aug 18, 2024
2 parents 604d089 + 842cd39 commit db64ba9
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 98 deletions.
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

0 comments on commit db64ba9

Please sign in to comment.