Adding remaining PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS. static_assert for…

Adding remaining PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS. static_assert for "necessary conditions" for both types of default holder, static_assert for "strict conditions" guarded by new PYBIND11_STRICT_ASSERTS_CLASS_HOLDER_VS_TYPE_CASTER_MIX. All tests build & run as before with unique_ptr as the default holder, all tests build for smart_holder as the default holder, even with the strict static_assert.
parent 093e0f45
......@@ -1286,6 +1286,18 @@ 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;
// 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::shared_ptr, holder_type>::value && type_caster_type_is_smart_holder_type_caster));
static_assert(!(holder_is_smart_holder && type_caster_type_is_type_caster_base_subtype));
#ifdef PYBIND11_STRICT_ASSERTS_CLASS_HOLDER_VS_TYPE_CASTER_MIX
// Strict conditions cannot be enforced universally at the moment (PR #2836).
static_assert(holder_is_smart_holder == type_caster_type_is_smart_holder_type_caster);
static_assert(!holder_is_smart_holder == type_caster_type_is_type_caster_base_subtype);
#endif
type_record record;
record.scope = scope;
record.name = name;
......@@ -1298,15 +1310,7 @@ public:
#ifndef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
record.default_holder = detail::is_instantiation<std::unique_ptr, holder_type>::value;
#else
static constexpr bool holder_is_smart_holder = std::is_same<holder_type, smart_holder>::value;
record.default_holder = holder_is_smart_holder;
#if 0
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;
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::shared_ptr, holder_type>::value && type_caster_type_is_smart_holder_type_caster));
static_assert(!(holder_is_smart_holder && type_caster_type_is_type_caster_base_subtype));
#endif
#endif
set_operator_new<type>(&record);
......
......@@ -139,6 +139,11 @@ public:
static std::shared_ptr<TestFactory3> construct3(int a) { return std::shared_ptr<TestFactory3>(new TestFactory3(a)); }
};
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(TestFactory3, std::shared_ptr<TestFactory3>)
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(TestFactory4, std::shared_ptr<TestFactory4>)
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(TestFactory5, std::shared_ptr<TestFactory5>)
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(TestFactory7, std::shared_ptr<TestFactory7>)
TEST_SUBMODULE(factory_constructors, m) {
// Define various trivial types to allow simpler overload resolution:
......
......@@ -150,6 +150,8 @@ struct RefQualified {
int constRefQualified(int other) const & { return value + other; }
};
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(NoneTester, std::shared_ptr<NoneTester>)
TEST_SUBMODULE(methods_and_attributes, m) {
// test_methods_and_attributes
py::class_<ExampleMandA> emna(m, "ExampleMandA");
......
......@@ -43,6 +43,37 @@ int WithStatic2::static_value2 = 2;
int VanillaStaticMix1::static_value = 12;
int VanillaStaticMix2::static_value = 12;
namespace {
struct Base1a {
Base1a(int i) : i(i) { }
int foo() { return i; }
int i;
};
struct Base2a {
Base2a(int i) : i(i) { }
int bar() { return i; }
int i;
};
struct Base12a : Base1a, Base2a {
Base12a(int i, int j) : Base1a(i), Base2a(j) { }
};
struct I801B1 { int a = 1; I801B1() = default; I801B1(const I801B1 &) = default; virtual ~I801B1() = default; };
struct I801B2 { int b = 2; I801B2() = default; I801B2(const I801B2 &) = default; virtual ~I801B2() = default; };
struct I801C : I801B1, I801B2 {};
struct I801D : I801C {}; // Indirect MI
} // namespace anonymous
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(Base1a, std::shared_ptr<Base1a>)
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(Base2a, std::shared_ptr<Base2a>)
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(Base12a, std::shared_ptr<Base12a>)
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(I801B1, std::shared_ptr<I801B1>)
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(I801B2, std::shared_ptr<I801B2>)
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(I801C, std::shared_ptr<I801C>)
PYBIND11_SMART_POINTER_HOLDER_TYPE_CASTERS(I801D, std::shared_ptr<I801D>)
TEST_SUBMODULE(multiple_inheritance, m) {
// test_multiple_inheritance_mix1
......@@ -99,27 +130,14 @@ TEST_SUBMODULE(multiple_inheritance, m) {
// test_multiple_inheritance_virtbase
// Test the case where not all base classes are specified, and where pybind11 requires the
// py::multiple_inheritance flag to perform proper casting between types.
struct Base1a {
Base1a(int i) : i(i) { }
int foo() { return i; }
int i;
};
py::class_<Base1a, std::shared_ptr<Base1a>>(m, "Base1a")
.def(py::init<int>())
.def("foo", &Base1a::foo);
struct Base2a {
Base2a(int i) : i(i) { }
int bar() { return i; }
int i;
};
py::class_<Base2a, std::shared_ptr<Base2a>>(m, "Base2a")
.def(py::init<int>())
.def("bar", &Base2a::bar);
struct Base12a : Base1a, Base2a {
Base12a(int i, int j) : Base1a(i), Base2a(j) { }
};
py::class_<Base12a, /* Base1 missing */ Base2a,
std::shared_ptr<Base12a>>(m, "Base12a", py::multiple_inheritance())
.def(py::init<int, int>());
......@@ -130,10 +148,6 @@ TEST_SUBMODULE(multiple_inheritance, m) {
// test_mi_unaligned_base
// test_mi_base_return
// Issue #801: invalid casting to derived type with MI bases
struct I801B1 { int a = 1; I801B1() = default; I801B1(const I801B1 &) = default; virtual ~I801B1() = default; };
struct I801B2 { int b = 2; I801B2() = default; I801B2(const I801B2 &) = default; virtual ~I801B2() = default; };
struct I801C : I801B1, I801B2 {};
struct I801D : I801C {}; // Indirect MI
// Unregistered classes:
struct I801B3 { int c = 3; virtual ~I801B3() = default; };
struct I801E : I801B3, I801D {};
......
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