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
include/pybind11/detail/descr.h
include/pybind11/detail/init.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_type_casters_inline_include.h
include/pybind11/detail/typeid.h
include/pybind11/attr.h
include/pybind11/buffer_info.h
......
......@@ -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));
}
//DETAIL/SMART_HOLDER_INIT_H/BEGIN/////////////////////////////////////////////////////////////////
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);
}
//DETAIL/SMART_HOLDER_INIT_H/END///////////////////////////////////////////////////////////////////
// SMART_HOLDER_WIP: Needs refactoring of existing pybind11 code.
#define PYBIND11_DETAIL_INIT_H_SMART_HOLDER_INIT_INLINE_INCLUDE_SAFETY_GUARD
#include "smart_holder_init_inline_include.h"
#undef PYBIND11_DETAIL_INIT_H_SMART_HOLDER_INIT_INLINE_INCLUDE_SAFETY_GUARD
// Implementing class for py::init<...>()
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
binding generator library
......@@ -1240,22 +1241,26 @@ auto method_adaptor(Return (Class::*pmf)(Args...) const) -> Return (Derived::*)(
return pmf;
}
// clang-format on
template <typename T>
#ifndef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
using default_holder_type = std::unique_ptr<T>;
#else
using default_holder_type = smart_holder;
#endif
// clang-format off
template <typename type_, typename... options>
class class_ : public detail::generic_type {
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>
// clang-format on
using is_holder = detail::any_of<detail::is_holder_type<type_, T>,
detail::all_of<detail::negation<is_base<T>>,
detail::negation<is_subtype<T>>,
detail::is_smart_holder_type_caster<type_>>>;
// clang-format off
// struct instead of using here to help MSVC:
template <typename T> struct is_valid_class_option :
detail::any_of<is_holder<T>, is_subtype<T>, is_base<T>> {};
......@@ -1286,16 +1291,22 @@ public:
none_of<std::is_same<multiple_inheritance, Extra>...>::value), // no multiple_inheritance attr
"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;
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;
// clang-format on
static constexpr bool holder_is_smart_holder
= 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.
static_assert(!(detail::is_instantiation<std::unique_ptr, holder_type>::value &&
type_caster_type_is_smart_holder_type_caster),
static_assert(
!(detail::is_instantiation<std::unique_ptr, holder_type>::value
&& type_caster_type_is_smart_holder_type_caster),
"py::class_ holder vs type_caster mismatch:"
" missing PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(T, std::unique_ptr<T>)?");
static_assert(!(detail::is_instantiation<std::shared_ptr, holder_type>::value &&
type_caster_type_is_smart_holder_type_caster),
static_assert(
!(detail::is_instantiation<std::shared_ptr, holder_type>::value
&& type_caster_type_is_smart_holder_type_caster),
"py::class_ holder vs type_caster mismatch:"
" 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),
......@@ -1312,6 +1323,7 @@ public:
" missing PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(T, ...)"
" or collision with custom py::detail::type_caster<T>?");
#endif
// clang-format off
type_record record;
record.scope = scope;
record.name = name;
......@@ -1322,7 +1334,7 @@ public:
record.init_instance = init_instance;
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;
set_operator_new<type>(&record);
......@@ -1541,19 +1553,19 @@ public:
}
private:
template <
typename T = type,
// clang-format on
template <typename T = type,
detail::enable_if_t<!detail::is_smart_holder_type_caster<T>::value, int> = 0>
void generic_type_initialize(const detail::type_record &record) {
generic_type::initialize(record, &detail::type_caster_generic::local_load);
}
template <
typename T = type,
template <typename T = type,
detail::enable_if_t<detail::is_smart_holder_type_caster<T>::value, int> = 0>
void generic_type_initialize(const detail::type_record &record) {
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
template <typename T>
......@@ -1611,12 +1623,13 @@ private:
init_holder(inst, v_h, (const holder_type *) holder_ptr, v_h.value_ptr<type>());
}
template <
typename T = type,
// clang-format on
template <typename T = type,
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) {
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.
static void dealloc(detail::value_and_holder &v_h) {
......
......@@ -42,7 +42,9 @@ detail_headers = {
"include/pybind11/detail/descr.h",
"include/pybind11/detail/init.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_type_casters_inline_include.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