github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/third_path/pybind11/tests/test_class.cpp (about) 1 /* 2 tests/test_class.cpp -- test py::class_ definitions and basic functionality 3 4 Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch> 5 6 All rights reserved. Use of this source code is governed by a 7 BSD-style license that can be found in the LICENSE file. 8 */ 9 10 #if defined(__INTEL_COMPILER) && __cplusplus >= 201703L 11 // Intel compiler requires a separate header file to support aligned new operators 12 // and does not set the __cpp_aligned_new feature macro. 13 // This header needs to be included before pybind11. 14 # include <aligned_new> 15 #endif 16 17 #include <pybind11/stl.h> 18 19 #include "constructor_stats.h" 20 #include "local_bindings.h" 21 #include "pybind11_tests.h" 22 23 #include <utility> 24 25 PYBIND11_WARNING_DISABLE_MSVC(4324) 26 // warning C4324: structure was padded due to alignment specifier 27 28 // test_brace_initialization 29 struct NoBraceInitialization { 30 explicit NoBraceInitialization(std::vector<int> v) : vec{std::move(v)} {} 31 template <typename T> 32 NoBraceInitialization(std::initializer_list<T> l) : vec(l) {} 33 34 std::vector<int> vec; 35 }; 36 37 namespace test_class { 38 namespace pr4220_tripped_over_this { // PR #4227 39 40 template <int> 41 struct SoEmpty {}; 42 43 template <typename T> 44 std::string get_msg(const T &) { 45 return "This is really only meant to exercise successful compilation."; 46 } 47 48 using Empty0 = SoEmpty<0x0>; 49 50 void bind_empty0(py::module_ &m) { 51 py::class_<Empty0>(m, "Empty0").def(py::init<>()).def("get_msg", get_msg<Empty0>); 52 } 53 54 } // namespace pr4220_tripped_over_this 55 } // namespace test_class 56 57 TEST_SUBMODULE(class_, m) { 58 m.def("obj_class_name", [](py::handle obj) { return py::detail::obj_class_name(obj.ptr()); }); 59 60 // test_instance 61 struct NoConstructor { 62 NoConstructor() = default; 63 NoConstructor(const NoConstructor &) = default; 64 NoConstructor(NoConstructor &&) = default; 65 static NoConstructor *new_instance() { 66 auto *ptr = new NoConstructor(); 67 print_created(ptr, "via new_instance"); 68 return ptr; 69 } 70 ~NoConstructor() { print_destroyed(this); } 71 }; 72 struct NoConstructorNew { 73 NoConstructorNew() = default; 74 NoConstructorNew(const NoConstructorNew &) = default; 75 NoConstructorNew(NoConstructorNew &&) = default; 76 static NoConstructorNew *new_instance() { 77 auto *ptr = new NoConstructorNew(); 78 print_created(ptr, "via new_instance"); 79 return ptr; 80 } 81 ~NoConstructorNew() { print_destroyed(this); } 82 }; 83 84 py::class_<NoConstructor>(m, "NoConstructor") 85 .def_static("new_instance", &NoConstructor::new_instance, "Return an instance"); 86 87 py::class_<NoConstructorNew>(m, "NoConstructorNew") 88 .def(py::init([](const NoConstructorNew &self) { return self; })) // Need a NOOP __init__ 89 .def_static("__new__", 90 [](const py::object &) { return NoConstructorNew::new_instance(); }); 91 92 // test_inheritance 93 class Pet { 94 public: 95 Pet(const std::string &name, const std::string &species) 96 : m_name(name), m_species(species) {} 97 std::string name() const { return m_name; } 98 std::string species() const { return m_species; } 99 100 private: 101 std::string m_name; 102 std::string m_species; 103 }; 104 105 class Dog : public Pet { 106 public: 107 explicit Dog(const std::string &name) : Pet(name, "dog") {} 108 std::string bark() const { return "Woof!"; } 109 }; 110 111 class Rabbit : public Pet { 112 public: 113 explicit Rabbit(const std::string &name) : Pet(name, "parrot") {} 114 }; 115 116 class Hamster : public Pet { 117 public: 118 explicit Hamster(const std::string &name) : Pet(name, "rodent") {} 119 }; 120 121 class Chimera : public Pet { 122 Chimera() : Pet("Kimmy", "chimera") {} 123 }; 124 125 py::class_<Pet> pet_class(m, "Pet"); 126 pet_class.def(py::init<std::string, std::string>()) 127 .def("name", &Pet::name) 128 .def("species", &Pet::species); 129 130 /* One way of declaring a subclass relationship: reference parent's class_ object */ 131 py::class_<Dog>(m, "Dog", pet_class).def(py::init<std::string>()); 132 133 /* Another way of declaring a subclass relationship: reference parent's C++ type */ 134 py::class_<Rabbit, Pet>(m, "Rabbit").def(py::init<std::string>()); 135 136 /* And another: list parent in class template arguments */ 137 py::class_<Hamster, Pet>(m, "Hamster").def(py::init<std::string>()); 138 139 /* Constructors are not inherited by default */ 140 py::class_<Chimera, Pet>(m, "Chimera"); 141 142 m.def("pet_name_species", 143 [](const Pet &pet) { return pet.name() + " is a " + pet.species(); }); 144 m.def("dog_bark", [](const Dog &dog) { return dog.bark(); }); 145 146 // test_automatic_upcasting 147 struct BaseClass { 148 BaseClass() = default; 149 BaseClass(const BaseClass &) = default; 150 BaseClass(BaseClass &&) = default; 151 virtual ~BaseClass() = default; 152 }; 153 struct DerivedClass1 : BaseClass {}; 154 struct DerivedClass2 : BaseClass {}; 155 156 py::class_<BaseClass>(m, "BaseClass").def(py::init<>()); 157 py::class_<DerivedClass1>(m, "DerivedClass1").def(py::init<>()); 158 py::class_<DerivedClass2>(m, "DerivedClass2").def(py::init<>()); 159 160 m.def("return_class_1", []() -> BaseClass * { return new DerivedClass1(); }); 161 m.def("return_class_2", []() -> BaseClass * { return new DerivedClass2(); }); 162 m.def("return_class_n", [](int n) -> BaseClass * { 163 if (n == 1) { 164 return new DerivedClass1(); 165 } 166 if (n == 2) { 167 return new DerivedClass2(); 168 } 169 return new BaseClass(); 170 }); 171 m.def("return_none", []() -> BaseClass * { return nullptr; }); 172 173 // test_isinstance 174 m.def("check_instances", [](const py::list &l) { 175 return py::make_tuple(py::isinstance<py::tuple>(l[0]), 176 py::isinstance<py::dict>(l[1]), 177 py::isinstance<Pet>(l[2]), 178 py::isinstance<Pet>(l[3]), 179 py::isinstance<Dog>(l[4]), 180 py::isinstance<Rabbit>(l[5]), 181 py::isinstance<UnregisteredType>(l[6])); 182 }); 183 184 struct Invalid {}; 185 186 // test_type 187 m.def("check_type", [](int category) { 188 // Currently not supported (via a fail at compile time) 189 // See https://github.com/pybind/pybind11/issues/2486 190 // if (category == 2) 191 // return py::type::of<int>(); 192 if (category == 1) { 193 return py::type::of<DerivedClass1>(); 194 } 195 return py::type::of<Invalid>(); 196 }); 197 198 m.def("get_type_of", [](py::object ob) { return py::type::of(std::move(ob)); }); 199 200 m.def("get_type_classic", [](py::handle h) { return h.get_type(); }); 201 202 m.def("as_type", [](const py::object &ob) { return py::type(ob); }); 203 204 // test_mismatched_holder 205 struct MismatchBase1 {}; 206 struct MismatchDerived1 : MismatchBase1 {}; 207 208 struct MismatchBase2 {}; 209 struct MismatchDerived2 : MismatchBase2 {}; 210 211 m.def("mismatched_holder_1", []() { 212 auto mod = py::module_::import("__main__"); 213 py::class_<MismatchBase1, std::shared_ptr<MismatchBase1>>(mod, "MismatchBase1"); 214 py::class_<MismatchDerived1, MismatchBase1>(mod, "MismatchDerived1"); 215 }); 216 m.def("mismatched_holder_2", []() { 217 auto mod = py::module_::import("__main__"); 218 py::class_<MismatchBase2>(mod, "MismatchBase2"); 219 py::class_<MismatchDerived2, std::shared_ptr<MismatchDerived2>, MismatchBase2>( 220 mod, "MismatchDerived2"); 221 }); 222 223 // test_override_static 224 // #511: problem with inheritance + overwritten def_static 225 struct MyBase { 226 static std::unique_ptr<MyBase> make() { return std::unique_ptr<MyBase>(new MyBase()); } 227 }; 228 229 struct MyDerived : MyBase { 230 static std::unique_ptr<MyDerived> make() { 231 return std::unique_ptr<MyDerived>(new MyDerived()); 232 } 233 }; 234 235 py::class_<MyBase>(m, "MyBase").def_static("make", &MyBase::make); 236 237 py::class_<MyDerived, MyBase>(m, "MyDerived") 238 .def_static("make", &MyDerived::make) 239 .def_static("make2", &MyDerived::make); 240 241 // test_implicit_conversion_life_support 242 struct ConvertibleFromUserType { 243 int i; 244 245 explicit ConvertibleFromUserType(UserType u) : i(u.value()) {} 246 }; 247 248 py::class_<ConvertibleFromUserType>(m, "AcceptsUserType").def(py::init<UserType>()); 249 py::implicitly_convertible<UserType, ConvertibleFromUserType>(); 250 251 m.def("implicitly_convert_argument", [](const ConvertibleFromUserType &r) { return r.i; }); 252 m.def("implicitly_convert_variable", [](const py::object &o) { 253 // `o` is `UserType` and `r` is a reference to a temporary created by implicit 254 // conversion. This is valid when called inside a bound function because the temp 255 // object is attached to the same life support system as the arguments. 256 const auto &r = o.cast<const ConvertibleFromUserType &>(); 257 return r.i; 258 }); 259 m.add_object("implicitly_convert_variable_fail", [&] { 260 auto f = [](PyObject *, PyObject *args) -> PyObject * { 261 auto o = py::reinterpret_borrow<py::tuple>(args)[0]; 262 try { // It should fail here because there is no life support. 263 o.cast<const ConvertibleFromUserType &>(); 264 } catch (const py::cast_error &e) { 265 return py::str(e.what()).release().ptr(); 266 } 267 return py::str().release().ptr(); 268 }; 269 270 auto *def = new PyMethodDef{"f", f, METH_VARARGS, nullptr}; 271 py::capsule def_capsule(def, 272 [](void *ptr) { delete reinterpret_cast<PyMethodDef *>(ptr); }); 273 return py::reinterpret_steal<py::object>( 274 PyCFunction_NewEx(def, def_capsule.ptr(), m.ptr())); 275 }()); 276 277 // test_operator_new_delete 278 struct HasOpNewDel { 279 std::uint64_t i; 280 static void *operator new(size_t s) { 281 py::print("A new", s); 282 return ::operator new(s); 283 } 284 static void *operator new(size_t s, void *ptr) { 285 py::print("A placement-new", s); 286 return ptr; 287 } 288 static void operator delete(void *p) { 289 py::print("A delete"); 290 return ::operator delete(p); 291 } 292 }; 293 struct HasOpNewDelSize { 294 std::uint32_t i; 295 static void *operator new(size_t s) { 296 py::print("B new", s); 297 return ::operator new(s); 298 } 299 static void *operator new(size_t s, void *ptr) { 300 py::print("B placement-new", s); 301 return ptr; 302 } 303 static void operator delete(void *p, size_t s) { 304 py::print("B delete", s); 305 return ::operator delete(p); 306 } 307 }; 308 struct AliasedHasOpNewDelSize { 309 std::uint64_t i; 310 static void *operator new(size_t s) { 311 py::print("C new", s); 312 return ::operator new(s); 313 } 314 static void *operator new(size_t s, void *ptr) { 315 py::print("C placement-new", s); 316 return ptr; 317 } 318 static void operator delete(void *p, size_t s) { 319 py::print("C delete", s); 320 return ::operator delete(p); 321 } 322 virtual ~AliasedHasOpNewDelSize() = default; 323 AliasedHasOpNewDelSize() = default; 324 AliasedHasOpNewDelSize(const AliasedHasOpNewDelSize &) = delete; 325 }; 326 struct PyAliasedHasOpNewDelSize : AliasedHasOpNewDelSize { 327 PyAliasedHasOpNewDelSize() = default; 328 explicit PyAliasedHasOpNewDelSize(int) {} 329 std::uint64_t j; 330 }; 331 struct HasOpNewDelBoth { 332 std::uint32_t i[8]; 333 static void *operator new(size_t s) { 334 py::print("D new", s); 335 return ::operator new(s); 336 } 337 static void *operator new(size_t s, void *ptr) { 338 py::print("D placement-new", s); 339 return ptr; 340 } 341 static void operator delete(void *p) { 342 py::print("D delete"); 343 return ::operator delete(p); 344 } 345 static void operator delete(void *p, size_t s) { 346 py::print("D wrong delete", s); 347 return ::operator delete(p); 348 } 349 }; 350 py::class_<HasOpNewDel>(m, "HasOpNewDel").def(py::init<>()); 351 py::class_<HasOpNewDelSize>(m, "HasOpNewDelSize").def(py::init<>()); 352 py::class_<HasOpNewDelBoth>(m, "HasOpNewDelBoth").def(py::init<>()); 353 py::class_<AliasedHasOpNewDelSize, PyAliasedHasOpNewDelSize> aliased(m, 354 "AliasedHasOpNewDelSize"); 355 aliased.def(py::init<>()); 356 aliased.attr("size_noalias") = py::int_(sizeof(AliasedHasOpNewDelSize)); 357 aliased.attr("size_alias") = py::int_(sizeof(PyAliasedHasOpNewDelSize)); 358 359 // This test is actually part of test_local_bindings (test_duplicate_local), but we need a 360 // definition in a different compilation unit within the same module: 361 bind_local<LocalExternal, 17>(m, "LocalExternal", py::module_local()); 362 363 // test_bind_protected_functions 364 class ProtectedA { 365 protected: 366 int foo() const { return value; } 367 368 private: 369 int value = 42; 370 }; 371 372 class PublicistA : public ProtectedA { 373 public: 374 using ProtectedA::foo; 375 }; 376 377 py::class_<ProtectedA>(m, "ProtectedA").def(py::init<>()).def("foo", &PublicistA::foo); 378 379 class ProtectedB { 380 public: 381 virtual ~ProtectedB() = default; 382 ProtectedB() = default; 383 ProtectedB(const ProtectedB &) = delete; 384 385 protected: 386 virtual int foo() const { return value; } 387 virtual void *void_foo() { return static_cast<void *>(&value); } 388 virtual void *get_self() { return static_cast<void *>(this); } 389 390 private: 391 int value = 42; 392 }; 393 394 class TrampolineB : public ProtectedB { 395 public: 396 int foo() const override { PYBIND11_OVERRIDE(int, ProtectedB, foo, ); } 397 void *void_foo() override { PYBIND11_OVERRIDE(void *, ProtectedB, void_foo, ); } 398 void *get_self() override { PYBIND11_OVERRIDE(void *, ProtectedB, get_self, ); } 399 }; 400 401 class PublicistB : public ProtectedB { 402 public: 403 // [workaround(intel)] = default does not work here 404 // Removing or defaulting this destructor results in linking errors with the Intel compiler 405 // (in Debug builds only, tested with icpc (ICC) 2021.1 Beta 20200827) 406 ~PublicistB() override{}; // NOLINT(modernize-use-equals-default) 407 using ProtectedB::foo; 408 using ProtectedB::get_self; 409 using ProtectedB::void_foo; 410 }; 411 412 m.def("read_foo", [](const void *original) { 413 const int *ptr = reinterpret_cast<const int *>(original); 414 return *ptr; 415 }); 416 417 m.def("pointers_equal", 418 [](const void *original, const void *comparison) { return original == comparison; }); 419 420 py::class_<ProtectedB, TrampolineB>(m, "ProtectedB") 421 .def(py::init<>()) 422 .def("foo", &PublicistB::foo) 423 .def("void_foo", &PublicistB::void_foo) 424 .def("get_self", &PublicistB::get_self); 425 426 // test_brace_initialization 427 struct BraceInitialization { 428 int field1; 429 std::string field2; 430 }; 431 432 py::class_<BraceInitialization>(m, "BraceInitialization") 433 .def(py::init<int, const std::string &>()) 434 .def_readwrite("field1", &BraceInitialization::field1) 435 .def_readwrite("field2", &BraceInitialization::field2); 436 // We *don't* want to construct using braces when the given constructor argument maps to a 437 // constructor, because brace initialization could go to the wrong place (in particular when 438 // there is also an `initializer_list<T>`-accept constructor): 439 py::class_<NoBraceInitialization>(m, "NoBraceInitialization") 440 .def(py::init<std::vector<int>>()) 441 .def_readonly("vec", &NoBraceInitialization::vec); 442 443 // test_reentrant_implicit_conversion_failure 444 // #1035: issue with runaway reentrant implicit conversion 445 struct BogusImplicitConversion { 446 BogusImplicitConversion(const BogusImplicitConversion &) = default; 447 }; 448 449 py::class_<BogusImplicitConversion>(m, "BogusImplicitConversion") 450 .def(py::init<const BogusImplicitConversion &>()); 451 452 py::implicitly_convertible<int, BogusImplicitConversion>(); 453 454 // test_qualname 455 // #1166: nested class docstring doesn't show nested name 456 // Also related: tests that __qualname__ is set properly 457 struct NestBase {}; 458 struct Nested {}; 459 py::class_<NestBase> base(m, "NestBase"); 460 base.def(py::init<>()); 461 py::class_<Nested>(base, "Nested") 462 .def(py::init<>()) 463 .def("fn", [](Nested &, int, NestBase &, Nested &) {}) 464 .def( 465 "fa", [](Nested &, int, NestBase &, Nested &) {}, "a"_a, "b"_a, "c"_a); 466 base.def("g", [](NestBase &, Nested &) {}); 467 base.def("h", []() { return NestBase(); }); 468 469 // test_error_after_conversion 470 // The second-pass path through dispatcher() previously didn't 471 // remember which overload was used, and would crash trying to 472 // generate a useful error message 473 474 struct NotRegistered {}; 475 struct StringWrapper { 476 std::string str; 477 }; 478 m.def("test_error_after_conversions", [](int) {}); 479 m.def("test_error_after_conversions", 480 [](const StringWrapper &) -> NotRegistered { return {}; }); 481 py::class_<StringWrapper>(m, "StringWrapper").def(py::init<std::string>()); 482 py::implicitly_convertible<std::string, StringWrapper>(); 483 484 #if defined(PYBIND11_CPP17) 485 struct alignas(1024) Aligned { 486 std::uintptr_t ptr() const { return (uintptr_t) this; } 487 }; 488 py::class_<Aligned>(m, "Aligned").def(py::init<>()).def("ptr", &Aligned::ptr); 489 #endif 490 491 // test_final 492 struct IsFinal final {}; 493 py::class_<IsFinal>(m, "IsFinal", py::is_final()); 494 495 // test_non_final_final 496 struct IsNonFinalFinal {}; 497 py::class_<IsNonFinalFinal>(m, "IsNonFinalFinal", py::is_final()); 498 499 // test_exception_rvalue_abort 500 struct PyPrintDestructor { 501 PyPrintDestructor() = default; 502 ~PyPrintDestructor() { py::print("Print from destructor"); } 503 void throw_something() { throw std::runtime_error("error"); } 504 }; 505 py::class_<PyPrintDestructor>(m, "PyPrintDestructor") 506 .def(py::init<>()) 507 .def("throw_something", &PyPrintDestructor::throw_something); 508 509 // test_multiple_instances_with_same_pointer 510 struct SamePointer {}; 511 static SamePointer samePointer; 512 py::class_<SamePointer, std::unique_ptr<SamePointer, py::nodelete>>(m, "SamePointer") 513 .def(py::init([]() { return &samePointer; })); 514 515 struct Empty {}; 516 py::class_<Empty>(m, "Empty").def(py::init<>()); 517 518 // test_base_and_derived_nested_scope 519 struct BaseWithNested { 520 struct Nested {}; 521 }; 522 523 struct DerivedWithNested : BaseWithNested { 524 struct Nested {}; 525 }; 526 527 py::class_<BaseWithNested> baseWithNested_class(m, "BaseWithNested"); 528 py::class_<DerivedWithNested, BaseWithNested> derivedWithNested_class(m, "DerivedWithNested"); 529 py::class_<BaseWithNested::Nested>(baseWithNested_class, "Nested") 530 .def_static("get_name", []() { return "BaseWithNested::Nested"; }); 531 py::class_<DerivedWithNested::Nested>(derivedWithNested_class, "Nested") 532 .def_static("get_name", []() { return "DerivedWithNested::Nested"; }); 533 534 // test_register_duplicate_class 535 struct Duplicate {}; 536 struct OtherDuplicate {}; 537 struct DuplicateNested {}; 538 struct OtherDuplicateNested {}; 539 540 m.def("register_duplicate_class_name", [](const py::module_ &m) { 541 py::class_<Duplicate>(m, "Duplicate"); 542 py::class_<OtherDuplicate>(m, "Duplicate"); 543 }); 544 m.def("register_duplicate_class_type", [](const py::module_ &m) { 545 py::class_<OtherDuplicate>(m, "OtherDuplicate"); 546 py::class_<OtherDuplicate>(m, "YetAnotherDuplicate"); 547 }); 548 m.def("register_duplicate_nested_class_name", [](const py::object >) { 549 py::class_<DuplicateNested>(gt, "DuplicateNested"); 550 py::class_<OtherDuplicateNested>(gt, "DuplicateNested"); 551 }); 552 m.def("register_duplicate_nested_class_type", [](const py::object >) { 553 py::class_<OtherDuplicateNested>(gt, "OtherDuplicateNested"); 554 py::class_<OtherDuplicateNested>(gt, "YetAnotherDuplicateNested"); 555 }); 556 557 test_class::pr4220_tripped_over_this::bind_empty0(m); 558 } 559 560 template <int N> 561 class BreaksBase { 562 public: 563 virtual ~BreaksBase() = default; 564 BreaksBase() = default; 565 BreaksBase(const BreaksBase &) = delete; 566 }; 567 template <int N> 568 class BreaksTramp : public BreaksBase<N> {}; 569 // These should all compile just fine: 570 using DoesntBreak1 = py::class_<BreaksBase<1>, std::unique_ptr<BreaksBase<1>>, BreaksTramp<1>>; 571 using DoesntBreak2 = py::class_<BreaksBase<2>, BreaksTramp<2>, std::unique_ptr<BreaksBase<2>>>; 572 using DoesntBreak3 = py::class_<BreaksBase<3>, std::unique_ptr<BreaksBase<3>>>; 573 using DoesntBreak4 = py::class_<BreaksBase<4>, BreaksTramp<4>>; 574 using DoesntBreak5 = py::class_<BreaksBase<5>>; 575 using DoesntBreak6 = py::class_<BreaksBase<6>, std::shared_ptr<BreaksBase<6>>, BreaksTramp<6>>; 576 using DoesntBreak7 = py::class_<BreaksBase<7>, BreaksTramp<7>, std::shared_ptr<BreaksBase<7>>>; 577 using DoesntBreak8 = py::class_<BreaksBase<8>, std::shared_ptr<BreaksBase<8>>>; 578 #define CHECK_BASE(N) \ 579 static_assert(std::is_same<typename DoesntBreak##N::type, BreaksBase<(N)>>::value, \ 580 "DoesntBreak" #N " has wrong type!") 581 CHECK_BASE(1); 582 CHECK_BASE(2); 583 CHECK_BASE(3); 584 CHECK_BASE(4); 585 CHECK_BASE(5); 586 CHECK_BASE(6); 587 CHECK_BASE(7); 588 CHECK_BASE(8); 589 #define CHECK_ALIAS(N) \ 590 static_assert( \ 591 DoesntBreak##N::has_alias \ 592 && std::is_same<typename DoesntBreak##N::type_alias, BreaksTramp<(N)>>::value, \ 593 "DoesntBreak" #N " has wrong type_alias!") 594 #define CHECK_NOALIAS(N) \ 595 static_assert(!DoesntBreak##N::has_alias \ 596 && std::is_void<typename DoesntBreak##N::type_alias>::value, \ 597 "DoesntBreak" #N " has type alias, but shouldn't!") 598 CHECK_ALIAS(1); 599 CHECK_ALIAS(2); 600 CHECK_NOALIAS(3); 601 CHECK_ALIAS(4); 602 CHECK_NOALIAS(5); 603 CHECK_ALIAS(6); 604 CHECK_ALIAS(7); 605 CHECK_NOALIAS(8); 606 #define CHECK_HOLDER(N, TYPE) \ 607 static_assert(std::is_same<typename DoesntBreak##N::holder_type, \ 608 std::TYPE##_ptr<BreaksBase<(N)>>>::value, \ 609 "DoesntBreak" #N " has wrong holder_type!") 610 CHECK_HOLDER(1, unique); 611 CHECK_HOLDER(2, unique); 612 CHECK_HOLDER(3, unique); 613 CHECK_HOLDER(4, unique); 614 CHECK_HOLDER(5, unique); 615 CHECK_HOLDER(6, shared); 616 CHECK_HOLDER(7, shared); 617 CHECK_HOLDER(8, shared); 618 619 // There's no nice way to test that these fail because they fail to compile; leave them here, 620 // though, so that they can be manually tested by uncommenting them (and seeing that compilation 621 // failures occurs). 622 623 // We have to actually look into the type: the typedef alone isn't enough to instantiate the type: 624 #define CHECK_BROKEN(N) \ 625 static_assert(std::is_same<typename Breaks##N::type, BreaksBase<-(N)>>::value, \ 626 "Breaks1 has wrong type!"); 627 628 #ifdef PYBIND11_NEVER_DEFINED_EVER 629 // Two holder classes: 630 typedef py:: 631 class_<BreaksBase<-1>, std::unique_ptr<BreaksBase<-1>>, std::unique_ptr<BreaksBase<-1>>> 632 Breaks1; 633 CHECK_BROKEN(1); 634 // Two aliases: 635 typedef py::class_<BreaksBase<-2>, BreaksTramp<-2>, BreaksTramp<-2>> Breaks2; 636 CHECK_BROKEN(2); 637 // Holder + 2 aliases 638 typedef py:: 639 class_<BreaksBase<-3>, std::unique_ptr<BreaksBase<-3>>, BreaksTramp<-3>, BreaksTramp<-3>> 640 Breaks3; 641 CHECK_BROKEN(3); 642 // Alias + 2 holders 643 typedef py::class_<BreaksBase<-4>, 644 std::unique_ptr<BreaksBase<-4>>, 645 BreaksTramp<-4>, 646 std::shared_ptr<BreaksBase<-4>>> 647 Breaks4; 648 CHECK_BROKEN(4); 649 // Invalid option (not a subclass or holder) 650 typedef py::class_<BreaksBase<-5>, BreaksTramp<-4>> Breaks5; 651 CHECK_BROKEN(5); 652 // Invalid option: multiple inheritance not supported: 653 template <> 654 struct BreaksBase<-8> : BreaksBase<-6>, BreaksBase<-7> {}; 655 typedef py::class_<BreaksBase<-8>, BreaksBase<-6>, BreaksBase<-7>> Breaks8; 656 CHECK_BROKEN(8); 657 #endif