mirror of
https://github.com/pybind/pybind11.git
synced 2025-02-17 22:20:41 +00:00
Introduce detail/using_smart_holder.h and remove pybindit::memory::
in most places.
This commit is contained in:
parent
583c07bffd
commit
7296c39705
@ -156,6 +156,7 @@ set(PYBIND11_HEADERS
|
|||||||
include/pybind11/detail/smart_holder_poc.h
|
include/pybind11/detail/smart_holder_poc.h
|
||||||
include/pybind11/detail/type_caster_base.h
|
include/pybind11/detail/type_caster_base.h
|
||||||
include/pybind11/detail/typeid.h
|
include/pybind11/detail/typeid.h
|
||||||
|
include/pybind11/detail/using_smart_holder.h
|
||||||
include/pybind11/detail/value_and_holder.h
|
include/pybind11/detail/value_and_holder.h
|
||||||
include/pybind11/attr.h
|
include/pybind11/attr.h
|
||||||
include/pybind11/buffer_info.h
|
include/pybind11/buffer_info.h
|
||||||
|
@ -1137,7 +1137,7 @@ struct is_holder_type<base, std::unique_ptr<base, deleter>> : std::true_type {};
|
|||||||
|
|
||||||
#ifdef PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT
|
#ifdef PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT
|
||||||
template <typename base>
|
template <typename base>
|
||||||
struct is_holder_type<base, pybindit::memory::smart_holder> : std::true_type {};
|
struct is_holder_type<base, smart_holder> : std::true_type {};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION // See PR #4888
|
#ifdef PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION // See PR #4888
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "class.h"
|
#include "class.h"
|
||||||
#include "smart_holder_poc.h"
|
#include "using_smart_holder.h"
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||||
|
|
||||||
@ -156,10 +156,8 @@ void construct(value_and_holder &v_h, Alias<Class> *alias_ptr, bool) {
|
|||||||
// holder. This also handles types like std::shared_ptr<T> and std::unique_ptr<T> where T is a
|
// 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
|
// derived type (through those holder's implicit conversion from derived class holder
|
||||||
// constructors).
|
// constructors).
|
||||||
template <
|
template <typename Class,
|
||||||
typename Class,
|
detail::enable_if_t<!std::is_same<Holder<Class>, smart_holder>::value, int> = 0>
|
||||||
detail::enable_if_t<!std::is_same<Holder<Class>, pybindit::memory::smart_holder>::value, int>
|
|
||||||
= 0>
|
|
||||||
void construct(value_and_holder &v_h, Holder<Class> holder, bool need_alias) {
|
void construct(value_and_holder &v_h, Holder<Class> holder, bool need_alias) {
|
||||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
||||||
auto *ptr = holder_helper<Holder<Class>>::get(holder);
|
auto *ptr = holder_helper<Holder<Class>>::get(holder);
|
||||||
@ -203,23 +201,21 @@ void construct(value_and_holder &v_h, Alias<Class> &&result, bool) {
|
|||||||
|
|
||||||
namespace originally_smart_holder_type_casters_h {
|
namespace originally_smart_holder_type_casters_h {
|
||||||
template <typename T, typename D>
|
template <typename T, typename D>
|
||||||
pybindit::memory::smart_holder smart_holder_from_unique_ptr(std::unique_ptr<T, D> &&unq_ptr,
|
smart_holder smart_holder_from_unique_ptr(std::unique_ptr<T, D> &&unq_ptr,
|
||||||
bool void_cast_raw_ptr) {
|
bool void_cast_raw_ptr) {
|
||||||
void *void_ptr = void_cast_raw_ptr ? static_cast<void *>(unq_ptr.get()) : nullptr;
|
void *void_ptr = void_cast_raw_ptr ? static_cast<void *>(unq_ptr.get()) : nullptr;
|
||||||
return pybindit::memory::smart_holder::from_unique_ptr(std::move(unq_ptr), void_ptr);
|
return smart_holder::from_unique_ptr(std::move(unq_ptr), void_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
pybindit::memory::smart_holder smart_holder_from_shared_ptr(std::shared_ptr<T> shd_ptr) {
|
smart_holder smart_holder_from_shared_ptr(std::shared_ptr<T> shd_ptr) {
|
||||||
return pybindit::memory::smart_holder::from_shared_ptr(shd_ptr);
|
return smart_holder::from_shared_ptr(shd_ptr);
|
||||||
}
|
}
|
||||||
} // namespace originally_smart_holder_type_casters_h
|
} // namespace originally_smart_holder_type_casters_h
|
||||||
|
|
||||||
template <
|
template <typename Class,
|
||||||
typename Class,
|
typename D = std::default_delete<Cpp<Class>>,
|
||||||
typename D = std::default_delete<Cpp<Class>>,
|
detail::enable_if_t<std::is_same<Holder<Class>, smart_holder>::value, int> = 0>
|
||||||
detail::enable_if_t<std::is_same<Holder<Class>, pybindit::memory::smart_holder>::value, int>
|
|
||||||
= 0>
|
|
||||||
void construct(value_and_holder &v_h, std::unique_ptr<Cpp<Class>, D> &&unq_ptr, bool need_alias) {
|
void construct(value_and_holder &v_h, std::unique_ptr<Cpp<Class>, D> &&unq_ptr, bool need_alias) {
|
||||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
||||||
auto *ptr = unq_ptr.get();
|
auto *ptr = unq_ptr.get();
|
||||||
@ -239,11 +235,9 @@ void construct(value_and_holder &v_h, std::unique_ptr<Cpp<Class>, D> &&unq_ptr,
|
|||||||
v_h.type->init_instance(v_h.inst, &smhldr);
|
v_h.type->init_instance(v_h.inst, &smhldr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template <typename Class,
|
||||||
typename Class,
|
typename D = std::default_delete<Alias<Class>>,
|
||||||
typename D = std::default_delete<Alias<Class>>,
|
detail::enable_if_t<std::is_same<Holder<Class>, smart_holder>::value, int> = 0>
|
||||||
detail::enable_if_t<std::is_same<Holder<Class>, pybindit::memory::smart_holder>::value, int>
|
|
||||||
= 0>
|
|
||||||
void construct(value_and_holder &v_h,
|
void construct(value_and_holder &v_h,
|
||||||
std::unique_ptr<Alias<Class>, D> &&unq_ptr,
|
std::unique_ptr<Alias<Class>, D> &&unq_ptr,
|
||||||
bool /*need_alias*/) {
|
bool /*need_alias*/) {
|
||||||
@ -255,10 +249,8 @@ void construct(value_and_holder &v_h,
|
|||||||
v_h.type->init_instance(v_h.inst, &smhldr);
|
v_h.type->init_instance(v_h.inst, &smhldr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template <typename Class,
|
||||||
typename Class,
|
detail::enable_if_t<std::is_same<Holder<Class>, smart_holder>::value, int> = 0>
|
||||||
detail::enable_if_t<std::is_same<Holder<Class>, pybindit::memory::smart_holder>::value, int>
|
|
||||||
= 0>
|
|
||||||
void construct(value_and_holder &v_h, std::shared_ptr<Cpp<Class>> &&shd_ptr, bool need_alias) {
|
void construct(value_and_holder &v_h, std::shared_ptr<Cpp<Class>> &&shd_ptr, bool need_alias) {
|
||||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
||||||
auto *ptr = shd_ptr.get();
|
auto *ptr = shd_ptr.get();
|
||||||
@ -272,10 +264,8 @@ void construct(value_and_holder &v_h, std::shared_ptr<Cpp<Class>> &&shd_ptr, boo
|
|||||||
v_h.type->init_instance(v_h.inst, &smhldr);
|
v_h.type->init_instance(v_h.inst, &smhldr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template <typename Class,
|
||||||
typename Class,
|
detail::enable_if_t<std::is_same<Holder<Class>, smart_holder>::value, int> = 0>
|
||||||
detail::enable_if_t<std::is_same<Holder<Class>, pybindit::memory::smart_holder>::value, int>
|
|
||||||
= 0>
|
|
||||||
void construct(value_and_holder &v_h,
|
void construct(value_and_holder &v_h,
|
||||||
std::shared_ptr<Alias<Class>> &&shd_ptr,
|
std::shared_ptr<Alias<Class>> &&shd_ptr,
|
||||||
bool /*need_alias*/) {
|
bool /*need_alias*/) {
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
#include "descr.h"
|
#include "descr.h"
|
||||||
#include "dynamic_raw_ptr_cast_if_possible.h"
|
#include "dynamic_raw_ptr_cast_if_possible.h"
|
||||||
#include "internals.h"
|
#include "internals.h"
|
||||||
#include "smart_holder_poc.h"
|
|
||||||
#include "typeid.h"
|
#include "typeid.h"
|
||||||
|
#include "using_smart_holder.h"
|
||||||
#include "value_and_holder.h"
|
#include "value_and_holder.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -484,9 +484,7 @@ struct value_and_holder_helper {
|
|||||||
return loaded_v_h.vh != nullptr && loaded_v_h.holder_constructed();
|
return loaded_v_h.vh != nullptr && loaded_v_h.holder_constructed();
|
||||||
}
|
}
|
||||||
|
|
||||||
pybindit::memory::smart_holder &holder() const {
|
smart_holder &holder() const { return loaded_v_h.holder<smart_holder>(); }
|
||||||
return loaded_v_h.holder<pybindit::memory::smart_holder>();
|
|
||||||
}
|
|
||||||
|
|
||||||
void throw_if_uninitialized_or_disowned_holder(const char *typeid_name) const {
|
void throw_if_uninitialized_or_disowned_holder(const char *typeid_name) const {
|
||||||
static const std::string missing_value_msg = "Missing value for wrapped C++ type `";
|
static const std::string missing_value_msg = "Missing value for wrapped C++ type `";
|
||||||
@ -548,7 +546,7 @@ handle smart_holder_from_unique_ptr(std::unique_ptr<T, D> &&src,
|
|||||||
if (self_life_support != nullptr) {
|
if (self_life_support != nullptr) {
|
||||||
value_and_holder &v_h = self_life_support->v_h;
|
value_and_holder &v_h = self_life_support->v_h;
|
||||||
if (v_h.inst != nullptr && v_h.vh != nullptr) {
|
if (v_h.inst != nullptr && v_h.vh != nullptr) {
|
||||||
auto &holder = v_h.holder<pybindit::memory::smart_holder>();
|
auto &holder = v_h.holder<smart_holder>();
|
||||||
if (!holder.is_disowned) {
|
if (!holder.is_disowned) {
|
||||||
pybind11_fail("smart_holder_from_unique_ptr: unexpected "
|
pybind11_fail("smart_holder_from_unique_ptr: unexpected "
|
||||||
"smart_holder.is_disowned failure.");
|
"smart_holder.is_disowned failure.");
|
||||||
@ -576,8 +574,7 @@ handle smart_holder_from_unique_ptr(std::unique_ptr<T, D> &&src,
|
|||||||
// SMART_HOLDER_WIP: IMPROVABLE: Is there a better solution?
|
// SMART_HOLDER_WIP: IMPROVABLE: Is there a better solution?
|
||||||
src_raw_void_ptr = nullptr;
|
src_raw_void_ptr = nullptr;
|
||||||
}
|
}
|
||||||
auto smhldr
|
auto smhldr = smart_holder::from_unique_ptr(std::move(src), src_raw_void_ptr);
|
||||||
= pybindit::memory::smart_holder::from_unique_ptr(std::move(src), src_raw_void_ptr);
|
|
||||||
tinfo->init_instance(inst_raw_ptr, static_cast<const void *>(&smhldr));
|
tinfo->init_instance(inst_raw_ptr, static_cast<const void *>(&smhldr));
|
||||||
|
|
||||||
if (policy == return_value_policy::reference_internal) {
|
if (policy == return_value_policy::reference_internal) {
|
||||||
@ -639,8 +636,8 @@ handle smart_holder_from_shared_ptr(const std::shared_ptr<T> &src,
|
|||||||
void *&valueptr = values_and_holders(inst_raw_ptr).begin()->value_ptr();
|
void *&valueptr = values_and_holders(inst_raw_ptr).begin()->value_ptr();
|
||||||
valueptr = src_raw_void_ptr;
|
valueptr = src_raw_void_ptr;
|
||||||
|
|
||||||
auto smhldr = pybindit::memory::smart_holder::from_shared_ptr(
|
auto smhldr
|
||||||
std::shared_ptr<void>(src, const_cast<void *>(st.first)));
|
= smart_holder::from_shared_ptr(std::shared_ptr<void>(src, const_cast<void *>(st.first)));
|
||||||
tinfo->init_instance(inst_raw_ptr, static_cast<const void *>(&smhldr));
|
tinfo->init_instance(inst_raw_ptr, static_cast<const void *>(&smhldr));
|
||||||
|
|
||||||
if (policy == return_value_policy::reference_internal) {
|
if (policy == return_value_policy::reference_internal) {
|
||||||
@ -710,7 +707,7 @@ inline std::unique_ptr<T, D> unique_with_deleter(T *raw_ptr, std::unique_ptr<D>
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct load_helper : value_and_holder_helper {
|
struct load_helper : value_and_holder_helper {
|
||||||
using holder_type = pybindit::memory::smart_holder;
|
using holder_type = smart_holder;
|
||||||
|
|
||||||
static std::shared_ptr<T> make_shared_ptr_with_responsible_parent(T *raw_ptr, handle parent) {
|
static std::shared_ptr<T> make_shared_ptr_with_responsible_parent(T *raw_ptr, handle parent) {
|
||||||
return std::shared_ptr<T>(raw_ptr, shared_ptr_parent_life_support(parent.ptr()));
|
return std::shared_ptr<T>(raw_ptr, shared_ptr_parent_life_support(parent.ptr()));
|
||||||
|
14
include/pybind11/detail/using_smart_holder.h
Normal file
14
include/pybind11/detail/using_smart_holder.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// Copyright (c) 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 "common.h"
|
||||||
|
#include "smart_holder_poc.h"
|
||||||
|
|
||||||
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||||
|
|
||||||
|
using pybindit::memory::smart_holder;
|
||||||
|
|
||||||
|
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
@ -13,7 +13,7 @@
|
|||||||
#include "detail/class.h"
|
#include "detail/class.h"
|
||||||
#include "detail/dynamic_raw_ptr_cast_if_possible.h"
|
#include "detail/dynamic_raw_ptr_cast_if_possible.h"
|
||||||
#include "detail/init.h"
|
#include "detail/init.h"
|
||||||
#include "detail/smart_holder_poc.h"
|
#include "detail/using_smart_holder.h"
|
||||||
#include "attr.h"
|
#include "attr.h"
|
||||||
#include "gil.h"
|
#include "gil.h"
|
||||||
#include "gil_safe_call_once.h"
|
#include "gil_safe_call_once.h"
|
||||||
@ -1800,7 +1800,7 @@ struct property_cpp_function<
|
|||||||
#ifdef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
|
#ifdef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
|
||||||
// BAKEIN_WIP: Add comment to explain: This is meant for stress-testing only.
|
// BAKEIN_WIP: Add comment to explain: This is meant for stress-testing only.
|
||||||
template <typename>
|
template <typename>
|
||||||
using default_holder_type = pybindit::memory::smart_holder;
|
using default_holder_type = smart_holder;
|
||||||
#else
|
#else
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using default_holder_type = std::unique_ptr<T>;
|
using default_holder_type = std::unique_ptr<T>;
|
||||||
@ -1863,7 +1863,7 @@ public:
|
|||||||
record.holder_enum_v = detail::holder_enum_t::std_unique_ptr;
|
record.holder_enum_v = detail::holder_enum_t::std_unique_ptr;
|
||||||
} else if (detail::is_instantiation<std::shared_ptr, holder_type>::value) {
|
} else if (detail::is_instantiation<std::shared_ptr, holder_type>::value) {
|
||||||
record.holder_enum_v = detail::holder_enum_t::std_shared_ptr;
|
record.holder_enum_v = detail::holder_enum_t::std_shared_ptr;
|
||||||
} else if (std::is_same<holder_type, pybindit::memory::smart_holder>::value) {
|
} else if (std::is_same<holder_type, smart_holder>::value) {
|
||||||
record.holder_enum_v = detail::holder_enum_t::smart_holder;
|
record.holder_enum_v = detail::holder_enum_t::smart_holder;
|
||||||
} else {
|
} else {
|
||||||
record.holder_enum_v = detail::holder_enum_t::custom_holder;
|
record.holder_enum_v = detail::holder_enum_t::custom_holder;
|
||||||
@ -2193,8 +2193,7 @@ private:
|
|||||||
/// an optional pointer to an existing holder to use; if not specified and the instance is
|
/// an optional pointer to an existing holder to use; if not specified and the instance is
|
||||||
/// `.owned`, a new holder will be constructed to manage the value pointer.
|
/// `.owned`, a new holder will be constructed to manage the value pointer.
|
||||||
template <typename H = holder_type,
|
template <typename H = holder_type,
|
||||||
detail::enable_if_t<!std::is_same<H, pybindit::memory::smart_holder>::value, int>
|
detail::enable_if_t<!std::is_same<H, smart_holder>::value, int> = 0>
|
||||||
= 0>
|
|
||||||
static void init_instance(detail::instance *inst, const void *holder_ptr) {
|
static void init_instance(detail::instance *inst, const void *holder_ptr) {
|
||||||
auto v_h = inst->get_value_and_holder(detail::get_type_info(typeid(type)));
|
auto v_h = inst->get_value_and_holder(detail::get_type_info(typeid(type)));
|
||||||
if (!v_h.instance_registered()) {
|
if (!v_h.instance_registered()) {
|
||||||
@ -2230,7 +2229,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename H = holder_type,
|
template <typename H = holder_type,
|
||||||
detail::enable_if_t<std::is_same<H, pybindit::memory::smart_holder>::value, int> = 0>
|
detail::enable_if_t<std::is_same<H, smart_holder>::value, int> = 0>
|
||||||
static void init_instance(detail::instance *inst, const void *holder_const_void_ptr) {
|
static void init_instance(detail::instance *inst, const void *holder_const_void_ptr) {
|
||||||
// Need for const_cast is a consequence of the type_info::init_instance type:
|
// Need for const_cast is a consequence of the type_info::init_instance type:
|
||||||
// void (*init_instance)(instance *, const void *);
|
// void (*init_instance)(instance *, const void *);
|
||||||
|
@ -16,9 +16,9 @@ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
|||||||
// Supports easier switching between py::class_<T> and py::class_<T, py::smart_holder>:
|
// Supports easier switching between py::class_<T> and py::class_<T, py::smart_holder>:
|
||||||
// users can simply replace the `_` in `class_` with `h` or vice versa.
|
// users can simply replace the `_` in `class_` with `h` or vice versa.
|
||||||
template <typename type_, typename... options>
|
template <typename type_, typename... options>
|
||||||
class classh : public class_<type_, pybindit::memory::smart_holder, options...> {
|
class classh : public class_<type_, smart_holder, options...> {
|
||||||
public:
|
public:
|
||||||
using class_<type_, pybindit::memory::smart_holder, options...>::class_;
|
using class_<type_, smart_holder, options...>::class_;
|
||||||
};
|
};
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "detail/common.h"
|
#include "detail/common.h"
|
||||||
#include "detail/smart_holder_poc.h"
|
#include "detail/using_smart_holder.h"
|
||||||
#include "detail/value_and_holder.h"
|
#include "detail/value_and_holder.h"
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||||
@ -40,7 +40,7 @@ struct trampoline_self_life_support {
|
|||||||
if (value_void_ptr != nullptr) {
|
if (value_void_ptr != nullptr) {
|
||||||
PyGILState_STATE threadstate = PyGILState_Ensure();
|
PyGILState_STATE threadstate = PyGILState_Ensure();
|
||||||
v_h.value_ptr() = nullptr;
|
v_h.value_ptr() = nullptr;
|
||||||
v_h.holder<pybindit::memory::smart_holder>().release_disowned();
|
v_h.holder<smart_holder>().release_disowned();
|
||||||
detail::deregister_instance(v_h.inst, value_void_ptr, v_h.type);
|
detail::deregister_instance(v_h.inst, value_void_ptr, v_h.type);
|
||||||
Py_DECREF((PyObject *) v_h.inst); // Must be after deregister.
|
Py_DECREF((PyObject *) v_h.inst); // Must be after deregister.
|
||||||
PyGILState_Release(threadstate);
|
PyGILState_Release(threadstate);
|
||||||
|
@ -62,6 +62,7 @@ detail_headers = {
|
|||||||
"include/pybind11/detail/smart_holder_poc.h",
|
"include/pybind11/detail/smart_holder_poc.h",
|
||||||
"include/pybind11/detail/type_caster_base.h",
|
"include/pybind11/detail/type_caster_base.h",
|
||||||
"include/pybind11/detail/typeid.h",
|
"include/pybind11/detail/typeid.h",
|
||||||
|
"include/pybind11/detail/using_smart_holder.h",
|
||||||
"include/pybind11/detail/value_and_holder.h",
|
"include/pybind11/detail/value_and_holder.h",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,8 +608,7 @@ CHECK_NOALIAS(8);
|
|||||||
std::TYPE##_ptr<BreaksBase<(N)>>>::value, \
|
std::TYPE##_ptr<BreaksBase<(N)>>>::value, \
|
||||||
"DoesntBreak" #N " has wrong holder_type!")
|
"DoesntBreak" #N " has wrong holder_type!")
|
||||||
#define CHECK_SMART_HOLDER(N) \
|
#define CHECK_SMART_HOLDER(N) \
|
||||||
static_assert(std::is_same<typename DoesntBreak##N::holder_type, \
|
static_assert(std::is_same<typename DoesntBreak##N::holder_type, py::smart_holder>::value, \
|
||||||
pybindit::memory::smart_holder>::value, \
|
|
||||||
"DoesntBreak" #N " has wrong holder_type!")
|
"DoesntBreak" #N " has wrong holder_type!")
|
||||||
CHECK_HOLDER(1, unique);
|
CHECK_HOLDER(1, unique);
|
||||||
CHECK_HOLDER(2, unique);
|
CHECK_HOLDER(2, unique);
|
||||||
|
Loading…
Reference in New Issue
Block a user