Commit d3b2d567 by Ralf W. Grosse-Kunstleve

Merge branch 'test_unique_ptr_member' into pr2672_use_smart_holder_as_default

parents dc10e8a9 6005632b
...@@ -105,7 +105,9 @@ set(PYBIND11_HEADERS ...@@ -105,7 +105,9 @@ set(PYBIND11_HEADERS
include/pybind11/detail/descr.h include/pybind11/detail/descr.h
include/pybind11/detail/init.h include/pybind11/detail/init.h
include/pybind11/detail/internals.h include/pybind11/detail/internals.h
include/pybind11/detail/smart_holder_init_inline_include.h
include/pybind11/detail/smart_holder_poc.h include/pybind11/detail/smart_holder_poc.h
include/pybind11/detail/smart_holder_type_casters_inline_include.h
include/pybind11/detail/typeid.h include/pybind11/detail/typeid.h
include/pybind11/attr.h include/pybind11/attr.h
include/pybind11/buffer_info.h include/pybind11/buffer_info.h
......
...@@ -169,55 +169,10 @@ void construct(value_and_holder &v_h, Alias<Class> &&result, bool) { ...@@ -169,55 +169,10 @@ void construct(value_and_holder &v_h, Alias<Class> &&result, bool) {
v_h.value_ptr() = new Alias<Class>(std::move(result)); v_h.value_ptr() = new Alias<Class>(std::move(result));
} }
//DETAIL/SMART_HOLDER_INIT_H/BEGIN///////////////////////////////////////////////////////////////// // SMART_HOLDER_WIP: Needs refactoring of existing pybind11 code.
#define PYBIND11_DETAIL_INIT_H_SMART_HOLDER_INIT_INLINE_INCLUDE_SAFETY_GUARD
template <typename Class, typename D = std::default_delete<Cpp<Class>>, #include "smart_holder_init_inline_include.h"
detail::enable_if_t<detail::is_smart_holder_type_caster<Cpp<Class>>::value, int> = 0> #undef PYBIND11_DETAIL_INIT_H_SMART_HOLDER_INIT_INLINE_INCLUDE_SAFETY_GUARD
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 = 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::is_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 = 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::is_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 = smart_holder::from_shared_ptr(std::move(shd_ptr));
v_h.value_ptr() = ptr;
v_h.type->init_instance(v_h.inst, &smhldr);
}
template <typename Class,
detail::enable_if_t<detail::is_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 = smart_holder::from_shared_ptr(std::move(shd_ptr));
v_h.value_ptr() = ptr;
v_h.type->init_instance(v_h.inst, &smhldr);
}
//DETAIL/SMART_HOLDER_INIT_H/END///////////////////////////////////////////////////////////////////
// Implementing class for py::init<...>() // Implementing class for py::init<...>()
template <typename... Args> template <typename... Args>
......
#ifndef PYBIND11_DETAIL_INIT_H_SMART_HOLDER_INIT_INLINE_INCLUDE_SAFETY_GUARD
# error "THIS FILE MUST ONLY BE INCLUDED FROM pybind11/detail/init.h"
#endif
template <typename Class,
typename D = std::default_delete<Cpp<Class>>,
detail::enable_if_t<detail::is_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 = 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::is_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 = 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::is_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 = smart_holder::from_shared_ptr(std::move(shd_ptr));
v_h.value_ptr() = ptr;
v_h.type->init_instance(v_h.inst, &smhldr);
}
template <typename Class,
detail::enable_if_t<detail::is_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 = smart_holder::from_shared_ptr(std::move(shd_ptr));
v_h.value_ptr() = ptr;
v_h.type->init_instance(v_h.inst, &smhldr);
}
// clang-format off
/* /*
pybind11/pybind11.h: Main header file of the C++11 python pybind11/pybind11.h: Main header file of the C++11 python
binding generator library binding generator library
...@@ -1240,22 +1241,26 @@ auto method_adaptor(Return (Class::*pmf)(Args...) const) -> Return (Derived::*)( ...@@ -1240,22 +1241,26 @@ auto method_adaptor(Return (Class::*pmf)(Args...) const) -> Return (Derived::*)(
return pmf; return pmf;
} }
// clang-format on
template <typename T> template <typename T>
#ifndef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT #ifndef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
using default_holder_type = std::unique_ptr<T>; using default_holder_type = std::unique_ptr<T>;
#else #else
using default_holder_type = smart_holder; using default_holder_type = smart_holder;
#endif #endif
// clang-format off
template <typename type_, typename... options> template <typename type_, typename... options>
class class_ : public detail::generic_type { class class_ : public detail::generic_type {
template <typename T> using is_subtype = detail::is_strict_base_of<type_, T>; template <typename T> using is_subtype = detail::is_strict_base_of<type_, T>;
template <typename T> using is_base = detail::is_strict_base_of<T, type_>; template <typename T> using is_base = detail::is_strict_base_of<T, type_>;
template <typename T> template <typename T>
// clang-format on
using is_holder = detail::any_of<detail::is_holder_type<type_, T>, using is_holder = detail::any_of<detail::is_holder_type<type_, T>,
detail::all_of<detail::negation<is_base<T>>, detail::all_of<detail::negation<is_base<T>>,
detail::negation<is_subtype<T>>, detail::negation<is_subtype<T>>,
detail::is_smart_holder_type_caster<type_>>>; detail::is_smart_holder_type_caster<type_>>>;
// clang-format off
// struct instead of using here to help MSVC: // struct instead of using here to help MSVC:
template <typename T> struct is_valid_class_option : template <typename T> struct is_valid_class_option :
detail::any_of<is_holder<T>, is_subtype<T>, is_base<T>> {}; detail::any_of<is_holder<T>, is_subtype<T>, is_base<T>> {};
...@@ -1286,16 +1291,22 @@ public: ...@@ -1286,16 +1291,22 @@ public:
none_of<std::is_same<multiple_inheritance, Extra>...>::value), // no multiple_inheritance attr none_of<std::is_same<multiple_inheritance, Extra>...>::value), // no multiple_inheritance attr
"Error: multiple inheritance bases must be specified via class_ template options"); "Error: multiple inheritance bases must be specified via class_ template options");
static constexpr bool holder_is_smart_holder = std::is_same<holder_type, smart_holder>::value; // clang-format on
static constexpr bool type_caster_type_is_smart_holder_type_caster = detail::is_smart_holder_type_caster<type>::value; static constexpr bool holder_is_smart_holder
static constexpr bool type_caster_type_is_type_caster_base_subtype = std::is_base_of<detail::type_caster_base<type>, detail::type_caster<type>>::value; = std::is_same<holder_type, smart_holder>::value;
static constexpr bool type_caster_type_is_smart_holder_type_caster
= detail::is_smart_holder_type_caster<type>::value;
static constexpr bool type_caster_type_is_type_caster_base_subtype
= std::is_base_of<detail::type_caster_base<type>, detail::type_caster<type>>::value;
// Necessary conditions, but not strict. // Necessary conditions, but not strict.
static_assert(!(detail::is_instantiation<std::unique_ptr, holder_type>::value && static_assert(
type_caster_type_is_smart_holder_type_caster), !(detail::is_instantiation<std::unique_ptr, holder_type>::value
&& type_caster_type_is_smart_holder_type_caster),
"py::class_ holder vs type_caster mismatch:" "py::class_ holder vs type_caster mismatch:"
" missing PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(T, std::unique_ptr<T>)?"); " missing PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(T, std::unique_ptr<T>)?");
static_assert(!(detail::is_instantiation<std::shared_ptr, holder_type>::value && static_assert(
type_caster_type_is_smart_holder_type_caster), !(detail::is_instantiation<std::shared_ptr, holder_type>::value
&& type_caster_type_is_smart_holder_type_caster),
"py::class_ holder vs type_caster mismatch:" "py::class_ holder vs type_caster mismatch:"
" missing PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(T, std::shared_ptr<T>)?"); " missing PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(T, std::shared_ptr<T>)?");
static_assert(!(holder_is_smart_holder && type_caster_type_is_type_caster_base_subtype), static_assert(!(holder_is_smart_holder && type_caster_type_is_type_caster_base_subtype),
...@@ -1312,6 +1323,7 @@ public: ...@@ -1312,6 +1323,7 @@ public:
" missing PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(T, ...)" " missing PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(T, ...)"
" or collision with custom py::detail::type_caster<T>?"); " or collision with custom py::detail::type_caster<T>?");
#endif #endif
// clang-format off
type_record record; type_record record;
record.scope = scope; record.scope = scope;
record.name = name; record.name = name;
...@@ -1322,7 +1334,7 @@ public: ...@@ -1322,7 +1334,7 @@ public:
record.init_instance = init_instance; record.init_instance = init_instance;
record.dealloc = dealloc; record.dealloc = dealloc;
// A better name would be uses_unique_ptr_holder. // A more fitting name would be uses_unique_ptr_holder.
record.default_holder = detail::is_instantiation<std::unique_ptr, holder_type>::value; record.default_holder = detail::is_instantiation<std::unique_ptr, holder_type>::value;
set_operator_new<type>(&record); set_operator_new<type>(&record);
...@@ -1541,19 +1553,19 @@ public: ...@@ -1541,19 +1553,19 @@ public:
} }
private: private:
template < // clang-format on
typename T = type, template <typename T = type,
detail::enable_if_t<!detail::is_smart_holder_type_caster<T>::value, int> = 0> detail::enable_if_t<!detail::is_smart_holder_type_caster<T>::value, int> = 0>
void generic_type_initialize(const detail::type_record &record) { void generic_type_initialize(const detail::type_record &record) {
generic_type::initialize(record, &detail::type_caster_generic::local_load); generic_type::initialize(record, &detail::type_caster_generic::local_load);
} }
template < template <typename T = type,
typename T = type,
detail::enable_if_t<detail::is_smart_holder_type_caster<T>::value, int> = 0> detail::enable_if_t<detail::is_smart_holder_type_caster<T>::value, int> = 0>
void generic_type_initialize(const detail::type_record &record) { void generic_type_initialize(const detail::type_record &record) {
generic_type::initialize(record, detail::type_caster<T>::get_local_load_function_ptr()); generic_type::initialize(record, detail::type_caster<T>::get_local_load_function_ptr());
} }
// clang-format off
/// Initialize holder object, variant 1: object derives from enable_shared_from_this /// Initialize holder object, variant 1: object derives from enable_shared_from_this
template <typename T> template <typename T>
...@@ -1611,12 +1623,13 @@ private: ...@@ -1611,12 +1623,13 @@ private:
init_holder(inst, v_h, (const holder_type *) holder_ptr, v_h.value_ptr<type>()); init_holder(inst, v_h, (const holder_type *) holder_ptr, v_h.value_ptr<type>());
} }
template < // clang-format on
typename T = type, template <typename T = type,
detail::enable_if_t<detail::is_smart_holder_type_caster<T>::value, int> = 0> detail::enable_if_t<detail::is_smart_holder_type_caster<T>::value, int> = 0>
static void init_instance(detail::instance *inst, const void *holder_ptr) { static void init_instance(detail::instance *inst, const void *holder_ptr) {
detail::type_caster<T>::template init_instance_for_type<type>(inst, holder_ptr); detail::type_caster<T>::template init_instance_for_type<type>(inst, holder_ptr);
} }
// clang-format off
/// Deallocates an instance; via holder, if constructed; otherwise via operator delete. /// Deallocates an instance; via holder, if constructed; otherwise via operator delete.
static void dealloc(detail::value_and_holder &v_h) { static void dealloc(detail::value_and_holder &v_h) {
......
...@@ -42,7 +42,9 @@ detail_headers = { ...@@ -42,7 +42,9 @@ detail_headers = {
"include/pybind11/detail/descr.h", "include/pybind11/detail/descr.h",
"include/pybind11/detail/init.h", "include/pybind11/detail/init.h",
"include/pybind11/detail/internals.h", "include/pybind11/detail/internals.h",
"include/pybind11/detail/smart_holder_init_inline_include.h",
"include/pybind11/detail/smart_holder_poc.h", "include/pybind11/detail/smart_holder_poc.h",
"include/pybind11/detail/smart_holder_type_casters_inline_include.h",
"include/pybind11/detail/typeid.h", "include/pybind11/detail/typeid.h",
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment